Using an array as an input for a multivariable function - python

If I have a multivariable function such as
F= lambda x,y: x**2+y**2
and if I need to use the input x0=np.array([1,1])
May I know how I should use x0 to get the value from F?
I understand that I could use something like F(x0[0],x0[1])
But I would like to know whether there is a way that I can directly use x0 rather than calling each cordinate manually
Appreciate your help

Python lets you do this by doing F(*x0), which expands the array into the parameters. In other languages this is sometimes called "splatting".

Related

How do I use newtons method on python to solve a system of equations?

I have an assignment where I need to make a single defined function that runs newtons method and then be able plug in other defined functions to it and it will solve them all. I wrote one that works for equations that have 1 variable, and I only need to solve for one variable from the system but I don't know how to do that in code without solving for all four of them.
the function I wrote to run newtons method is this:
def fnewton(function, dx, x, n):
#defined the functions that need to be evaluated so that this code can be applied to any function I call
def f(x):
f=eval(function)
return f
#eval is used to evaluate whatever I put in the function place when I recall fnewton
#this won't work without eval to run the functions
def df(x):
df=eval(dx)
return df
for intercept in range(1,n):
i= x-(f(x)/df(x))
x= i
#this is literally just newtons method
#to find an intercept you can literally input intercept in a for loop and it'll do it for you
#I just found this out
#putting n in the range makes it count iterations
print ('root is at')
print (x)
print ('after this many iterations:')
print (n)
my current system of equations function looks like this:
def c(x):
T=x[0]
y=x[1]
nl=x[2]
nv=x[3]
RLN=.63*Antoine(An,Bn,Cn,T)-y*760
RLH=(1-.63)*Antoine(Ah,Bh,Ch,T)-(1-y)*760
N=.63*nl+y*nv-50
H=(1-.63)*nl+(1-y)*nv-50
return[RLN,RLH,N,H]
To use my function to solve this I've entered multiple variations of:
fnewton("c(x)","dcdx(x)", (2,2,2,2), 10)
Do I need to change the system of equations into 1 equation somehow or something I don't know how to manipulate my code to make this work and also work for equations with only 1 variable.
To perform Newton's method in multiple dimensions, you must replace the simple derivative by a Jacobian matrix, that is, a matrix that has the derivatives of all components of your multidimensional function with respect to all given variables. This is decribed here: https://en.wikipedia.org/wiki/Newton%27s_method#Systems_of_equations,
(or, perhaps more helpful, here: https://web.mit.edu/18.06/www/Spring17/Multidimensional-Newton.pdf in Sec. 1.4)
Instead of f(x)/f'(x), you need to work with the inverse of the Jacobian matrix times the vector function f. So the formula is actually quite similar!

How to define a python function 'on the fly' for use with pymanopt/autodifferentiation

I had no idea how to phrase the title of this question, so apologies for any confusion there. I am using the pymanopt package for optimization and would like to be able to create some sort of a function/method that allows for a generalized input (variable amount of input arrays). To use pymanopt, one has to provide a cost function defined in terms of array that are to be optimized to minimize the cost.
For example, a cost function could be:
#pymanopt.function.Autograd
def f(A,B):
return ((X - A#B.T)**2).sum()
To do the optimization, the variable X is defined prior to f, then f is supplied as the cost function to the pymanopt solver. Optimization is done with respect to the arguments of f and these arrays are returned by pymanopt with values that minimize the cost function.
Ideally, I would like to be able to do this definition more dynamically. So instead of defining a function in terms of hard coded arrays, to be able to supply a list of variables to be optimized. So if my cost function was instead:
#pymanopt.function.Autograd
def f(L):
return ((X - np.linalg.multi_dot(L)**2).sum()
Where the arrays A,B,...,C would be stored in a list, L. However, as far as I can tell, the variables to be optimized have to be directly defined as individual arrays in the cost function supplied to the solver.
The only thing I can think of doing is to define the cost function by creating a string that contains the 'hard coded' function and executing it via exec() with something like this:
args = ','.join(['A{}'.format(i) for i in range(len(L))])
exec('#pymanopt.function.Autograd\ndef({}):\n\treturn ((X-np.linalg.multi_dot({}))**2).sum()'.format(args,args))
but I understand that using this method should be avoided if possible. Any advice for navigating this sort of problem is greatly appreciated - thanks! Please let me know if anything is unclear/doesn't make sense.

Can I pass additional arguments into a scipy bvp function or boundary conditions? / SciPy questions from MATLAB

I'm working on converting a code that solves a BVP (Boundary Value Problem) from MATLAB to Python (SciPy). However, I'm having a little bit of trouble. I wanted to pass a few arguments into the function and the boundary conditions; so in MATLAB, it's something like:
solution = bvp4c(#(x,y)fun(x,y,args),#(ya,yb)boundarycond(ya,yb,arg1,args),solinit);
Where arg1 is a value, and args is a structure or a class instance. So I've been trying to do this on scipy, and the closest I get to is something like:
solBVP = solve_bvp(func(x,y,args), boundC(x,y,arg1,args), x, y)
But then it errors out saying that y is not defined (which it isn't, because it's the vector of first order DEs).
Has anyone tried to pass additional arguments into solve_bvp? If so, how did you manage to do it? I have a workaround right now essentially putting args and arg1 as global variables, but that seems incredibly sketchy if I want to make this code somewhat modular.
Thank you!

scipy curve_fitting uses xdata array wrong

When I try call curve_data
Like so:
curve_fit(func, xdata=np.arange(50), ydata=some_array)
It calls func using all xdata at once ( the whole array) instead of e.g. the first element of the xadata (xdata[0])
What is happening.
Cheers.
For people who happen to come across this: Scipy uses broadcasting, meaning if you use a math function in the function your are trying to fit, it also has to work with broadcasting, which basically means it internally loops over input vectors using c which is more efficient than looping in python. https://numpy.org/doc/stable/user/basics.broadcasting.html
For me the problem was, that I used the math library which does not support this.

Arbitrary functions

I'm trying to teach myself programming and am currently working my way through 'A Primer on Scientific Programming with Python' by Hans Petter Langtangen.
Right now I'm on Exercise 3.20. Unfortunately I don't have any solutions to the problems..
I know I can use an arbitrary (mathematical) function f in the definition of a method:
def diff(f,x,h=0.001):
return (f(x+h)-f(x-h))/2*h
And when I call it i can use whatever function I wish:
print diff(math.exp,0)
print diff(math.cos,2*math.pi)
So here's my question:
Is There a way to accomodate more complex functions in this way?
Say for example I would like to approximate the derivative of a function like
x(t) = e^(-(t-4)^2)
like I did above for cos(x) and e^(x).
Edit: maybe I should be more clear. I'm not specifically trying to differentiate this one function e^(-(t-4)^2) but would like to define a method that takes ANY function of x as an argument and approximates a derivative at point x.
I was impressed when I learned that you could do it for simple functions like cos(x), sin(x) and exp(x) at all. So I thought if that works there must be a way to make it more general..
Sure, just define it first:
def x(t):
return math.exp(-(t-4)**2)
print diff(x, 0)
Instead of using def, it's often possible to use lambda if the function consists of a single expression that is returned:
print diff(lambda t: math.exp(-(t-4)**2), 0)
sure:
def x(t):
return diff(math.exp(-(t-4)**2))

Categories