Home > database >  Difference between Results in Manual Function and Matrix Multiplication with odeint
Difference between Results in Manual Function and Matrix Multiplication with odeint

Time:11-20

I'm currently trying to develop a function that performs matrix multiplication while expanding a differential equation with odeint in Python and am seeing strange results.

I converted the function:


    def f(x, t):
        return [
            -0.1 * x[0]   2 * x[1],
            -2 * x[0] - 0.1 * x[1]        
        ]

to the below so that I can incorporate different matrices. I have the below matrix of values and function that takes specific values of that matrix:

from scipy.integrate import odeint
x0_train = [2,0]
dt = 0.01
t = np.arange(0, 1000, dt)
matrix_a = np.array([-0.09999975, 1.999999, -1.999999, -0.09999974])
# Function to run odeint with
def f(x, t, a):
    return [
        a[0] * x[0]   a[1] * x[1],
        a[2] * x[0] - a[3] * x[1]
    ]
odeint(f, x0_train, t, args=(matrix_a,))

>>> array([[ 2.        ,  0.        ],
       [ 1.99760115, -0.03999731],
       [ 1.99440529, -0.07997867],
       ...,
       [ 1.69090227,  1.15608741],
       [ 1.71199436,  1.12319701],
       [ 1.73240339,  1.08985846]])

This seems right, but when I create my own function to perform multiplication/regression, I see the results at the bottom of the array are completely different. I have two sparse arrays that provide the same conditions as matrix_a but with zeros around them.

from sklearn.preprocessing import PolynomialFeatures
new_matrix_a = array([[ 0.        , -0.09999975,  1.999999  ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ],
       [ 0.        , -1.999999  , -0.09999974,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
         0.        ]])
# New function
def f_new(x, t, parameters):
    polynomials = PolynomialFeatures(degree=5)
    x = np.array(x).reshape(-1,2)
    #x0_train_array_reshape = x0_train_array.reshape(1,2)
    polynomial_transform = polynomials.fit(x)
    polynomial_features = polynomial_transform.fit_transform(x).T
    x_ode = np.matmul(parameters[0],polynomial_features)
    y_ode = np.matmul(parameters[1],polynomial_features)
    return np.concatenate((x_ode, y_ode), axis=None).tolist()

odeint(f_new, x0_train, t, args=(new_matrix_a,))

>>> array([[ 2.00000000e 00,  0.00000000e 00],
       [ 1.99760142e 00, -3.99573216e-02],
       [ 1.99440742e 00, -7.98188169e-02],
       ...,
       [-3.50784051e-21, -9.99729456e-22],
       [-3.50782881e-21, -9.99726119e-22],
       [-3.50781711e-21, -9.99722781e-22]])

As you can see, I'm getting completely different values at the end of the array. I've been running through my code and can't seem to find a reason why they would be different. Does anybody have a clear reason why or if I'm doing something wrong with my f_new? Ideally, I'd like to develop a function that can take any values in that matrix_a, which is why I'm trying to create this new function.

Thanks in advance.

CodePudding user response:

You should perhaps use numpy even more in the first version, to avoid sign errors in routine algorithms.

def f(x, t, a):
    return a.reshape([2,2]) @ x # or use matmul, or a.reshape([2,2]).dot(x)

or, for efficiency, pass the already reshaped a.

  • Related