-2

What I have tried:

def df(t,x,*system_constants):
a,b,c,d,e,f,g,h,i,j,k,l,m = system_constants #unpack system constants
    #algebra with these constants to calculate something
    return something

This returns an error when called, saying: "ValueError: not enough values to unpack (expected 13, got 0).

Also (regardless of this error), it might be better to use a short form unpacking with a for loop. What would this for loop look like?

def df(t,x,*system_constants):

    for arg in system_constants:
        arg = system_constants
    #algebra with these constants to calculate something
    return something

The only objective here is to pass a tuple to a function without getting the above error, such that I can use the arguments without calling by index (i.e. without converting to a list)

The function is being called as an argument to the scipy.solve_ivp integrator:

sol = solve_ivp(df, [t0,tf], x0, dense_output = True)

The system_constants are stored in the same script just simply as:

system_constants = a,b,c,d,e,f,g,h,i,j,k,l,m
  • 2
    We can't see how you're actually _calling_ that function, but frankly expecting exactly 13 "var"args seems weird. Why not just accept the actual tuple (or use e.g. a `namedtuple` to hold those constants in a way you can access by _name_ rather than _index_) as a _single_ parameter? – jonrsharpe May 30 '22 at 09:36
  • 1
    Depending on where and how those system constants are stored, it might also be an option _not_ to pass them as parameters at all but just use them from the global context. – tobias_k May 30 '22 at 09:41
  • Hi, I have added how the function is being called. This '13' changes depending on how many system_constants I have in the system_constants tuple i.e. if I add one to the definition tuple in the main script then the 13 error changes to 14 – casualguitar May 30 '22 at 09:45
  • 1
    If you don't know how many arguments there are ahead of time, then *why do you want to unpack them*? If you are writing code that *could possibly deal with* the uncertainty, then it deals with that uncertainty by *iterating over* the arguments. In which case, the thing to do is to *leave them in the `args` tuple*, which is perfect for iterating over with a comprehension or a `for` loop. – Karl Knechtel May 30 '22 at 09:47
  • If you're currently doing `df(some, other, *system_constants)`, my point is that you should just call `df(some, other, system_constants)` instead. But per the newest information and the answer below it sounds like that's not what it's being called with _at all_ and it's unclear why you thought you'd get them as parameters. – jonrsharpe May 30 '22 at 09:48
  • If you have a loop like `for arg in system_constants:`, then that **already means** "every time through the loop, `arg` shall become equal to one of the values from `system_constants`, each one in turn". Doing `arg = system_constants` is both useless and wrong. – Karl Knechtel May 30 '22 at 09:48
  • "The function is being called as an argument to the scipy.solve_ivp integrator:" that means, it will call your `df` function, and it will control what is passed to `df`, according to the logic explained in the documentation. It is not passing anything for the `system_constants`, because it doesn't have any data to pass there, nor does it have any reason to, according to its internal logic. – Karl Knechtel May 30 '22 at 09:50
  • Error solved below by Soren. There is clearly another understanding error on my part going on in that I do not know why I choose *system_constants over simply system_cosntants. Using *args seems to be the standard approach however in this case there is no obvious reason to do so – casualguitar May 30 '22 at 09:57

1 Answers1

2

According to the documentation,

The calling signature is fun(t, y).

The function is only called with 2 arguments, you are expecting 15. That won't work.

Sören
  • 1,803
  • 2
  • 16
  • 23
  • Thank you, you are right. This is the error. I am calling the solve_ivp function incorrectly. One moment I'll try to fix this – casualguitar May 30 '22 at 09:47
  • Could I not leave it as it is? Or would it be more efficient long term to access the global variable if this system_constants variable will change quite a bit? – casualguitar May 30 '22 at 09:50
  • You're right. I tend to avoid global variables, so I misremembered when you have to use global and when not. – Sören May 30 '22 at 09:53