Search code examples
pythonarraysnumpymatrixlinear-algebra

Setting up a numpy array with parameters in it


I want to create a matrix which contains parameters from a series of ODEs I have. I have 5 ODEs, and all the parameters from them must be in this matrix in a certain order

Howver I cannot find the most logical way of doing this. I setup a 5x5 matrix of zeroes, and tried to replace certain positions in the matrix with my parameters, but these parameters are not defined previously and I am entering them as they are (undefined values) as I will use them later. My code is this:

import numpy as np


####create matrix

zeros = np.zeros((5,5))
params = ['-lambda', 'lambda', '-u-v', 'u', '-w', 'v', 'w','-gamma', 'gamma']
pos = [(0,0),(1,0),(1,1),(2,1),(2,2),(3,1),(3,2),(3,3),(4,3)]
rows, cols = zip(*pos)
zeros[rows, cols] = params

What I am trying to get coded is something that looks like this:

enter image description here

--------------------------------edit

the purpose for all this is so when I multiply out my matrix with another vector, I will be left with the equations for my ODEs (see below as an example, multiplying first row with the vector gives 'dU', and so on.

enter image description here

enter image description here


Solution

  • We can just input the rows and columns as separate lists of x and y positions; and you probably want to populate the numpy array with (the values of) the variables u, v, w, gamma, and _lambda (FYI don't name variables the same as existing built-in ones like lambda which is already a function with some syntactic sugar shortening the code to define or invoke a function, here's a link: How are lambdas useful?):

    import numpy as np
    zeros = np.zeros((5, 5))
    _lambda = 1
    u = 3
    v = 4
    w = 5
    gamma = 6
    params = [-_lambda, _lambda, -u-v, u, -w, v, w, -gamma, gamma]
    posx = [0, 1, 1, 2, 2, 3, 3, 3, 4]
    posy = [0, 0, 1, 1, 2, 1, 2, 3, 3]
    zeros[posx, posy] = params
    

    print(zeros) outputs:

    [[-1.  0.  0.  0.  0.]
     [ 1. -7.  0.  0.  0.]
     [ 0.  3. -5.  0.  0.]
     [ 0.  4.  5. -6.  0.]
     [ 0.  0.  0.  6.  0.]]
    

    If you do actually want to populate the array with that list of string names in your question (['-lambda', 'lambda', '-u-v', 'u', '-w', 'v', 'w','-gamma', 'gamma']) then we can do the same thing, but we need to set the dtype of the initial numpy array as string, too:

    import numpy as np
    zeros = np.zeros((5, 5)).astype(str)
    params = ['-lambda', 'lambda', '-u-v', 'u', '-w', 'v', 'w','-gamma', 'gamma']
    posx = [0, 1, 1, 2, 2, 3, 3, 3, 4]
    posy = [0, 0, 1, 1, 2, 1, 2, 3, 3]
    zeros[posx, posy] = params
    

    print(zeros) outputs:

    [['-lambda' '0.0' '0.0' '0.0' '0.0']
     ['lambda' '-u-v' '0.0' '0.0' '0.0']
     ['0.0' 'u' '-w' '0.0' '0.0']
     ['0.0' 'v' 'w' '-gamma' '0.0']
     ['0.0' '0.0' '0.0' 'gamma' '0.0']]
    

    If we want to get the values, then we can evaluate the strings in the array:

    print(f'{zeros[-1, -2]}: {eval(zeros[-1, -2])}')
    

    Outputs:

    gamma: 6