A MATLAB code contains the use of the function sgolay as:
[b,g] = sgolay(k, f)
Using this, I need to find the smoothness, first derivative, and second derivative. for finding the above, I need the value of g.
These have to be performed in Python instead of MATLAB.
Python's savgol_filter(arr, k, f) works the same as MATLAB's sgolay(arr, k, f), however, there is no alternative to sgolay(k, f) which designs the filter and returns g.
What would be a Python equivalent to the sgolay() function?
I understand your problem now. (You had a typo, you meant sgolayfilt(arr, k, f) instead of sgolay(arr, k, f).)
So,
MATLAB's sgolayfilt is related to python's savgol_filter
MATLAB's sgolay is related to python's savgol_coeffs
Note that, in python's function, the order of the parameters is:
smoothingfilter = savgol_coeffs(window_length, polyorder)
while in MATLAB is the other way around:
[smoothingfilter,g] = sgolay(ORDER,FRAMELEN)
If you now want the differentiation filters, which in matlab are in g you will need to pass that optional parameter to the python function:
smoothingfilter_deriv = savgol_coeffs(window_length, polyorder, deriv)
which will be derived deriv times. In your particular case, you want:
smoothingfilter1 = savgol_coeffs(window_length, polyorder, 1)
smoothingfilter2 = savgol_coeffs(window_length, polyorder, 2)
that are the python's equivalent to:
g(:,1) (for smoothingfilter1)
and
g(:,2) (for smoothingfilter2)
where g was obtained doing:
[b,g] = sgolay(polyorder,window_length)
Related
I need to write this code
sorted(labeled_points,key=lambda (point, _): distance(point,new_point))
where distance is just Euclidean distance between vectors.
The error message I receive is that it isn't possible in Python 3 - Sublist parameters are not supported in Python 3.x .
I tried to replace it with this code
sorted(labeled_points,key=lambda point: distance(point,new_point))
but it seems this isn't working.
I also looked at examples and found that we can make do without lambda, we need to define function
def func(point,new_point):
return distance(point,new_point)
...
sorted(labeled_points,key=func(new_point))
But this does not seem to be evaluated.
So,, how one could write this in Python 3?
Instead of
sorted(labeled_points, key=lambda (point, _): distance(point, new_point))
do
sorted(labeled_points, key=lambda labeled_point: distance(labeled_point[0], new_point))
See the end of PEP 3113's Transition Plan for a similar example (that's the PEP that removed this Python 2 syntax in Python 3).
You have a distance function to get the distance between two arbitrary points. You want to sort based on the distance from a fixed point - one of the parameters will always be the same. You can use functools.partial to create a new function that sets static parameters and use that to generate the sort key.
import math
import functools
def distance(v,w):
return math.sqrt(sum(((v_i-w_i)*(v_i-w_i) for v_i in v for w_i in w)))
fixed_point = (9,9)
points = [(3,4), (20,6), (1,1), (9,9)]
print(list(sorted(points, key=functools.partial(distance, fixed_point))))
I am writing a script to calculate the definite integral of an equation. I'm writing a helper function that would take in coefficients as parameters and return a function of x.
def eqn(x, k, c, a):
return ((k*x + c**(1-a))
Next, I define a function that calculates the definite integral, using quad imported from scipy:
from scipy.integrate import quad
def integral(eqn, c_i, y_i):
integral_i, integral_err = quad(eqn, c_i, y_i)
print integral_i
Then I call the function by passing in parameters
k = calc_k(7511675,1282474,0,38,2)
eqn = carbon_path_eqn(x, k, 7511675, 2)
carbon_path_def_int(eqn,0,38)
However, I get an error saying that 'name x is not defined'. I understand that x isn't defined globally, but I'm wondering how I can write a helper function, that takes in parameters, and still returns a function of x that can be used in quad?
Thank you!
PS -
#bpachev, this is a follow up from the other post
The mistake here is that the function 'eqn' does not return a function, it returns the value of a function at some point x, given parameters k,c,a.
quad should be passed a function (in your case, eqn) where the first argument (in your case, x) is assumed to be the variable over which the function is integrated. You also need to pass quad a tuple of the remaining parameters (in your case (k,c,a)) and two limits (in your case, c_i,y_i). In other words, call quad like this:
quad(eqn,c_i,y_i,args=(k,c,a))
This is all explained in the scipy documentation http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.quad.html.
This is not what you asked. However, as someone else has mentioned, sympy would probably make your life much easier. For instance, suppose you need to be able to evaluate integrals of functions of x such as f in the code below, where a and b are arbitrary constants. Here's how you can use sympy to do that.
Define the function, integrate it with respect to x and save the result, then evaluate the result for values of a, b and x.
I want to integrate a function using python, where the output is a new function rather than a numerical value. For example, I have the equation (from Arnett 1982 -- analytical description of a supernova):
def A(z,tm,tni):
y=tm/(2*tni)
tm=8.8 # diffusion parameter
tni=8.77 # efolding time of Ni56
return 2*z*np.exp((-2*z*y)+(z**2))
I want to then find the integral of A, and then plot the results. First, I naively tried scipy.quad:
def Arnett(t,z,tm,tni,tco,Mni,Eni,Eco):
x=t/tm
Eni=3.90e+10 # Heating from Ni56 decay
Eco=6.78e+09 # Heating from Co56 decay
tni=8.77 # efolding time of Ni56
tco=111.3 # efolding time of Co56
tm=8.8 # diffusion parameter
f=integrate.quad(A(z,tm,tni),0,x) #integral of A
h=integrate.quad(B(z,tm,tni,tco),0,x) #integral of B
g=np.exp((-(x/tm)**2))
return Mni*g*((Eni-Eco)*f+Eco*h)
Where B is also a pre-defined function (not presented here). Both A and B are functions of z, however the final equation is a function of time, t. (I believe that it is herein I am causing my code to fail.)
The integrals of A and B run from zero to x, where x is a function of time t. Attempting to run the code as it stands gives me an error: "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()".
So after a short search I thought that maybe sympy would be the way to go. However I am failing with this as well.
I wonder if anyone has a helpful suggestion how to complete this task please?
Many thanks,
Zach
You can integrate A analytically. Assuming I'm not missing something silly due to being up way too late, does the following help?
import sympy as sy
sys.displayhook = sy.pprint
A, y, z, tm, t, tni = sy.symbols('A, y, z, tm, t, tni')
A = 2*z*sy.exp(-2*z*y + z**2)
expr = sy.integrate(A, (z,0,t)) # patience - this takes a while
expr
# check:
(sy.diff(expr,t).simplify() - A.replace(z,t)).simplify()
# thus, the result:
expr.replace(y,tm/(2*tni)).replace(t,t/tm)
The last line yields the integral of your A function in analytic form, though it does require evaluating the imaginary error function (which you can do with scipy.special.erfi()).
I think what you are looking for are lambda expression (if i understood correctly what you said.. see here for extra information and some examples on lambda functions).
What they allow you to do is define an anonymous function in A and return it so that you get your B function, should work something like this:
def A(parameters):
return lambda x: x * parameters # for simplicity i applied a multiplication
# but you can apply anything you want to x
B = A(args)
x = B(2)
Hope I could provide you with a decent response!
I think the error you get comes from an incorrect call to scipy.integrate.quad:
The first argument needs to be just the function name, integration is then performed over the first variable of this function. The values of the other variables can be passed to the function via the args keyword.
The output of scipy.integrate.quad contains not only the value of the integral, but also an error estimate. So a tuple of 2 values is returned!
In the end the following function should work:
def Arnett(t, z, Mni, tm=8.8, tni=8.77, tco=111.3, Eni=3.90e+10,
Eco=6.78e+09):
x=t/tm
f,err=integrate.quad(A,0,x,args=(tm,tni)) #integral of A
h,err=integrate.quad(B,0,x,args=(tm,tni,tco)) #integral of B
g=np.exp((-(x/tm)**2))
return Mni*g*((Eni-Eco)*f+Eco*h)
But an even better solution would probably be integrating A and B analytically and then evaluating the expression as murison suggested.
I am trying to convert a Matlab code to Python. I want to implement fdesign.lowpass() of Matlab in Python. What will be the exact substitute of this Matlab code using scipy.signal.firwin():
demod_1_a = mod_noisy * 2.*cos(2*pi*Fc*t+phi);
d = fdesign.lowpass('N,Fc', 10, 40, 1600);
Hd = design(d);
y = filter(Hd, demod_1_a);
A very basic approach would be to invoke
# spell out the args that were passed to the Matlab function
N = 10
Fc = 40
Fs = 1600
# provide them to firwin
h = scipy.signal.firwin(numtaps=N, cutoff=40, nyq=Fs/2)
# 'x' is the time-series data you are filtering
y = scipy.signal.lfilter(h, 1.0, x)
This should yield a filter similar to the one that ends up being made in the Matlab code.
If your goal is to obtain functionally equivalent results, this should provide a useful
filter.
However, if your goal is that the python code provide exactly the same results,
then you'll have to look under the hood of the design call (in Matlab); From my quick check, it's not trivial to parse through the Matlab calls to identify exactly what it is doing, i.e. what design method is used and so on, and how to map that into corresponding scipy calls. If you really want compatibility, and you only need to do this for a limited number
of filters, you could, by hand, look at the Hd.Numerator field -- this array of numbers directly corresponds to the h variable in the python code above. So if you copy those
numbers into an array by hand, you'll get numerically equivalent results.
Apologies for the simplicity of this question.
I would like to implement an equation in Python. In this equation, K_0 is the zeroth-order modifed Bessel function.
What is the best way of implementing K_0 in Python?
No need to implement it; it's included. See the docs for the scipy.special module, in particular the optimized common ones here:
>>> import scipy.special
>>> print scipy.special.k0.__doc__
k0(x[, out])
y=k0(x) returns the modified Bessel function of the second kind (sometimes called the third kind) of
order 0 at x.
>>> scipy.special.k0(1)
0.42102443824070823
or more generally:
>>> print scipy.special.kn.__doc__
kn(x1, x2[, out])
y=kn(n,x) returns the modified Bessel function of the second kind (sometimes called the third kind) for
integer order n at x.
>>> scipy.special.kn(0, 1)
0.42102443824070834