Exemplo n.º 1
0
    def test_state_transition_operator_2d(self):
        # two-dimensional case
        C_0, C_1 = symbols('C_0 C_1')
        state_vector = [C_0, C_1]
        time_symbol = Symbol('t')
        input_fluxes = {}
        output_fluxes = {0: C_0, 1: C_1}
        internal_fluxes = {}
        srm = SmoothReservoirModel(state_vector, time_symbol, input_fluxes,
                                   output_fluxes, internal_fluxes)

        start_values = np.array([5, 3])
        times = np.linspace(0, 1, 11)
        smr = SmoothModelRun(srm, {}, start_values, times)

        x = np.array([1, 3])
        Phix = smr._state_transition_operator(1, 0, x)

        self.assertEqual(Phix.shape, (2, ))

        # test t < t_0
        with self.assertRaises(Exception):
            Phix = smr._state_transition_operator(0, 1, x)

        # test if operator works correctly also late in time
        C = Symbol('C')
        state_vector = [C]
        time_symbol = Symbol('t')
        # are inputs really ignored in the computation of Phi?
        input_fluxes = {0: 1}
        output_fluxes = {0: C}
        internal_fluxes = {}
        srm = SmoothReservoirModel(state_vector, time_symbol, input_fluxes,
                                   output_fluxes, internal_fluxes)

        start_values = np.array([5])
        times = np.linspace(0, 100, 101)
        smr = SmoothModelRun(srm, {}, start_values, times)

        x = np.array([1])

        Phix = smr._state_transition_operator(91, 89, x)
        self.assertTrue(abs(Phix - np.exp(-2)) < 1e-03)
Exemplo n.º 2
0
    def test_phi_2d_linear(self):
        C_0, C_1 = symbols('C_0 C_1')
        state_vector = [C_0, C_1]
        time_symbol = Symbol('t')
        input_fluxes = {}
        output_fluxes = {0: C_0, 1: C_1}
        internal_fluxes = {}
        srm = SmoothReservoirModel(state_vector, time_symbol, input_fluxes,
                                   output_fluxes, internal_fluxes)

        start_values = np.array([1, 2])
        t_0 = 0
        t_max = 4
        nt = 200
        times = np.linspace(t_0, t_max, nt)
        smr = SmoothModelRun(srm, {}, start_values, times)
        smr.initialize_state_transition_operator_cache(lru_maxsize=None,
                                                       size=2)

        nr_pools = srm.nr_pools

        def baseVector(i):
            e_i = np.zeros((nr_pools, 1))
            e_i[i] = 1
            return e_i

        bvs = [baseVector(i) for i in range(nr_pools)]

        for s in np.linspace(t_0, t_max, 5):
            for t in np.linspace(s, t_max, 5):

                phi_ref = np.eye(2) * np.exp(-(t - s))
                # test the matrix valued results
                with self.subTest():
                    self.assertTrue(
                        np.allclose(smr.Phi(t, s), phi_ref, rtol=1e-2))

                # test the vectored valued results
                for x in bvs:
                    for phi_x in [
                            smr._state_transition_operator(t, s, x),
                            smr._state_transition_operator_for_linear_systems(
                                t, s, x)
                    ]:
                        with self.subTest():
                            self.assertTrue(
                                np.allclose(phi_x,
                                            np.matmul(phi_ref,
                                                      x).reshape(nr_pools, ),
                                            rtol=1e-2))
Exemplo n.º 3
0
    def test_state_transition_operator_1d(self):
        # one-dimensional case
        C = Symbol('C')
        state_vector = [C]
        time_symbol = Symbol('t')
        # are inputs really ignored in the computation of Phi?
        input_fluxes = {0: 1}
        output_fluxes = {0: C}
        internal_fluxes = {}
        srm = SmoothReservoirModel(state_vector, time_symbol, input_fluxes,
                                   output_fluxes, internal_fluxes)

        start_values = np.array([5])
        times = np.linspace(0, 1, 11)
        smr = SmoothModelRun(srm, {}, start_values, times)

        x = np.array([1])

        Phix = smr._state_transition_operator(1, 0, x)

        self.assertEqual(Phix.shape, (1, ))
        self.assertTrue(abs(Phix - np.exp(-1)) < 1e-03)
Exemplo n.º 4
0
def test_stateTransitionOperator_by_different_methods():
    # The state transition operator Phi can be used to reproduce the solution
    k_0_val = 1
    k_1_val = 2
    x0_0 = np.float(0.5)
    x0_1 = np.float(1.5)
    delta_t = np.float(1. / 4.)
    #
    var(["x_0", "x_1", "k_0", "k_1", "t", "u"])
    #
    inputs = {0: u, 1: u * t}
    outputs = {0: k_0 * x_0**2, 1: k_1 * x_1}
    internal_fluxes = {}
    svec = Matrix([x_0, x_1])
    srm = SmoothReservoirModel(state_vector=svec,
                               time_symbol=t,
                               input_fluxes=inputs,
                               output_fluxes=outputs,
                               internal_fluxes=internal_fluxes)
    t_0 = 0
    t_max = 4
    nt = 5
    times = np.linspace(t_0, t_max, nt)
    double_times = np.linspace(t_0, t_max, 2 * (nt - 1) + 1)
    quad_times = np.linspace(t_0, t_max, 4 * (nt - 1) + 1)
    parameter_dict = {k_0: k_0_val, k_1: k_1_val, u: 1}
    func_dict = {}
    start_x = np.array([x0_0, x0_1])  #make it a column vector for later use
    #create the model run
    smr = SmoothModelRun(model=srm,
                         parameter_dict=parameter_dict,
                         start_values=start_x,
                         times=times,
                         func_set=func_dict)
    smr.build_state_transition_operator_cache(size=4)
    nr_pools = smr.nr_pools

    # to be able to compare the results we have to compute them for a
    # set of n linear independent vectors
    def baseVector(i):
        e_i = np.zeros((nr_pools, 1))
        e_i[i] = 1
        return e_i

    bvs = [baseVector(i) for i in range(nr_pools)]
    #pe('Phi_skew(2,1,bvs[0])',locals())
    #raise

    test_times = np.linspace(t_0, t_max, 11)

    # We now rebuild the solution by means of phi and plot it along with the original solution
    original_sol, sol_func = smr.solve()

    u_sym = srm.external_inputs
    u_num = numerical_function_from_expression(u_sym, (t, ), parameter_dict,
                                               {})

    def vectorlist2array(l):
        return np.stack([vec.flatten() for vec in l], 1)


#    def lists_dict2array_dict(d):
#        return {key:vectorlist2array(val) for key,val in d.items()}
#

    def continiuous_integral_values(integrator, times):
        start = time.time()
        res = vectorlist2array([
            integrator(
                lambda tau: smr._state_transition_operator(t, tau, u_num(tau)),
                t_0, t) for t in times
        ])
        stop = time.time()
        exec_time = stop - start
        #pe('exec_time',locals())
        return (times, res, exec_time)

    def discrete_integral_values(integrator, times):
        start = time.time()
        res = vectorlist2array([
            integrator(
                lambda tau: smr._state_transition_operator(t, tau, u_num(tau)),
                taus=+times[0:i + 1]) for i, t in enumerate(times)
        ])
        stop = time.time()
        exec_time = stop - start
        #pe('exec_time',locals())
        return (times, res, exec_time)

    ## reconstruct the solution with Phi and the integrand
    # x_t=Phi(t,t0)*x_0+int_t0^t Phi(tau,t0)*u(tau) dtau
    # x_t=a(t)+b(t)
    et = bvs[0] + bvs[1]
    phi_arrays = {
        'skew':
        (times,
         vectorlist2array([
             smr._state_transition_operator(t, t_0,
                                            et).reshape(srm.nr_pools, 1)
             for t in times
         ]))
    }

    a_arrays = {
        'skew':
        (times,
         vectorlist2array([
             smr._state_transition_operator(t, t_0,
                                            start_x).reshape(srm.nr_pools, 1)
             for t in times
         ])),
        'trapez1':
        (times,
         vectorlist2array([
             smr._state_transition_operator(t, t_0,
                                            start_x).reshape(srm.nr_pools, 1)
             for t in times
         ])),
        'trapez2':
        (double_times,
         vectorlist2array([
             smr._state_transition_operator(t, t_0,
                                            start_x).reshape(srm.nr_pools, 1)
             for t in double_times
         ])),
        'trapez4':
        (quad_times,
         vectorlist2array([
             smr._state_transition_operator(t, t_0,
                                            start_x).reshape(srm.nr_pools, 1)
             for t in quad_times
         ]))
    }
    nested_boundary_tuples = [(0, t) for t in reversed(times)]

    b_arrays_trapez = {}
    b_arrays = {
        'skew':
        continiuous_integral_values(array_integration_by_ode, times),
        'trapez1':
        discrete_integral_values(array_integration_by_values, times),
        'trapez2':
        discrete_integral_values(array_integration_by_values, double_times),
        'trapez4':
        discrete_integral_values(array_integration_by_values, quad_times)
    }

    b_arrays_quad = {
        'skew': continiuous_integral_values(array_quad_result, times)
    }

    x_arrays = {
        key: (a_arrays[key][0], a_arrays[key][1] + b_arrays[key][1])
        for key in a_arrays.keys()
    }
    #x_arrays['trapez']=(times,a_arrays['skew'][1]+b_arrays['trapez'][1])

    styleDict = OrderedDict({
        'skew': ('green', 6),
        'trapez1': ('black', 4),
        'trapez2': ('blue', 4),
        'trapez4': ('brown', 2)
    })

    def plot_comparison(axl, axr, d):
        for key in styleDict.keys():
            if key in d.keys():
                val = d[key]
                if len(val) == 3:
                    time = "{:7.1e}".format(val[2])
                else:
                    time = ""
                axl.plot(val[0],
                         val[1][0, :],
                         '+',
                         color=styleDict[key][0],
                         markersize=styleDict[key][1],
                         label=key + "[0]" + time)
                axr.plot(val[0],
                         val[1][1, :],
                         'x',
                         color=styleDict[key][0],
                         markersize=styleDict[key][1],
                         label=key + "[1]" + time)

    fig = plt.figure(figsize=(17, 27))
    rpn = 5
    cpn = 2
    r = 1
    axl = fig.add_subplot(rpn, cpn, r)
    plt.title("""phi components, nonlinear part of the system (x[0]) """)
    axr = fig.add_subplot(rpn, cpn, r + 1)
    plt.title("""phi components, linear part of the system (x[1]) """)
    plot_comparison(axl, axr, phi_arrays)
    axl.legend()

    r += cpn
    axl = fig.add_subplot(rpn, cpn, r)
    plt.title('''
    original solution and reconstruction via phi, 
    imprecise for trapez_rule and wrong for the old method
    ''')
    axr = fig.add_subplot(rpn, cpn, r + 1)
    axl.plot(times,
             original_sol[:, 0],
             'o',
             color='blue',
             label="original_sol[:,0]")
    axr.plot(times,
             original_sol[:, 1],
             'o',
             color='blue',
             label="original_sol[:,1]")

    plot_comparison(axl, axr, x_arrays)
    axl.legend()
    axr.legend()

    r += cpn
    axl = fig.add_subplot(rpn, cpn, r)
    plt.title('phi(t,ti-0) x0 ')
    axr = fig.add_subplot(rpn, cpn, r + 1)
    ax = fig.add_subplot(rpn, cpn, r)
    plot_comparison(axl, axr, a_arrays)
    axl.legend()
    axr.legend()

    r += cpn
    axl = fig.add_subplot(rpn, cpn, r)
    plt.title('\int_{t0}^t phi(tau,t) u(tau) d tau')
    axr = fig.add_subplot(rpn, cpn, r + 1)
    plot_comparison(axl, axr, b_arrays)
    axl.legend()
    axr.legend()

    #r+=cpn
    r += cpn
    axl = fig.add_subplot(rpn, cpn, r)
    plt.title('\int_{t0}^t phi(tau,t) u(tau) d tau by quad')
    axr = fig.add_subplot(rpn, cpn, r + 1)
    plot_comparison(axl, axr, b_arrays_quad)
    axl.legend()
    axr.legend()

    fig.savefig("solutions.pdf")
Exemplo n.º 5
0
    def test_phi_2d_non_linear(self):
        k_0_val = 1
        k_1_val = 2
        x0_0 = np.float(0.5)
        x0_1 = np.float(1.5)
        x_0, x_1, k_0, k_1, t, u = symbols("x_0 x_1 k_0 k_1 t u")

        inputs = {0: u, 1: u * t}
        outputs = {0: k_0 * x_0**2, 1: k_1 * x_1}
        internal_fluxes = {}
        svec = Matrix([x_0, x_1])
        srm = SmoothReservoirModel(state_vector=svec,
                                   time_symbol=t,
                                   input_fluxes=inputs,
                                   output_fluxes=outputs,
                                   internal_fluxes=internal_fluxes)
        t_0 = 0
        t_max = 4
        nt = 20000
        times = np.linspace(t_0, t_max, nt)
        parameter_dict = {k_0: k_0_val, k_1: k_1_val, u: 1}
        func_dict = {}
        # make it a column vector for later use
        start_x = np.array([x0_0, x0_1])
        # create the model run
        smr = SmoothModelRun(
            model=srm,
            parameter_dict=parameter_dict,
            start_values=start_x,
            times=times,
            func_set=func_dict,
        )
        smr.initialize_state_transition_operator_cache(lru_maxsize=None,
                                                       size=4)

        nr_pools = srm.nr_pools

        def baseVector(i):
            e_i = np.zeros((nr_pools, 1))
            e_i[i] = 1
            return e_i

        bvs = [baseVector(i) for i in range(nr_pools)]

        smrl = smr.linearize_old()

        for s in np.linspace(t_0, t_max, 5):
            for t in np.linspace(s, t_max, 5):
                for x in bvs:
                    with self.subTest():
                        self.assertTrue(
                            np.allclose(
                                smr._state_transition_operator(t, s, x),
                                smrl.
                                _state_transition_operator_for_linear_systems(
                                    t, s, x),  # noqa: E501
                                rtol=1.5 * 1e-2))

        for t in np.linspace(t_0, t_max, 6):
            for phi_mat in [smr.Phi(t, t_0), smrl.Phi(t, t_0)]:
                for x in bvs:
                    with self.subTest():
                        self.assertTrue(
                            np.allclose(np.matmul(phi_mat,
                                                  x).reshape(nr_pools, ),
                                        smr._state_transition_operator(
                                            t, t_0, x),
                                        rtol=1.5 * 1e-2))