Example #1
0
def log(expr):
    """Logarithm"""
    if type(expr) == GC:
        return GC(se.log(expr.expr),
                  {s: d / expr.expr
                   for s, d in expr.gradients.items()})
    return se.log(expr)
def test_ternary_candidate_models_are_constructed_correctly():
    """Candidate models should be generated for all valid combinations of possible models in the ternary case"""
    features = OrderedDict([("CPM_FORM", (v.T * symengine.log(v.T), v.T**2)),
                            ("SM_FORM", (v.T, )),
                            ("HM_FORM", (symengine.S.One, ))])
    YS = symengine.Symbol('YS')
    V_I, V_J, V_K = symengine.Symbol('V_I'), symengine.Symbol(
        'V_J'), symengine.Symbol('V_K')
    candidate_models = build_candidate_models((('A', 'B', 'C'), 'A'), features)
    assert candidate_models == OrderedDict([
        ('CPM_FORM', [
            [v.T * YS * symengine.log(v.T)],
            [v.T * YS * symengine.log(v.T), v.T**2 * YS],
            [
                v.T * V_I * YS * symengine.log(v.T),
                v.T * V_J * YS * symengine.log(v.T),
                v.T * V_K * YS * symengine.log(v.T)
            ],
            [
                v.T * V_I * YS * symengine.log(v.T), v.T**2 * V_I * YS,
                v.T * V_J * YS * symengine.log(v.T), v.T**2 * V_J * YS,
                v.T * V_K * YS * symengine.log(v.T), v.T**2 * V_K * YS
            ],
        ]),
        ('SM_FORM', [[v.T * YS],
                     [v.T * V_I * YS, v.T * V_J * YS, v.T * V_K * YS]]),
        ('HM_FORM', [[YS], [V_I * YS, V_J * YS, V_K * YS]])
    ])
Example #3
0
def test_log():
    x = Symbol("x")
    x1 = sympy.Symbol("x")

    assert log(x) == log(x1)
    assert log(x)._sympy_() == sympy.log(x1)
    assert sympify(sympy.log(x1)) == log(x)

    y = Symbol("y")
    y1 = sympy.Symbol("y")

    assert log(x, y) == log(x, y1)
    assert log(x1, y) == log(x1, y1)
    assert log(x, y)._sympy_() == sympy.log(x1, y1)
    assert sympify(sympy.log(x1, y1)) == log(x, y)
Example #4
0
def test_log():
    x = Symbol("x")
    x1 = sympy.Symbol("x")

    assert log(x) == log(x1)
    assert log(x)._sympy_() == sympy.log(x1)
    assert sympify(sympy.log(x1)) == log(x)

    y = Symbol("y")
    y1 = sympy.Symbol("y")

    assert log(x, y) == log(x, y1)
    assert log(x1, y) == log(x1, y1)
    assert log(x, y)._sympy_() == sympy.log(x1, y1)
    assert sympify(sympy.log(x1, y1)) == log(x, y)
def test_loggamma():
    assert loggamma(-1) == oo
    assert loggamma(-2) == oo
    assert loggamma(0) == oo
    assert loggamma(1) == 0
    assert loggamma(2) == 0
    assert loggamma(3) == log(2)
Example #6
0
def test_FunctionWrapper():
    import sympy
    n, m, theta, phi = sympy.symbols("n, m, theta, phi")
    r = sympy.Ynm(n, m, theta, phi)
    s = Integer(2) * r
    assert isinstance(s, Mul)
    assert isinstance(s.args[1]._sympy_(), sympy.Ynm)

    x = symbols("x")
    e = x + sympy.loggamma(x)
    assert str(e) == "x + loggamma(x)"
    assert isinstance(e, Add)
    assert e + sympy.loggamma(x) == x + 2 * sympy.loggamma(x)

    f = e.subs({x: 10})
    assert f == 10 + log(362880)

    f = e.subs({x: 2})
    assert f == 2

    f = e.subs({x: 100})
    v = f.n(53, real=True)
    assert abs(float(v) - 459.13420537) < 1e-7

    f = e.diff(x)
    assert f == 1 + sympy.polygamma(0, x)
def test_FunctionWrapper():
    import sympy
    n, m, theta, phi = sympy.symbols("n, m, theta, phi")
    r = sympy.Ynm(n, m, theta, phi)
    s = Integer(2)*r
    assert isinstance(s, Mul)
    assert isinstance(s.args[1]._sympy_(), sympy.Ynm)

    x = symbols("x")
    e = x + sympy.loggamma(x)
    assert str(e) == "x + loggamma(x)"
    assert isinstance(e, Add)
    assert e + sympy.loggamma(x) == x + 2*sympy.loggamma(x)

    f = e.subs({x : 10})
    assert f == 10 + log(362880)

    f = e.subs({x : 2})
    assert f == 2

    f = e.subs({x : 100});
    v = f.n(53, real=True);
    assert abs(float(v) - 459.13420537) < 1e-7

    f = e.diff(x)
    assert f == 1 + sympy.polygamma(0, x)
Example #8
0
def _get_array():
    X, Y, Z = inp = array.array('d', [1, 2, 3])
    args = x, y, z = se.symbols('x y z')
    exprs = [x+y+z, se.sin(x)*se.log(y)*se.exp(z)]
    ref = [X+Y+Z, math.sin(X)*math.log(Y)*math.exp(Z)]

    def check(arr):
        assert all([abs(x1-x2) < 1e-13 for x1, x2 in zip(ref, arr)])
    return args, exprs, inp, check
def _get_array():
    X, Y, Z = inp = array.array('d', [1, 2, 3])
    args = x, y, z = se.symbols('x y z')
    exprs = [x+y+z, se.sin(x)*se.log(y)*se.exp(z)]
    ref = [X+Y+Z, math.sin(X)*math.log(Y)*math.exp(Z)]

    def check(arr):
        assert all([abs(x1-x2) < 1e-13 for x1, x2 in zip(ref, arr)])
    return args, exprs, inp, check
Example #10
0
 def __pow__(self, other):
     if type(other) == GradientContainer:
         gradients = {
             s: d * other.expr * (self.expr**(other.expr - 1))
             for s, d in self.gradients.items()
         }
         for s, d in other.gradients.items():
             if s in gradients:
                 gradients[s] += d * self.expr * se.log(
                     self.expr) * (self.expr**(other.expr - 1))
             else:
                 gradients[s] = se.log(self.expr) * d * (self.expr**
                                                         other.expr)
         return GradientContainer(self.expr**other.expr, gradients)
     return GradientContainer(
         self.expr**other, {
             s: d * other * (self.expr**(other - 1))
             for s, d in self.gradients.items()
         })
Example #11
0
    def LLF_sym(self, hazard, covariate_data):
        # x = b, b1, b2, b2 = symengine.symbols('b b1 b2 b3')

        x = symengine.symbols(f'x:{self.numSymbols}')
        second = []
        prodlist = []
        for i in range(self.n):
            sum1 = 1
            sum2 = 1
            TempTerm1 = 1
            for j in range(self.numParameters, self.numSymbols):
                TempTerm1 = TempTerm1 * symengine.exp(
                    covariate_data[j - self.numParameters][i] * x[j])
            sum1 = 1 - ((1 -
                         (hazard(i + 1, x[:self.numParameters])))**(TempTerm1))
            for k in range(i):
                TempTerm2 = 1
                for j in range(self.numParameters, self.numSymbols):
                    TempTerm2 = TempTerm2 * symengine.exp(
                        covariate_data[j - self.numParameters][k] * x[j])
                sum2 = sum2 * (
                    (1 - (hazard(i + 1, x[:self.numParameters])))**(TempTerm2))
            second.append(sum2)
            prodlist.append(sum1 * sum2)

        firstTerm = -sum(self.failures)  #Verified
        secondTerm = sum(self.failures) * symengine.log(
            sum(self.failures) / sum(prodlist))
        logTerm = []  #Verified
        for i in range(self.n):
            logTerm.append(self.failures[i] * symengine.log(prodlist[i]))
        thirdTerm = sum(logTerm)
        factTerm = []  #Verified
        for i in range(self.n):
            factTerm.append(symengine.log(math.factorial(self.failures[i])))
        fourthTerm = sum(factTerm)

        f = firstTerm + secondTerm + thirdTerm - fourthTerm
        return f, x
Example #12
0
def solve_chi_saddlepoint(mu, Sigma):
    """Compute the saddlepoint approximation for the generalized chi square distribution given a mean and a covariance matrix. Currently has two different ways of solving:
        1. If the mean is close to zero, the system can be solved symbolically."""
    P = None
    eigenvalues, eigenvectors = np.linalg.eig(Sigma)
    if (eigenvectors == np.diag(eigenvalues)).all():
        P = np.eye(len(mu))
    else:
        P = eigenvectors.T
    Sigma_12 = np.linalg.cholesky(Sigma)
    b = P @ Sigma_12 @ mu

    x = sym.Symbol("x")
    t = sym.Symbol("t")

    # Cumulant function
    K = 0
    for i, l in enumerate(eigenvalues):
        K += (t * b[i]**2 * l) / (1 - 2 * t * l) - 1 / 2 * sym.log(1 -
                                                                   2 * l * t)

    Kp = sym.diff(K, t).simplify()
    Kpp = sym.diff(K, t, t).simplify()

    roots = sym.lib.symengine_wrapper.solve(sym.Eq(Kp, x), t).args
    if len(roots) > 1:
        for expr in roots:
            trial = Kpp.subs(t, expr).subs(x, np.dot(b, b))
            if trial >= 0.0:
                s_hat = expr
    else:
        s_hat = roots[0]

    f = 1 / sym.sqrt(2 * sym.pi * Kpp.subs(
        t, s_hat)) * sym.exp(K.subs(t, s_hat) - s_hat * x)
    fp = sym.Lambdify(x, f.simplify())

    c = integrate.quad(fp, 0, np.inf)[0]
    return lambda x: 1 / c * fp(x)
Example #13
0
def test_get_data_quantities_AL_NI_VA_interaction():
    """Test that an interaction with a VA produces the correct data quantities

    We just have a template database that has the phase defined. We then hot
    patch the Model object to have the GM from the fixed model we printed out
    and the data we printed out. The hot patch is needed because this is
    formation enthalpy data and the model needs to have the lower order terms
    in composition.

    One possible issue is that the new GM in the fixed model does not have any
    individual contributions, so it cannot be used to test excluded model
    contributions. The only excluded model contributions in this data are
    idmix, but the property we are testing is HM_FORM, so the feature transform
    of the idmix property should be zero.

    """
    # Hack the namespace to make the copy-pasted Gibbs energy function work
    from symengine import log, Piecewise, And
    T = v.T

    data = [{
        'components': ['AL', 'NI', 'VA'],
        'phases': ['BCC_B2'],
        'solver': {
            'mode':
            'manual',
            'sublattice_occupancies': [[1.0, [0.5, 0.5], 1.0],
                                       [1.0, [0.75, 0.25], 1.0]],
            'sublattice_site_ratios': [0.5, 0.5, 1.0],
            'sublattice_configurations':
            (('AL', ('NI', 'VA'), 'VA'), ('AL', ('NI', 'VA'), 'VA')),
            'comment':
            'BCC_B2 sublattice configuration (2SL)'
        },
        'conditions': {
            'P': 101325.0,
            'T': np.array([300.])
        },
        'reference_state': 'SGTE91',
        'output': 'HM_FORM',
        'values': np.array([[[-40316.61077, -56361.58554]]]),
        'reference': 'C. Jiang 2009 (constrained SQS)',
        'excluded_model_contributions': ['idmix']
    }, {
        'components': ['AL', 'NI', 'VA'],
        'phases': ['BCC_B2'],
        'solver': {
            'mode':
            'manual',
            'sublattice_occupancies': [[1.0, [0.5, 0.5], 1.0],
                                       [1.0, [0.75, 0.25], 1.0]],
            'sublattice_site_ratios': [0.5, 0.5, 1.0],
            'sublattice_configurations':
            (('AL', ('NI', 'VA'), 'VA'), ('AL', ('NI', 'VA'), 'VA')),
            'comment':
            'BCC_B2 sublattice configuration (2SL)'
        },
        'conditions': {
            'P': 101325.0,
            'T': np.array([300.])
        },
        'reference_state': 'SGTE91',
        'output': 'HM_FORM',
        'values': np.array([[[-41921.43363, -57769.49473]]]),
        'reference': 'C. Jiang 2009 (relaxed SQS)',
        'excluded_model_contributions': ['idmix']
    }]
    NEW_GM = 8.3145 * T * (
        0.5 * Piecewise((v.SiteFraction("BCC_B2", 0, "AL") *
                         log(v.SiteFraction("BCC_B2", 0, "AL")),
                         v.SiteFraction("BCC_B2", 0, "AL") > 1.0e-16),
                        (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + 0.5 * Piecewise(
             (v.SiteFraction("BCC_B2", 0, "NI") *
              log(v.SiteFraction("BCC_B2", 0, "NI")),
              v.SiteFraction("BCC_B2", 0, "NI") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + 0.5 * Piecewise(
             (v.SiteFraction("BCC_B2", 0, "VA") *
              log(v.SiteFraction("BCC_B2", 0, "VA")),
              v.SiteFraction("BCC_B2", 0, "VA") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + 0.5 * Piecewise(
             (v.SiteFraction("BCC_B2", 1, "AL") *
              log(v.SiteFraction("BCC_B2", 1, "AL")),
              v.SiteFraction("BCC_B2", 1, "AL") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + 0.5 * Piecewise(
             (v.SiteFraction("BCC_B2", 1, "NI") *
              log(v.SiteFraction("BCC_B2", 1, "NI")),
              v.SiteFraction("BCC_B2", 1, "NI") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + 0.5 * Piecewise(
             (v.SiteFraction("BCC_B2", 1, "VA") *
              log(v.SiteFraction("BCC_B2", 1, "VA")),
              v.SiteFraction("BCC_B2", 1, "VA") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI")) + Piecewise(
             (v.SiteFraction("BCC_B2", 2, "VA") *
              log(v.SiteFraction("BCC_B2", 2, "VA")),
              v.SiteFraction("BCC_B2", 2, "VA") > 1.0e-16), (0, True)) /
        (0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
            "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
         0.5 * v.SiteFraction("BCC_B2", 1, "NI"))
    ) + (
        45262.9 * v.SiteFraction("BCC_B2", 0, "AL") *
        v.SiteFraction("BCC_B2", 0, "NI") * v.SiteFraction("BCC_B2", 1, "AL") *
        v.SiteFraction("BCC_B2", 2, "VA") +
        45262.9 * v.SiteFraction("BCC_B2", 0, "AL") *
        v.SiteFraction("BCC_B2", 1, "AL") * v.SiteFraction("BCC_B2", 1, "NI") *
        v.SiteFraction("BCC_B2", 2, "VA")) / (
            0.5 * v.SiteFraction("BCC_B2", 0, "AL") + 0.5 * v.SiteFraction(
                "BCC_B2", 0, "NI") + 0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
            0.5 * v.SiteFraction("BCC_B2", 1, "NI")
        ) + (1.0 * v.SiteFraction("BCC_B2", 0, "AL") * v.SiteFraction(
            "BCC_B2", 1, "AL") * v.SiteFraction("BCC_B2", 2, "VA") * Piecewise(
                (10083 - 4.813 * T, And((T >= 298.15),
                                        (T < 2900.0))), (0, True)) +
             v.SiteFraction("BCC_B2", 0, "AL") * v.SiteFraction(
                 "BCC_B2", 1, "NI") * v.SiteFraction("BCC_B2", 2, "VA") *
             (9.52839e-8 * T**3 + 0.00123463 * T**2 +
              0.000871898 * T * log(T) + 1.31471 * T - 64435.3 + 23095.2 / T) +
             v.SiteFraction("BCC_B2", 0, "AL") * v.SiteFraction(
                 "BCC_B2", 1, "VA") * v.SiteFraction("BCC_B2", 2, "VA") *
             (10.0 * T + 16432.5) +
             v.SiteFraction("BCC_B2", 0, "NI") * v.SiteFraction(
                 "BCC_B2", 1, "AL") * v.SiteFraction("BCC_B2", 2, "VA") *
             (9.52839e-8 * T**3 + 0.00123463 * T**2 + 0.000871898 * T * log(T)
              + 1.31471 * T - 64435.3 + 23095.2 / T) + 1.0 * v.SiteFraction(
                  "BCC_B2", 0, "NI") * v.SiteFraction("BCC_B2", 1, "NI") *
             v.SiteFraction("BCC_B2", 2, "VA") * Piecewise(
                 (8715.084 - 3.556 * T, And((T >= 298.15),
                                            (T < 3000.0))), (0, True)) +
             32790.6 * v.SiteFraction("BCC_B2", 0, "NI") * v.SiteFraction(
                 "BCC_B2", 1, "VA") * v.SiteFraction("BCC_B2", 2, "VA") +
             v.SiteFraction("BCC_B2", 0, "VA") * v.SiteFraction(
                 "BCC_B2", 1, "AL") * v.SiteFraction("BCC_B2", 2, "VA") *
             (10.0 * T + 16432.5) +
             32790.6 * v.SiteFraction("BCC_B2", 0, "VA") * v.SiteFraction(
                 "BCC_B2", 1, "NI") * v.SiteFraction("BCC_B2", 2, "VA")) / (
                     0.5 * v.SiteFraction("BCC_B2", 0, "AL") +
                     0.5 * v.SiteFraction("BCC_B2", 0, "NI") +
                     0.5 * v.SiteFraction("BCC_B2", 1, "AL") +
                     0.5 * v.SiteFraction("BCC_B2", 1, "NI"))

    dbf = Database(
        """$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    $ Date: 2019-12-08 18:05
    $ Components: AL, NI, VA
    $ Phases: BCC_B2
    $ Generated by brandon (pycalphad 0.8.1.post1)
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

    ELEMENT AL FCC_A1 26.982 4577.3 28.322 !
    ELEMENT NI FCC_A1 58.69 4787.0 29.796 !
    ELEMENT VA VACUUM 0.0 0.0 0.0 !

    TYPE_DEFINITION % SEQ * !
    DEFINE_SYSTEM_DEFAULT ELEMENT 2 !
    DEFAULT_COMMAND DEFINE_SYSTEM_ELEMENT VA !

    PHASE BCC_B2 %  3 0.5 0.5 1 !
    CONSTITUENT BCC_B2 :AL,NI,VA:AL,NI,VA:VA: !

    """)
    mod = Model(dbf, ['AL', 'NI', 'VA'], 'BCC_B2')
    dd = {ky: 0.0 for ky in mod.models.keys()}
    dd['GM'] = NEW_GM
    mod.models = dd
    print(mod.HM)
    config_tup = (('AL', ), ('NI', 'VA'), ('VA', ))
    calculate_dict = get_prop_samples(data, config_tup)
    sample_condition_dicts = _get_sample_condition_dicts(
        calculate_dict, list(map(len, config_tup)))
    qty = get_data_quantities('HM_FORM', mod, [0], data,
                              sample_condition_dicts)
    print(qty)
    assert np.all(
        np.isclose(
            [-6254.7802775, -5126.1206475, -7458.3974225, -6358.04118875],
            qty))
Example #14
0
def test_log():
    x = Symbol("x")
    y = Symbol("y")
    assert log(E) == 1
    assert log(x, x) == 1
    assert log(x, y) == log(x) / log(y)
Example #15
0
def Paci2018(tDrugApplication, INaFRedMed, ICaLRedMed, IKrRedMed, IKsRedMed):
    dY = [None] * 23

    VmaxUp = 0.5113  # millimolar_per_second (in calcium_dynamics)
    g_irel_max = 62.5434  # millimolar_per_second (in calcium_dynamics)
    RyRa1 = 0.05354  # uM
    RyRa2 = 0.0488  # uM
    RyRahalf = 0.02427  # uM
    RyRohalf = 0.01042  # uM
    RyRchalf = 0.00144  # uM
    kNaCa = 3917.0463  # A_per_F (in i_NaCa)
    PNaK = 2.6351  # A_per_F (in i_NaK)
    Kup = 3.1928e-4  # millimolar (in calcium_dynamics)
    V_leak = 4.7279e-4  # per_second (in calcium_dynamics)
    alpha = 2.5371  # dimensionless (in i_NaCa)

    ## Constants
    F = 96485.3415  # coulomb_per_mole (in model_parameters)
    R = 8.314472  # joule_per_mole_kelvin (in model_parameters)
    T = 310.0  # kelvin (in model_parameters)

    ## Cell geometry
    V_SR = 583.73  # micrometre_cube (in model_parameters)
    Vc = 8800.0  # micrometre_cube (in model_parameters)
    Cm = 9.87109e-11  # farad (in model_parameters)

    ## Extracellular concentrations
    Nao = 151.0  # millimolar (in model_parameters)
    Ko = 5.4  # millimolar (in model_parameters)
    Cao = 1.8  #3#5#1.8   # millimolar (in model_parameters)

    ## Intracellular concentrations
    # Naio = 10 mM y(17)
    Ki = 150.0  # millimolar (in model_parameters)
    # Cai  = 0.0002 mM y(2)
    # caSR = 0.3 mM y(1)

    # time (second)

    ## Nernst potential
    E_Na = R * T / F * symengine.log(Nao / y(17))
    E_Ca = 0.5 * R * T / F * symengine.log(Cao / y(2))

    E_K = R * T / F * log(Ko / Ki)
    PkNa = 0.03  # dimensionless (in electric_potentials)
    E_Ks = R * T / F * symengine.log((Ko + PkNa * Nao) / (Ki + PkNa * y(17)))

    ## INa
    g_Na = 3671.2302  # S_per_F (in i_Na)
    drug_no_drug_na = [
        g_Na * y(13)**3.0 * y(11) * y(12) * (y(0) - E_Na),
        INaFRedMed * g_Na * y(13)**3.0 * y(11) * y(12) * (y(0) - E_Na)
    ]
    i_Na = drug_no_drug_na[0]

    h_inf = 1.0 / symengine.sqrt(1.0 +
                                 symengine.exp((y(0) * 1000.0 + 72.1) / 5.7))
    alpha_h = 0.057 * symengine.exp(-(y(0) * 1000.0 + 80.0) / 6.8)
    beta_h = 2.7 * symengine.exp(
        0.079 * y(0) * 1000.0) + 3.1 * 10.0**5.0 * symengine.exp(
            0.3485 * y(0) * 1000.0)

    tau_h = sigmoid_generator(y(0), -0.0385, -1) * (1.5 / (
        (alpha_h + beta_h) * 1000.0)) + sigmoid_generator(
            y(0), -0.0385, 1) * (1.5 * 1.6947 / 1000.0)

    dY[11] = (h_inf - y(11)) / tau_h

    j_inf = 1.0 / symengine.sqrt(1.0 +
                                 symengine.exp((y(0) * 1000.0 + 72.1) / 5.7))
    alpha_j = sigmoid_generator(y(0), -0.04, -1) * (
        -25428.0 * symengine.exp(0.2444 * y(0) * 1000.0) - 6.948 * 10.0**-6.0 *
        symengine.exp(-0.04391 * y(0) * 1000.0)) * (y(0) * 1000.0 + 37.78) / (
            1.0 + symengine.exp(0.311 *
                                (y(0) * 1000.0 + 79.23))) + sigmoid_generator(
                                    y(0), -0.04, 1) * 0

    beta_j = sigmoid_generator(y(0), -0.04, -1) * (
        (0.02424 * symengine.exp(-0.01052 * y(0) * 1000) /
         (1 + symengine.exp(-0.1378 *
                            (y(0) * 1000 + 40.14))))) + sigmoid_generator(
                                y(0), -0.04, 1) * (
                                    (0.6 * symengine.exp(
                                        (0.057) * y(0) * 1000) /
                                     (1 + symengine.exp(-0.1 *
                                                        (y(0) * 1000 + 32)))))

    tau_j = 7.0 / ((alpha_j + beta_j) * 1000.0)
    dY[12] = (j_inf - y(12)) / tau_j

    m_inf = 1.0 / (1.0 + symengine.exp(
        (-y(0) * 1000.0 - 34.1) / 5.9))**(1.0 / 3.0)
    alpha_m = 1.0 / (1.0 + symengine.exp((-y(0) * 1000.0 - 60.0) / 5.0))
    beta_m = 0.1 / (1.0 + symengine.exp(
        (y(0) * 1000.0 + 35.0) / 5.0)) + 0.1 / (1.0 + symengine.exp(
            (y(0) * 1000.0 - 50.0) / 200.0))
    tau_m = 1.0 * alpha_m * beta_m / 1000.0
    dY[13] = (m_inf - y(13)) / tau_m

    ## INaL
    myCoefTauM = 1
    tauINaL = 200  #ms
    GNaLmax = 2.3 * 7.5  #(S/F)
    Vh_hLate = 87.61
    i_NaL = GNaLmax * y(18)**(3) * y(19) * (y(0) - E_Na)

    m_inf_L = 1 / (1 + symengine.exp(-(y(0) * 1000 + 42.85) / (5.264)))
    alpha_m_L = 1 / (1 + symengine.exp((-60 - y(0) * 1000) / 5))
    beta_m_L = 0.1 / (1 + symengine.exp(
        (y(0) * 1000 + 35) / 5)) + 0.1 / (1 + symengine.exp(
            (y(0) * 1000 - 50) / 200))
    tau_m_L = 1 / 1000 * myCoefTauM * alpha_m_L * beta_m_L
    dY[18] = (m_inf_L - y(18)) / tau_m_L

    h_inf_L = 1 / (1 + symengine.exp((y(0) * 1000 + Vh_hLate) / (7.488)))
    tau_h_L = 1 / 1000 * tauINaL
    dY[19] = (h_inf_L - y(19)) / tau_h_L

    ## If
    E_f = -0.017  # volt (in i_f)
    g_f = 30.10312  # S_per_F (in i_f)

    i_f = g_f * y(14) * (y(0) - E_f)
    i_fNa = 0.42 * g_f * y(14) * (y(0) - E_Na)

    Xf_infinity = 1.0 / (1.0 + symengine.exp((y(0) * 1000.0 + 77.85) / 5.0))
    tau_Xf = 1900.0 / (1.0 + symengine.exp(
        (y(0) * 1000.0 + 15.0) / 10.0)) / 1000.0
    dY[14] = (Xf_infinity - y(14)) / tau_Xf

    ## ICaL
    g_CaL = 8.635702e-5  # metre_cube_per_F_per_s (in i_CaL)
    drug_no_drug_CaL = [
        g_CaL * 4.0 * y(0) * F**2.0 / (R * T) *
        (y(2) * symengine.exp(2.0 * y(0) * F / (R * T)) - 0.341 * Cao) /
        (symengine.exp(2.0 * y(0) * F / (R * T)) - 1.0) * y(4) * y(5) * y(6) *
        y(7), ICaLRedMed * g_CaL * 4.0 * y(0) * F**2.0 / (R * T) *
        (y(2) * symengine.exp(2.0 * y(0) * F / (R * T)) - 0.341 * Cao) /
        (symengine.exp(2.0 * y(0) * F /
                       (R * T)) - 1.0) * y(4) * y(5) * y(6) * y(7)
    ]
    i_CaL = drug_no_drug_CaL[0]

    d_infinity = 1.0 / (1.0 + symengine.exp(-(y(0) * 1000.0 + 9.1) / 7.0))
    alpha_d = 0.25 + 1.4 / (1.0 + symengine.exp(
        (-y(0) * 1000.0 - 35.0) / 13.0))
    beta_d = 1.4 / (1.0 + symengine.exp((y(0) * 1000.0 + 5.0) / 5.0))
    gamma_d = 1.0 / (1.0 + symengine.exp((-y(0) * 1000.0 + 50.0) / 20.0))
    tau_d = (alpha_d * beta_d + gamma_d) * 1.0 / 1000.0
    dY[4] = (d_infinity - y(4)) / tau_d

    f1_inf = 1.0 / (1.0 + symengine.exp((y(0) * 1000.0 + 26.0) / 3.0))
    constf1 = sigmoid_generator(f1_inf - y(5), 0, 1) * 1.0 + 1433.0 * (
        y(2) - 50.0 * 1.0e-6) + sigmoid_generator(f1_inf - y(5), 0, -1) * 1.0

    tau_f1 = (20.0 + 1102.5 * symengine.exp(-(
        (y(0) * 1000.0 + 27.0)**2.0 / 15.0)**2.0) + 200.0 /
              (1.0 + symengine.exp((13.0 - y(0) * 1000.0) / 10.0)) + 180.0 /
              (1.0 + symengine.exp(
                  (30.0 + y(0) * 1000.0) / 10.0))) * constf1 / 1000.0
    dY[5] = (f1_inf - y(5)) / tau_f1

    f2_inf = 0.33 + 0.67 / (1.0 + symengine.exp((y(0) * 1000.0 + 32.0) / 4.0))
    constf2 = 1.0
    tau_f2 = (600.0 * symengine.exp(-(y(0) * 1000.0 + 25.0)**2.0 / 170.0) +
              31.0 / (1.0 + symengine.exp(
                  (25.0 - y(0) * 1000.0) / 10.0)) + 16.0 /
              (1.0 + symengine.exp(
                  (30.0 + y(0) * 1000.0) / 10.0))) * constf2 / 1000.0
    dY[6] = (f2_inf - y(6)) / tau_f2

    alpha_fCa = 1.0 / (1.0 + (y(2) / 0.0006)**8.0)
    beta_fCa = 0.1 / (1.0 + symengine.exp((y(2) - 0.0009) / 0.0001))
    gamma_fCa = 0.3 / (1.0 + symengine.exp((y(2) - 0.00075) / 0.0008))
    fCa_inf = (alpha_fCa + beta_fCa + gamma_fCa) / 1.3156
    constfCa = sigmoid_generator(y(0), -0.06, 1) * sigmoid_generator(
        fCa_inf, y(7), 1) * 0 + (sigmoid_generator(y(0), -0.06, -1) +
                                 sigmoid_generator(fCa_inf, y(7), -1)) * 1.0

    tau_fCa = 0.002  # second (in i_CaL_fCa_gate)
    dY[7] = constfCa * (fCa_inf - y(7)) / tau_fCa

    ## Ito
    g_to = 29.9038  # S_per_F (in i_to)
    i_to = g_to * (y(0) - E_K) * y(15) * y(16)

    q_inf = 1.0 / (1.0 + symengine.exp((y(0) * 1000.0 + 53.0) / 13.0))
    tau_q = (6.06 + 39.102 /
             (0.57 * symengine.exp(-0.08 * (y(0) * 1000.0 + 44.0)) +
              0.065 * symengine.exp(0.1 * (y(0) * 1000.0 + 45.93)))) / 1000.0
    dY[15] = (q_inf - y(15)) / tau_q

    r_inf = 1.0 / (1.0 + symengine.exp(-(y(0) * 1000.0 - 22.3) / 18.75))
    tau_r = (2.75352 + 14.40516 /
             (1.037 * symengine.exp(0.09 * (y(0) * 1000.0 + 30.61)) +
              0.369 * symengine.exp(-0.12 * (y(0) * 1000.0 + 23.84)))) / 1000.0
    dY[16] = (r_inf - y(16)) / tau_r

    ## IKs
    g_Ks = 2.041  # S_per_F (in i_Ks)
    drug_no_drug_Ks = [
        g_Ks * (y(0) - E_Ks) * y(10)**2.0 *
        (1.0 + 0.6 / (1.0 + (3.8 * 0.00001 / y(2))**1.4)),
        IKsRedMed * g_Ks * (y(0) - E_Ks) * y(10)**2.0 *
        (1.0 + 0.6 / (1.0 + (3.8 * 0.00001 / y(2))**1.4))
    ]
    i_Ks = drug_no_drug_Ks[0]

    Xs_infinity = 1.0 / (1.0 + symengine.exp((-y(0) * 1000.0 - 20.0) / 16.0))
    alpha_Xs = 1100.0 / symengine.sqrt(1.0 + symengine.exp(
        (-10.0 - y(0) * 1000.0) / 6.0))
    beta_Xs = 1.0 / (1.0 + symengine.exp((-60.0 + y(0) * 1000.0) / 20.0))
    tau_Xs = 1.0 * alpha_Xs * beta_Xs / 1000.0
    dY[10] = (Xs_infinity - y(10)) / tau_Xs

    ## IKr
    L0 = 0.025  # dimensionless (in i_Kr_Xr1_gate)
    Q = 2.3  # dimensionless (in i_Kr_Xr1_gate)
    g_Kr = 29.8667  # S_per_F (in i_Kr)
    drug_no_drug_Kr = [
        g_Kr * (y(0) - E_K) * y(8) * y(9) * sqrt(Ko / 5.4),
        IKrRedMed * g_Kr * (y(0) - E_K) * y(8) * y(9) * sqrt(Ko / 5.4)
    ]
    i_Kr = drug_no_drug_Kr[0]

    V_half = 1000.0 * (-R * T / (F * Q) * log(
        (1.0 + Cao / 2.6)**4.0 / (L0 * (1.0 + Cao / 0.58)**4.0)) - 0.019)

    Xr1_inf = 1.0 / (1.0 + symengine.exp((V_half - y(0) * 1000.0) / 4.9))
    alpha_Xr1 = 450.0 / (1.0 + symengine.exp((-45.0 - y(0) * 1000.0) / 10.0))
    beta_Xr1 = 6.0 / (1.0 + symengine.exp((30.0 + y(0) * 1000.0) / 11.5))
    tau_Xr1 = 1.0 * alpha_Xr1 * beta_Xr1 / 1000.0
    dY[8] = (Xr1_inf - y(8)) / tau_Xr1

    Xr2_infinity = 1.0 / (1.0 + symengine.exp((y(0) * 1000.0 + 88.0) / 50.0))
    alpha_Xr2 = 3.0 / (1.0 + symengine.exp((-60.0 - y(0) * 1000.0) / 20.0))
    beta_Xr2 = 1.12 / (1.0 + symengine.exp((-60.0 + y(0) * 1000.0) / 20.0))
    tau_Xr2 = 1.0 * alpha_Xr2 * beta_Xr2 / 1000.0
    dY[9] = (Xr2_infinity - y(9)) / tau_Xr2

    ## IK1
    alpha_K1 = 3.91 / (1.0 +
                       symengine.exp(0.5942 *
                                     (y(0) * 1000.0 - E_K * 1000.0 - 200.0)))
    beta_K1 = (-1.509 * symengine.exp(0.0002 *
                                      (y(0) * 1000.0 - E_K * 1000.0 + 100.0)) +
               symengine.exp(0.5886 * (y(0) * 1000.0 - E_K * 1000.0 - 10.0))
               ) / (1.0 + symengine.exp(0.4547 *
                                        (y(0) * 1000.0 - E_K * 1000.0)))
    XK1_inf = alpha_K1 / (alpha_K1 + beta_K1)
    g_K1 = 28.1492  # S_per_F (in i_K1)
    i_K1 = g_K1 * XK1_inf * (y(0) - E_K) * sqrt(Ko / 5.4)

    ## INaCa
    KmCa = 1.38  # millimolar (in i_NaCa)
    KmNai = 87.5  # millimolar (in i_NaCa)
    Ksat = 0.1  # dimensionless (in i_NaCa)
    gamma = 0.35  # dimensionless (in i_NaCa)
    kNaCa1 = kNaCa  # A_per_F (in i_NaCa)
    i_NaCa = kNaCa1 * (symengine.exp(gamma * y(0) * F /
                                     (R * T)) * y(17)**3.0 * Cao -
                       symengine.exp(
                           (gamma - 1.0) * y(0) * F /
                           (R * T)) * Nao**3.0 * y(2) * alpha) / (
                               (KmNai**3.0 + Nao**3.0) * (KmCa + Cao) *
                               (1.0 + Ksat * symengine.exp(
                                   (gamma - 1.0) * y(0) * F / (R * T))))

    ## INaK
    Km_K = 1.0  # millimolar (in i_NaK)
    Km_Na = 40.0  # millimolar (in i_NaK)
    PNaK1 = PNaK  # A_per_F (in i_NaK)
    i_NaK = PNaK1 * Ko / (Ko + Km_K) * y(17) / (y(17) + Km_Na) / (
        1.0 + 0.1245 * symengine.exp(-0.1 * y(0) * F / (R * T)) +
        0.0353 * symengine.exp(-y(0) * F / (R * T)))

    ## IpCa
    KPCa = 0.0005  # millimolar (in i_PCa)
    g_PCa = 0.4125  # A_per_F (in i_PCa)
    i_PCa = g_PCa * y(2) / (y(2) + KPCa)

    ## Background currents
    g_b_Na = 0.95  # S_per_F (in i_b_Na)
    i_b_Na = g_b_Na * (y(0) - E_Na)

    g_b_Ca = 0.727272  # S_per_F (in i_b_Ca)
    i_b_Ca = g_b_Ca * (y(0) - E_Ca)

    ## Sarcoplasmic reticulum
    i_up = VmaxUp / (1.0 + Kup**2.0 / y(2)**2.0)

    i_leak = (y(1) - y(2)) * V_leak

    dY[3] = 0

    # RyR
    RyRSRCass = (1 - 1 / (1 + symengine.exp((y(1) - 0.3) / 0.1)))
    i_rel = g_irel_max * RyRSRCass * y(21) * y(22) * (y(1) - y(2))

    RyRainfss = RyRa1 - RyRa2 / (1 + symengine.exp(
        (1000 * y(2) - (RyRahalf)) / 0.0082))
    RyRtauadapt = 1  #s
    dY[20] = (RyRainfss - y(20)) / RyRtauadapt

    RyRoinfss = (1 - 1 / (1 + symengine.exp(
        (1000 * y(2) - (y(20) + RyRohalf)) / 0.003)))
    RyRtauact = sigmoid_generator(
        RyRoinfss, y(21), 1) * 18.75e-3 + 0.1 * 18.75e-3 * sigmoid_generator(
            RyRoinfss, y(21), -1)

    dY[21] = (RyRoinfss - y(21)) / RyRtauact

    RyRcinfss = (1 / (1 + symengine.exp(
        (1000 * y(2) - (y(20) + RyRchalf)) / 0.001)))

    RyRtauinact = sigmoid_generator(RyRcinfss, y(22),
                                    1) * 2 * 87.5e-3 + sigmoid_generator(
                                        RyRcinfss, y(22), -1) * 87.5e-3

    dY[22] = (RyRcinfss - y(22)) / RyRtauinact

    ## Ca2+ buffering
    Buf_C = 0.25  # millimolar (in calcium_dynamics)
    Buf_SR = 10.0  # millimolar (in calcium_dynamics)
    Kbuf_C = 0.001  # millimolar (in calcium_dynamics)
    Kbuf_SR = 0.3  # millimolar (in calcium_dynamics)
    Cai_bufc = 1.0 / (1.0 + Buf_C * Kbuf_C / (y(2) + Kbuf_C)**2.0)
    Ca_SR_bufSR = 1.0 / (1.0 + Buf_SR * Kbuf_SR / (y(1) + Kbuf_SR)**2.0)

    ## Ionic concentrations
    #Nai
    dY[17] = -Cm * (i_Na + i_NaL + i_b_Na + 3.0 * i_NaK + 3.0 * i_NaCa +
                    i_fNa) / (F * Vc * 1.0e-18)
    #caSR
    dY[2] = Cai_bufc * (i_leak - i_up + i_rel -
                        (i_CaL + i_b_Ca + i_PCa - 2.0 * i_NaCa) * Cm /
                        (2.0 * Vc * F * 1.0e-18))
    #Cai
    dY[1] = Ca_SR_bufSR * Vc / V_SR * (i_up - (i_rel + i_leak))

    ## Stimulation
    i_stim_Amplitude = 7.5e-10  # ampere (in stim_mode)
    i_stim_End = 1000.0  # second (in stim_mode)
    i_stim_PulseDuration = 0.005  # second (in stim_mode)
    i_stim_Start = 0.0  # second (in stim_mode)
    i_stim_frequency = 60.0  # per_second (in stim_mode)
    stim_flag = 0.0  # dimensionless (in stim_mode)
    i_stim_Period = 60.0 / i_stim_frequency

    i_stim = 0  #(sigmoid_generator(time, i_stim_Start, 1) * sigmoid_generator(time, i_stim_End, -1) * (sigmoid_generator(time-i_stim_Start-symengine.floor((time-i_stim_Start)/i_stim_Period)*i_stim_Period, i_stim_PulseDuration, -1) ))*stim_flag*i_stim_Amplitude/Cm+0.0

    ## Membrane potential
    dY[0] = -(i_K1 + i_to + i_Kr + i_Ks + i_CaL + i_NaK + i_Na + i_NaL +
              i_NaCa + i_PCa + i_f + i_b_Na + i_b_Ca - i_stim)

    ## Output variables
    IK1 = i_K1
    Ito = i_to
    IKr = i_Kr
    IKs = i_Ks
    ICaL = i_CaL
    INaK = i_NaK
    INa = i_Na
    INaCa = i_NaCa
    IpCa = i_PCa
    If = i_f
    IbNa = i_b_Na
    IbCa = i_b_Ca
    Irel = i_rel
    Iup = i_up
    Ileak = i_leak
    Istim = i_stim
    INaL = i_NaL

    dati = [
        INa, If, ICaL, Ito, IKs, IKr, IK1, INaCa, INaK, IpCa, IbNa, IbCa, Irel,
        Iup, Ileak, Istim, E_K, E_Na, INaL
    ]

    return dY

    # 1 - evaluate function at Y...
    # 2 - loop over Y, perturb each element by a small percent of its total
    # 3 - during each loop, find dY/dt, given the perturbation
    # 4 - find the change in Y as a function of the change in the perturbation

    # Conditionals
    # tau_h   = 1.5*1.6947/1000.0
    # alpha_j = 0.0
    # beta_j  = ((0.6*exp((0.057)*Y[0]*1000)/(1+exp(-0.1*(Y[0]*1000+32)))))
    # constf1 = 1.0
    # constfCa = 1.0
    # RyRtauact = 0.1*18.75e-3   #s
    # RyRtauinact = 87.5e-3      #s
    # i_stim = 0.0
    '''
def test_dirichlet_eta():
    assert dirichlet_eta(0) == Rational(1, 2)
    assert dirichlet_eta(-1) == Rational(1, 4)
    assert dirichlet_eta(1) == log(2)
    assert dirichlet_eta(2) == pi**2 / 12
    assert dirichlet_eta(4) == pi**4 * Rational(7, 720)
def Paci2018(tDrugApplication, INaFRedMed,ICaLRedMed, IKrRedMed, IKsRedMed):
    dY = [None]*23

    '''
    Parameters from optimizer   
      VmaxUp    = param(1)
      g_irel_max  = param(2)
      RyRa1         = param(3)
      RyRa2         = param(4)
      RyRahalf      = param(5)
      RyRohalf      = param(6)
      RyRchalf      = param(7)
      kNaCa         = param(8)
      PNaK          = param(9)
      Kup     = param(10)
      V_leak    = param(11)
      alpha         = param(12)
    '''
    VmaxUp = 0.5113      # millimolar_per_second (in calcium_dynamics)
    g_irel_max = 62.5434 # millimolar_per_second (in calcium_dynamics)
    RyRa1 = 0.05354      # uM
    RyRa2 = 0.0488       # uM
    RyRahalf = 0.02427   # uM
    RyRohalf = 0.01042   # uM
    RyRchalf = 0.00144   # uM
    kNaCa = 3917.0463    # A_per_F (in i_NaCa)
    PNaK = 2.6351        # A_per_F (in i_NaK)
    Kup = 3.1928e-4      # millimolar (in calcium_dynamics)
    V_leak = 4.7279e-4   # per_second (in calcium_dynamics)
    alpha = 2.5371       # dimensionless (in i_NaCa)

    ## Constants
    F = 96485.3415   # coulomb_per_mole (in model_parameters)
    R = 8.314472   # joule_per_mole_kelvin (in model_parameters)
    T = 310   # kelvin (in model_parameters)

    ## Cell geometry
    V_SR = 583.73   # micrometre_cube (in model_parameters)
    Vc   = 8800   # micrometre_cube (in model_parameters)
    Cm   = 9.87109e-11   # farad (in model_parameters)

    ## Extracellular concentrations
    Nao = 151   # millimolar (in model_parameters)
    Ko  = 5.4   # millimolar (in model_parameters)
    Cao = 1.8 #3#5#1.8   # millimolar (in model_parameters)

    ## Intracellular concentrations
    # Naio = 10 mM y(17)
    Ki = 150   # millimolar (in model_parameters)
    # Cai  = 0.0002 mM y(2)
    # caSR = 0.3 mM y(1)

    ## Nernst potential
    E_Na = R*T/F*log(Nao/y(17))
    E_Ca = 0.5*R*T/F*log(Cao/y(2))

    E_K  = R*T/F*log(Ko/Ki)
    PkNa = 0.03   # dimensionless (in electric_potentials)
    E_Ks = R*T/F*log((Ko+PkNa*Nao)/(Ki+PkNa*y(17)))


    ## INa
    g_Na        = 3671.2302   # S_per_F (in i_Na)
    i_Na        = g_Na*y(13)**3*y(11)*y(12)*(y(0)-E_Na)

    h_inf       = 1/sqrt(1+exp((y(0)*1000+72.1)/5.7))
    alpha_h     = 0.057*exp(-(y(0)*1000+80)/6.8)
    beta_h      = 2.7*exp(0.079*y(0)*1000)+3.1*10**5*exp(0.3485*y(0)*1000)
    
    tau_h = conditional(y(0),-0.0385,1.5/((alpha_h+beta_h)*1000),1.5*1.6947/1000)

    dY[11]   = (h_inf-y(11))/tau_h

    j_inf       = 1/sqrt(1+exp((y(0)*1000+72.1)/5.7))
    alpha_j = conditional(y(0),-0.04,(-25428*exp(0.2444*y(0)*1000)-6.948*10**-6*exp(-0.04391*y(0)*1000))*(y(0)*1000+37.78)/(1+exp(0.311*(y(0)*1000+79.23))),0)
    
    beta_j  = conditional(
            y(0),-0.04,
            0.02424*exp(-0.01052*y(0)*1000)/(1+exp(-0.1378*(y(0)*1000+40.14))),
            0.6*exp((0.057)*y(0)*1000)/(1+exp(-0.1*(y(0)*1000+32))),
        )
    
    tau_j       = 7/((alpha_j+beta_j)*1000)
    dY[12]   = (j_inf-y(12))/tau_j

    m_inf       = 1/(1+exp((-y(0)*1000-34.1)/5.9))**(1/3)
    alpha_m     = 1/(1+exp((-y(0)*1000-60)/5))
    beta_m      = 0.1/(1+exp((y(0)*1000+35)/5))+0.1/(1+exp((y(0)*1000-50)/200))
    tau_m       = 1*alpha_m*beta_m/1000
    dY[13]   = (m_inf-y(13))/tau_m

    

    ## INaL
    myCoefTauM  = 1
    tauINaL     = 200 #ms
    GNaLmax     = 2.3*7.5 #(S/F)
    Vh_hLate    = 87.61
    i_NaL       = GNaLmax* y(18)**(3)*y(19)*(y(0)-E_Na)

    m_inf_L     = 1/(1+exp(-(y(0)*1000+42.85)/(5.264)))
    alpha_m_L   = 1/(1+exp((-60-y(0)*1000)/5))
    beta_m_L    = 0.1/(1+exp((y(0)*1000+35)/5))+0.1/(1+exp((y(0)*1000-50)/200))
    tau_m_L     = 1/1000 * myCoefTauM*alpha_m_L*beta_m_L
    dY[18]   = (m_inf_L-y(18))/tau_m_L

    h_inf_L     = 1/(1+exp((y(0)*1000+Vh_hLate)/(7.488)))
    tau_h_L     = 1/1000 * tauINaL
    dY[19]   = (h_inf_L-y(19))/tau_h_L

    ## If
    E_f         = -0.017   # volt (in i_f)
    g_f         = 30.10312   # S_per_F (in i_f)

    i_f         = g_f*y(14)*(y(0)-E_f)
    i_fNa       = 0.42*g_f*y(14)*(y(0)-E_Na)

    Xf_infinity = 1/(1+exp((y(0)*1000+77.85)/5))
    tau_Xf      = 1900/(1+exp((y(0)*1000+15)/10))/1000
    dY[14]   = (Xf_infinity-y(14))/tau_Xf




    ## ICaL
    g_CaL       = 8.635702e-5   # metre_cube_per_F_per_s (in i_CaL)
    i_CaL       = g_CaL*4*y(0)*F**2/(R*T)*(y(2)*exp(2*y(0)*F/(R*T))-0.341*Cao)/(exp(2*y(0)*F/(R*T))-1)*y(4)*y(5)*y(6)*y(7)

    d_infinity  = 1/(1+exp(-(y(0)*1000+9.1)/7))
    alpha_d     = 0.25+1.4/(1+exp((-y(0)*1000-35)/13))
    beta_d      = 1.4/(1+exp((y(0)*1000+5)/5))
    gamma_d     = 1/(1+exp((-y(0)*1000+50)/20))
    tau_d       = (alpha_d*beta_d+gamma_d)*1/1000
    dY[4]    = (d_infinity-y(4))/tau_d

    f1_inf      = 1/(1+exp((y(0)*1000+26)/3))
    constf1 = 1 + 1433*(y(2)-50*1e-6)
    
    tau_f1      = (20+1102.5*exp(-((y(0)*1000+27)**2/15)**2)+200/(1+exp((13-y(0)*1000)/10))+180/(1+exp((30+y(0)*1000)/10)))*constf1/1000
    dY[5]    = (f1_inf-y(5))/tau_f1
    
    f2_inf      = 0.33+0.67/(1+exp((y(0)*1000+32)/4))
    constf2     = 1
    tau_f2      = (600*exp(-(y(0)*1000+25)**2/170)+31/(1+exp((25-y(0)*1000)/10))+16/(1+exp((30+y(0)*1000)/10)))*constf2/1000
    dY[6]    = (f2_inf-y(6))/tau_f2

    alpha_fCa   = 1/(1+(y(2)/0.0006)**8)
    beta_fCa    = 0.1/(1+exp((y(2)-0.0009)/0.0001))
    gamma_fCa   = 0.3/(1+exp((y(2)-0.00075)/0.0008))
    fCa_inf     = (alpha_fCa+beta_fCa+gamma_fCa)/1.3156
    constfCa    = conditional( y(0), -0.06, 1, conditional(fCa_inf,y(7),1,0) )
    
    tau_fCa     = 0.002   # second (in i_CaL_fCa_gate)
    dY[7]    = constfCa*(fCa_inf-y(7))/tau_fCa

    ## Ito
    g_to        = 29.9038   # S_per_F (in i_to)
    i_to        = g_to*(y(0)-E_K)*y(15)*y(16)

    q_inf       = 1/(1+exp((y(0)*1000+53)/13))
    tau_q       = (6.06+39.102/(0.57*exp(-0.08*(y(0)*1000+44))+0.065*exp(0.1*(y(0)*1000+45.93))))/1000
    dY[15]   = (q_inf-y(15))/tau_q

    r_inf       = 1/(1+exp(-(y(0)*1000-22.3)/18.75))
    tau_r       = (2.75352+14.40516/(1.037*exp(0.09*(y(0)*1000+30.61))+0.369*exp(-0.12*(y(0)*1000+23.84))))/1000
    dY[16]   = (r_inf-y(16))/tau_r

    ## IKs
    g_Ks        = 2.041   # S_per_F (in i_Ks)
    i_Ks        = g_Ks*(y(0)-E_Ks)*y(10)**2*(1+0.6/(1+(3.8*0.00001/y(2))**1.4))

    Xs_infinity = 1/(1+exp((-y(0)*1000-20)/16))
    alpha_Xs    = 1100/sqrt(1+exp((-10-y(0)*1000)/6))
    beta_Xs     = 1/(1+exp((-60+y(0)*1000)/20))
    tau_Xs      = 1*alpha_Xs*beta_Xs/1000
    dY[10]   = (Xs_infinity-y(10))/tau_Xs

    ## IKr
    L0           = 0.025   # dimensionless (in i_Kr_Xr1_gate)
    Q            = 2.3   # dimensionless (in i_Kr_Xr1_gate)
    g_Kr         = 29.8667   # S_per_F (in i_Kr)
    i_Kr         = g_Kr*(y(0)-E_K)*y(8)*y(9)*sqrt(Ko/5.4)

    V_half       = 1000*(-R*T/(F*Q)*log((1+Cao/2.6)**4/(L0*(1+Cao/0.58)**4))-0.019)

    Xr1_inf      = 1/(1+exp((V_half-y(0)*1000)/4.9))
    alpha_Xr1    = 450/(1+exp((-45-y(0)*1000)/10))
    beta_Xr1     = 6/(1+exp((30+y(0)*1000)/11.5))
    tau_Xr1      = 1*alpha_Xr1*beta_Xr1/1000
    dY[8]     = (Xr1_inf-y(8))/tau_Xr1

    Xr2_infinity = 1/(1+exp((y(0)*1000+88)/50))
    alpha_Xr2    = 3/(1+exp((-60-y(0)*1000)/20))
    beta_Xr2     = 1.12/(1+exp((-60+y(0)*1000)/20))
    tau_Xr2      = 1*alpha_Xr2*beta_Xr2/1000
    dY[9]    = (Xr2_infinity-y(9))/tau_Xr2
    
    ## IK1
    alpha_K1 = 3.91/(1+exp(0.5942*(y(0)*1000-E_K*1000-200)))
    beta_K1  = (-1.509*exp(0.0002*(y(0)*1000-E_K*1000+100))+exp(0.5886*(y(0)*1000-E_K*1000-10)))/(1+exp(0.4547*(y(0)*1000-E_K*1000)))
    XK1_inf  = alpha_K1/(alpha_K1+beta_K1)
    g_K1     = 28.1492   # S_per_F (in i_K1)
    i_K1     = g_K1*XK1_inf*(y(0)-E_K)*sqrt(Ko/5.4)

    ## INaCa
    KmCa   = 1.38   # millimolar (in i_NaCa)
    KmNai  = 87.5   # millimolar (in i_NaCa)
    Ksat   = 0.1   # dimensionless (in i_NaCa)
    gamma  = 0.35   # dimensionless (in i_NaCa)
    kNaCa1 = kNaCa   # A_per_F (in i_NaCa)
    i_NaCa = kNaCa1*(exp(gamma*y(0)*F/(R*T))*y(17)**3*Cao-exp((gamma-1)*y(0)*F/(R*T))*Nao**3*y(2)*alpha)/((KmNai**3+Nao**3)*(KmCa+Cao)*(1+Ksat*exp((gamma-1)*y(0)*F/(R*T))))

    ## INaK
    Km_K  = 1   # millimolar (in i_NaK)
    Km_Na = 40   # millimolar (in i_NaK)
    PNaK1 = PNaK   # A_per_F (in i_NaK)
    i_NaK = PNaK1*Ko/(Ko+Km_K)*y(17)/(y(17)+Km_Na)/(1+0.1245*exp(-0.1*y(0)*F/(R*T))+0.0353*exp(-y(0)*F/(R*T)))

    ## IpCa
    KPCa  = 0.0005   # millimolar (in i_PCa)
    g_PCa = 0.4125   # A_per_F (in i_PCa)
    i_PCa = g_PCa*y(2)/(y(2)+KPCa)

    ## Background currents
    g_b_Na = 0.95   # S_per_F (in i_b_Na)
    i_b_Na = g_b_Na*(y(0)-E_Na)

    g_b_Ca = 0.727272   # S_per_F (in i_b_Ca)
    i_b_Ca = g_b_Ca*(y(0)-E_Ca)

    ## Sarcoplasmic reticulum
    i_up = VmaxUp/(1+Kup**2/y(2)**2)

    i_leak = (y(1)-y(2))*V_leak

    dY[3] = 0

    # RyR
    RyRSRCass = (1 - 1/(1 +  exp((y(1)-0.3)/0.1)))
    i_rel = g_irel_max*RyRSRCass*y(21)*y(22)*(y(1)-y(2))

    RyRainfss = RyRa1-RyRa2/(1 + exp((1000*y(2)-(RyRahalf))/0.0082))
    RyRtauadapt = 1 #s
    dY[20] = (RyRainfss- y(20))/RyRtauadapt

    RyRoinfss = (1 - 1/(1 +  exp((1000*y(2)-(y(20)+ RyRohalf))/0.003)))
    RyRtauact = conditional(RyRoinfss,y(21),0.1,1)*18.75e-3
    
    dY[21] = (RyRoinfss- y(21))/RyRtauact

    RyRcinfss = (1/(1 + exp((1000*y(2)-(y(20)+RyRchalf))/0.001)))
    
    RyRtauinact = conditional(RyRcinfss,y(22),1,2)*87.5e-3
    
    dY[22] = (RyRcinfss- y(22))/RyRtauinact
    
    ## Ca2+ buffering
    Buf_C       = 0.25   # millimolar (in calcium_dynamics)
    Buf_SR      = 10   # millimolar (in calcium_dynamics)
    Kbuf_C      = 0.001   # millimolar (in calcium_dynamics)
    Kbuf_SR     = 0.3   # millimolar (in calcium_dynamics)
    Cai_bufc    = 1/(1+Buf_C*Kbuf_C/(y(2)+Kbuf_C)**2)
    Ca_SR_bufSR = 1/(1+Buf_SR*Kbuf_SR/(y(1)+Kbuf_SR)**2)

    ## Ionic concentrations
    #Nai
    dY[17] = -Cm*(i_Na+i_NaL+i_b_Na+3*i_NaK+3*i_NaCa+i_fNa)/(F*Vc*1e-18)
    #caSR
    dY[2]  = Cai_bufc*(i_leak-i_up+i_rel-(i_CaL+i_b_Ca+i_PCa-2*i_NaCa)*Cm/(2*Vc*F*1e-18))
    #Cai
    dY[1]  = Ca_SR_bufSR*Vc/V_SR*(i_up-(i_rel+i_leak))

    i_stim = 0
    

    ## Membrane potential
    dY[0] = -(i_K1+i_to+i_Kr+i_Ks+i_CaL+i_NaK+i_Na+i_NaL+i_NaCa+i_PCa+i_f+i_b_Na+i_b_Ca-i_stim)
    
    return dY
def test_lambertw():
    assert LambertW(0) == 0
    assert LambertW(E) == 1
    assert LambertW(-1 / E) == -1
    assert LambertW(-log(2) / 2) == -log(2)
def test_log():
    x = Symbol("x")
    y = Symbol("y")
    assert log(E) == 1
    assert log(x, x) == 1
    assert log(x, y) == log(x) / log(y)
Example #20
0
def test_sage_conversions():

    x, y = sage.SR.var('x y')
    x1, y1 = symbols('x, y')

    # Symbol
    assert x1._sage_() == x
    assert x1 == sympify(x)

    # Integer
    assert Integer(12)._sage_() == sage.Integer(12)
    assert Integer(12) == sympify(sage.Integer(12))

    # Rational
    assert (Integer(1) / 2)._sage_() == sage.Integer(1) / 2
    assert Integer(1) / 2 == sympify(sage.Integer(1) / 2)

    # Operators
    assert x1 + y == x1 + y1
    assert x1 * y == x1 * y1
    assert x1**y == x1**y1
    assert x1 - y == x1 - y1
    assert x1 / y == x1 / y1

    assert x + y1 == x + y
    assert x * y1 == x * y
    # Doesn't work in Sage 6.1.1ubuntu2
    # assert x ** y1 == x ** y
    assert x - y1 == x - y
    assert x / y1 == x / y

    # Conversions
    assert (x1 + y1)._sage_() == x + y
    assert (x1 * y1)._sage_() == x * y
    assert (x1**y1)._sage_() == x**y
    assert (x1 - y1)._sage_() == x - y
    assert (x1 / y1)._sage_() == x / y

    assert x1 + y1 == sympify(x + y)
    assert x1 * y1 == sympify(x * y)
    assert x1**y1 == sympify(x**y)
    assert x1 - y1 == sympify(x - y)
    assert x1 / y1 == sympify(x / y)

    # Functions
    assert sin(x1) == sin(x)
    assert sin(x1)._sage_() == sage.sin(x)
    assert sin(x1) == sympify(sage.sin(x))

    assert cos(x1) == cos(x)
    assert cos(x1)._sage_() == sage.cos(x)
    assert cos(x1) == sympify(sage.cos(x))

    assert function_symbol('f', x1, y1)._sage_() == sage.function('f')(x, y)
    assert (function_symbol('f', 2 * x1,
                            x1 + y1).diff(x1)._sage_() == sage.function('f')(
                                2 * x, x + y).diff(x))

    assert LambertW(x1) == LambertW(x)
    assert LambertW(x1)._sage_() == sage.lambert_w(x)

    assert KroneckerDelta(x1, y1) == KroneckerDelta(x, y)
    assert KroneckerDelta(x1, y1)._sage_() == sage.kronecker_delta(x, y)

    assert erf(x1) == erf(x)
    assert erf(x1)._sage_() == sage.erf(x)

    assert lowergamma(x1, y1) == lowergamma(x, y)
    assert lowergamma(x1, y1)._sage_() == sage.gamma_inc_lower(x, y)

    assert uppergamma(x1, y1) == uppergamma(x, y)
    assert uppergamma(x1, y1)._sage_() == sage.gamma_inc(x, y)

    assert loggamma(x1) == loggamma(x)
    assert loggamma(x1)._sage_() == sage.log_gamma(x)

    assert beta(x1, y1) == beta(x, y)
    assert beta(x1, y1)._sage_() == sage.beta(x, y)

    assert floor(x1) == floor(x)
    assert floor(x1)._sage_() == sage.floor(x)

    assert ceiling(x1) == ceiling(x)
    assert ceiling(x1)._sage_() == sage.ceil(x)

    assert conjugate(x1) == conjugate(x)
    assert conjugate(x1)._sage_() == sage.conjugate(x)

    # For the following test, sage needs to be modified
    # assert sage.sin(x) == sage.sin(x1)

    # Constants and Booleans
    assert pi._sage_() == sage.pi
    assert E._sage_() == sage.e
    assert I._sage_() == sage.I
    assert GoldenRatio._sage_() == sage.golden_ratio
    assert Catalan._sage_() == sage.catalan
    assert EulerGamma._sage_() == sage.euler_gamma
    assert oo._sage_() == sage.oo
    assert zoo._sage_() == sage.unsigned_infinity
    assert nan._sage_() == sage.NaN
    assert true._sage_() == True
    assert false._sage_() == False

    assert pi == sympify(sage.pi)
    assert E == sympify(sage.e)
    assert GoldenRatio == sympify(sage.golden_ratio)
    assert Catalan == sympify(sage.catalan)
    assert EulerGamma == sympify(sage.euler_gamma)
    assert oo == sympify(sage.oo)
    assert zoo == sympify(sage.unsigned_infinity)
    assert nan == sympify(sage.NaN)

    # SympyConverter does not support converting the following
    # assert I == sympify(sage.I)

    # Matrix
    assert DenseMatrix(1, 2, [x1, y1])._sage_() == sage.matrix([[x, y]])

    # SympyConverter does not support converting the following
    # assert DenseMatrix(1, 2, [x1, y1]) == sympify(sage.matrix([[x, y]]))

    # Sage Number
    a = sage.Mod(2, 7)
    b = PyNumber(a, sage_module)

    a = a + 8
    b = b + 8
    assert isinstance(b, PyNumber)
    assert b._sage_() == a
    assert str(a) == str(b)

    # Sage Function
    e = x1 + wrap_sage_function(sage.log_gamma(x))
    assert str(e) == "x + log_gamma(x)"
    assert isinstance(e, Add)
    assert (e + wrap_sage_function(sage.log_gamma(x)) == x1 +
            2 * wrap_sage_function(sage.log_gamma(x)))

    f = e.subs({x1: 10})
    assert f == 10 + log(362880)

    f = e.subs({x1: 2})
    assert f == 2

    f = e.subs({x1: 100})
    v = f.n(53, real=True)
    assert abs(float(v) - 459.13420537) < 1e-7

    f = e.diff(x1)
def test_binary_candidate_models_are_constructed_correctly():
    """Candidate models should be generated for all valid combinations of possible models in the binary case"""
    features = OrderedDict([("CPM_FORM", (v.T * symengine.log(v.T), v.T**2)),
                            ("SM_FORM", (v.T, )),
                            ("HM_FORM", (symengine.S.One, ))])
    YS = symengine.Symbol('YS')
    Z = symengine.Symbol('Z')
    candidate_models = build_candidate_models((('A', 'B'), 'A'), features)
    assert candidate_models == OrderedDict([
        ('CPM_FORM',
         [[v.T * YS * symengine.log(v.T)],
          [v.T * YS * symengine.log(v.T), v.T**2 * YS],
          [v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T)],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T),
              v.T**2 * YS * Z**2
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T),
              v.T**2 * YS * Z**2, v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T * YS * Z * symengine.log(v.T),
              v.T**2 * YS * Z, v.T * YS * Z**2 * symengine.log(v.T),
              v.T**2 * YS * Z**2, v.T * YS * Z**3 * symengine.log(v.T),
              v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T),
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T),
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T)
          ],
          [
              v.T * YS * symengine.log(v.T), v.T**2 * YS,
              v.T * YS * Z * symengine.log(v.T), v.T**2 * YS * Z,
              v.T * YS * Z**2 * symengine.log(v.T), v.T**2 * YS * Z**2,
              v.T * YS * Z**3 * symengine.log(v.T), v.T**2 * YS * Z**3
          ]]),
        ('SM_FORM',
         [[v.T * YS], [v.T * YS, v.T * YS * Z],
          [v.T * YS, v.T * YS * Z, v.T * YS * Z**2],
          [v.T * YS, v.T * YS * Z, v.T * YS * Z**2, v.T * YS * Z**3]]),
        ('HM_FORM', [[YS], [YS, YS * Z], [YS, YS * Z, YS * Z**2],
                     [YS, YS * Z, YS * Z**2, YS * Z**3]])
    ])
Example #22
0
def fit_formation_energy(dbf,
                         comps,
                         phase_name,
                         configuration,
                         symmetry,
                         datasets,
                         ridge_alpha=None,
                         aicc_phase_penalty=None,
                         features=None):
    """
    Find suitable linear model parameters for the given phase.
    We do this by successively fitting heat capacities, entropies and
    enthalpies of formation, and selecting against criteria to prevent
    overfitting. The "best" set of parameters minimizes the error
    without overfitting.

    Parameters
    ----------
    dbf : Database
        pycalphad Database. Partially complete, so we know what degrees of freedom to fix.
    comps : [str]
        Names of the relevant components.
    phase_name : str
        Name of the desired phase for which the parameters will be found.
    configuration : ndarray
        Configuration of the sublattices for the fitting procedure.
    symmetry : [[int]]
        Symmetry of the sublattice configuration.
    datasets : PickleableTinyDB
        All the datasets desired to fit to.
    ridge_alpha : float
        Value of the :math:`\\alpha` hyperparameter used in ridge regression. Defaults to 1.0e-100, which should be degenerate
        with ordinary least squares regression. For now, the parameter is applied to all features.
    aicc_feature_factors : dict
        Map of phase name to feature to a multiplication factor for the AICc's parameter penalty.
    features : dict
        Maps "property" to a list of features for the linear model.
        These will be transformed from "GM" coefficients
        e.g., {"CPM_FORM": (v.T*symengine.log(v.T), v.T**2, v.T**-1, v.T**3)} (Default value = None)

    Returns
    -------
    dict
        {feature: estimated_value}

    """
    aicc_feature_factors = aicc_phase_penalty if aicc_phase_penalty is not None else {}
    if interaction_test(configuration):
        _log.debug('ENDMEMBERS FROM INTERACTION: %s',
                   endmembers_from_interaction(configuration))
        fitting_steps = (["CPM_FORM",
                          "CPM_MIX"], ["SM_FORM",
                                       "SM_MIX"], ["HM_FORM", "HM_MIX"])

    else:
        # We are only fitting an endmember; no mixing data needed
        fitting_steps = (["CPM_FORM"], ["SM_FORM"], ["HM_FORM"])

    # create the candidate models and fitting steps
    if features is None:
        features = OrderedDict([
            ("CPM_FORM", (v.T * symengine.log(v.T), v.T**2, v.T**-1, v.T**3)),
            ("SM_FORM", (v.T, )),
            ("HM_FORM", (symengine.S.One, )),
        ])
    # dict of {feature, [candidate_models]}
    candidate_models_features = build_candidate_models(configuration, features)

    # All possible parameter values that could be taken on. This is some legacy
    # code from before there were many candidate models built. For very large
    # sets of candidate models, this could be quite slow.
    # TODO: we might be able to remove this initialization for clarity, depends on fixed poritions
    parameters = {}
    for candidate_models in candidate_models_features.values():
        for model in candidate_models:
            for coef in model:
                parameters[coef] = 0

    # These is our previously fit partial model from previous steps
    # Subtract out all of these contributions (zero out reference state because these are formation properties)
    fixed_model = None  # Profiling suggests we delay instantiation
    fixed_portions = [0]

    for desired_props in fitting_steps:
        feature_type = desired_props[0].split('_')[0]  # HM_FORM -> HM
        aicc_factor = aicc_feature_factors.get(feature_type, 1.0)
        solver_qry = (where('solver').test(
            symmetry_filter, configuration,
            recursive_tuplify(symmetry) if symmetry else symmetry))
        desired_data = get_prop_data(comps,
                                     phase_name,
                                     desired_props,
                                     datasets,
                                     additional_query=solver_qry)
        desired_data = filter_configurations(desired_data, configuration,
                                             symmetry)
        desired_data = filter_temperatures(desired_data)
        _log.trace('%s: datasets found: %s', desired_props, len(desired_data))
        if len(desired_data) > 0:
            if fixed_model is None:
                fixed_model = Model(dbf,
                                    comps,
                                    phase_name,
                                    parameters={
                                        'GHSER' + (c.upper() * 2)[:2]: 0
                                        for c in comps
                                    })
            config_tup = tuple(map(tuplify, configuration))
            calculate_dict = get_prop_samples(desired_data, config_tup)
            sample_condition_dicts = _get_sample_condition_dicts(
                calculate_dict, list(map(len, config_tup)))
            weights = calculate_dict['weights']
            assert len(sample_condition_dicts) == len(weights)

            # We assume all properties in the same fitting step have the same
            # features (all CPM, all HM, etc., but different ref states).
            # data quantities are the same for each candidate model and can be computed up front
            data_qtys = get_data_quantities(feature_type, fixed_model,
                                            fixed_portions, desired_data,
                                            sample_condition_dicts)

            # build the candidate model transformation matrix and response vector (A, b in Ax=b)
            feature_matricies = []
            data_quantities = []
            for candidate_coefficients in candidate_models_features[
                    desired_props[0]]:
                # Map coeffiecients in G to coefficients in the feature_type (H, S, CP)
                transformed_coefficients = list(
                    map(feature_transforms[feature_type],
                        candidate_coefficients))
                if interaction_test(configuration, 3):
                    feature_matricies.append(
                        _build_feature_matrix(sample_condition_dicts,
                                              transformed_coefficients))
                else:
                    feature_matricies.append(
                        _build_feature_matrix(sample_condition_dicts,
                                              transformed_coefficients))
                data_quantities.append(data_qtys)

            # provide candidate models and get back a selected model.
            selected_model = select_model(zip(
                candidate_models_features[desired_props[0]], feature_matricies,
                data_quantities),
                                          ridge_alpha,
                                          weights=weights,
                                          aicc_factor=aicc_factor)
            selected_features, selected_values = selected_model
            parameters.update(zip(*(selected_features, selected_values)))
            # Add these parameters to be fixed for the next fitting step
            fixed_portion = np.array(selected_features, dtype=np.object_)
            fixed_portion = np.dot(fixed_portion, selected_values)
            fixed_portions.append(fixed_portion)
    return parameters