Beispiel #1
0
 def approx_cost_df(self,xopt):
     '''
         A discrete approximation to the cost fn and its derivative
         
         Mainly useful for testing as it can be done faster
         
         If DerApproximator is not available, the 'full'
         cost function is returned, which doesn't allow a test.
         Check log file or try:
         
             from DerApproximator import get_d1
         
         if you are concerned about that.
         
         '''
     try:
         from DerApproximator import get_d1
     except:
         self.confs.logger.error(\
                                 "Cannot import DerApproximator for derivative approx'")
         J = self.cost(xopt)
         J_prime = self.cost_df(xopt)
         self.J_prime_approx = J_prime.flatten()
         return self.J_prime_approx
     
     self.J_prime_approx = get_d1(self.cost,xopt)
     return self.J_prime_approx
Beispiel #2
0
    def approx_cost_df(self, xopt):
        '''
            A discrete approximation to the cost fn and its derivative
            
            Mainly useful for testing as it can be done faster
            
            If DerApproximator is not available, the 'full'
            cost function is returned, which doesn't allow a test.
            Check log file or try:
            
                from DerApproximator import get_d1
            
            if you are concerned about that.
            
            '''
        try:
            from DerApproximator import get_d1
        except:
            self.confs.logger.error(\
                                    "Cannot import DerApproximator for derivative approx'")
            J = self.cost(xopt)
            J_prime = self.cost_df(xopt)
            self.J_prime_approx = J_prime.flatten()
            return self.J_prime_approx

        self.J_prime_approx = get_d1(self.cost, xopt)
        return self.J_prime_approx
Beispiel #3
0
    def check(f, f_grad, x0, name, verbose=False):
        """
        Checks whether gradients of function ``f`` at point x0 is same as the gradients provided by ``f_grad``.
        ``error`` is the difference between numerical and provided gradients.
         '%error' = abs(error) / numerical gradient.

        Parameters
        ----------
        f : callable
         input function to check gradients against

        f_grad : callable
         input function which provides gradients

        x0 : ndarray
         the point at which gradients should be calculated

        name : list
         a vector with the size of the number of parameters, which provides name for each parameter. This
         name will be used when generating output table

        verbose : boolean
         whether to print output for each parameter separately

        Returns
        -------
        avg : float
         average of the percentage error over all the parameters, i.e., mean(%error)
        """

        g = f_grad(x0)
        if len(g) != len(x0):
            raise Exception('dimensions mismatch')
        table = Texttable()
        table.set_cols_align(["l", "r", "c", "c", "c"])
        table.set_cols_valign(["t", "m", "b" , "r", "c"])
        rows = []
        rows += [["Name  ", "analytical  ", "numerical   ", "error   ", "% error   "]]
        if verbose:
            print 'dimensions:', len(x0)
        aver_error = 0
        for i in range(len(x0)):
            def f_i(x):
                return f((concatenate((x0[:i], x, x0[(i+1):]))))
            t = get_d1(f_i, [x0[i]])
            p_errro=None
            if t != 0:
                p_errro = abs(t-g[i]) / abs(t)
            rows += [[name[i], g[i], t, abs(t-g[i]), p_errro]]
            if abs(g[i]) <1e-4 and abs(t) < 1e-4:
                pass
            else:
                aver_error += abs(t-g[i]) / abs(t)
            if verbose:
                print 'element:', i
        table.add_rows(rows)
        if verbose:
            print(table.draw())
        return aver_error / len(x0)
Beispiel #4
0
from numpy import *
from DerApproximator import get_d1
func = lambda x: (x**4).sum()
x = arange(1.0, 6.0)

r1 = get_d1(func, x, stencil=1, diffInt=1e-4)
print(
    r1
)  # [   4.00060004   32.00240008  108.00540012  256.00960016  500.0150002 ]
r2 = get_d1(func, x, stencil=2, diffInt=1e-4)
print(
    r2
)  # [   4.00000004   32.00000008  108.00000012  256.00000016  500.0000002 ]
r3 = get_d1(func, x, stencil=3, diffInt=1e-4)
print(r3)  # [   4.   32.  108.  256.  500.]
Beispiel #5
0
def A_n_analytical(Z_f):
    Z_shaped = Z_f.reshape((M, Dim))
    An = mdot(kernel.K(X[np.newaxis, n,:], Z_shaped), inv(kernel.K(Z_shaped, Z_shaped)))
    # return kernel.gradients_X_(mdot(inv(kernel.K(Z_shaped, Z_shaped)), O), Z_shaped, X[np.newaxis, n,:])- \
    return        kernel.gradients_X(mdot(An.T, mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).T ), Z_shaped)

def A_n_analytical_vec(Z_f):
    Z_shaped = Z_f.reshape((M, Dim))
    A = mdot(kernel.K(X, Z_shaped), inv(kernel.K(Z_shaped, Z_shaped)))
    An = mdot(kernel.K(X[np.newaxis, n,:], Z_shaped), inv(kernel.K(Z_shaped, Z_shaped)))
    # return (kernel.get_gradients_X_AK(mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).repeat(N, 1), Z_shaped, X)) - \
    return            kernel.get_gradients_X_SKD(A, mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).repeat(N, 1), Z_shaped)[1,:,:]


print get_d1(A_n, Z.flatten()).reshape((M, Dim))

print

print A_n_analytical(Z.flatten())

print A_n_analytical_vec(Z.flatten())

O1 = np.random.normal(0, 1,  M) \
            .reshape((M, 1))

O2 = np.random.normal(0, 1,  M) \
            .reshape((M, 1))

OO = np.random.normal(0, 1,  M * M) \
            .reshape((M, M))
Beispiel #6
0
    def wrapped_func(p, x, IND, userFunctionType, ignorePrev,
                     getDerivative):  #, _linePointDescriptor = None):
        if isinstance(x, dict):
            if not p.isFDmodel:
                p.err(
                    'calling the function with argument of type dict is allowed for FuncDesigner models only'
                )
            x = p._point2vector(x)
        if not getattr(p.userProvided, userFunctionType): return array([])
        if p.istop == USER_DEMAND_EXIT:
            if p.solver.useStopByException:
                raise killThread
            else:
                return nan

        if getDerivative and not p.isFDmodel and not DerApproximatorIsInstalled:
            p.err(
                'For the problem you should have DerApproximator installed, see http://openopt.org/DerApproximator'
            )

        #userFunctionType should be 'f', 'c', 'h'
        funcs = getattr(p.user, userFunctionType)
        #funcs_num = getattr(p, 'n'+userFunctionType)
        if IND is not None:
            ind = p.getCorrectInd(IND)
        else:
            ind = None

        # this line had been added because some solvers pass tuple instead of
        # x being vector p.n x 1 or matrix X=[x1 x2 x3...xk], size(X)=[p.n, k]
        if not isspmatrix(x):
            x = atleast_1d(x)
#            if not str(x.dtype).startswith('float'):
#                x = asfarray(x)
        else:
            if p.debug:
                p.pWarn(
                    '[oo debug] sparse matrix x in nonlinfuncs.py has been encountered'
                )

#        if not ignorePrev:
#            prevKey = p.prevVal[userFunctionType]['key']
#        else:
#            prevKey = None
#
#        # TODO: move it into runprobsolver or baseproblem
#        if p.prevVal[userFunctionType]['val'] is None:
#            p.prevVal[userFunctionType]['val'] = zeros(getattr(p, 'n'+userFunctionType))
#
#        if prevKey is not None and p.iter > 0 and array_equal(x,  prevKey) and ind is None and not ignorePrev:
#            #TODO: add counter of the situations
#            if not getDerivative:
#                r = copy(p.prevVal[userFunctionType]['val'])
#                #if p.debug: assert array_equal(r,  p.wrapped_func(x, IND, userFunctionType, True, getDerivative))
#                if ind is not None: r = r[ind]
#
#                if userFunctionType == 'f':
#                    if p.isObjFunValueASingleNumber: r = r.sum(0)
#                    if p.invertObjFunc: r = -r
#                    if  p.solver.funcForIterFcnConnection=='f' and any(isnan(x)):
#                        p.nEvals['f'] += 1
#
#                        if p.nEvals['f']%p.f_iter == 0:
#                            p.iterfcn(x, fk = r)
#                return r

        args = getattr(p.args, userFunctionType)

        # TODO: handle it in prob prepare
        if not hasattr(p, 'n' + userFunctionType):
            setNonLinFuncsNumber(p, userFunctionType)

        #        if ind is None:
        #            nFuncsToObtain = getattr(p, 'n'+ userFunctionType)
        #        else:
        #            nFuncsToObtain = len(ind)

        if x.shape[0] != p.n and (x.ndim < 2 or x.shape[1] != p.n):
            p.err('x with incorrect shape passed to non-linear function')

        #TODO: code cleanup (below)
        if getDerivative or x.ndim <= 1 or x.shape[0] == 1:
            nXvectors = 1
            x_0 = copy(x)
        else:
            nXvectors = x.shape[0]

        # TODO: use certificate instead
        if p.isFDmodel:
            if getDerivative:
                if p.freeVars is None or (p.fixedVars is not None and
                                          len(p.freeVars) < len(p.fixedVars)):
                    funcs2 = [(lambda x, i=i: \
                      p._pointDerivative2array(
                                               funcs[i].D(x, Vars = p.freeVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True),
                                               useSparse=p.useSparse, func=funcs[i], point=x)) \
                      for i in range(len(funcs))]
                else:
                    funcs2 = [(lambda x, i=i: \
                      p._pointDerivative2array(
                                               funcs[i].D(x, fixedVars = p.fixedVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True),
                                               useSparse=p.useSparse, func=funcs[i], point=x)) \
                      for i in range(len(funcs))]
            else:
                if p.freeVars is None or (p.fixedVars is not None and
                                          len(p.freeVars) < len(p.fixedVars)):
                    funcs2 = [(lambda x, i=i: \
                               funcs[i]._getFuncCalcEngine(x, Vars = p.freeVars, fixedVarsScheduleID=p._FDVarsID))\
                      for i in range(len(funcs))]
                else:
                    funcs2 = [(lambda x, i=i: \
                               funcs[i]._getFuncCalcEngine(x, fixedVars = p.fixedVars, fixedVarsScheduleID=p._FDVarsID))\
                      for i in range(len(funcs))]
        else:
            funcs2 = funcs

        if ind is None:
            Funcs = funcs2
        elif ind is not None and p.functype[
                userFunctionType] == 'some funcs R^nvars -> R':
            Funcs = [funcs2[i] for i in ind]
        else:
            Funcs = getFuncsAndExtractIndexes(p, funcs2, ind, userFunctionType)

#        agregate_counter = 0

        Args = () if p.isFDmodel else args

        if nXvectors == 1:
            if p.isFDmodel:
                X = p._vector2point(x)
                X._p = p
                #X._linePointDescriptor = _linePointDescriptor
            else:
                X = x

        if nXvectors > 1:  # and hence getDerivative isn't involved
            #temporary, to be fixed
            if userFunctionType == 'f':
                assert p.isObjFunValueASingleNumber

            if p.isFDmodel:
                assert ind is None
                if isPyPy or p.hasVectorizableFuncs:  # TODO: get rid of box-bound constraints
                    from FuncDesigner.ooPoint import ooPoint as oopoint
                    from FuncDesigner.multiarray import multiarray

                    # TODO: new
                    xx = []
                    counter = 0
                    #xT = x.T
                    for i, oov in enumerate(p._freeVarsList):
                        s = p._optVarSizes[oov]
                        xx.append(
                            (oov,
                             (x[:, counter:counter + s].flatten() if s == 1
                              else x[:,
                                     counter:counter + s]).view(multiarray)))
                        #                        xx.append((oov, multiarray(x[:, counter: counter + s].flatten() if s == 1 else x[:, counter: counter + s])))
                        counter += s
                    X = oopoint(xx)
                    X.update(p.dictOfFixedFuncs)
                    X.maxDistributionSize = p.maxDistributionSize
                    X._p = p
                if len(p.unvectorizableFuncs) != 0:
                    XX = [p._vector2point(x[i]) for i in range(nXvectors)]
                    for _X in XX:
                        _X._p = p
                        _X.update(p.dictOfFixedFuncs)

                r = vstack([[fun(xx) for xx in XX]
                            if funcs[i] in p.unvectorizableFuncs else fun(X).T
                            for i, fun in enumerate(Funcs)]).T

#                X = [p._vector2point(x[i]) for i in range(nXvectors)]
#                r = hstack([[fun(xx) for xx in X] for fun in Funcs]).reshape(1, -1)

#new
#                if p.vectorizable:
#                    from FuncDesigner.ooPoint import ooPoint as oopoint, multiarray
#
#                    X = dict([(oovar, x[:, i].view(multiarray)) for i, oovar in enumerate(p._freeVarsList)])
#                    X = oopoint(X, skipArrayCast = True)
#                    X.N = nXvectors
#                    X.isMultiPoint = True
#                    X.update(p.dictOfFixedFuncs)
#                    r = hstack([fun(X) for fun in Funcs]).reshape(1, -1)
#
#                #old
#                else:
#                    X = [p._vector2point(x[i]) for i in range(nXvectors)]
#                    r = hstack([[fun(xx) for xx in X] for fun in Funcs]).reshape(1, -1)
            else:
                X = [(x[i], ) + Args for i in range(nXvectors)]

                #r = hstack([[fun(*xx) for xx in X] for fun in Funcs])
                R = []
                for xx in X:
                    tmp = [fun(*xx) for fun in Funcs]
                    r_ = hstack(tmp[0]) if len(tmp) == 1 and isinstance(
                        tmp[0],
                        (list,
                         tuple)) else hstack(tmp) if len(tmp) > 1 else tmp[0]
                    R.append(r_)

                r = hstack(R)  #.T
                #print(r.shape, userFunctionType)

        elif not getDerivative:
            tmp = [fun(*(X, ) + Args) for fun in Funcs]
            r = hstack(tmp[0]) if len(tmp) == 1 and isinstance(
                tmp[0],
                (list, tuple)) else hstack(tmp) if len(tmp) > 1 else tmp[0]

            #print(x.shape, r.shape, x, r)
#            if not ignorePrev and ind is None:
#                p.prevVal[userFunctionType]['key'] = copy(x_0)
#                p.prevVal[userFunctionType]['val'] = r.copy()
        elif getDerivative and p.isFDmodel:
            rr = [fun(X) for fun in Funcs]
            r = Vstack(rr) if scipyInstalled and any(
                [isspmatrix(elem) for elem in rr]) else vstack(rr)
        else:
            r = []
            if getDerivative:
                #r = zeros((nFuncsToObtain, p.n))
                diffInt = p.diffInt
                abs_x = abs(x)
                finiteDiffNumbers = 1e-10 * abs_x
                if p.diffInt.size == 1:
                    finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt
                else:
                    finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt[
                        finiteDiffNumbers < diffInt]
            else:
                #r = zeros((nFuncsToObtain, nXvectors))
                r = []

            for index, fun in enumerate(Funcs):
                # OLD
                #                v = ravel(fun(*((X,) + Args)))
                #                if  (ind is None or funcs_num == 1) and not ignorePrev:
                #                    #TODO: ADD COUNTER OF THE CASE
                #                    if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0)
                #                    p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy()
                #                r[agregate_counter:agregate_counter+v.size,0] = v

                #NEW

                if not getDerivative:
                    r.append(fun(*((X, ) + Args)))
#                    v = r[-1]
#r[agregate_counter:agregate_counter+v.size,0] = fun(*((X,) + Args))

#                if (ind is None or funcs_num == 1) and not ignorePrev:
#                    #TODO: ADD COUNTER OF THE CASE
#                    if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0)
#                    p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy()
                """                                                 getting derivatives                                                 """
                if getDerivative:

                    def func(x):
                        r = fun(*((x, ) + Args))
                        return r if type(r) not in (
                            list, tuple) or len(r) != 1 else r[0]

                    d1 = get_d1(func,
                                x,
                                pointVal=None,
                                diffInt=finiteDiffNumbers,
                                stencil=p.JacobianApproximationStencil,
                                exactShape=True)
                    #r[agregate_counter:agregate_counter+d1.size] = d1
                    r.append(d1)
#                    v = r[-1]

#                agregate_counter += atleast_1d(v).shape[0]
            r = hstack(r) if not getDerivative else vstack(r)
            #assert r.size != 30
        #if type(r) == matrix: r = r.A

        if type(r) != ndarray and not isscalar(r):  # multiarray
            r = r.view(ndarray).flatten(
            ) if userFunctionType == 'f' else r.view(ndarray)
        #elif userFunctionType == 'f' and p.isObjFunValueASingleNumber and prod(r.shape) > 1 and (type(r) == ndarray or min(r.shape) > 1):
        #r = r.sum(0)
        elif userFunctionType == 'f' and p.isObjFunValueASingleNumber and not isscalar(
                r):
            if prod(r.shape) > 1 and not getDerivative and nXvectors == 1:
                p.err(
                    'implicit summation in objective is no longer available to prevent possibly hidden bugs'
                )
#            if r.size == 1:
#                r = r.item()

        if userFunctionType == 'f' and p.isObjFunValueASingleNumber:
            if getDerivative and r.ndim > 1:
                if min(r.shape) > 1:
                    p.err('incorrect shape of objective func derivative')

                # TODO: omit cast to dense array. Somewhere bug triggers?
                if hasattr(r, 'toarray'):
                    r = r.toarray()
                r = r.flatten()

        if userFunctionType != 'f' and nXvectors != 1:
            r = r.reshape(nXvectors, int(r.size / nXvectors))
#        if type(r) == matrix:
#            raise 0
#            r = r.A # if _dense_numpy_matrix !

        if nXvectors == 1 and (not getDerivative or prod(
                r.shape) == 1):  # DO NOT REPLACE BY r.size - r may be sparse!
            r = r.flatten() if type(r) == ndarray else r.toarray().flatten(
            ) if not isscalar(r) else atleast_1d(r)

        if p.invertObjFunc and userFunctionType == 'f':
            r = -r

        if not getDerivative:
            if ind is None:
                p.nEvals[userFunctionType] += nXvectors
            else:
                p.nEvals[userFunctionType] = p.nEvals[userFunctionType] + float(
                    nXvectors * len(ind)) / getattr(p, 'n' + userFunctionType)

        if getDerivative:
            assert x.size == p.n  #TODO: add python list possibility here
            x = x_0  # for to suppress numerical instability effects while x +/- delta_x

        #if userFunctionType == 'f' and p.isObjFunValueASingleNumber and r.size == 1:
        #r = r.item()

        if userFunctionType == 'f' and hasattr(
                p, 'solver'
        ) and p.solver.funcForIterFcnConnection == 'f' and hasattr(
                p, 'f_iter') and not getDerivative:
            if p.nEvals['f'] % p.f_iter == 0 or nXvectors > 1:
                p.iterfcn(x, r)

        return r
Beispiel #7
0
def getDerivativeSelf(Self, x, fixedVarsScheduleID, Vars, fixedVars):
    Input = Self._getInput(x,
                           fixedVarsScheduleID=fixedVarsScheduleID,
                           Vars=Vars,
                           fixedVars=fixedVars)
    expectedTotalInputLength = sum([Len(elem) for elem in Input])

    #        if hasattr(Self, 'size') and isscalar(Self.size): nOutput = Self.size
    #        else: nOutput = Self(x).size

    hasUserSuppliedDerivative = Self.d is not None
    if hasUserSuppliedDerivative:
        derivativeSelf = []
        if type(Self.d) == tuple:
            if len(Self.d) != len(Self.input):
                raise FuncDesignerException(
                    'oofun error: num(derivatives) not equal to neither 1 nor num(inputs)'
                )

            for i, deriv in enumerate(Self.d):
                inp = Self.input[i]
                if not isinstance(inp, OOFun) or inp.discrete:
                    #if deriv is not None:
                    #raise FuncDesignerException('For an oofun with some input oofuns declared as discrete you have to set oofun.d[i] = None')
                    continue

                #!!!!!!!!! TODO: handle fixed cases properly!!!!!!!!!!!!
                #if hasattr(inp, 'fixed') and inp.fixed: continue
                if inp.is_oovar and (
                    (Vars is not None and inp not in Vars) or
                    (fixedVars is not None and inp in fixedVars)):
                    continue

                if deriv is None:
                    if not DerApproximatorIsInstalled:
                        raise FuncDesignerException(
                            'To perform gradients check you should have DerApproximator installed, see http://openopt.org/DerApproximator'
                        )
                    derivativeSelf.append(get_d1(Self.fun, Input, diffInt=Self.diffInt, stencil = Self.stencil, \
                                                 args=Self.args, varForDifferentiation = i, pointVal = Self._getFuncCalcEngine(x), exactShape = True))
                else:
                    # !!!!!!!!!!!!!! TODO: add check for user-supplied derivative shape
                    tmp = deriv(*Input)
                    if not isscalar(tmp) and type(tmp) in (
                            ndarray, tuple, list
                    ) and type(
                            tmp
                    ) != DiagonalType:  # i.e. not a scipy.sparse matrix
                        tmp = atleast_2d(tmp)

                        ########################################

                        _tmp = Input[i]
                        Tmp = 1 if isscalar(_tmp) or prod(
                            _tmp.shape) == 1 else len(Input[i])
                        if tmp.shape[1] != Tmp:
                            # TODO: add debug msg
                            #                                print('incorrect shape in FD AD _getDerivativeSelf')
                            #                                print tmp.shape[0], nOutput, tmp
                            if tmp.shape[0] != Tmp:
                                raise FuncDesignerException(
                                    'error in getDerivativeSelf()')
                            tmp = tmp.T

                        ########################################

                    derivativeSelf.append(tmp)
        else:
            tmp = Self.d(*Input)
            if not isscalar(tmp) and type(tmp) in (
                    ndarray, tuple, list):  # i.e. not a scipy.sparse matrix
                tmp = atleast_2d(tmp)

                if tmp.shape[1] != expectedTotalInputLength:
                    # TODO: add debug msg
                    if tmp.shape[0] != expectedTotalInputLength:
                        raise FuncDesignerException(
                            'error in getDerivativeSelf()')
                    tmp = tmp.T

            ac = 0
            if isinstance(tmp, ndarray) and hasattr(
                    tmp, 'toarray') and not isinstance(tmp, multiarray):
                tmp = tmp.A  # is dense matrix

            #if not isinstance(tmp, ndarray) and not isscalar(tmp) and type(tmp) != DiagonalType:
            if len(Input) == 1:
                #                    if type(tmp) == DiagonalType:
                #                            # TODO: mb rework it
                #                            if Input[0].size > 150 and tmp.size > 150:
                #                                tmp = tmp.resolve(True).tocsc()
                #                            else: tmp =  tmp.resolve(False)
                derivativeSelf = [tmp]
            else:
                for i, inp in enumerate(Input):
                    t = Self.input[i]
                    if t.discrete or (t.is_oovar and (
                        (Vars is not None and t not in Vars) or
                        (fixedVars is not None and t in fixedVars))):
                        ac += inp.size
                        continue
                    if isinstance(tmp, ndarray):
                        TMP = tmp[:, ac:ac + Len(inp)]
                    elif isscalar(tmp):
                        TMP = tmp
                    elif type(tmp) == DiagonalType:
                        if tmp.size == inp.size and ac == 0:
                            TMP = tmp
                        else:
                            # print debug warning here
                            # TODO: mb rework it
                            if inp.size > 150 and tmp.size > 150:
                                tmp = tmp.resolve(True).tocsc()
                            else:
                                tmp = tmp.resolve(False)
                            TMP = tmp[:, ac:ac + inp.size]
                    else:  # scipy.sparse matrix
                        TMP = tmp.tocsc()[:, ac:ac + inp.size]
                    ac += Len(inp)
                    derivativeSelf.append(TMP)

        # TODO: is it required?
#                if not hasattr(Self, 'outputTotalLength'): Self(x)
#
#                if derivativeSelf.shape != (Self.outputTotalLength, Self.inputTotalLength):
#                    s = 'incorrect shape for user-supplied derivative of oofun '+Self.name+': '
#                    s += '(%d, %d) expected, (%d, %d) obtained' % (Self.outputTotalLength, Self.inputTotalLength,  derivativeSelf.shape[0], derivativeSelf.shape[1])
#                    raise FuncDesignerException(s)
    else:
        if Vars is not None or (fixedVars is not None and len(fixedVars) != 0):
            raise FuncDesignerException(
                "sorry, custom oofun derivatives don't work with Vars/fixedVars arguments yet"
            )
        if not DerApproximatorIsInstalled:
            raise FuncDesignerException(
                'To perform this operation you should have DerApproximator installed, see http://openopt.org/DerApproximator'
            )

        derivativeSelf = get_d1(Self.fun,
                                Input,
                                diffInt=Self.diffInt,
                                stencil=Self.stencil,
                                args=Self.args,
                                pointVal=Self._getFuncCalcEngine(x),
                                exactShape=True)
        if type(derivativeSelf) == tuple:
            derivativeSelf = list(derivativeSelf)
        elif type(derivativeSelf) != list:
            derivativeSelf = [derivativeSelf]

    #assert all([elem.ndim > 1 for elem in derivativeSelf])

# assert len(derivativeSelf[0])!=16
#assert (type(derivativeSelf[0]) in (int, float)) or derivativeSelf[0][0]>480.00006752 or derivativeSelf[0][0]<480.00006750
    return derivativeSelf
Beispiel #8
0
             mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).T), Z_shaped)


def A_n_analytical_vec(Z_f):
    Z_shaped = Z_f.reshape((M, Dim))
    A = mdot(kernel.K(X, Z_shaped), inv(kernel.K(Z_shaped, Z_shaped)))
    An = mdot(kernel.K(X[np.newaxis, n, :], Z_shaped),
              inv(kernel.K(Z_shaped, Z_shaped)))
    # return (kernel.get_gradients_X_AK(mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).repeat(N, 1), Z_shaped, X)) - \
    return kernel.get_gradients_X_SKD(
        A,
        mdot(inv(kernel.K(Z_shaped, Z_shaped)), O).repeat(N, 1),
        Z_shaped)[1, :, :]


print get_d1(A_n, Z.flatten()).reshape((M, Dim))

print

print A_n_analytical(Z.flatten())

print A_n_analytical_vec(Z.flatten())

O1 = np.random.normal(0, 1,  M) \
            .reshape((M, 1))

O2 = np.random.normal(0, 1,  M) \
            .reshape((M, 1))

OO = np.random.normal(0, 1,  M * M) \
            .reshape((M, M))
Beispiel #9
0
from numpy import *
from DerApproximator import get_d1
func = lambda x: (x**4).sum()
x = arange(1.0, 6.0)

r1 = get_d1(func, x, stencil = 1, diffInt = 1e-4)
print(r1) # [   4.00060004   32.00240008  108.00540012  256.00960016  500.0150002 ]
r2 = get_d1(func, x, stencil = 2, diffInt = 1e-4)
print(r2) # [   4.00000004   32.00000008  108.00000012  256.00000016  500.0000002 ]
r3 = get_d1(func, x, stencil = 3, diffInt = 1e-4)
print(r3) # [   4.   32.  108.  256.  500.]
Beispiel #10
0
    def wrapped_func(p, x, IND, userFunctionType, ignorePrev, getDerivative):#, _linePointDescriptor = None):
        if isinstance(x, dict):
            if not p.isFDmodel: p.err('calling the function with argument of type dict is allowed for FuncDesigner models only')
            x = p._point2vector(x)
        if not getattr(p.userProvided, userFunctionType): return array([])
        if p.istop == USER_DEMAND_EXIT:
            if p.solver.useStopByException:
                raise killThread
            else:
                return nan                
                
        if getDerivative and not p.isFDmodel and not DerApproximatorIsInstalled:
            p.err('For the problem you should have DerApproximator installed, see http://openopt.org/DerApproximator')

        #userFunctionType should be 'f', 'c', 'h'
        funcs = getattr(p.user, userFunctionType)
        #funcs_num = getattr(p, 'n'+userFunctionType)
        if IND is not None:
            ind = p.getCorrectInd(IND)
        else: ind = None

        # this line had been added because some solvers pass tuple instead of
        # x being vector p.n x 1 or matrix X=[x1 x2 x3...xk], size(X)=[p.n, k]
        if not isspmatrix(x): 
            x = atleast_1d(x)
#            if not str(x.dtype).startswith('float'):
#                x = asfarray(x)
        else:
            if p.debug:
                p.pWarn('[oo debug] sparse matrix x in nonlinfuncs.py has been encountered')
        
#        if not ignorePrev: 
#            prevKey = p.prevVal[userFunctionType]['key']
#        else:
#            prevKey = None
#            
#        # TODO: move it into runprobsolver or baseproblem
#        if p.prevVal[userFunctionType]['val'] is None:
#            p.prevVal[userFunctionType]['val'] = zeros(getattr(p, 'n'+userFunctionType))
#
#        if prevKey is not None and p.iter > 0 and array_equal(x,  prevKey) and ind is None and not ignorePrev:
#            #TODO: add counter of the situations
#            if not getDerivative:
#                r = copy(p.prevVal[userFunctionType]['val'])
#                #if p.debug: assert array_equal(r,  p.wrapped_func(x, IND, userFunctionType, True, getDerivative))
#                if ind is not None: r = r[ind]
#                
#                if userFunctionType == 'f':
#                    if p.isObjFunValueASingleNumber: r = r.sum(0)
#                    if p.invertObjFunc: r = -r
#                    if  p.solver.funcForIterFcnConnection=='f' and any(isnan(x)):
#                        p.nEvals['f'] += 1
#
#                        if p.nEvals['f']%p.f_iter == 0:
#                            p.iterfcn(x, fk = r)
#                return r

        args = getattr(p.args, userFunctionType)

        # TODO: handle it in prob prepare
        if not hasattr(p, 'n'+userFunctionType): setNonLinFuncsNumber(p,  userFunctionType)

#        if ind is None:
#            nFuncsToObtain = getattr(p, 'n'+ userFunctionType)
#        else:
#            nFuncsToObtain = len(ind)

        if x.shape[0] != p.n and (x.ndim<2 or x.shape[1] != p.n): 
            p.err('x with incorrect shape passed to non-linear function')

        #TODO: code cleanup (below)
        if getDerivative or x.ndim <= 1 or x.shape[0] == 1:
            nXvectors = 1
            x_0 = copy(x)
        else:
            nXvectors = x.shape[0]

        # TODO: use certificate instead 
        if p.isFDmodel:
            if getDerivative:
                if p.freeVars is None or (p.fixedVars is not None and len(p.freeVars) < len(p.fixedVars)):
                    funcs2 = [(lambda x, i=i: \
                      p._pointDerivative2array(
                                               funcs[i].D(x, Vars = p.freeVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True), 
                                               useSparse=p.useSparse, func=funcs[i], point=x)) \
                      for i in range(len(funcs))]
                else:
                    funcs2 = [(lambda x, i=i: \
                      p._pointDerivative2array(
                                               funcs[i].D(x, fixedVars = p.fixedVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True), 
                                               useSparse=p.useSparse, func=funcs[i], point=x)) \
                      for i in range(len(funcs))]
            else:
                if p.freeVars is None or (p.fixedVars is not None and len(p.freeVars) < len(p.fixedVars)):
                    funcs2 = [(lambda x, i=i: \
                               funcs[i]._getFuncCalcEngine(x, Vars = p.freeVars, fixedVarsScheduleID=p._FDVarsID))\
                      for i in range(len(funcs))]
                else:
                    funcs2 = [(lambda x, i=i: \
                               funcs[i]._getFuncCalcEngine(x, fixedVars = p.fixedVars, fixedVarsScheduleID=p._FDVarsID))\
                      for i in range(len(funcs))]
        else:
            funcs2 = funcs
            
        if ind is None: 
            Funcs = funcs2
        elif ind is not None and p.functype[userFunctionType] == 'some funcs R^nvars -> R':
            Funcs = [funcs2[i] for i in ind]
        else:
            Funcs = getFuncsAndExtractIndexes(p, funcs2, ind, userFunctionType)

#        agregate_counter = 0
        
        Args = () if p.isFDmodel else args
            
        if nXvectors == 1:
            if p.isFDmodel:
                X = p._vector2point(x) 
                X._p = p
                #X._linePointDescriptor = _linePointDescriptor
            else:
                X = x
        
        if nXvectors > 1: # and hence getDerivative isn't involved
            #temporary, to be fixed
            if userFunctionType == 'f':
               assert p.isObjFunValueASingleNumber
            

            if p.isFDmodel:
                assert ind is None
                if isPyPy or p.hasVectorizableFuncs: # TODO: get rid of box-bound constraints
                    from FuncDesigner.ooPoint import ooPoint as oopoint
                    from FuncDesigner.multiarray import multiarray
                    
                    # TODO: new
                    xx = []
                    counter = 0
                    #xT = x.T
                    for i, oov in enumerate(p._freeVarsList):
                        s = p._optVarSizes[oov]
                        xx.append((oov, (x[:, counter: counter + s].flatten() if s == 1 else x[:, counter: counter + s]).view(multiarray)))
#                        xx.append((oov, multiarray(x[:, counter: counter + s].flatten() if s == 1 else x[:, counter: counter + s])))
                        counter += s
                    X = oopoint(xx)
                    X.update(p.dictOfFixedFuncs)
                    X.maxDistributionSize = p.maxDistributionSize
                    X._p = p
                if len(p.unvectorizableFuncs) != 0:
                    XX = [p._vector2point(x[i]) for i in range(nXvectors)]
                    for _X in XX: 
                        _X._p = p
                        _X.update(p.dictOfFixedFuncs)

                r = vstack([[fun(xx) for xx in XX] if funcs[i] in p.unvectorizableFuncs else fun(X).T for i, fun in enumerate(Funcs)]).T
                
                
#                X = [p._vector2point(x[i]) for i in range(nXvectors)]
#                r = hstack([[fun(xx) for xx in X] for fun in Funcs]).reshape(1, -1)

                #new 
#                if p.vectorizable:
#                    from FuncDesigner.ooPoint import ooPoint as oopoint, multiarray
#                    
#                    X = dict([(oovar, x[:, i].view(multiarray)) for i, oovar in enumerate(p._freeVarsList)])
#                    X = oopoint(X, skipArrayCast = True)
#                    X.N = nXvectors
#                    X.isMultiPoint = True
#                    X.update(p.dictOfFixedFuncs)
#                    r = hstack([fun(X) for fun in Funcs]).reshape(1, -1)
#                
#                #old
#                else:
#                    X = [p._vector2point(x[i]) for i in range(nXvectors)]
#                    r = hstack([[fun(xx) for xx in X] for fun in Funcs]).reshape(1, -1)
            else:
                X = [(x[i],) + Args for i in range(nXvectors)] 
                
                #r = hstack([[fun(*xx) for xx in X] for fun in Funcs])
                R = []
                for xx in X:
                    tmp = [fun(*xx) for fun in Funcs]
                    r_ = hstack(tmp[0]) if len(tmp) == 1 and isinstance(tmp[0], (list, tuple)) else hstack(tmp) if len(tmp) > 1 else tmp[0]
                    R.append(r_)
                
                r = hstack(R)#.T
                #print(r.shape, userFunctionType)
                
                
        elif not getDerivative:
            tmp = [fun(*(X, )+Args) for fun in Funcs]
            r = hstack(tmp[0]) if len(tmp) == 1 and isinstance(tmp[0], (list, tuple)) else hstack(tmp) if len(tmp) > 1 else tmp[0]
                
            #print(x.shape, r.shape, x, r)
#            if not ignorePrev and ind is None:
#                p.prevVal[userFunctionType]['key'] = copy(x_0)
#                p.prevVal[userFunctionType]['val'] = r.copy()                
        elif getDerivative and p.isFDmodel:
            rr = [fun(X) for fun in Funcs]
            r = Vstack(rr) if scipyInstalled and any([isspmatrix(elem) for elem in rr]) else vstack(rr)
        else:
            r = []
            if getDerivative:
                #r = zeros((nFuncsToObtain, p.n))
                diffInt = p.diffInt
                abs_x = abs(x)
                finiteDiffNumbers = 1e-10 * abs_x
                if p.diffInt.size == 1:
                    finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt
                else:
                    finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt[finiteDiffNumbers < diffInt]
            else:
                #r = zeros((nFuncsToObtain, nXvectors))
                r = []
            
            for index, fun in enumerate(Funcs):
                # OLD
#                v = ravel(fun(*((X,) + Args)))
#                if  (ind is None or funcs_num == 1) and not ignorePrev:
#                    #TODO: ADD COUNTER OF THE CASE
#                    if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0)
#                    p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy()                
#                r[agregate_counter:agregate_counter+v.size,0] = v
                
                #NEW
                
                if not getDerivative:
                    r.append(fun(*((X,) + Args)))
#                    v = r[-1]
                    #r[agregate_counter:agregate_counter+v.size,0] = fun(*((X,) + Args))
                    
#                if (ind is None or funcs_num == 1) and not ignorePrev:
#                    #TODO: ADD COUNTER OF THE CASE
#                    if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0)
#                    p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy()                
                
                

                """                                                 getting derivatives                                                 """
                if getDerivative:
                    def func(x):
                        r = fun(*((x,) + Args))
                        return r if type(r) not in (list, tuple) or len(r)!=1 else r[0]
                    d1 = get_d1(func, x, pointVal = None, diffInt = finiteDiffNumbers, stencil=p.JacobianApproximationStencil, exactShape=True)
                    #r[agregate_counter:agregate_counter+d1.size] = d1
                    r.append(d1)
#                    v = r[-1]
                    
#                agregate_counter += atleast_1d(v).shape[0]
            r = hstack(r) if not getDerivative else vstack(r)
            #assert r.size != 30
        #if type(r) == matrix: r = r.A

        if type(r) != ndarray and not isscalar(r): # multiarray
            r = r.view(ndarray).flatten() if userFunctionType == 'f' else r.view(ndarray)
        #elif userFunctionType == 'f' and p.isObjFunValueASingleNumber and prod(r.shape) > 1 and (type(r) == ndarray or min(r.shape) > 1): 
            #r = r.sum(0)
        elif userFunctionType == 'f' and p.isObjFunValueASingleNumber and not isscalar(r):
            if prod(r.shape) > 1 and not getDerivative and nXvectors == 1:
                p.err('implicit summation in objective is no longer available to prevent possibly hidden bugs')
#            if r.size == 1:
#                r = r.item()
        
        if userFunctionType == 'f' and p.isObjFunValueASingleNumber:
            if getDerivative and r.ndim > 1:
                if min(r.shape) > 1:
                    p.err('incorrect shape of objective func derivative')
                
                # TODO: omit cast to dense array. Somewhere bug triggers?
                if hasattr(r, 'toarray'):
                    r=r.toarray()
                r = r.flatten()

        if userFunctionType != 'f' and nXvectors != 1:
            r = r.reshape(nXvectors, int(r.size/nXvectors))
#        if type(r) == matrix: 
#            raise 0
#            r = r.A # if _dense_numpy_matrix !

        if nXvectors == 1 and (not getDerivative or prod(r.shape) == 1): # DO NOT REPLACE BY r.size - r may be sparse!
            r = r.flatten() if type(r) == ndarray else r.toarray().flatten() if not isscalar(r) else atleast_1d(r)
        
        if p.invertObjFunc and userFunctionType=='f':
            r = -r

        if not getDerivative:
            if ind is None:
                p.nEvals[userFunctionType] += nXvectors
            else:
                p.nEvals[userFunctionType] = p.nEvals[userFunctionType] + float(nXvectors * len(ind)) / getattr(p, 'n'+ userFunctionType)

        if getDerivative:
            assert x.size == p.n#TODO: add python list possibility here
            x = x_0 # for to suppress numerical instability effects while x +/- delta_x
        
        #if userFunctionType == 'f' and p.isObjFunValueASingleNumber and r.size == 1:
            #r = r.item()
        
        if userFunctionType == 'f' and hasattr(p, 'solver') and p.solver.funcForIterFcnConnection=='f' and hasattr(p, 'f_iter') and not getDerivative:
            if p.nEvals['f']%p.f_iter == 0 or nXvectors > 1:
                p.iterfcn(x, r)

        return r