Ejemplo n.º 1
0
def ad_Jacobian(F, x0):
    '''
    Computes Jacobian using automatic differentiation
    '''
    a_x = ad.independent(x0)
    a_F = F(a_x)
    return ad.adfun(a_x, a_F).jacobian(x0)
Ejemplo n.º 2
0
def MakeParameterization(plus_func, x0, delta0):

  global_size = len(x0)
  local_size  = len(delta0)

  in_var = pycppad.independent( np.hstack( [x0, delta0] ) )
  x_part, delta_part = np.split(in_var, [global_size])
  out_var = plus_func( x_part, delta_part )
  jac_func = pycppad.adfun(in_var, out_var).jacobian
  def jac_delta(x):
    inp = np.hstack( [x, np.zeros(local_size) ])
    J = check_nan(jac_func(inp))
    return J[:, global_size:]

  class AutoDiffLocalParameterization(LocalParameterization):
    def __init__(self):
      super(AutoDiffLocalParameterization, self).__init__()

    def Plus(self, x, delta):
      return plus_func(x, delta)

    def ComputeJacobian(self, x):
      return jac_delta(x)

    def GlobalSize(self):
      return global_size

    def LocalSize(self):
      return local_size

  return AutoDiffLocalParameterization
Ejemplo n.º 3
0
 def _create_tape(self, xVec):
     """
     Generate main CppAD tape
 
     Normally there is no need to call this function manually as tapes
     are generated as needed.
     """
     # Create derivative vector
     a_xVec = ad.independent(xVec)
     # perform actual calculation 
     # Linear contribution 
     a_out = np.dot(self.G, a_xVec)
     xin = np.zeros(len(xVec), dtype = type(a_out[0]))
     # Nonlinear contribution
     for elem in self.ckt.nD_nlinElem:
         # first have to retrieve port voltages from a_xVec
         xin[:len(elem.controlPorts)] = 0.
         #import pdb; pdb.set_trace()
         set_xin(xin, elem.nD_vpos, elem.nD_vneg, a_xVec)
         (outV, qVec) = elem.eval_cqs(xin)
         # Update iVec. outV may have extra charge elements but
         # they are not used in the following
         set_i(a_out, elem.nD_cpos, elem.nD_cneg, outV)
     # Save main function tape
     self._func = ad.adfun(a_xVec, a_out)
     # optimize main function tape
     self._func.optimize()
Ejemplo n.º 4
0
def ad_Jacobian(F,x0):
    '''
    Computes Jacobian using automatic differentiation
    '''
    a_x = ad.independent(x0)
    a_F = F(a_x)
    return ad.adfun(a_x,a_F).jacobian(x0)
Ejemplo n.º 5
0
 def _create_tape(self, xVec):
     """
     Generate main CppAD tape
 
     Normally there is no need to call this function manually as tapes
     are generated as needed.
     """
     # Create derivative vector
     a_xVec = ad.independent(xVec)
     # perform actual calculation
     # Linear contribution
     a_out = np.dot(self.G, a_xVec)
     xin = np.zeros(len(xVec), dtype=type(a_out[0]))
     # Nonlinear contribution
     for elem in self.ckt.nD_nlinElem:
         # first have to retrieve port voltages from a_xVec
         xin[:len(elem.controlPorts)] = 0.
         #import pdb; pdb.set_trace()
         set_xin(xin, elem.nD_vpos, elem.nD_vneg, a_xVec)
         (outV, qVec) = elem.eval_cqs(xin)
         # Update iVec. outV may have extra charge elements but
         # they are not used in the following
         set_i(a_out, elem.nD_cpos, elem.nD_cneg, outV)
     # Save main function tape
     self._func = ad.adfun(a_xVec, a_out)
     # optimize main function tape
     self._func.optimize()
Ejemplo n.º 6
0
    def _trace_cons(self, x):
        ax = pycppad.independent(x)
        ay = self.cons(ax)

        if not isinstance(ay, np.ndarray):
            ay = np.array([ay])

        self._cppad_adfun_cons = pycppad.adfun(ax, ay)
Ejemplo n.º 7
0
    def _trace_cons_pos(self, x):
        ax = pycppad.independent(x)
        ay = self.cons_pos(ax)

        if not isinstance(ay, np.ndarray):
            ay = np.array([ay])

        self._cppad_adfun_cons_pos = pycppad.adfun(ax, ay)
Ejemplo n.º 8
0
 def _trace_lag(self, x, z):
     if self.m == 0 and self.nbounds == 0:
         self._cppad_adfun_lag = self._cppad_adfun_obj
         return
     axz = pycppad.independent(np.concatenate((x, z)))
     ax = axz[:self.nvar]
     az = axz[self.nvar:]
     ay = self.lag(ax, az)
     self._cppad_adfun_lag = pycppad.adfun(axz, np.array([ay]))
Ejemplo n.º 9
0
    def _add_constraint(self, g, g_jac, x_blocks, l_blocks):
        xl_vec = [b.array for b in x_blocks + l_blocks]
        xl_sizes = [len(vec) for vec in xl_vec]
        """ 1. Generate Jacobian function by cppad if g_jac is not supplied"""
        if g_jac is None:
            xl_indices = np.cumsum(xl_sizes)[:-1]
            var = np.hstack(xl_vec)
            var_in = pycppad.independent(var)
            var_out = np.atleast_1d(g(*np.split(var_in, xl_indices)))
            var_jacobian = pycppad.adfun(var_in, var_out).jacobian

            def g_jac(*vec):
                J = var_jacobian(np.hstack(vec))
                return np.split(J, xl_indices, axis=1)

        """ 2. Sanity check of size and validation"""
        tmp_res = np.atleast_1d(g(*xl_vec))
        tmp_jac = list(g_jac(*xl_vec))

        inequal_size = [
            j.shape != (len(tmp_res), size)
            for j, size in zip(tmp_jac, xl_sizes)
        ]
        if len(tmp_jac) != len(xl_sizes) or np.any(inequal_size):
            raise RuntimeError("Jacobian Size Not fit")
        valid_value = [
            np.isfinite(m).all() and not np.all(m == 0)
            for m in [tmp_res] + tmp_jac
        ]
        if not np.all(valid_value):
            raise RuntimeError("return value of function Not valid")
        dim_res = len(tmp_res)
        """ 3. Make and append compound vector for constraint residual """
        res_off, res_vec = self.cv_res.NewSegment(dim_res)
        """ 4. Generate functor that use the mapped vectors to calcuate residual and jacobians"""
        def g_residual():
            res_vec[:] = g(*xl_vec)

        def g_jacobians():
            jac = list(g_jac(*xl_vec))
            jac.reverse()  # reversed, to pop(-1) instead of pop(0)
            for dm in dms:
                dm.Write(check_allzero(jac.pop()))

        """ 5. Make new DenseMatrix that will hold the jacobians """
        dms = []
        for b in x_blocks + l_blocks:  #'array', 'dim', 'isfixed', 'param', 'jac'
            new_dm = DenseMatrix(res_off, 0)
            new_dm.shape = [dim_res, 0]
            b.jac.append(new_dm)
            dms.append(new_dm)
        """ 6. new record in the system"""
        self.constraint_blocks.append(
            GaussHelmertProblem.ConstraintBlock(res_off, g_residual,
                                                g_jacobians))
Ejemplo n.º 10
0
def create_OP_tape(dev, vPort):
    """
    Generate operating point CppAD tape

    Normally there is no need to call this function manually as tapes
    are generated as needed.
    """
    assert dev.isNonlinear
    a_vPort = ad.independent(vPort)
    (i_out, q_out, a_opvars) = dev.eval_cqs(a_vPort, saveOP=True)
    # Save operating point variable tape
    dev._opfunc = ad.adfun(a_vPort, a_opvars)
Ejemplo n.º 11
0
	def setParams(self, params):
		'''
		Save parameters in the object and create
		automatic differentiation object
		'''
		self.A  = params['A']
		self.w  = params['w']
		self.mu = params['mu']
		
		ax = pcad.independent(np.zeros(self.w.shape[0]*2))
		ay = self.oscillator(ax)
		self.gf = pcad.adfun(ax, ay)
		self.gf.optimize()
Ejemplo n.º 12
0
def ad_Hessian(F, x0):
    '''
    Computes Hessian of F using automatic differentiation
    '''
    a_x = ad.independent(x0)
    a_F = F(a_x)
    n = x0.shape[0]
    m = a_F.shape[0]
    HF = np.empty((m, n, n))
    I = np.eye(m)

    adF = ad.adfun(a_x, a_F)
    for i in range(m):
        HF[i, :, :] = adF.hessian(x0, I[i])

    return HF
Ejemplo n.º 13
0
def MakeJacobianFunction(g, *args):
    arg_sizes = [len(np.atleast_1d(vec)) for vec in args]

    arg_indices = np.cumsum(arg_sizes)[:-1]
    var = np.hstack(args)
    var_in = pycppad.independent(var)
    var_out = np.atleast_1d(g(*np.split(var_in, arg_indices)))
    var_jacobian = pycppad.adfun(var_in, var_out).jacobian

    def g_jac_auto(*vec):
        J = var_jacobian(np.hstack(vec))
        check_nan(J)
        check_allzero(J)
        return np.split(J, arg_indices, axis=1)

    return g_jac_auto
Ejemplo n.º 14
0
def ad_Hessian(F,x0):
    '''
    Computes Hessian of F using automatic differentiation
    '''
    a_x = ad.independent(x0)
    a_F = F(a_x)
    n = x0.shape[0]
    m = a_F.shape[0]
    HF = np.empty((m,n,n))
    I = np.eye(m)
    
    adF = ad.adfun(a_x,a_F)
    for i in range(m):
        HF[i,:,:] = adF.hessian(x0,I[i])
    
    return HF
Ejemplo n.º 15
0
def create_tape(dev, vPort):
    """
    Generate main CppAD tape

    Normally there is no need to call this function manually as tapes
    are generated as needed.
    """
    #import pdb; pdb.set_trace()
    assert dev.isNonlinear
    # Create derivative vector
    a_vPort = ad.independent(vPort)
    # perform actual calculation
    (i_out, q_out) = dev.eval_cqs(a_vPort)
    # Concatenate vectors as we want only one tape to be generated
    a_out = np.concatenate((i_out, q_out), axis=0)
    # Save main function tape
    dev._func = ad.adfun(a_vPort, a_out)
    # optimize main function tape
    dev._func.optimize()
Ejemplo n.º 16
0
def create_tape(dev, vPort):
    """
    Generate main CppAD tape

    Normally there is no need to call this function manually as tapes
    are generated as needed.
    """
    #import pdb; pdb.set_trace()
    assert dev.isNonlinear
    # Create derivative vector
    a_vPort = ad.independent(vPort)
    # perform actual calculation 
    (i_out, q_out) = dev.eval_cqs(a_vPort)
    # Concatenate vectors as we want only one tape to be generated
    a_out = np.concatenate((i_out, q_out), axis=0)
    # Save main function tape
    dev._func = ad.adfun(a_vPort, a_out)
    # optimize main function tape
    dev._func.optimize()
Ejemplo n.º 17
0
def ode_function(num_step, age_local, all_local, scipy=False):
    global age, incidence, remission, excess, all_cause
    global susceptible, condition

    if scipy == False:
        N = len(age_local)
        age = age_local
        all_cause = all_local
        susceptible = pycppad.ad(numpy.zeros(N))
        condition = pycppad.ad(numpy.zeros(N))
        incidence = .00 * numpy.ones(N)
        remission = .00 * numpy.ones(N)
        excess = .00 * numpy.ones(N)
        s0 = 0.
        c0 = 0.
        x = numpy.hstack((incidence, remission, excess, s0, c0))
        x = pycppad.independent(x)
        incidence = x[(0 * N):(1 * N)]
        remission = x[(1 * N):(2 * N)]
        excess = x[(2 * N):(3 * N)]
        s0 = x[3 * N]
        c0 = x[3 * N + 1]
        ode_integrate(N, num_step, s0, c0)
        y = numpy.hstack((susceptible, condition))
        fun = pycppad.adfun(x, y)

        return fun

    if scipy == True:
        res = integrate.solve_ivp(fun=odefun,
                                  t_span=(age[0], age[-1]),
                                  y0=[s0, c0],
                                  method='RK45',
                                  t_eval=age)

        print(res.message)
        s = res.y[0, :]
        c = res.y[1, :]

        return s, c
Ejemplo n.º 18
0
def ode_function(num_step, age_local, all_local) :
	global age, incidence, remission, excess, all_cause
	global susceptible, condition
	N            = len( age_local )
	age          = age_local
	all_cause    = all_local
	susceptible  = pycppad.ad( numpy.zeros(N) )
	condition    = pycppad.ad( numpy.zeros(N) )
	incidence    = .00 * numpy.ones(N)
	remission    = .00 * numpy.ones(N)
	excess       = .00 * numpy.ones(N)
	s0           = 0.
	c0           = 0.
	x            = numpy.hstack( (incidence, remission, excess, s0, c0) )
	x            = pycppad.independent( x )
	incidence    = x[(0*N):(1*N)]
	remission    = x[(1*N):(2*N)]
	excess       = x[(2*N):(3*N)]
	s0           = x[3*N]
	c0           = x[3*N+1]
	ode_integrate(N, num_step, s0, c0)
	y            = numpy.hstack( (susceptible, condition) )
	fun          = pycppad.adfun(x, y)
	return fun
Ejemplo n.º 19
0
def ode_function(num_step, age_local, all_local):
    global age, incidence, remission, excess, all_cause
    global susceptible, condition
    N = len(age_local)
    age = age_local
    all_cause = all_local
    susceptible = pycppad.ad(numpy.zeros(N))
    condition = pycppad.ad(numpy.zeros(N))
    incidence = .00 * numpy.ones(N)
    remission = .00 * numpy.ones(N)
    excess = .00 * numpy.ones(N)
    s0 = 0.
    c0 = 0.
    x = numpy.hstack((incidence, remission, excess, s0, c0))
    x = pycppad.independent(x)
    incidence = x[(0 * N):(1 * N)]
    remission = x[(1 * N):(2 * N)]
    excess = x[(2 * N):(3 * N)]
    s0 = x[3 * N]
    c0 = x[3 * N + 1]
    ode_integrate(N, num_step, s0, c0)
    y = numpy.hstack((susceptible, condition))
    fun = pycppad.adfun(x, y)
    return fun
Ejemplo n.º 20
0
 def _trace_obj(self, x):
     ax = pycppad.independent(x)
     ay = self.obj(ax)
     self._cppad_adfun_obj = pycppad.adfun(ax, np.array([ay]))
Ejemplo n.º 21
0
if __name__ == "__main__":
	N_max = 120
	reps = 100

	Ns = list(range(2,N_max,5))
	adolc_gradient_runtimes = []
	cppad_gradient_runtimes = []
	adolc_hessian_runtimes = []
	cppad_hessian_runtimes = []
	
	for N in Ns:
	
		# cppad timing
		x     = numpy.zeros(N, dtype=float)
		ax   = pycppad.independent(x)
		
		atmp = []
		for n in range(N):
			atmp.append(numpy.sin( numpy.sum(ax[:n])))
		ay   = numpy.array( [ ax[0] * numpy.sin( numpy.sum(atmp)) ] )
		f   = pycppad.adfun(ax, ay)
		x   = numpy.random.rand(N)
		w   = numpy.array( [ 1.] ) # compute Hessian of x0 * sin(x1)
		
		cppad_hessian_runtime  = timeit.Timer('f.hessian(x, w)', 'from __main__ import f,x,w').timeit(number=reps)/reps
		cppad_gradient_runtime = timeit.Timer('f.jacobian(x)', 'from __main__ import f,x').timeit(number=reps)/reps
		
		# adolc timing
		x     = numpy.zeros(N, dtype=float)
		adolc.trace_on(0)
Ejemplo n.º 22
0
if __name__ == "__main__":
    N_max = 120
    reps = 100

    Ns = range(2, N_max, 5)
    adolc_gradient_runtimes = []
    cppad_gradient_runtimes = []
    adolc_hessian_runtimes = []
    cppad_hessian_runtimes = []

    for N in Ns:

        # cppad timing
        x = numpy.zeros(N, dtype=float)
        ax = pycppad.independent(x)

        atmp = []
        for n in range(N):
            atmp.append(numpy.sin(numpy.sum(ax[:n])))
        ay = numpy.array([ax[0] * numpy.sin(numpy.sum(atmp))])
        f = pycppad.adfun(ax, ay)
        x = numpy.random.rand(N)
        w = numpy.array([1.])  # compute Hessian of x0 * sin(x1)

        cppad_hessian_runtime = timeit.Timer(
            'f.hessian(x, w)',
            'from __main__ import f,x,w').timeit(number=reps) / reps
        cppad_gradient_runtime = timeit.Timer(
            'f.jacobian(x)',
            'from __main__ import f,x').timeit(number=reps) / reps
Ejemplo n.º 23
0
def create_sensitivity_tape(device, parList, inVec):
    """
    Create sensitivity AD tape

    Inputs:

        device: device with nodal attributes 
        parList: list of parameters to calculate sensitivities

        inVec: input vector including parameters and perhaps nonlinear
        control voltages at the end of the vector

    Side effects: operating point attributes lost in internal terminals
    """
    # Should store some parameter information for safety
    #
    # Create AD tape -----------------------------------------------------
    #
    a_inVec = ad.independent(inVec)
    # set adouble attributes: a_inVec may be longer than parList but
    # zip() truncates to the shortest list
    for item, a_val in zip(parList, a_inVec):
        setattr(device, item[0], a_val)
    # Re-calculate coductances / parameters
    linVec = np.empty(shape=0)
    device.process_params()
    if device.linearVCCS:
        gList = []
        for vccs in device.linearVCCS:
            # Linear output current
            g = vccs[2]
            # Kludge: Make sure all elements are of the correct type
            if type(g) != ad.cppad_.a_float:
                g = ad.cppad_.a_float(g)
            gList.append(g)
        # Overwrite output vector
        linVec = np.array(gList)
    #import pdb; pdb.set_trace()

    # Later add for time- and frequency- domain
    if device.isDCSource:
        val = device.get_DCsource()
        # Kludge: Make sure all elements are of the correct type
        if type(val) != ad.cppad_.a_float:
            val = ad.cppad_.a_float(val)
        valVec = np.array([val])
        sourceVec = np.concatenate((linVec, valVec), axis=0)
    else:
        sourceVec = linVec

    if device.isNonlinear:
        # calculate nonlinear currents and concatenate to output
        (iVec, qVec) = device.eval_cqs(a_inVec[-device.nD_nxin:])
        #        # Kludge: Make sure all elements are of the correct type (not needed?)
        #        for k,i in enumerate(iVec):
        #            if type(i) != ad.cppad_.a_float:
        #                iVec[k] = ad.cppad_.a_float(i)
        a_outVec = np.concatenate((sourceVec, iVec), axis=0)
    else:
        # Just copy whatever we have
        a_outVec = sourceVec

    # tape stored in f
    f = ad.adfun(a_inVec, a_outVec)
    f.optimize()
    # Restore element to original state
    device.clean_attributes()
    device.set_attributes()
    device.process_params()
    nd.restore_RCnumbers(device)
    # End of crate tape ------------------------------------------------
    return f
Ejemplo n.º 24
0
def create_sensitivity_tape(device, parList, inVec):
    """
    Create sensitivity AD tape

    Inputs:

        device: device with nodal attributes 
        parList: list of parameters to calculate sensitivities

        inVec: input vector including parameters and perhaps nonlinear
        control voltages at the end of the vector

    Side effects: operating point attributes lost in internal terminals
    """
    # Should store some parameter information for safety
    #
    # Create AD tape -----------------------------------------------------
    # 
    a_inVec = ad.independent(inVec)
    # set adouble attributes: a_inVec may be longer than parList but
    # zip() truncates to the shortest list
    for item, a_val in zip(parList, a_inVec):
        setattr(device, item[0], a_val)
    # Re-calculate coductances / parameters
    linVec = np.empty(shape=0)
    device.process_params()
    if device.linearVCCS:
        gList = []
        for vccs in device.linearVCCS:
            # Linear output current
            g = vccs[2]
            # Kludge: Make sure all elements are of the correct type
            if type(g) != ad.cppad_.a_float:
                g = ad.cppad_.a_float(g)
            gList.append(g)
        # Overwrite output vector
        linVec = np.array(gList)
    #import pdb; pdb.set_trace()

    # Later add for time- and frequency- domain
    if device.isDCSource:
        val = device.get_DCsource()
        # Kludge: Make sure all elements are of the correct type
        if type(val) != ad.cppad_.a_float:
            val = ad.cppad_.a_float(val)
        valVec = np.array([val])
        sourceVec = np.concatenate((linVec, valVec), axis=0)
    else:
        sourceVec = linVec
    
    if device.isNonlinear:
        # calculate nonlinear currents and concatenate to output
        (iVec, qVec) = device.eval_cqs(a_inVec[-device.nD_nxin:])
#        # Kludge: Make sure all elements are of the correct type (not needed?)
#        for k,i in enumerate(iVec):
#            if type(i) != ad.cppad_.a_float:
#                iVec[k] = ad.cppad_.a_float(i)
        a_outVec = np.concatenate((sourceVec, iVec), axis=0)
    else:
        # Just copy whatever we have
        a_outVec = sourceVec

    # tape stored in f
    f = ad.adfun(a_inVec, a_outVec)
    f.optimize()
    # Restore element to original state
    device.clean_attributes()
    device.set_attributes()
    device.process_params()
    nd.restore_RCnumbers(device)
    # End of crate tape ------------------------------------------------
    return f
Ejemplo n.º 25
0
 def _trace_obj(self, x):
     ax = pycppad.independent(x)
     ay = self.obj(ax)
     self._cppad_adfun_obj = pycppad.adfun(ax, np.array([ay]))