Exemplo n.º 1
0
def FIM_t(xpdot, b, criterion):
    '''
    computes FIM at a given time.
    b is the bonary variable which selects or not the time point
    '''
    n_x = 2
    n_theta = 4
    FIM_sample = np.zeros([n_theta, n_theta])
    FIM_0 = cad.inv((((10.0 - 0.001)**2) / 12) * cad.SX.eye(n_theta))
    FIM_sample += FIM_0
    for i in range(np.shape(xpdot)[0] - 1):
        xp_r = cad.reshape(xpdot[i + 1], (n_x, n_theta))
        #    vv = np.zeros([ntheta[0], ntheta[0], 1 + N])
        #    for i in range(0, 1 + N):
        FIM_sample += b[i] * xp_r.T @ np.linalg.inv(
            np.array([[0.01, 0], [0, 0.05]])
        ) @ xp_r  # + np.linalg.inv(np.array([[0.01, 0, 0, 0], [0, 0.05, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0.2]]))
#    FIM  = solve(FIM1, SX.eye(FIM1.size1()))
#   [Q, R] = qr(FIM1.expand())

    if criterion == 'D_optimal':
        #        objective = -cad.log(cad.det(FIM_sample) + 1e-10)
        objective = -2 * cad.sum1(cad.log(cad.diag(
            cad.chol(FIM_sample))))  # by Cholesky factorisation


#        objective = -cad.log((cad.det(FIM_sample)**2))
#        objective = -cad.det(FIM_sample)
    elif criterion == 'A_optimal':
        objective = -cad.log(cad.trace(FIM_sample) + 1e-10)
    return objective
Exemplo n.º 2
0
 def getWind():
     z0 = conf['z0']
     zt_roughness = conf['zt_roughness']
     zsat = 0.5*(z+C.sqrt(z*z))
     wind_x = dae['w0']*C.log((zsat+zt_roughness+2)/zt_roughness)/C.log(z0/zt_roughness)
 #    wind_x = dae['w0']
     return wind_x
Exemplo n.º 3
0
    def plotLogProbVsDistance():
        spchar = " "
        rspace = np.linspace(-0.1, 0.75, num=1000)
        for theta_val in (theta_low, theta_high):
            uspace_type = [
                -log(1 + exp(-beta[0] - beta[1] * theta_val - beta[2] * rval))
                for rval in rspace
            ]
            ax3.plot(rspace,
                     uspace_type,
                     color=color_type_map[theta_val],
                     label=f"Utility{spchar}for Type {theta_val}",
                     zorder=-1)
        low_index = theta.index(theta_low)
        high_index = theta.index(theta_high)
        # yvals_inverted = [0 if v==1 else 1 for v in yvals]
        # gp_inverted = [i for i,v in enumerate(yvals_inverted) if v==1]
        # xlist_inverted = [ gp_inverted[np.argmin([dist[i][j] for j in gp_inverted])] for i in range(nIndiv)]
        # r_inverted = [dist[i][xlist_inverted[i]] for i in range(nIndiv)]
        r_inverted = list(reversed(rvals))
        r_inverted_and_not = {1: rvals, 0: r_inverted}
        utility_inverted_and_not = {
            inversion: sum([
                -log(1 + exp(-beta[0] - beta[1] * theta[ind] -
                             beta[2] * rvals_possibly_inverted[ind]))
                for ind in range(nIndiv)
            ])
            for inversion, rvals_possibly_inverted in
            r_inverted_and_not.items()
        }

        for inversion, rvals_possibly_inverted in r_inverted_and_not.items():
            for ind in reversed(range(nIndiv)):
                ax3.scatter(
                    rvals_possibly_inverted[ind], [
                        -log(1 + exp(-beta[0] - beta[1] * theta[ind] -
                                     beta[2] * rvals_possibly_inverted[ind]))
                    ],
                    marker="+",
                    c=[facility_color_map[inversion]],
                    s=[facility_size_options[inversion]],
                    label=
                    f"Utility from{spchar}{facility_states[inversion].lower()} facility (Sum: {utility_inverted_and_not[inversion]:.02})",
                    zorder=1)
        # for ind in range(len(theta)):
        # 	ax3.scatter(r_inverted[ind],[1/(1+exp(-beta[0] - beta[1]*theta[ind] - beta[2]*r_inverted[ind]))],marker = "+",c=[facility_color_map[0]],s=[facility_size_options[0]],label=f"Utility from {facility_states[0]} facility")
        legend_dict = {
            artist.properties().get('label'): artist
            for artist in ax3.collections.copy() + ax3.lines.copy()
            if "no_legend" not in artist.properties().get('label')
        }
        # ax3.legend(legend_dict.values(),legend_dict.keys(),loc='upper center', bbox_to_anchor=(0.5, -0.2), ncol=len(legend_dict),fontsize='small')
        ax3.legend(legend_dict.values(),
                   legend_dict.keys(),
                   loc='best',
                   fontsize='small')
        ax3.set_xlabel("distance from nearest selected facility")
        ax3.set_ylabel("$log[P(Success)]$")
        ax3.set_title("$log[P(success)]$ vs Distance Differs by Type")
Exemplo n.º 4
0
def loglikilihood(r, params1, params2, ):

    running_sum = 0
    p_1_tm1 = 1
    p_2_tm1 = 0
    g_1_tm1 = 1
    g_2_tm1 = 1
    h_1_tm1 = .25 ** 2 / STEPS
    h_2_tm1 = .25 ** 2 / STEPS
    p_1_tm1_agg_1 = .5
    p_1_tm1_agg_2 = .5

    pm1 = params1
    pm2 = params2
    p_1, p_2, h_1, h_2 = [], [], [], []
    for t in xrange(1, len(r)):
        r_t = r[t]
        P_t = get_P_t(pm1.d, pm1.e, r_t)
        Q_t = get_Q_t(pm2.d, pm2.e, r_t)
        p_1_t = p_1_t_f(P_t, Q_t, g_1_tm1, p_1_tm1, g_2_tm1)
        p_2_t = 1 - p_1_t
        #import pdb; pdb.set_trace()
        p_1_tm1_agg_1 = p_1_tm1_agg_1_f(pm1.d, pm1.e, pm1.lamb, pm1.gamma, h_1_tm1, p_1_tm1, pm2.d, pm2.e, pm2.lamb, pm2.gamma, h_2_tm1, p_2_tm1)
        p_1_tm1_agg_2 = 1- p_1_tm1_agg_1
        h_tm1_agg_1 = h_tm1_agg_i(p_1_tm1_agg_1, h_1_tm1, h_2_tm1, pm1.lamb, pm1.gamma, pm2.lamb, pm2.gamma)
        h_tm1_agg_2 = h_tm1_agg_i(p_1_tm1_agg_2, h_1_tm1, h_2_tm1, pm1.lamb, pm1.gamma, pm2.lamb, pm2.gamma)
        delta_t_agg_1 = delta_t_agg_i(p_1_tm1_agg_1, r_t, pm1.lamb, pm1.gamma, pm2.lamb, pm2.gamma, h_1_tm1, h_2_tm1)
        delta_t_agg_2 = delta_t_agg_i(p_1_tm1_agg_2, r_t, pm1.lamb, pm1.gamma, pm2.lamb, pm2.gamma, h_1_tm1, h_2_tm1)

        h_1_t = h_i_t(pm1.omega, pm1.alpha, pm1.beta, pm1.b, pm1.c, pm1.mu, pm1.v, h_tm1_agg_1, delta_t_agg_1)
        h_2_t = h_i_t(pm2.omega, pm2.alpha, pm2.beta, pm2.b, pm2.c, pm2.mu, pm2.v, h_tm1_agg_2, delta_t_agg_2)
        #if t % 50 == 1:
        #    import pdb; pdb.set_trace()
        #    print (h_1_tm1 * STEPS)**.5, (h_1_t * STEPS)**.5

        f_1_t = f(r_t, h_1_tm1, pm1.lamb, pm1.gamma)
        f_2_t = f(r_t, h_2_tm1, pm2.lamb, pm2.gamma)
        #import pdb; pdb.set_trace()
        running_sum += casadi.log(f_1_t)
        running_sum += casadi.log(f_2_t)

        p_1_tm1 = p_1_t
        p_2_tm1 = p_2_t
        g_1_tm1 = f_1_t
        g_2_tm1 = f_2_t
        h_1_tm1 = h_1_t
        h_2_tm1 = h_2_t
        p_1.append(p_1_t)
        p_2.append(p_2_t)
        h_1.append(h_1_t)
        h_2.append(h_2_t)

    return -running_sum, (p_1, p_2, h_1, h_2)
Exemplo n.º 5
0
 def getWind():
     if conf['wind_model']['name'] == 'wind_shear':
         # use a logarithmic wind shear model
         # wind(z) = w0 * log((z+zt)/zt) / log(z0/zt)
         # where w0 is wind at z0 altitude
         # zt is surface roughness characteristic length
         z0 = conf['wind_model']['z0']
         zt_roughness = conf['wind_model']['zt_roughness']
         return dae['w0']*C.log((-z+zt_roughness)/zt_roughness)/C.log(z0/zt_roughness)
     elif conf['wind_model']['name'] == 'constant':
         # constant wind
         return dae['w0']
Exemplo n.º 6
0
 def getWind():
     if conf['wind_model']['name'] == 'wind_shear':
         # use a logarithmic wind shear model
         # wind(z) = w0 * log((z+zt)/zt) / log(z0/zt)
         # where w0 is wind at z0 altitude
         # zt is surface roughness characteristic length
         z0 = conf['wind_model']['z0']
         zt_roughness = conf['wind_model']['zt_roughness']
         return dae['w0'] * C.log(
             (-z + zt_roughness) / zt_roughness) / C.log(z0 / zt_roughness)
     elif conf['wind_model']['name'] == 'constant':
         # constant wind
         return dae['w0']
Exemplo n.º 7
0
def Model(param, x, args):
    T = x[:, 0]
    A, B = param[0], param[1]

    return exp(
        A / 8.31446 + B / (8.31446 * T) -
        (68.2 / 8.31446) * log(T / 298.15))  # Pvp calculation - vectorized
Exemplo n.º 8
0
def Cd_profile_2412(alpha, Re_c):
    # A curve fit I did to a NACA 2412 airfoil in incompressible flow.
    # Within -2 < alpha < 12 and 10^5 < Re_c < 10^7, has R^2 = 0.9713

    print(
        "Warning: Cd_profile_e216() recommended over Cd_profile_2412(); those are MUCH more accurate fits."
    )

    Re_c = cas.fmax(Re_c, 1)
    log_Re = cas.log(Re_c)

    CD0 = -5.249
    Re0 = 15.61
    Re1 = 15.31
    alpha0 = 1.049
    alpha1 = -4.715
    cx = 0.009528
    cxy = -0.00588
    cy = 0.04838

    log_CD = CD0 + cx * (alpha - alpha0)**2 + cy * (log_Re - Re0)**2 + cxy * (
        alpha - alpha1) * (log_Re - Re1
                           )  # basically, a rotated paraboloid in logspace
    CD = cas.exp(log_CD)

    return CD
def mass_hpa_propeller(diameter,
                       max_power,
                       include_variable_pitch_mechanism=False):
    """
    Returns the estimated mass of a propeller assembly for low-disc-loading applications (human powered airplane, paramotor, etc.)

    :param diameter: diameter of the propeller [m]
    :param max_power: maximum power of the propeller [W]
    :param include_variable_pitch_mechanism: boolean, does this propeller have a variable pitch mechanism?
    :return: estimated weight [kg]
    """
    smoothmax = lambda value1, value2, hardness: cas.log(
        cas.exp(hardness * value1) + cas.exp(hardness * value2)
    ) / hardness  # soft maximum

    mass_propeller = (
        0.495 * (diameter / 1.25)**1.6 *
        smoothmax(0.6, max_power / 14914, hardness=5)**2
    )  # Baselining to a 125cm E-Props Top 80 Propeller for paramotor, with some sketchy scaling assumptions
    # Parameters on diameter exponent and min power were chosen such that Daedalus propeller is roughly on the curve.

    mass_variable_pitch_mech = 216.8 / 800 * mass_propeller
    # correlation to Daedalus data: http://journals.sfu.ca/ts/index.php/ts/article/viewFile/760/718
    if include_variable_pitch_mechanism:
        mass_propeller += mass_variable_pitch_mech

    return mass_propeller
Exemplo n.º 10
0
def Cd_cylinder(Re_D, subcritical_only=False):
    """
    Returns the drag coefficient of a cylinder in crossflow as a function of its Reynolds number.
    :param Re_D: Reynolds number, referenced to diameter
    :param subcritical_only: Determines whether the model models purely subcritical (Re < 300k) cylinder flows. Useful, since
    this model is now convex and can be more well-behaved.
    :return: Drag coefficient
    """
    csigc = 5.5766722118597247
    csigh = 23.7460859935990563
    csub0 = -0.6989492360435040
    csub1 = 1.0465189382830078
    csub2 = 0.7044228755898569
    csub3 = 0.0846501115443938
    csup0 = -0.0823564417206403
    csupc = 6.8020230357616764
    csuph = 9.9999999999999787
    csupscl = -0.4570690347113859

    x = cas.log10(Re_D)

    if subcritical_only:
        Cd = 10**(csub0 * x + csub1) + csub2 + csub3 * x
        return Cd
    else:
        log10_Cd = (
            (cas.log10(10**(csub0 * x + csub1) + csub2 + csub3 * x)) *
            (1 - 1 / (1 + cas.exp(-csigh * (x - csigc)))) +
            (csup0 +
             csupscl / csuph * cas.log(cas.exp(csuph * (csupc - x)) + 1)) *
            (1 / (1 + cas.exp(-csigh * (x - csigc)))))
        Cd = 10**log10_Cd
        return Cd
Exemplo n.º 11
0
    def __init__(self, state_probabilities, asset_values):
        self.state_probabilities = state_probabilities
        self.asset_values = asset_values
        self.validate()

        n_states = self.n_states
        n_assets = self.n_assets

        self.opti = opti = casadi.Opti()
        self.expressions = {}
        p_asset_values = opti.parameter(n_states, n_assets)
        opti.set_value(p_asset_values, asset_values)
        p_state_probabilities = opti.parameter(n_states)
        opti.set_value(p_state_probabilities, state_probabilities)

        v_coded = opti.variable(n_assets)
        coded_total = casadi.sum1(v_coded)
        asset_weights = v_coded / (coded_total + 1)  # the rest is cash
        cash = 1.0 / (coded_total + 1)  # 1-sum(weights)
        state_values = casadi.mtimes(p_asset_values, asset_weights) + cash
        kelly_criterion = casadi.dot(casadi.log(state_values),
                                     p_state_probabilities)
        opti.minimize(-kelly_criterion)
        opti.subject_to(v_coded >= 0)
        opti.set_initial(v_coded, np.ones(n_assets))
        opti.solver('ipopt')

        self.expressions = DS({
            name: value
            for name, value in locals().items()
            if isinstance(value, casadi.MX)
        })
Exemplo n.º 12
0
def solve_enumerative():
    bbax = bax()
    yvals = np.zeros((nFac), dtype=int)
    rvals = np.zeros((nIndiv))
    uvals = np.full((nIndiv), -np.inf)

    for ind, gp in enumerate(bbax.bax_gen(nFac, nSelectedFac)):
        gp = gp.toList()
        xlist = [
            gp[np.argmin([dist[i][j] for j in gp])] for i in range(nIndiv)
        ]
        r = [dist[i][xlist[i]] for i in range(nIndiv)]
        u = [
            -log(1 + exp(-beta[0] - beta[1] * theta[i] - beta[2] * r[i]))
            for i in range(nIndiv)
        ]
        if sum(u) > sum(uvals):
            uvals = u
            rvals = r
            yvals = np.zeros((nFac), dtype=int)
            yvals[gp] = 1

    fstar = sum(uvals)
    prob_success = np.exp(uvals)
    print(f"Solved enumeratively")
    return yvals, rvals, uvals, prob_success, fstar
Exemplo n.º 13
0
def calc_xs_full_ode(Ex, Ey, e_hat, y_hat, state_compressor):

    t = cs.SX.sym('t', 1)
    x_sym = cs.SX.sym('x', sc.nm)
    y_sym = cs.SX.sym('y', ny)
    e_sym = cs.SX.sym('e', sc.nr)
    Ex_sym = cs.SX.sym('Ex', sc.nr, sc.nm)
    Ey_sym = cs.SX.sym('Ex', sc.nr, Ey.shape[1])

    v = e_sym * v_star * (1 + Ex_sym @ cs.log(x_sym / sc.x_star) +
                          Ey @ np.log(y_hat))
    v_fun = cs.Function('v', [x_sym, e_sym, Ex_sym], [v])

    ode = cs.mtimes(cs.DM(N), v_fun(x_sym, e_sym, Ex_sym))

    integrator = cs.integrator(
        'full', 'cvodes', {
            't': t,
            'x': x_sym,
            'p': cs.vertcat(e_sym, Ex_sym.reshape((-1, 1))),
            'ode': ode,
        }, {
            'tf': 2000,
            'regularity_check': True,
        })

    p = np.hstack([e_hat, Ex.reshape((-1, 1), order='F').squeeze()])
    xs = np.array(integrator(x0=sc.x_star, p=p)['xf']).flatten()

    return xs
Exemplo n.º 14
0
 def getWind():
     if 'wind_model' not in conf:
         return 0
     if conf['wind_model']['name'] == 'wind_shear':
         # use a logarithmic wind shear model
         # wind(z) = w0 * log((altitude+zt)/zt) / log(z0/zt)
         # where w0 is wind at z0 altitude
         # zt is surface roughness characteristic length
         # altitude is -z - altitude0, where altitude0 is a user parameter
         z0 = conf['wind_model']['z0']
         zt_roughness = conf['wind_model']['zt_roughness']
         altitude = -z - conf['wind_model']['altitude0']
         return dae['w0']*C.log((altitude+zt_roughness)/zt_roughness)/C.log(z0/zt_roughness)
     elif conf['wind_model']['name'] in ['constant','hardcoded']:
         # constant wind
         return dae['w0']
Exemplo n.º 15
0
def get_wind(dae, conf):
    '''
    return the wind at current altitude based on configuration
    '''
    if conf['wind_model']['name'] == 'wind_shear':
        # use a logarithmic wind shear model
        # wind(z) = w0 * log((z+zt)/zt) / log(z0/zt)
        # where w0 is wind at z0 altitude
        # zt is surface roughness characteristic length
        z = dae['r_n2b_n_z']
        z0 = conf['wind_model']['z0']
        zt_roughness = conf['wind_model']['zt_roughness']
        return dae['w0']*C.log((-z+zt_roughness)/zt_roughness) / \
                         C.log(z0/zt_roughness)
    elif conf['wind_model']['name'] == 'constant':
        # constant wind
        return dae['w0']
Exemplo n.º 16
0
def solve_casadi():
    opti = Opti()
    x = [[opti.variable() for j in range(nFac)]
         for i in range(nIndiv)]  # nIndiv X nFac
    y = [opti.variable() for j in range(nFac)]
    r = [opti.variable() for i in range(nIndiv)]
    u = [opti.variable() for i in range(nIndiv)]
    discrete = []
    discrete += [False for j in range(nFac) for i in range(nIndiv)
                 ]  #x variables - will be binary without integer constraint
    discrete += [True for j in range(nFac)]  #y variables
    discrete += [False for i in range(nIndiv)]  #r variables
    discrete += [False for i in range(nIndiv)]  #u variables
    opti.minimize(-sum(u))  #maximize sum u
    opti.subject_to([
        u[i] == -log(1 + exp(-beta[0] - beta[1] * theta[i] - beta[2] * r[i]))
        for i in range(nIndiv)
    ])  #log prob(success)
    # opti.subject_to([u[i] == 1/(1+exp(-beta[0] - beta[1]*theta[i] - beta[2]*r[i])) for i in range(nIndiv)]) #prob(success)
    opti.subject_to([
        r[i] >= sum([dist[i, j] * x[i][j] for j in range(nFac)])
        for i in range(nIndiv)
    ])
    opti.subject_to([sum(x[i]) == 1 for i in range(nIndiv)])
    opti.subject_to(
        [x[i][j] <= y[j] for i in range(nIndiv) for j in range(nFac)])
    opti.subject_to(sum(y) <= nSelectedFac)
    opti.subject_to([opti.bounded(0, y[j], 1) for j in range(nFac)])
    opti.subject_to([
        opti.bounded(0, x[i][j], 1) for i in range(nIndiv) for j in range(nFac)
    ])
    p_options = {"discrete": discrete, "expand": True}
    s_options = {"max_iter": 100, 'tol': 100}
    opti.solver('bonmin', p_options, s_options)
    sol = opti.solve()
    # possibilities for tolerance in s_options (https://web.casadi.org/python-api/):
    #only 'tol' works...
    # for key in ['tol','boundTolerance','epsIterRef','terminationTolerance','abstol','opttol']:
    # 	try:
    # 		s_options = {"max_iter": 100,key: .1}
    # 		opti.solver('bonmin',p_options,s_options)
    # 		sol = opti.solve()
    # 		print(f"NOTE: '{key}' works in s_options!!")
    # 	except Exception as e:
    # 		print(e)
    # 		print(f"NOTE: '{key}' is not a valid s_option!")

    xvals = np.round(
        np.array([[sol.value(x[i][j]) for j in range(nFac)]
                  for i in range(nIndiv)])).astype(int)
    yvals = np.array([sol.value(y[j]) for j in range(nFac)]).astype(int)
    rvals = np.array([sol.value(r[i]) for i in range(nIndiv)])
    uvals = np.array([sol.value(u[i]) for i in range(nIndiv)])
    # prob_success = np.array([1/(1+exp(-beta[0] - beta[1]*theta[i] - beta[2]*rvals[i])) for i in range(nIndiv)])
    prob_success = np.exp(uvals)
    fstar = sol.value(opti.f)
    print(f"Solved using CasADI")
    return xvals, yvals, rvals, uvals, prob_success, fstar
Exemplo n.º 17
0
def get_wind(dae, conf):
    '''
    return the wind at current altitude based on configuration
    '''
    if conf['wind_model']['name'] == 'wind_shear':
        # use a logarithmic wind shear model
        # wind(z) = w0 * log((altitude+zt)/zt) / log(z0/zt)
        # where w0 is wind at z0 altitude
        # zt is surface roughness characteristic length
        # altitude is -z - altitude0, where altitude0 is a user parameter
        z = dae['r_n2b_n_z']
        z0 = conf['wind_model']['z0']
        zt_roughness = conf['wind_model']['zt_roughness']
        altitude = -z - conf['wind_model']['altitude0']
        return dae['w0']*C.log((altitude+zt_roughness)/zt_roughness) / \
                         C.log(z0/zt_roughness)
    elif conf['wind_model']['name'] == 'constant':
        # constant wind
        return dae['w0']
Exemplo n.º 18
0
def prod(x, axis: int = None):
    """
    Return the product of array elements over a given axis.

    See syntax here: https://numpy.org/doc/stable/reference/generated/numpy.prod.html
    """
    if not is_casadi_type(x):
        return _onp.prod(x, axis=axis)

    else:
        return _cas.exp(sum(_cas.log(x), axis=axis))
Exemplo n.º 19
0
        def SSE_objective(params):
            """
            Given some parameters for the model, what is the "badness" of the corresponding fit.

            Args:
                params

            Returns: A scalar representing the "badness" of the fit.

            """
            y_model = model(x_data, params)
            if y_model is None:
                raise TypeError(
                    "model(x, param_guesses) returned None, when it should've returned a 1D ndarray."
                )

            if put_residuals_in_logspace:
                residuals = cas.log(y_model) - cas.log(y_data)
            else:
                residuals = y_model - y_data

            return cas.sum1(weights * residuals**2)
Exemplo n.º 20
0
 def getWind():
     if 'wind_model' not in conf:
         return C.veccat([0, 0, 0])
     
     if conf['wind_model']['name'] == 'wind_shear':
         # use a logarithmic wind shear model
         # wind(z) = w0 * log((altitude+zt)/zt) / log(z0/zt)
         # where w0 is wind at z0 altitude
         # zt is surface roughness characteristic length
         # altitude is -z - altitude0, where altitude0 is a user parameter
         z0 = conf['wind_model']['z0']
         zt_roughness = conf['wind_model']['zt_roughness']
         altitude = -z - conf['wind_model']['altitude0']
         wind = dae['w0']*C.log((altitude+zt_roughness)/zt_roughness)/C.log(z0/zt_roughness)
         
         dae['wind_at_altitude'] = wind
         
         return C.mul([R_g2c, C.veccat([wind, 0, 0])])
         
     elif conf['wind_model']['name'] in ['constant','hardcoded']:
         # constant wind
         dae['wind_at_altitude'] = dae['w0']
         
         return C.mul([R_g2c, C.veccat([dae['w0'], 0, 0])])
         
     elif conf['wind_model']['name'] == 'random_walk':
         dae.addU('delta_wind_x')
         dae.addU('delta_wind_y')
         dae.addU('delta_wind_z')
         
         wind_x = dae.addX('wind_x')
         wind_y = dae.addX('wind_y')
         wind_z = dae.addX('wind_z')
         
         dae['wind_at_altitude'] = wind_x
         
         return C.veccat([wind_x, wind_y, wind_z])
Exemplo n.º 21
0
 def getWind():
     if 'wind_model' not in conf:
         return C.veccat([0, 0, 0])
     
     if conf['wind_model']['name'] == 'wind_shear':
         # use a logarithmic wind shear model
         # wind(z) = w0 * log((altitude+zt)/zt) / log(z0/zt)
         # where w0 is wind at z0 altitude
         # zt is surface roughness characteristic length
         # altitude is -z - altitude0, where altitude0 is a user parameter
         z0 = conf['wind_model']['z0']
         zt_roughness = conf['wind_model']['zt_roughness']
         altitude = -z - conf['wind_model']['altitude0']
         wind = dae['w0']*C.log((altitude+zt_roughness)/zt_roughness)/C.log(z0/zt_roughness)
         
         dae['wind_at_altitude'] = wind
         
         return C.mul([R_g2c, C.veccat([wind, 0, 0])])
         
     elif conf['wind_model']['name'] in ['constant','hardcoded']:
         # constant wind
         dae['wind_at_altitude'] = dae['w0']
         
         return C.mul([R_g2c, C.veccat([dae['w0'], 0, 0])])
         
     elif conf['wind_model']['name'] == 'random_walk':
         dae.addU('delta_wind_x')
         dae.addU('delta_wind_y')
         dae.addU('delta_wind_z')
         
         wind_x = dae.addX('wind_x')
         wind_y = dae.addX('wind_y')
         wind_z = dae.addX('wind_z')
         
         dae['wind_at_altitude'] = wind_x
         
         return C.veccat([wind_x, wind_y, wind_z])
Exemplo n.º 22
0
def sample_parameter_log_normal_distribution_with_sobol(
        mean, covariance, n_samples=1):
    """Sample parameter using Sobol sampling with a log-normal distribution.

    :param mean:
    :param covariance:
    :param n_samples:
    :return:
    """
    if isinstance(mean, list):
        mean = vertcat(*mean)

    mean_log = log(mean)
    log_samples = sample_parameter_normal_distribution_with_sobol(
        mean_log, covariance, n_samples)
    samples = exp(log_samples)
    return samples
Exemplo n.º 23
0
def smoothmax(value1, value2, hardness):
    """
    A smooth maximum between two functions.
    Useful because it's differentiable and convex!
    Great writeup by John D Cook here:
        https://www.johndcook.com/soft_maximum.pdf
    :param value1: Value of function 1.
    :param value2: Value of function 2.
    :param hardness: Hardness parameter. Higher values make this closer to max(x1, x2).
    :return: Soft maximum of the two supplied values.
    """
    value1 = value1 * hardness
    value2 = value2 * hardness
    max = cas.fmax(value1, value2)
    min = cas.fmin(value1, value2)
    out = max + cas.log(1 + cas.exp(min - max))
    out /= hardness
    return out
Exemplo n.º 24
0
def _process_expr(expr, var_dict):
    if expr.is_constant():
        return expr.value
    from pyomo.core.base.var import _GeneralVarData
    if isinstance(expr, _GeneralVarData):
        # create a new CasADi variable if one doesn't already exist
        pyo_var, cas_var = var_dict.get(expr.local_name, (expr, None))
        if cas_var is None:
            cas_var = SX.sym(expr.local_name)
            var_dict[pyo_var.local_name] = (pyo_var, cas_var)
        return cas_var
    from pyomo.core.base.expr import _SumExpression, _ProductExpression, _PowExpression, _IntrinsicFunctionExpression
    if isinstance(expr, _SumExpression):
        return sum(
            _process_expr(expr._args[i], var_dict) * expr._coef[i]
            for i in range(len(expr._args))) + expr._const
    if isinstance(expr, _ProductExpression):
        prod = expr._coef
        for num in expr._numerator:
            prod *= _process_expr(num, var_dict)
        for denom in expr._denominator:
            prod /= _process_expr(denom, var_dict)
        return prod
    if isinstance(expr, _PowExpression):
        return _process_expr(expr._args[0],
                             var_dict)**_process_expr(expr._args[1], var_dict)
    if isinstance(expr, _IntrinsicFunctionExpression):
        if expr._name == 'log':
            return casadi.log(_process_expr(expr._args[0], var_dict))
        if expr._name == 'exp':
            return casadi.exp(_process_expr(expr._args[0], var_dict))
        if expr._name == 'sqrt':
            return casadi.sqrt(_process_expr(expr._args[0], var_dict))
        # else: (We don't recognize the function)
        raise NotImplementedError('Unrecognized function: ' + expr._name)
    # else: (We don't recognize the expression)
    raise NotImplementedError('Unrecognized expression: ' + str(expr))
Exemplo n.º 25
0
def h_ISA(p):
    """Compute ISA altitude for a given pressure.

    Args:
        p (float or ndarray): Pressure (in Pa).

    Returns:
        float or ndarray: altitude (m).

    """
    # Lower altitude regions
    if p >= 22630:
        T = T0 * (p0 / p)**((-0.0065 * R) / g0)
        h = (T - T0) / -0.0065
    elif p < 22630 and p >= 5470:
        T1 = T0 - 0.0065 * (11000)
        p1 = 22630
        h = -R * T1 / g0 * ca.log(p / p1) + 11000
    else:
        raise ValueError(
            "The given pressure is too low, you are above 20 kilometers altitude"
        )

    return h
Exemplo n.º 26
0
    def _convert(self, symbol, t, y, y_dot, inputs):
        """ See :meth:`CasadiConverter.convert()`. """
        if isinstance(
            symbol,
            (
                pybamm.Scalar,
                pybamm.Array,
                pybamm.Time,
                pybamm.InputParameter,
                pybamm.ExternalVariable,
            ),
        ):
            return casadi.MX(symbol.evaluate(t, y, y_dot, inputs))

        elif isinstance(symbol, pybamm.StateVector):
            if y is None:
                raise ValueError("Must provide a 'y' for converting state vectors")
            return casadi.vertcat(*[y[y_slice] for y_slice in symbol.y_slices])

        elif isinstance(symbol, pybamm.StateVectorDot):
            if y_dot is None:
                raise ValueError("Must provide a 'y_dot' for converting state vectors")
            return casadi.vertcat(*[y_dot[y_slice] for y_slice in symbol.y_slices])

        elif isinstance(symbol, pybamm.BinaryOperator):
            left, right = symbol.children
            # process children
            converted_left = self.convert(left, t, y, y_dot, inputs)
            converted_right = self.convert(right, t, y, y_dot, inputs)

            if isinstance(symbol, pybamm.Minimum):
                return casadi.fmin(converted_left, converted_right)
            if isinstance(symbol, pybamm.Maximum):
                return casadi.fmax(converted_left, converted_right)

            # _binary_evaluate defined in derived classes for specific rules
            return symbol._binary_evaluate(converted_left, converted_right)

        elif isinstance(symbol, pybamm.UnaryOperator):
            converted_child = self.convert(symbol.child, t, y, y_dot, inputs)
            if isinstance(symbol, pybamm.AbsoluteValue):
                return casadi.fabs(converted_child)
            return symbol._unary_evaluate(converted_child)

        elif isinstance(symbol, pybamm.Function):
            converted_children = [
                self.convert(child, t, y, y_dot, inputs) for child in symbol.children
            ]
            # Special functions
            if symbol.function == np.min:
                return casadi.mmin(*converted_children)
            elif symbol.function == np.max:
                return casadi.mmax(*converted_children)
            elif symbol.function == np.abs:
                return casadi.fabs(*converted_children)
            elif symbol.function == np.sqrt:
                return casadi.sqrt(*converted_children)
            elif symbol.function == np.sin:
                return casadi.sin(*converted_children)
            elif symbol.function == np.arcsinh:
                return casadi.arcsinh(*converted_children)
            elif symbol.function == np.arccosh:
                return casadi.arccosh(*converted_children)
            elif symbol.function == np.tanh:
                return casadi.tanh(*converted_children)
            elif symbol.function == np.cosh:
                return casadi.cosh(*converted_children)
            elif symbol.function == np.sinh:
                return casadi.sinh(*converted_children)
            elif symbol.function == np.cos:
                return casadi.cos(*converted_children)
            elif symbol.function == np.exp:
                return casadi.exp(*converted_children)
            elif symbol.function == np.log:
                return casadi.log(*converted_children)
            elif symbol.function == np.sign:
                return casadi.sign(*converted_children)
            elif isinstance(symbol.function, (PchipInterpolator, CubicSpline)):
                return casadi.interpolant("LUT", "bspline", [symbol.x], symbol.y)(
                    *converted_children
                )
            elif symbol.function.__name__.startswith("elementwise_grad_of_"):
                differentiating_child_idx = int(symbol.function.__name__[-1])
                # Create dummy symbolic variables in order to differentiate using CasADi
                dummy_vars = [
                    casadi.MX.sym("y_" + str(i)) for i in range(len(converted_children))
                ]
                func_diff = casadi.gradient(
                    symbol.differentiated_function(*dummy_vars),
                    dummy_vars[differentiating_child_idx],
                )
                # Create function and evaluate it using the children
                casadi_func_diff = casadi.Function("func_diff", dummy_vars, [func_diff])
                return casadi_func_diff(*converted_children)
            # Other functions
            else:
                return symbol._function_evaluate(converted_children)
        elif isinstance(symbol, pybamm.Concatenation):
            converted_children = [
                self.convert(child, t, y, y_dot, inputs) for child in symbol.children
            ]
            if isinstance(symbol, (pybamm.NumpyConcatenation, pybamm.SparseStack)):
                return casadi.vertcat(*converted_children)
            # DomainConcatenation specifies a particular ordering for the concatenation,
            # which we must follow
            elif isinstance(symbol, pybamm.DomainConcatenation):
                slice_starts = []
                all_child_vectors = []
                for i in range(symbol.secondary_dimensions_npts):
                    child_vectors = []
                    for child_var, slices in zip(
                        converted_children, symbol._children_slices
                    ):
                        for child_dom, child_slice in slices.items():
                            slice_starts.append(symbol._slices[child_dom][i].start)
                            child_vectors.append(
                                child_var[child_slice[i].start : child_slice[i].stop]
                            )
                    all_child_vectors.extend(
                        [v for _, v in sorted(zip(slice_starts, child_vectors))]
                    )
                return casadi.vertcat(*all_child_vectors)

        else:
            raise TypeError(
                """
                Cannot convert symbol of type '{}' to CasADi. Symbols must all be
                'linear algebra' at this stage.
                """.format(
                    type(symbol)
                )
            )
Exemplo n.º 27
0
def setupModel(dae, conf):
    #  PARAMETERS OF THE KITE :
    #  ##############
    m =  conf['mass'] #  mass of the kite               #  [ kg    ]
                 
    #   PHYSICAL CONSTANTS :
    #  ##############
    g = conf['g'] #  gravitational constant         #  [ m /s^2]
    
    #  PARAMETERS OF THE CABLE :
    #  ##############
     
    #INERTIA MATRIX (Kurt's direct measurements)
    j1 =  conf['j1']
    j31 = conf['j31']
    j2 =  conf['j2']
    j3 =  conf['j3']
    
    #Carousel Friction & inertia
    jCarousel = conf['jCarousel']
    cfric = conf['cfric']

    zt = conf['zt']
    rA = conf['rArm']

    ###########     model integ ###################
    e11 = dae['e11']
    e12 = dae['e12']
    e13 = dae['e13']

    e21 = dae['e21']
    e22 = dae['e22']
    e23 = dae['e23']

    e31 = dae['e31']
    e32 = dae['e32']
    e33 = dae['e33']
                   
    x =   dae['x']
    y =   dae['y']
    z =   dae['z']

    dx  =  dae['dx']
    dy  =  dae['dy']
    dz  =  dae['dz']

    w1  =  dae['w1']
    w2  =  dae['w2']
    w3  =  dae['w3']

    ddelta = dae['ddelta']

    r = dae['r']
    dr = dae['dr']
    
    ddr = dae['ddr']
    
    tc = dae['motor_torque'] #Carousel motor torque

    # wind
    if 'w0' in dae:
        z0 = conf['z0']
        zt_roughness = conf['zt_roughness']
        zsat = 0.5*(z+C.sqrt(z*z))
        wind_x = dae['w0']*C.log((zsat+zt_roughness+2)/zt_roughness)/C.log(z0/zt_roughness)
    else:
        wind_x = 0
    dae['wind at altitude'] = wind_x

    dp_carousel_frame = C.veccat( [ dx - ddelta*y
                                  , dy + ddelta*(rA + x)
                                  , dz
                                  ]) - C.veccat([dae['cos_delta']*wind_x, dae['sin_delta']*wind_x, 0])
    R_c2b = C.veccat( [dae[n] for n in ['e11', 'e12', 'e13',
                                        'e21', 'e22', 'e23',
                                        'e31', 'e32', 'e33']]
                      ).reshape((3,3))

    # Aircraft velocity w.r.t. inertial frame, given in its own reference frame
    # (needed to compute the aero forces and torques !)
    dpE = C.mul( R_c2b, dp_carousel_frame )

    (f1, f2, f3, t1, t2, t3) = aeroForcesTorques(dae, conf, dp_carousel_frame, dpE,
                                                 (dae['w1'], dae['w2'], dae['w3']),
                                                 (dae['e21'], dae['e22'], dae['e23']),
                                                 (dae['aileron'],dae['elevator'])
                                                 )

    # mass matrix
    mm = C.SXMatrix(8, 8)
    mm[0,0] = jCarousel + m*rA*rA + m*x*x + m*y*y + 2*m*rA*x 
    mm[0,1] = -m*y 
    mm[0,2] = m*(rA + x) 
    mm[0,3] = 0 
    mm[0,4] = 0 
    mm[0,5] = 0 
    mm[0,6] = 0 
    mm[0,7] = 0
    
    mm[1,0] = -m*y 
    mm[1,1] = m 
    mm[1,2] = 0 
    mm[1,3] = 0 
    mm[1,4] = 0 
    mm[1,5] = 0 
    mm[1,6] = 0 
    mm[1,7] = x + zt*e31
    
    mm[2,0] = m*(rA + x) 
    mm[2,1] = 0 
    mm[2,2] = m 
    mm[2,3] = 0 
    mm[2,4] = 0 
    mm[2,5] = 0 
    mm[2,6] = 0 
    mm[2,7] = y + zt*e32
    
    mm[3,0] = 0 
    mm[3,1] = 0 
    mm[3,2] = 0 
    mm[3,3] = m 
    mm[3,4] = 0 
    mm[3,5] = 0 
    mm[3,6] = 0 
    mm[3,7] = z + zt*e33
    
    mm[4,0] = 0 
    mm[4,1] = 0 
    mm[4,2] = 0 
    mm[4,3] = 0 
    mm[4,4] = j1 
    mm[4,5] = 0 
    mm[4,6] = j31 
    mm[4,7] = -zt*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33)
    
    mm[5,0] = 0 
    mm[5,1] = 0 
    mm[5,2] = 0 
    mm[5,3] = 0 
    mm[5,4] = 0 
    mm[5,5] = j2 
    mm[5,6] = 0 
    mm[5,7] = zt*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33)
    
    mm[6,0] = 0 
    mm[6,1] = 0 
    mm[6,2] = 0 
    mm[6,3] = 0 
    mm[6,4] = j31 
    mm[6,5] = 0 
    mm[6,6] = j3 
    mm[6,7] = 0
    
    mm[7,0] = -zt*(e11*e23*x - e13*e21*x + e12*e23*y - e13*e22*y + zt*e11*e23*e31 - zt*e13*e21*e31 + zt*e12*e23*e32 - zt*e13*e22*e32) 
    mm[7,1] = x + zt*e31 
    mm[7,2] = y + zt*e32 
    mm[7,3] = z + zt*e33 
    mm[7,4] = -zt*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33) 
    mm[7,5] = zt*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) 
    mm[7,6] = 0 
    mm[7,7] = 0

    # right hand side
    zt2 = zt*zt
    rhs = C.veccat(
          [ tc - cfric*ddelta - f1*y + f2*(rA + x) + dy*m*(dx - 2*ddelta*y) - dx*m*(dy + 2*ddelta*rA + 2*ddelta*x) 
          , f1 + ddelta*m*(dy + ddelta*rA + ddelta*x) + ddelta*dy*m 
          , f2 - ddelta*m*(dx - ddelta*y) - ddelta*dx*m 
          , f3 - g*m 
          , t1 - w2*(j3*w3 + j31*w1) + j2*w2*w3 
          , t2 + w1*(j3*w3 + j31*w1) - w3*(j1*w1 + j31*w3) 
          , t3 + w2*(j1*w1 + j31*w3) - j2*w1*w2
          , ddr*r-(zt*w1*(e11*x+e12*y+e13*z+zt*e11*e31+zt*e12*e32+zt*e13*e33)+zt*w2*(e21*x+e22*y+e23*z+zt*e21*e31+zt*e22*e32+zt*e23*e33))*(w3-ddelta*e33)-dx*(dx-zt*e21*(w1-ddelta*e13)+zt*e11*(w2-ddelta*e23))-dy*(dy-zt*e22*(w1-ddelta*e13)+zt*e12*(w2-ddelta*e23))-dz*(dz-zt*e23*(w1-ddelta*e13)+zt*e13*(w2-ddelta*e23))+dr*dr+(w1-ddelta*e13)*(e21*(zt*dx-zt2*e21*(w1-ddelta*e13)+zt2*e11*(w2-ddelta*e23))+e22*(zt*dy-zt2*e22*(w1-ddelta*e13)+zt2*e12*(w2-ddelta*e23))+zt*e23*(dz+zt*e13*w2-zt*e23*w1)+zt*e33*(w1*z+zt*e33*w1+ddelta*e11*x+ddelta*e12*y+zt*ddelta*e11*e31+zt*ddelta*e12*e32)+zt*e31*(x+zt*e31)*(w1-ddelta*e13)+zt*e32*(y+zt*e32)*(w1-ddelta*e13))-(w2-ddelta*e23)*(e11*(zt*dx-zt2*e21*(w1-ddelta*e13)+zt2*e11*(w2-ddelta*e23))+e12*(zt*dy-zt2*e22*(w1-ddelta*e13)+zt2*e12*(w2-ddelta*e23))+zt*e13*(dz+zt*e13*w2-zt*e23*w1)-zt*e33*(w2*z+zt*e33*w2+ddelta*e21*x+ddelta*e22*y+zt*ddelta*e21*e31+zt*ddelta*e22*e32)-zt*e31*(x+zt*e31)*(w2-ddelta*e23)-zt*e32*(y+zt*e32)*(w2-ddelta*e23))
          ] )
 
    dRexp = C.SXMatrix(3,3)

    dRexp[0,0] = e21*(w3 - ddelta*e33) - e31*(w2 - ddelta*e23) 
    dRexp[0,1] = e31*(w1 - ddelta*e13) - e11*(w3 - ddelta*e33) 
    dRexp[0,2] = e11*(w2 - ddelta*e23) - e21*(w1 - ddelta*e13) 

    dRexp[1,0] = e22*(w3 - ddelta*e33) - e32*(w2 - ddelta*e23) 
    dRexp[1,1] = e32*(w1 - ddelta*e13) - e12*(w3 - ddelta*e33) 
    dRexp[1,2] = e12*(w2 - ddelta*e23) - e22*(w1 - ddelta*e13) 

    dRexp[2,0] = e23*w3 - e33*w2 
    dRexp[2,1] = e33*w1 - e13*w3 
    dRexp[2,2] = e13*w2 - e23*w1
    
    c =(x + zt*e31)**2/2 + (y + zt*e32)**2/2 + (z + zt*e33)**2/2 - r**2/2
    
    cdot =dx*(x + zt*e31) + dy*(y + zt*e32) + dz*(z + zt*e33) + zt*(w2 - ddelta*e23)*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) - zt*(w1 - ddelta*e13)*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33) - r*dr

#    ddx = dae['ddx']
#    ddy = dae['ddy']
#    ddz = dae['ddz']
#    dw1 = dae['dw1']
#    dw2 = dae['dw2']
#    dddelta = dae['dddelta']
    ddx = dae.ddt('dx')
    ddy = dae.ddt('dy')
    ddz = dae.ddt('dz')
    dw1 = dae.ddt('w1')
    dw2 = dae.ddt('w2')
    dddelta = dae.ddt('ddelta')
    
    cddot = -(w1-ddelta*e13)*(zt*e23*(dz+zt*e13*w2-zt*e23*w1)+zt*e33*(w1*z+zt*e33*w1+ddelta*e11*x+ddelta*e12*y+zt*ddelta*e11*e31+zt*ddelta*e12*e32)+zt*e21*(dx+zt*e11*w2-zt*e21*w1-zt*ddelta*e11*e23+zt*ddelta*e13*e21)+zt*e22*(dy+zt*e12*w2-zt*e22*w1-zt*ddelta*e12*e23+zt*ddelta*e13*e22)+zt*e31*(x+zt*e31)*(w1-ddelta*e13)+zt*e32*(y+zt*e32)*(w1-ddelta*e13))+(w2-ddelta*e23)*(zt*e13*(dz+zt*e13*w2-zt*e23*w1)-zt*e33*(w2*z+zt*e33*w2+ddelta*e21*x+ddelta*e22*y+zt*ddelta*e21*e31+zt*ddelta*e22*e32)+zt*e11*(dx+zt*e11*w2-zt*e21*w1-zt*ddelta*e11*e23+zt*ddelta*e13*e21)+zt*e12*(dy+zt*e12*w2-zt*e22*w1-zt*ddelta*e12*e23+zt*ddelta*e13*e22)-zt*e31*(x+zt*e31)*(w2-ddelta*e23)-zt*e32*(y+zt*e32)*(w2-ddelta*e23))-ddr*r+(zt*w1*(e11*x+e12*y+e13*z+zt*e11*e31+zt*e12*e32+zt*e13*e33)+zt*w2*(e21*x+e22*y+e23*z+zt*e21*e31+zt*e22*e32+zt*e23*e33))*(w3-ddelta*e33)+dx*(dx+zt*e11*w2-zt*e21*w1-zt*ddelta*e11*e23+zt*ddelta*e13*e21)+dy*(dy+zt*e12*w2-zt*e22*w1-zt*ddelta*e12*e23+zt*ddelta*e13*e22)+dz*(dz+zt*e13*w2-zt*e23*w1)+ddx*(x+zt*e31)+ddy*(y+zt*e32)+ddz*(z+zt*e33)-dr*dr+zt*(dw2-dddelta*e23)*(e11*x+e12*y+e13*z+zt*e11*e31+zt*e12*e32+zt*e13*e33)-zt*(dw1-dddelta*e13)*(e21*x+e22*y+e23*z+zt*e21*e31+zt*e22*e32+zt*e23*e33)-zt*dddelta*(e11*e23*x-e13*e21*x+e12*e23*y-e13*e22*y+zt*e11*e23*e31-zt*e13*e21*e31+zt*e12*e23*e32-zt*e13*e22*e32)

#    cddot = (zt*w1*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) + zt*w2*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33))*(w3 - ddelta*e33) + dx*(dx + zt*e11*w2 - zt*e21*w1 - zt*ddelta*e11*e23 + zt*ddelta*e13*e21) + dy*(dy + zt*e12*w2 - zt*e22*w1 - zt*ddelta*e12*e23 + zt*ddelta*e13*e22) + dz*(dz + zt*e13*w2 - zt*e23*w1) + ddx*(x + zt*e31) + ddy*(y + zt*e32) + ddz*(z + zt*e33) - (w1 - ddelta*e13)*(e21*(zt*dx - zt**2*e21*(w1 - ddelta*e13) + zt**2*e11*(w2 - ddelta*e23)) + e22*(zt*dy - zt**2*e22*(w1 - ddelta*e13) + zt**2*e12*(w2 - ddelta*e23)) + zt*e33*(z*w1 + ddelta*e11*x + ddelta*e12*y + zt*e33*w1 + zt*ddelta*e11*e31 + zt*ddelta*e12*e32) + zt*e23*(dz + zt*e13*w2 - zt*e23*w1) + zt*e31*(w1 - ddelta*e13)*(x + zt*e31) + zt*e32*(w1 - ddelta*e13)*(y + zt*e32)) + (w2 - ddelta*e23)*(e11*(zt*dx - zt**2*e21*(w1 - ddelta*e13) + zt**2*e11*(w2 - ddelta*e23)) + e12*(zt*dy - zt**2*e22*(w1 - ddelta*e13) + zt**2*e12*(w2 - ddelta*e23)) - zt*e33*(z*w2 + ddelta*e21*x + ddelta*e22*y + zt*e33*w2 + zt*ddelta*e21*e31 + zt*ddelta*e22*e32) + zt*e13*(dz + zt*e13*w2 - zt*e23*w1) - zt*e31*(w2 - ddelta*e23)*(x + zt*e31) - zt*e32*(w2 - ddelta*e23)*(y + zt*e32)) + zt*(dw2 - dddelta*e23)*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) - zt*(dw1 - dddelta*e13)*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33) - zt*dddelta*(e11*e23*x - e13*e21*x + e12*e23*y - e13*e22*y + zt*e11*e23*e31 - zt*e13*e21*e31 + zt*e12*e23*e32 - zt*e13*e22*e32)
#      where
#        dw1 = dw @> 0
#        dw2 = dw @> 1
#        {-
#        dw3 = dw @> 2
#        -}
#        ddx = ddX @> 0
#        ddy = ddX @> 1
#        ddz = ddX @> 2
#        dddelta = dddelta' @> 0

    dae['c'] =  c
    dae['cdot'] = cdot
    dae['cddot'] = cddot
    return (mm, rhs, dRexp)
Exemplo n.º 28
0
FIM1_maxeigv = []
for i in range(np.shape(xp_opt)[1] - 1):
    xp_r = np.reshape(xp_opt[:, i + 1], (2, 4))
    #    vv = np.zeros([ntheta[0], ntheta[0], 1 + N])
    #    for i in range(0, 1 + N):
    FIM_t += [xp_r.T @ np.linalg.inv(np.array([[0.01, 0], [0, 0.05]])) @ xp_r]

obsFIM = []
for i in range(np.shape(FIM_t)[0]):
    obsFIM += [
        np.linalg.inv((((10.0 - 0.001)**2) / 12) * np.identity(n_theta)) +
        sum(FIM_t[:i + 1])
    ]

for i in range(np.shape(xp_opt)[1] - 1):
    FIM1_det += [2 * cad.sum1(cad.log(cad.diag(cad.chol(obsFIM[i]))))]
    FIM1_trace += [cad.trace(obsFIM[i])]
    FIM_det += [2 * np.sum(np.log(np.diag(np.linalg.cholesky(obsFIM[i]))))]
    FIM_trace += [np.trace(obsFIM[i])]
    FIM1_mineigv += [min(np.linalg.eig(obsFIM[i])[0])]
    FIM1_maxeigv += [max(np.linalg.eig(obsFIM[i])[0])]

V_theta = np.linalg.inv(sum(FIM_t[i] for i in range(len(FIM_t))))
theta1 = w_opt[n_x + n_x * n_theta:n_x + n_x * n_theta + n_theta]

t_value = np.zeros(n_theta)
for i in range(n_theta):
    t_value[i] = theta1[i] / np.sqrt(V_theta[i, i])

FIM1_trace_array = np.array(FIM1_trace)
FIM1_det_array = np.array(FIM1_det)
Exemplo n.º 29
0
####################################################################################################
# SET UP MODEL
####################################################################################################

#define input and parameters
x = cs.SX.sym('x', 1)
xnames = ['Light']
p = cs.SX.sym('p', 5)
pnames = ['alpha0', 'alpha', 'n', 'K', 'gamma']

#define steady state
gfp_mean = cs.exp(p[0]) + cs.exp(p[1]) * x[0]**cs.exp(
    p[2]) / (cs.exp(p[3])**cs.exp(p[2]) + x[0]**cs.exp(p[2]))
gfp_var = cs.exp(p[4]) * gfp_mean

geo_mean = cs.log(gfp_mean**2 / cs.sqrt(gfp_mean**2 + gfp_var))
geo_var = cs.log(1 + gfp_var / gfp_mean**2)
#geo_mean = 2/3 * cs.log(gfp_mean) - 1/2 * cs.log(cs.exp(p[4]) + gfp_mean)
#2 * cs.log(gfp_mean) - 1/2 * cs.log(p[4]*gfp_mean + gfp_mean**2)
#geo_var = cs.log(cs.exp(p[4]) + gfp_mean) - cs.log(gfp_mean)

#link the deterministic model to the sampling statistics (here normal mean and variance)
lognorm_stats = cs.vertcat(geo_mean, geo_var)

#create a casadi function mapping input and parameters to sampling statistics (mean and var)
y = cs.Function('GFP', [x, p], [lognorm_stats])

# enter the function as a tuple with label indicating normal error, into observation list
observ_list = [(y, 'Lognormal')]

#instantiate nloed model class
Exemplo n.º 30
0
def setupModel(dae, conf):
    #  PARAMETERS OF THE KITE :
    #  ##############
    m = conf["kite"]["mass"]  #  mass of the kite               #  [ kg    ]

    #   PHYSICAL CONSTANTS :
    #  ##############
    g = conf["env"]["g"]  #  gravitational constant         #  [ m /s^2]

    #  PARAMETERS OF THE CABLE :
    #  ##############

    # INERTIA MATRIX (Kurt's direct measurements)
    j1 = conf["kite"]["j1"]
    j31 = conf["kite"]["j31"]
    j2 = conf["kite"]["j2"]
    j3 = conf["kite"]["j3"]

    # Carousel Friction & inertia
    jCarousel = conf["carousel"]["jCarousel"]
    cfric = conf["carousel"]["cfric"]

    zt = conf["kite"]["zt"]
    rA = conf["carousel"]["rArm"]

    ###########     model integ ###################
    e11 = dae.x("e11")
    e12 = dae.x("e12")
    e13 = dae.x("e13")

    e21 = dae.x("e21")
    e22 = dae.x("e22")
    e23 = dae.x("e23")

    e31 = dae.x("e31")
    e32 = dae.x("e32")
    e33 = dae.x("e33")

    x = dae.x("x")
    y = dae.x("y")
    z = dae.x("z")

    dx = dae.x("dx")
    dy = dae.x("dy")
    dz = dae.x("dz")

    w1 = dae.x("w1")
    w2 = dae.x("w2")
    w3 = dae.x("w3")

    delta = 0
    ddelta = 0

    r = dae.x("r")
    dr = dae.x("dr")

    ddr = dae.u("ddr")

    # wind
    z0 = conf["wind shear"]["z0"]
    zt_roughness = conf["wind shear"]["zt_roughness"]
    zsat = 0.5 * (z + C.sqrt(z * z))
    wind_x = dae.p("w0") * C.log((zsat + zt_roughness + 2) / zt_roughness) / C.log(z0 / zt_roughness)
    dae.addOutput("wind at altitude", wind_x)
    dae.addOutput("w0", dae.p("w0"))

    dp_carousel_frame = C.veccat([dx - ddelta * y, dy + ddelta * (rA + x), dz]) - C.veccat(
        [C.cos(delta) * wind_x, C.sin(delta) * wind_x, 0]
    )
    R_c2b = C.veccat(dae.x(["e11", "e12", "e13", "e21", "e22", "e23", "e31", "e32", "e33"])).reshape((3, 3))

    # Aircraft velocity w.r.t. inertial frame, given in its own reference frame
    # (needed to compute the aero forces and torques !)
    dpE = C.mul(R_c2b, dp_carousel_frame)

    (f1, f2, f3, t1, t2, t3) = aeroForcesTorques(
        dae,
        conf,
        dp_carousel_frame,
        dpE,
        dae.x(("w1", "w2", "w3")),
        dae.x(("e21", "e22", "e23")),
        dae.u(("aileron", "elevator")),
    )

    # mass matrix
    mm = C.SXMatrix(7, 7)
    mm[0, 0] = m
    mm[0, 1] = 0
    mm[0, 2] = 0
    mm[0, 3] = 0
    mm[0, 4] = 0
    mm[0, 5] = 0
    mm[0, 6] = x + zt * e31

    mm[1, 0] = 0
    mm[1, 1] = m
    mm[1, 2] = 0
    mm[1, 3] = 0
    mm[1, 4] = 0
    mm[1, 5] = 0
    mm[1, 6] = y + zt * e32

    mm[2, 0] = 0
    mm[2, 1] = 0
    mm[2, 2] = m
    mm[2, 3] = 0
    mm[2, 4] = 0
    mm[2, 5] = 0
    mm[2, 6] = z + zt * e33

    mm[3, 0] = 0
    mm[3, 1] = 0
    mm[3, 2] = 0
    mm[3, 3] = j1
    mm[3, 4] = 0
    mm[3, 5] = j31
    mm[3, 6] = -zt * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)

    mm[4, 0] = 0
    mm[4, 1] = 0
    mm[4, 2] = 0
    mm[4, 3] = 0
    mm[4, 4] = j2
    mm[4, 5] = 0
    mm[4, 6] = zt * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)

    mm[5, 0] = 0
    mm[5, 1] = 0
    mm[5, 2] = 0
    mm[5, 3] = j31
    mm[5, 4] = 0
    mm[5, 5] = j3
    mm[5, 6] = 0

    mm[6, 0] = x + zt * e31
    mm[6, 1] = y + zt * e32
    mm[6, 2] = z + zt * e33
    mm[6, 3] = -zt * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)
    mm[6, 4] = zt * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)
    mm[6, 5] = 0
    mm[6, 6] = 0

    # right hand side
    zt2 = zt * zt
    rhs = C.veccat(
        [
            f1 + ddelta * m * (dy + ddelta * rA + ddelta * x) + ddelta * dy * m,
            f2 - ddelta * m * (dx - ddelta * y) - ddelta * dx * m,
            f3 - g * m,
            t1 - w2 * (j3 * w3 + j31 * w1) + j2 * w2 * w3,
            t2 + w1 * (j3 * w3 + j31 * w1) - w3 * (j1 * w1 + j31 * w3),
            t3 + w2 * (j1 * w1 + j31 * w3) - j2 * w1 * w2,
            ddr * r
            - (
                zt * w1 * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)
                + zt * w2 * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)
            )
            * (w3 - ddelta * e33)
            - dx * (dx - zt * e21 * (w1 - ddelta * e13) + zt * e11 * (w2 - ddelta * e23))
            - dy * (dy - zt * e22 * (w1 - ddelta * e13) + zt * e12 * (w2 - ddelta * e23))
            - dz * (dz - zt * e23 * (w1 - ddelta * e13) + zt * e13 * (w2 - ddelta * e23))
            + dr * dr
            + (w1 - ddelta * e13)
            * (
                e21 * (zt * dx - zt2 * e21 * (w1 - ddelta * e13) + zt2 * e11 * (w2 - ddelta * e23))
                + e22 * (zt * dy - zt2 * e22 * (w1 - ddelta * e13) + zt2 * e12 * (w2 - ddelta * e23))
                + zt * e23 * (dz + zt * e13 * w2 - zt * e23 * w1)
                + zt
                * e33
                * (
                    w1 * z
                    + zt * e33 * w1
                    + ddelta * e11 * x
                    + ddelta * e12 * y
                    + zt * ddelta * e11 * e31
                    + zt * ddelta * e12 * e32
                )
                + zt * e31 * (x + zt * e31) * (w1 - ddelta * e13)
                + zt * e32 * (y + zt * e32) * (w1 - ddelta * e13)
            )
            - (w2 - ddelta * e23)
            * (
                e11 * (zt * dx - zt2 * e21 * (w1 - ddelta * e13) + zt2 * e11 * (w2 - ddelta * e23))
                + e12 * (zt * dy - zt2 * e22 * (w1 - ddelta * e13) + zt2 * e12 * (w2 - ddelta * e23))
                + zt * e13 * (dz + zt * e13 * w2 - zt * e23 * w1)
                - zt
                * e33
                * (
                    w2 * z
                    + zt * e33 * w2
                    + ddelta * e21 * x
                    + ddelta * e22 * y
                    + zt * ddelta * e21 * e31
                    + zt * ddelta * e22 * e32
                )
                - zt * e31 * (x + zt * e31) * (w2 - ddelta * e23)
                - zt * e32 * (y + zt * e32) * (w2 - ddelta * e23)
            ),
        ]
    )

    dRexp = C.SXMatrix(3, 3)

    dRexp[0, 0] = e21 * (w3 - ddelta * e33) - e31 * (w2 - ddelta * e23)
    dRexp[0, 1] = e31 * (w1 - ddelta * e13) - e11 * (w3 - ddelta * e33)
    dRexp[0, 2] = e11 * (w2 - ddelta * e23) - e21 * (w1 - ddelta * e13)

    dRexp[1, 0] = e22 * (w3 - ddelta * e33) - e32 * (w2 - ddelta * e23)
    dRexp[1, 1] = e32 * (w1 - ddelta * e13) - e12 * (w3 - ddelta * e33)
    dRexp[1, 2] = e12 * (w2 - ddelta * e23) - e22 * (w1 - ddelta * e13)

    dRexp[2, 0] = e23 * w3 - e33 * w2
    dRexp[2, 1] = e33 * w1 - e13 * w3
    dRexp[2, 2] = e13 * w2 - e23 * w1

    c = (x + zt * e31) ** 2 / 2 + (y + zt * e32) ** 2 / 2 + (z + zt * e33) ** 2 / 2 - r ** 2 / 2

    cdot = (
        dx * (x + zt * e31)
        + dy * (y + zt * e32)
        + dz * (z + zt * e33)
        + zt * (w2 - ddelta * e23) * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)
        - zt * (w1 - ddelta * e13) * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)
        - r * dr
    )

    ddx = dae.z("ddx")
    ddy = dae.z("ddy")
    ddz = dae.z("ddz")
    dw1 = dae.z("dw1")
    dw2 = dae.z("dw2")
    dddelta = 0

    cddot = (
        -(w1 - ddelta * e13)
        * (
            zt * e23 * (dz + zt * e13 * w2 - zt * e23 * w1)
            + zt
            * e33
            * (
                w1 * z
                + zt * e33 * w1
                + ddelta * e11 * x
                + ddelta * e12 * y
                + zt * ddelta * e11 * e31
                + zt * ddelta * e12 * e32
            )
            + zt * e21 * (dx + zt * e11 * w2 - zt * e21 * w1 - zt * ddelta * e11 * e23 + zt * ddelta * e13 * e21)
            + zt * e22 * (dy + zt * e12 * w2 - zt * e22 * w1 - zt * ddelta * e12 * e23 + zt * ddelta * e13 * e22)
            + zt * e31 * (x + zt * e31) * (w1 - ddelta * e13)
            + zt * e32 * (y + zt * e32) * (w1 - ddelta * e13)
        )
        + (w2 - ddelta * e23)
        * (
            zt * e13 * (dz + zt * e13 * w2 - zt * e23 * w1)
            - zt
            * e33
            * (
                w2 * z
                + zt * e33 * w2
                + ddelta * e21 * x
                + ddelta * e22 * y
                + zt * ddelta * e21 * e31
                + zt * ddelta * e22 * e32
            )
            + zt * e11 * (dx + zt * e11 * w2 - zt * e21 * w1 - zt * ddelta * e11 * e23 + zt * ddelta * e13 * e21)
            + zt * e12 * (dy + zt * e12 * w2 - zt * e22 * w1 - zt * ddelta * e12 * e23 + zt * ddelta * e13 * e22)
            - zt * e31 * (x + zt * e31) * (w2 - ddelta * e23)
            - zt * e32 * (y + zt * e32) * (w2 - ddelta * e23)
        )
        - ddr * r
        + (
            zt * w1 * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)
            + zt * w2 * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)
        )
        * (w3 - ddelta * e33)
        + dx * (dx + zt * e11 * w2 - zt * e21 * w1 - zt * ddelta * e11 * e23 + zt * ddelta * e13 * e21)
        + dy * (dy + zt * e12 * w2 - zt * e22 * w1 - zt * ddelta * e12 * e23 + zt * ddelta * e13 * e22)
        + dz * (dz + zt * e13 * w2 - zt * e23 * w1)
        + ddx * (x + zt * e31)
        + ddy * (y + zt * e32)
        + ddz * (z + zt * e33)
        - dr * dr
        + zt * (dw2 - dddelta * e23) * (e11 * x + e12 * y + e13 * z + zt * e11 * e31 + zt * e12 * e32 + zt * e13 * e33)
        - zt * (dw1 - dddelta * e13) * (e21 * x + e22 * y + e23 * z + zt * e21 * e31 + zt * e22 * e32 + zt * e23 * e33)
        - zt
        * dddelta
        * (
            e11 * e23 * x
            - e13 * e21 * x
            + e12 * e23 * y
            - e13 * e22 * y
            + zt * e11 * e23 * e31
            - zt * e13 * e21 * e31
            + zt * e12 * e23 * e32
            - zt * e13 * e22 * e32
        )
    )

    #    cddot = (zt*w1*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) + zt*w2*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33))*(w3 - ddelta*e33) + dx*(dx + zt*e11*w2 - zt*e21*w1 - zt*ddelta*e11*e23 + zt*ddelta*e13*e21) + dy*(dy + zt*e12*w2 - zt*e22*w1 - zt*ddelta*e12*e23 + zt*ddelta*e13*e22) + dz*(dz + zt*e13*w2 - zt*e23*w1) + ddx*(x + zt*e31) + ddy*(y + zt*e32) + ddz*(z + zt*e33) - (w1 - ddelta*e13)*(e21*(zt*dx - zt**2*e21*(w1 - ddelta*e13) + zt**2*e11*(w2 - ddelta*e23)) + e22*(zt*dy - zt**2*e22*(w1 - ddelta*e13) + zt**2*e12*(w2 - ddelta*e23)) + zt*e33*(z*w1 + ddelta*e11*x + ddelta*e12*y + zt*e33*w1 + zt*ddelta*e11*e31 + zt*ddelta*e12*e32) + zt*e23*(dz + zt*e13*w2 - zt*e23*w1) + zt*e31*(w1 - ddelta*e13)*(x + zt*e31) + zt*e32*(w1 - ddelta*e13)*(y + zt*e32)) + (w2 - ddelta*e23)*(e11*(zt*dx - zt**2*e21*(w1 - ddelta*e13) + zt**2*e11*(w2 - ddelta*e23)) + e12*(zt*dy - zt**2*e22*(w1 - ddelta*e13) + zt**2*e12*(w2 - ddelta*e23)) - zt*e33*(z*w2 + ddelta*e21*x + ddelta*e22*y + zt*e33*w2 + zt*ddelta*e21*e31 + zt*ddelta*e22*e32) + zt*e13*(dz + zt*e13*w2 - zt*e23*w1) - zt*e31*(w2 - ddelta*e23)*(x + zt*e31) - zt*e32*(w2 - ddelta*e23)*(y + zt*e32)) + zt*(dw2 - dddelta*e23)*(e11*x + e12*y + e13*z + zt*e11*e31 + zt*e12*e32 + zt*e13*e33) - zt*(dw1 - dddelta*e13)*(e21*x + e22*y + e23*z + zt*e21*e31 + zt*e22*e32 + zt*e23*e33) - zt*dddelta*(e11*e23*x - e13*e21*x + e12*e23*y - e13*e22*y + zt*e11*e23*e31 - zt*e13*e21*e31 + zt*e12*e23*e32 - zt*e13*e22*e32)
    #      where
    #        dw1 = dw @> 0
    #        dw2 = dw @> 1
    #        {-
    #        dw3 = dw @> 2
    #        -}
    #        ddx = ddX @> 0
    #        ddy = ddX @> 1
    #        ddz = ddX @> 2
    #        dddelta = dddelta' @> 0

    dae.addOutput("c", c)
    dae.addOutput("cdot", cdot)
    dae.addOutput("cddot", cddot)
    return (mm, rhs, dRexp)
Exemplo n.º 31
0
    def variable(
        self,
        n_vars: int = 1,
        init_guess: Union[float, np.ndarray] = None,
        scale: float = None,
        log_transform: bool = False,
        category: str = "Uncategorized",
        freeze: bool = False,
    ) -> cas.MX:
        """
        Initializes a new decision variable (or vector of decision variables, if n_vars != 1).
        
        It is recommended that you provide an initial guess (`init_guess`) and scale (`scale`) for each variable,
        although these are not strictly required.

        Args:
            n_vars: [Optional] Number of variables to initialize (used to initialize a vector of variables). If you are
                initializing a scalar variable (the most typical case), leave this equal to 1. When using vector variables,
                individual components of this vector of variables can be accessed via normal indexing.

                Example:
                    >>> opti = asb.Opti()
                    >>> my_var = opti.variable(n_vars = 5)
                    >>> opti.subject_to(my_var[3] >= my_var[2])  # This is a valid way of indexing
                    >>> my_sum = asb.cas.sum1(my_var)  # This will sum up all elements of `my_var`

            init_guess: [Optional] Initial guess for the variable being initialized. For scalar variables, this should be a
                float. For vector variables (see `n_vars`), you can provide either a float (in which case all elements
                of the vector will be initialized to the given value) or an iterable of equal length (in which case
                each element will be initialized to the corresponding value in the given iterable).

                In the case where the variable is to be log-transformed (see `log_transform`), the initial guess should
                not be log-transformed as well; this happens under the hood. The initial guess must, of course, be a
                positive number in this case.

                If not specified, initial guess defaults to 0 for non-log-transformed variables and 1 for
                log-transformed variables.

            scale: [Optional] Approximate scale of the variable. If not specified, defaults to the supplied initial
                guess if one exists; otherwise, defaults to 1.

            log_transform: [Optional] Advanced use only. A flag of whether to internally-log-transform this variable
            before passing it to the optimizer. Good for known positive engineering quantities that become nonsensical
            if negative (e.g. mass). Log-transforming these variables can help maintain convexity.

            category: [Optional] What category of variables does this belong to

        Returns:
            The variable itself as a symbolic CasADi variable (MX type).

        """
        # Validate the inputs
        if log_transform and init_guess is not None:
            if np.any(init_guess <= 0):
                raise ValueError(
                    "If you are initializing a log-transformed variable, the initial guess(es) must be positive."
                )

        # Set defaults
        if init_guess is None:
            init_guess = 1 if log_transform else 0
        if scale is None:
            scale = init_guess if log_transform else 1

        # Validate the inputs
        if np.any(scale <= 0):
            raise ValueError("The 'scale' argument must be a positive number.")

        # If the variable is in a category to be frozen, fix the variable at the initial guess.
        is_manually_frozen = freeze
        if category in self.variable_categories_to_freeze:
            freeze = True

        # If the variable is to be frozen, return the initial guess. Otherwise, define the variable using CasADi symbolics.
        if freeze:
            # var = init_guess * np.ones(n_vars)
            var = self.parameter(n_params=n_vars, value=init_guess)
        else:
            if not log_transform:
                var = scale * super().variable(n_vars)
                self.set_initial(var, init_guess)
            else:
                log_scale = scale / init_guess
                log_var = log_scale * super().variable(n_vars)
                var = cas.exp(log_var)
                self.set_initial(log_var, cas.log(init_guess))

        # Track the variable
        if category not in self.variables_categorized:  # Add a category if it does not exist
            self.variables_categorized[category] = []
        self.variables_categorized[category].append(var)
        var.is_manually_frozen = is_manually_frozen

        return var
import numpy as np
import casadi as cas

opti = cas.Opti()  # Initialize a SAND environment

# Define Assumptions
L = 34.1376 / 2
n = 200
x = cas.linspace(0, L, n)
dx = cas.diff(x)
E = 228e9  # Pa, modulus of CF
G = E / 2 / (1 + 0.5)  # TODO fix this!!! CFRP is not isotropic!
max_allowable_stress = 570e6 / 1.75

log_nominal_diameter = opti.variable(n)
opti.set_initial(log_nominal_diameter, cas.log(200e-3))
nominal_diameter = cas.exp(log_nominal_diameter)

thickness = 0.14e-3 * 5
opti.subject_to([
    nominal_diameter > thickness,
])

# Bending loads

I = cas.pi / 64 * ((nominal_diameter + thickness)**4 -
                   (nominal_diameter - thickness)**4)
EI = E * I
total_lift_force = 9.81 * 103.873 / 2
lift_distribution = "elliptical"
if lift_distribution == "rectangular":
Exemplo n.º 33
0
def logPredProb(rr):
    u = [
        -log(1 + exp(-beta[0] - beta[1] * theta[i] - beta[2] * rr[i]))
        for i in range(nIndiv)
    ]
    return u
Exemplo n.º 34
0
    def __init__(self,
                 op,
                 options,
                 measurements,
                 inputs,
                 time,
                 costType="integral",
                 hs=False):
        """

        """
        self.op = op
        self.options = options
        self.measurements = measurements
        self.inputs = inputs
        self.time = time
        self.costType = costType

        self.prefix = "GreyBox_"
        self.free_parameters = set()

        # if non-constant sample period for measurements
        if hs:
            diffTimePoints = np.diff(time)
            sumTimePoints = np.sum(diffTimePoints)
            self.options['hs'] = diffTimePoints / sumTimePoints

        # create time parameters
        N_meas = len(time)
        self.tf = time[-1]
        self.t0 = time[0]

        # set start and final time
        startTime = self._add_real_parameter('startTime')
        self.op.set('startTime', self.t0)
        finalTime = self._add_real_parameter('finalTime')
        self.op.set('finalTime', self.tf)
        op.setStartTime(MX(self.t0))
        op.setFinalTime(MX(self.tf))

        # Check if free parameters already in model
        for par in self.op.getVariables(self.op.REAL_PARAMETER_INDEPENDENT):
            if par.hasAttributeSet('free'):
                if par.getAttribute('free'):
                    self.free_parameters.add(par.getName())

        for par in self.op.getVariables(self.op.REAL_PARAMETER_DEPENDENT):
            if par.hasAttributeSet('free'):
                if par.getAttribute('free'):
                    self.free_parameters.add(par.getName())

        # set number of collocation elements so their endpoint coincide with measurement points
        self.options['n_e'] = (N_meas - 1)

        # add parameters for noise convariance of measured variables
        # add input real for measured signals
        if costType == "integral":
            self.options['n_cp'] = 1
            self.weight = options['n_e'] / (self.tf - self.t0)

            for var in measurements.keys():
                # Add parameter for noise convariance, set initial guess to base nominal squared
                r = self._add_real_parameter(self.prefix + 'r_' + var)
                base_var = op.getVariable(var)
                value = base_var.getAttribute('nominal').getValue()
                self.op.set(self.prefix + 'r_' + var, value**2)
                r.setAttribute('initialGuess', value**2)
                r.setAttribute('min', 0)

                # Create real input for measurement data
                meas = self._add_real_input(self.prefix + 'measured_' + var)

                # Add w*(y-y_meas)²/r to Objective Integrand
                oi = self.op.getObjectiveIntegrand()
                self.op.setObjectiveIntegrand(
                    oi + self.weight *
                    (base_var.getVar() - meas.getVar())**2 / r.getVar())

                # Add log term and first measurement to objective
                timed_var = self._add_timed_variable(var, time[0])
                obj = self.op.getObjective()
                self.op.setObjective(obj + (N_meas) * casadi.log(r.getVar()) +
                                     (timed_var.getVar() -
                                      measurements[var][0])**2 / r.getVar())

        elif costType == "sum":

            # add parameters for noise convariance of measured variables
            # add timed variable for each variable and measurementpoint
            for var in measurements.keys():

                # Add parameter for noise convariance, set initial guess to base nominal squared
                r = self._add_real_parameter(self.prefix + 'r_' + var)
                base_var = op.getVariable(var)
                value = base_var.getAttribute('nominal').getValue()
                self.op.set(self.prefix + 'r_' + var, value**2)
                r.setAttribute('initialGuess', value**2)
                r.setAttribute('min', 0)

                for i in range(0, len(self.time)):
                    # Add timed variable
                    timed_var = self._add_timed_variable(var, time[i])

                    obj = self.op.getObjective()
                    self.op.setObjective(
                        obj + (timed_var.getVar() - measurements[var][i])**2 /
                        r.getVar())

                # add logterm
                obj = self.op.getObjective()
                self.op.setObjective(obj + (N_meas) * casadi.log(r.getVar()))

        else:
            warning("costType not implemented")

        self._create_external_data()
Exemplo n.º 35
0
    sorted(np.random.choice(range(nFac), nEdgePerIndiv, replace=False))
    for i in range(nIndiv)
]
edges = [(i, e) for i in range(nIndiv) for e in edges_list_of_lists[i]]
# edges = [(i,e) for i in range(nIndiv) for e in sorted(np.random.choice(range(nFac),nEdgePerIndiv,replace=False))]
fac_vals = sorted([np.random.rand() for i in range(nFac)])
theta = [theta_low for i in range(nIndiv // 2)
         ] + [theta_high for i in range(nIndiv - (nIndiv // 2))]
edge_weights = [
    edge_val(theta[indiv_ind], fac_vals[fac_ind])
    for (indiv_ind, fac_ind) in edges
]
weights_mat = sparse((edge_weights, list(zip(*edges)))).toarray()
edge_index = {edge: ind for ind, edge in enumerate(edges)}
used_fac = sorted(list(set(e for (i, e) in edges)))
MMM = nIndiv * max([abs(log(ew)) for ew in edge_weights]) + 1000
# @setmeta(name="$P(Success)$",axes_inset=[0.7,0.05,0.25,0.25])
# def probSuccess(ttheta,rr):
# 	return 1/(1+exp(-beta[0] - beta[1]*ttheta-beta[2]*rr))

# @setmeta(name="$\\log \\left(P(Success)\\right)$",axes_inset=[0.7,0.05,0.25,0.25])
# def logProbSuccess(ttheta,rr):
# 	return -log(1+exp(-beta[0] - beta[1]*ttheta-beta[2]*rr))


def solve_casadi():
    all_xvals = {}
    all_edgeVals = {}
    all_indVals = {}
    all_edgeUtility = {}
    all_indUtility = {}
Exemplo n.º 36
0
def log_utility(utility):
    return log(utility)
Exemplo n.º 37
0
def get_h_i_t():
    w_i, alpha_i, beta_i, b_i, c_i, mu_i, v_i, h_tm1_agg_i, delta_t_agg_i = casadi.SX.sym('w_i'), casadi.SX.sym('alpha_i'), casadi.SX.sym('beta_i'), casadi.SX.sym('b_i'), casadi.SX.sym('c_i'), casadi.SX.sym('mu_i'), casadi.SX.sym('v_i'), casadi.SX.sym('h_tm1_agg_i'), casadi.SX.sym('delta_t_agg_i'),
    boolM = mu_i > 0
    sqrthtpowmu = casadi.sqrt(h_tm1_agg_i) ** mu_i
    zTrue = (w_i + alpha_i * sqrthtpowmu * f_i(delta_t_agg_i, b_i, c_i) ** v_i + beta_i * sqrthtpowmu) ** (2./mu_i)
    sqrtht = casadi.sqrt(h_tm1_agg_i)
    zFalse= (casadi.exp(w_i + alpha_i * f_i(delta_t_agg_i, b_i, c_i)  ** v_i + beta_i * casadi.log(sqrtht)) ** (2.))
    z = casadi.if_else(boolM, zTrue, zFalse)
    return casadi.Function('h_i_t',
        [w_i, alpha_i, beta_i, b_i, c_i, mu_i, v_i, h_tm1_agg_i, delta_t_agg_i],
        [z])
Exemplo n.º 38
0
    def setup(self,
              bending_BC_type="cantilevered"
              ):
        """
        Sets up the problem. Run this last.
        :return: None (in-place)
        """
        ### Discretize and assign loads

        # Discretize
        point_load_locations = [load["location"] for load in self.point_loads]
        point_load_locations.insert(0, 0)
        point_load_locations.append(self.length)
        self.x = cas.vertcat(*[
            cas.linspace(
                point_load_locations[i],
                point_load_locations[i + 1],
                self.points_per_point_load)
            for i in range(len(point_load_locations) - 1)
        ])

        # Post-process the discretization
        self.n = self.x.shape[0]
        dx = cas.diff(self.x)

        # Add point forces
        self.point_forces = cas.GenMX_zeros(self.n - 1)
        for i in range(len(self.point_loads)):
            load = self.point_loads[i]
            self.point_forces[self.points_per_point_load * (i + 1) - 1] = load["force"]

        # Add distributed loads
        self.force_per_unit_length = cas.GenMX_zeros(self.n)
        self.moment_per_unit_length = cas.GenMX_zeros(self.n)
        for load in self.distributed_loads:
            if load["type"] == "uniform":
                self.force_per_unit_length += load["force"] / self.length
            elif load["type"] == "elliptical":
                load_to_add = load["force"] / self.length * (
                        4 / cas.pi * cas.sqrt(1 - (self.x / self.length) ** 2)
                )
                self.force_per_unit_length += load_to_add
            else:
                raise ValueError("Bad value of \"type\" for a load within beam.distributed_loads!")

        # Initialize optimization variables
        log_nominal_diameter = self.opti.variable(self.n)
        self.opti.set_initial(log_nominal_diameter, cas.log(self.diameter_guess))
        self.nominal_diameter = cas.exp(log_nominal_diameter)

        self.opti.subject_to([
            log_nominal_diameter > cas.log(self.thickness)
        ])

        def trapz(x):
            out = (x[:-1] + x[1:]) / 2
            # out[0] += x[0] / 2
            # out[-1] += x[-1] / 2
            return out

        # Mass
        self.volume = cas.sum1(
            cas.pi / 4 * trapz(
                (self.nominal_diameter + self.thickness) ** 2 -
                (self.nominal_diameter - self.thickness) ** 2
            ) * dx
        )
        self.mass = self.volume * self.density

        # Mass proxy
        self.volume_proxy = cas.sum1(
            cas.pi * trapz(
                self.nominal_diameter
            ) * dx * self.thickness
        )
        self.mass_proxy = self.volume_proxy * self.density

        # Find moments of inertia
        self.I = cas.pi / 64 * (  # bending
                (self.nominal_diameter + self.thickness) ** 4 -
                (self.nominal_diameter - self.thickness) ** 4
        )
        self.J = cas.pi / 32 * (  # torsion
                (self.nominal_diameter + self.thickness) ** 4 -
                (self.nominal_diameter - self.thickness) ** 4
        )

        if self.bending:
            # Set up derivatives
            self.u = 1 * self.opti.variable(self.n)
            self.du = 0.1 * self.opti.variable(self.n)
            self.ddu = 0.01 * self.opti.variable(self.n)
            self.dEIddu = 1 * self.opti.variable(self.n)
            self.opti.set_initial(self.u, 0)
            self.opti.set_initial(self.du, 0)
            self.opti.set_initial(self.ddu, 0)
            self.opti.set_initial(self.dEIddu, 0)

            # Define derivatives
            self.opti.subject_to([
                cas.diff(self.u) == trapz(self.du) * dx,
                cas.diff(self.du) == trapz(self.ddu) * dx,
                cas.diff(self.E * self.I * self.ddu) == trapz(self.dEIddu) * dx,
                cas.diff(self.dEIddu) == trapz(self.force_per_unit_length) * dx + self.point_forces,
            ])

            # Add BCs
            if bending_BC_type == "cantilevered":
                self.opti.subject_to([
                    self.u[0] == 0,
                    self.du[0] == 0,
                    self.ddu[-1] == 0,  # No tip moment
                    self.dEIddu[-1] == 0,  # No tip higher order stuff
                ])
            else:
                raise ValueError("Bad value of bending_BC_type!")

            # Stress
            self.stress_axial = (self.nominal_diameter + self.thickness) / 2 * self.E * self.ddu

        if self.torsion:

            # Set up derivatives
            phi = 0.1 * self.opti.variable(self.n)
            dphi = 0.01 * self.opti.variable(self.n)

            # Add forcing term
            ddphi = -self.moment_per_unit_length / (self.G * self.J)

        self.stress = self.stress_axial
        self.opti.subject_to([
            self.stress / self.max_allowable_stress < 1,
            self.stress / self.max_allowable_stress > -1,
        ])