I need to perform a definite integral in python (or, alternatively, in fortran), but instead of having a function I have an array of samples. I'm currently using the method given by scipy.integrate.trapz. However I'm wondering if there is an alternative method to perform such operation (for instance, the quadrature method would be a good one, but I'm afraid I can use functions but not arrays of samples). Any suggestion?
If you have only array of samples you can use numpy.trapz(y[,x]) instead of scipy.integrate.trapz
Related
I am working on a project related to gravitational lensing, for which I need to evaluate the confluent hypergeometric function 1F1(a,b,z) for an array z of length ~ 10^8 complex points, a = 1+0.48j and b = 1. I am looking for an efficient way to evaluate this on large array sizes. The scipy implementation is fast but does not accept complex arguments for a and b.
mpmath seems to be the best way to calculate 1F1 for complex parameters but mpmath.hyp1f1 does not accept array values. The best workaround I found for this was to use np.vectorize or np.frompyfunc to allow passing a NumPy array as a parameter. However, this is extremely slow and would take days to execute (even with gmpy2 installed). I assume this is because mpmath functions are always slow on large array sizes.
a nonpython implementation would be fine as well, as long as I can somehow save the result on disk and read it into my python code. I have seen some implementations (for example https://www.math.ucla.edu/~mason/research/pearson_final.pdf) which could possibly work but I'm not sure.
Another possible way would be to interpolate the function
(consecutive points in my input array are extremely close) but I'm not sure what would be the best way to do that.
Thanks!
I was having a very similar problem than you have.
I figured out that the mpmath package has a "hidden" set of function with (only) float precision, which one can access by writing fp. upfront. This does not exist for hyp1f1 but for the more general hyper. Meaning there is a fp.hyper in the mpmath package which is with fp.hyper([a],[b],z) equivalent to hyper1f1(a,b,z), but is a lot faster.
If you vectorize this with np.vectorize this should make your calculation substansially faster.
Disclaimer: I got an error message saying that some complex value is converted to real by dropping the imaginary part when evaluating this, but so far the results i have gotten seem sensible and compatible to the hyper1f1(a,b,z) values.
Added: It seems that fp.hyper does not like getting numpy datatypes even if they are scalars, as in the case of a,b,z beeing numpy scalars (for example one element of an numpy array) it will simply return 1 without giving an error message independent of the actual input. If you use np.vectorize however everything should be fine.
Eitherway: Use at own risc.
I am currently using version 1.92 of numpy which I believe is the latest publicly available one. I wish to use the central difference method quickly on an n dimensional array and specify an axis over which to perform the calculation.
My first thought was to use numpy.diff which allows axis specification, however this returns a right difference rather than a central difference and has limited functionality.
I understand the following method works using numpy.gradient
num_vectors=10 #number of 3-vectors in the 2D array
vectorarray=numpy.empty((num_vectors,3))
vectorarray[0]=[4,5,6]
vectorarray[1]=[1,4,4]
vectorarray[2]=[8,8,1] #add some arbitrary data for illustrative purposes
c1,c2=numpy.gradient(vectorarray)
So c1 stores the useful information that I require. The problem is that I also have to generate c2, and I want to do this sort of calculation with many dimensional arrays and will incur a time loss by generating all this useless data.
Is there any other method I can achieve this same result without the redundancy, preferably this also includes using nested for loops.
You can read Numpy's gradient code at https://github.com/numpy/numpy/blob/master/numpy/lib/function_base.py#L1119 and use the algorithm therein.
You can also copy it and change for i, axis in enumerate(axes): to for i, axis in [[0,0]]: so that it only runs once, but keep in mind that your modified code may fall under Numpy's license.
Are there functions in python that will fill out missing values in a matrix for you, by using collaborative filtering (ex. alternating minimization algorithm, etc). Or does one need to implement such functions from scratch?
[EDIT]: Although this isn't a matrix-completion example, but just to illustrate a similar situation, I know there is an svd() function in Matlab that takes a matrix as input and automatically outputs the singular value decomposition (svd) of it. I'm looking for something like that in Python, hopefully a built-in function, but even a good library out there would be great.
Check out numpy's linalg library to find a python SVD implementation
There is a library fancyimpute. Also, sklearn NMF
I have a 3D array that I need to integrate numerically using Python. My array is a function of wavelength, depth and time. It is data that I have modelled numerically using another software package and don't have an analytical form of the function, just the 3d array output from the other package. I need to find the triple integral of this array. In Matlab I use trapz(my_array, 3) where 3 is the ndims to integrate over. The Scipy trapz only seems to work on a single integral.
I think I may have 2 options but I am I need some advice.
opt 1. use 3d interpolation in scipy that returns a function handle, do these exist? the 1d version returns a function, and then use scipy.integrate.tplquad to do the integration over the interpolated function where I use the max and in values in my array as the integration limits.
opt 2. use three nested trapz calls like this suggestion for 2d I found on another site. --> sp.trapz(sp.trapz(f, y[np.newaxis,:], axis=1), x, axis=0))
Can't quite get my head around to make either work. Any help/advice would be appreciated. I need to make sure that my integration error is as low as possible.
I will have to implement a convolution of two functions in Python, but SciPy/Numpy appear to have functions only for the convolution of two arrays.
Before I try to implement this by using the the regular integration expression of convolution, I would like to ask if someone knows of an already available module that performs these operations.
Failing that, which of the several kinds of integration that SciPy provides is the best suited for this?
Thanks!
You could try to implement the Discrete Convolution if you need it point by point.
Yes, SciPy/Numpy is mostly concerned about arrays.
If you can tolerate an approximate solution, and your functions only operate over a range of value (not infinite) you can fill an array with the values and convolve the arrays.
If you want something more "correct" calculus-wise you would probably need a powerful solver (mathmatica, maple...)