Bound Scipy optimisation of a function returning 1D data - python

this is more of a question on what is an appropriate approach to my problem.
I have a function that takes some 1D vector as input and returns a 1D array (in actuality its a 2D array that is flattened). I am looking to do least squares optimisation of this function. I already have my bounds and constraints on x all sorted, and had thought about doing something like this
result = optimize.minimize(func,x0,method='SLSQP',bounds=my_bounds,constraints=dict_of_constraints,args=(my_args,))
however, this approach uses _minimize_slsqp which requires that the objective function return a scalar. Is there any such approach that would work similarly to the above, but work on an objective function that can return 1D (or 2D?) data?
Cheers

You need to form a scalar function (a function that returns a single scalar value). Likely something like
||F(x)||
where ||.|| is a norm. This new scalar function can be passed on to optimize.minimize.

Related

Vector to matrix function in NumPy without accessing elements of vector

I would like to create a NumPy function that computes the Jacobian of a function at a certain point - with the Jacobian hard coded into the function.
Say I have a vector containing two arbitrary scalars X = np.array([[x],[y]]), and a function f(X) = np.array([[2xy],[3xy]]).
This function has Jacobian J = np.array([[2y, 2x],[3y, 3x]])
How can I write a function that takes in the array X and returns the Jacobian? Of course, I could do this using array indices (e.g. x = X[0,0]), but am wondering if there is a way to do this directly without accessing the individual elements of X.
I am looking for something that works like this:
def foo(x,y):
return np.array([[2*y, 2*x],[3*y, 3*x]])
X = np.array([[3],[7]])
J = foo(X)
Given that this is possible on 1-dimensional arrays, e.g. the following works:
def foo(x):
return np.array([x,x,x])
X = np.array([1,2,3,4])
J = foo(X)
You want the jacobian, which is the differential of the function. Is that correct? I'm afraid numpy is not the right tool for that.
Numpy works with fixed numbers not with variables. That is given some number you can calculate the value of a function. The differential is a different function, that has a special relationship to the original function but is not the same. You cannot just calculate the differential but must deduce it from the functional form of the original function using differentiating rules. Numpy cannot do that.
As far as I know you have three options:
use a numeric library to calculate the differential at a specific point. However you only will get the jacobian at a specific point (x,y) and no formula for it.
take a look at a pythen CAS library like e.g. sympy. There you can define expressions in terms of variables and compute the differential with respect to that variables.
Use a library that perform automatic differentiation. Maschine learning toolkits like pytorch or tensorflow have excellent support for automatic differentiation and good integration of numpy arrays. They essentially calculate the differential, by knowing the differential for all basic operation like multiplication or addition. For composed functions, the chain rule is applied and the difderential can be calculated for arbitray complex functions.

Implementing MATLAB's filter function in Swift or Python

I am trying to the equivalent of MATLAB's filter function in Swift code. MATLAB's filter function is defined as follows:
filter(b,a,x)
y = filter(b,a,x) filters the input data x using a rational transfer function defined by the numerator and denominator coefficients b and a.
If a(1) is not equal to 1, then filter normalizes the filter coefficients by a(1). Therefore, a(1) must be nonzero.
If x is a vector, then filter returns the filtered data as a vector of the same size as x.
If x is a matrix, then filter acts along the first dimension and returns the filtered data for each column.
If x is a multidimensional array, then filter acts along the first array dimension whose size does not equal 1.
I realize that Python has the numpy module and associated functions to help implement this function. However, I am not aware of a similar toolset within the context of Swift. I really would like to avoid the logic of implementing a rational-transfer function, so I was wondering if there was an existing Swift module or reference for this. I could also translate a bare-bones implementation written in Python into Swift.
Does filter exist in Swift?
In python you have a similar function scipy.signal.lfilter.

Why do np.random.randn and np.zeros take different kinds of argument?

Initializing an array with random numbers can be achieved like this:
arr_1 = np.random.randn(3,5)
Initializing with all entries equal to 0 is done like so:
arr_2 = np.zeros((3,5))
To specify the desired shape, np.random.randn takes integers as arguments, whereas np.zeros expects a tuple of integers (which is then equal to the shape of the returned array). When working with these functions, I often confuse one with the other.
Why do these functions take different kinds of arguments for specifying the shape?
First, I thought that functions from np.random (like randn) do this way and functions directly from np (like zeros or ones) do that way. This seems however not to be the case: np.random.randint takes, among other parameters, the shape as a tuple, unlike np.random.randn.
This is explained in the documentation:
This is a convenience function for users porting code from Matlab, and wraps standard_normal. That function takes a tuple to specify the size of the output, which is consistent with other NumPy functions like numpy.zeros and numpy.ones.

"Direct" numpy functions on an array vs numpy array functions

I have a question about the design of Python. I have realised that some functions are implemented directly on container classes (e.g. numpy arrays) while other function that act on these containers must be called from numpy itself. An example would be:
import numpy as np
y = np.array([4,7,9,1])
m1 = np.mean(y) # Ok
m2 = y.mean() # Ok
print(m1 == m2) # True
x = [2,3]
r1 = np.concatenate([x, y]) # Ok
r2 = y.concatenate(x) # AttributeError: 'numpy.ndarray' object has no attribute 'concatenate'
print(r1 == r2)
Why can the mean be calculated directly from the array while the array as no method to concatenate another one to it? Is there a general rule which functions can be called directly on the array and which ones not? And if both is possible what is the pythonic way to do it?
The overview of NumPy history gives an indication of why not everything is consistent: it has two predecessors that were developed independently. Backward compatibility requires the project to keep array methods like max. Ongoing development favors the function syntax np.fun(array). I suppose one reason for the latter is that it allows array_like input (the term used throughout NumPy documentation): anything that NumPy can turn into an ndarray.
The question of why there are both methods and functions of the same name has been discussed and links provided.
But to focus on your two examples:
mean uses just one array. Logically it can be an ndarray method.
concatenate takes a list of arrays, and doesn't give priority to any one of them.
There is a np.append function that looks superficially like the list .append method. But it just passes the task on to concatenate with just a few modifications. And it causes all kinds of newby errors - it isn't inplace, it ravels, and it is slow compared to the list method.
Or consider the large family of ufunc. Those are functions, some take one array, others two. They share a common ufunc functionality.
np.add(a,b) <=> a+b <=> a.__add__(b)
np.sin(a) # no a.sin()
I suspect the choice to make sin a ufunc rather than a method has been influenced by common mathematical notation.
To me a big plus to the function approach is that it can be applied to a list or scalar. np.sin(1) works just as well as np.sin([0,.5,1]) or np.sin(np.arange(0,1,.5)).
Yes, history goes a long way toward excusing the mix of functions of methods, but many of the choices are logical.

How to cache the function that is returned by scipy interpolation

Trying to speed up a potential flow aerodynamic solver. Instead of calculating velocity at an arbitrary point using a relatively expensive formula I tried to precalculate a velocity field so that I could interpolate the values and (hopefully) speed up the code. Result was a slow-down due (I think) to the scipy.interpolate.RegularGridInterpolator method running on every call. How can I cache the function that is the result of this call? Everything I tried gets me hashing errors.
I have a method that implements the interpolator and a second 'factory' method to reduce the argument list so that it can be used in an ODE solver.
x_panels and y_panels are 1D arrays/tuples, vels is a 2D array/tuple, x and y are floats.
def _vol_vel_factory(x_panels, y_panels, vels):
# Function factory method
def _vol_vel(x, y, t=0):
return _volume_velocity(x, y, x_panels, y_panels, vels)
return _vol_vel
def _volume_velocity(x, y, x_panels, y_panels, vels):
velfunc = sp_int.RegularGridInterpolator(
(x_panels, y_panels), vels
)
return velfunc(np.array([x, y])).reshape(2)
By passing tuples instead of arrays as inputs I was able to get a bit further but converting the method output to a tuple did not make a difference; I still got the hashing error.
In any case, caching the result of the _volume_velocity method is not really what I want to do, I really want to somehow cache the result of _vol_vel_factory, whose result is a function. I am not sure if this is even a valid concept.
scipy.interpolate.RegularGridInterpolator returns a numpy array. This is not cacheable because it doesn't implement hash.
You can store other representations of the numpy array and cache that and then convert it back to a numpy array though. For details on how to do that look at the following.
How to hash a large object (dataset) in Python?

Categories

Resources