0

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

Landon
  • 93
  • 11
  • You can't mix numbers and strings in a numpy array. – Barmar May 02 '23 at 19:35
  • please see my edit. to clarify what I meant. Will this method work with that Im trying to achieve? – Landon May 02 '23 at 20:02
  • Pick the solver, and then practice with the examples, gradually expanding on them until you understand the nature of kinds of inputs it can work with. – hpaulj May 02 '23 at 20:50

1 Answers1

0

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
Ori Yarden PhD
  • 1,287
  • 1
  • 4
  • 8
  • Through applying the strings now though, when I want to use lambda or w or gamma later on, will these be of the type that values can be stored in them? – Landon May 02 '23 at 19:40
  • Nope, these are `str`ings. If you want to store the variables lambda, gamma, etc. then that's different. Though you can do something like `eval(zeros[-1, -2])` assuming gamma, etc. are already defined variables. – Ori Yarden PhD May 02 '23 at 19:49
  • I guess it doesn't make sense to use strings, but numbers, and something like this to set the values, once you have them. Then you can modify the array again if the data changes. `params = [-lambda_, lambda_, -u-v, u, -w, v, w, -gamma, gamma]` – antont May 02 '23 at 19:59
  • @OriYarden please see my edit. to clarify what I meant. Will this method work with that Im trying to achieve? – Landon May 02 '23 at 20:02
  • I agree with @antont , you probably want to fill the numpy array using the actual variables not the names of the variables in string. I'll edit my answer to include that as well (in an hour or two I'm busy at the moment); I did answer your actual question, but you can wait to accept it till I edit it to provide the answer to the question you were supposed to be asking. – Ori Yarden PhD May 02 '23 at 20:13
  • @Landon yes, just give me a moment to edit the question I can't do it this minute. – Ori Yarden PhD May 02 '23 at 20:14
  • Ok thank you, whenever you have time, Id be grateful. Thanks – Landon May 02 '23 at 20:20
  • @Landon is it supposed to be `-u-v` or `-(u+v)` because your sample code is the former while the pictures you included shows the latter? – Ori Yarden PhD May 03 '23 at 14:21
  • yes, either, as the latter is just a simplification of the former. – Landon May 03 '23 at 18:34
  • Im still confused - so as I want to multiply out my 5x5 matrix with the vector I have, strings dont allow this do they? What im trying to achieve is literally have the ODEs I have on paper when I multiply out the matrix – Landon May 03 '23 at 18:35
  • @Landon so do you want a 5x5 matrix of those string names or a 5x5 matrix of the (values of those) variables? For example, is `gamma` an actual variable already defined in your code? Do you want to input `gamma`'s value into the matrix or do want input `'gamma'` in string into the matrix? I provided both scenarios in the answer, but if it's neither of the two can you clarify further? – Ori Yarden PhD May 03 '23 at 18:43
  • Assuming I dont yet have these variables pre defined, then itll have to be used as a string, right? But with a string, i wont be able to multiply out my 5x5 with my 5x1 vector – Landon May 03 '23 at 18:49
  • @Landon well if the variables aren't defined then you wouldn't be able to multiply out your 5x5 anyways. You can fill it with string names instead, when you do want to multiply out your 5x5 then you can use the `eval` function to get the actual values (after first defining those variables). Either way you'd have to define the variables and assign them values at some point in order to multiply out the 5x5, so it just depends on what you want (i.e. does it make it "easier" to have a matrix filled with string names? If yes, then do that). I provided solutions for either scenario in the answer. – Ori Yarden PhD May 03 '23 at 18:58