Correctly unwrapping arctangent function in Numpy - python

I'm trying to figure out a better way to unwrap the output of numpy's arctan function. Lets say I have:
import numpy as np
pi = np.pi
angles = np.deg2rad(range(0,5*360))
tangent = np.tan(angles)
arctangent = np.arctan(tangent)
Now I have the angles returned by they are only from -pi/2 to pi/2, but I want them back unwrapped (from 0 to 10 pi). Using the numpy function np.unwrap does not work for this and I'm not sure why, so I've been using my own function:
def arctan_unwrap(phase_data):
phase = [2 *(x + pi/2) for x in phase_data]
phase = np.unwrap(phase)
phase = [(x/2.0 - np.pi/2) for x in phase]
return phase
Which does return the original angles. I'm trying to figure out a way to clean this up or have np.unwrap do this on its own but can't figure it out. Does anyone know how to do this?

Since np.tan and np.arctan both return an array, even if the input is a list, your unwrap can be written as:
np.unwrap(2*(x+np.pi/2))/2-np.pi/2
For the test values
np.unwrap(2*x)/2
works. But presumably you know what you are doing in adding the pi/2.
np.unwrap is pure numpy Python, so you can easily study its method.

Related

Is there a method for finding the root of a function represented as an narray?

I have a function represented as a narray i. e. y = f(x), where y and x are two narrays.
I am searching for a method that find the roots of f(x).
Reading the scipy documentation, I was able to find just methods that works on user defined functions, like scipy.optimize.root_scalar. I thought about using scipy.interpolate.interp1d to get an interpolated version of my function to be used in scipy.optimize.root_scalar, but I'm not sure it can work and it seems pretty complicated.
Is it there some other function that I can use instead?
You have to interpolate a function defined by numpy arrays as all the solvers require a function that can return a value for any input x, not just those in your array. But this is not complicated, here is an example
from scipy import optimize
from scipy import interpolate
# our xs and ys
xs = np.array([0,2,5])
ys = np.array([-3,-1,2])
# interpolated function
f = interpolate.interp1d(xs, ys)
sol = optimize.root_scalar(f, bracket = [xs[0],xs[-1]])
print(f'root is {sol.root}')
# check
f0 = f(sol.root)
print(f'value of function at the root: f({sol.root})={f0}')
output:
root is 3.0
value of function at the root: f(3.0)=0.0
You may also want to interpolate with higher-degree polynomials for higher accuracy of your root-finding, eg How to perform cubic spline interpolation in python?

Trying to find a minimum of g(x) function and the x value at this minimum

I am trying to find a minimum of a created function g(alpha) and what is more important, to find value of the alpha at this minimum, or close to the minimum.
The code I use is the following: it creates function f, vectors D,avec and grad and uses it for creation of function g(alpha), minimum of which I want to find, together with the alpha value.
The problem is that after applying solve from sympy library I don't get numerical number of alpha. Instead of I get the following error:
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'
The code:
import numpy as np
from scipy.optimize import fmin
from sympy import Symbol, solve
from scipy import interpolate
Emax = 10
bins = 200
x = np.linspace(1, Emax, num = Emax, dtype=np.int) #create grid of indexes
y = np.linspace(1, bins, num = bins, dtype=np.int)
z = np.random.rand(bins, Emax) # random matrix
f = interpolate.interp2d(x,y,z, kind='cubic') # make the matrix continious
D= np.zeros(bins)
D = 2*f(1.5, y) # create vector
avec = np.array([4.0, 16.0])
grad = np.array([1e-5,1e-5])
g= lambda alpha: np.sum(np.square(np.subtract(D, (avec[0]-alpha*grad[0])*f((avec[1]-
alpha*grad[1]),y))))
oo= fmin(g,(0.0))
alfa = Symbol("alfa")
slv= solve((np.sum(np.square(np.subtract(D, (avec[0]-alfa*grad[0])*f((avec[1]-
alfa*grad[1]),y)))) - oo), alfa)
I know that this solution may not be the best for this problem. I'm new in Python and if you have any better suggestions how to find alpha here, please tell me.
I think you are really confusing what sympy does. sympy is a module to solve and print analytical equations. You do not need to use that package at all for this task.
You actually do find the minimum of g here. You store this result in oo.
So basically, delete the last 2 lines starting alfa = ... and slv = ... and then just put print(oo). oo is the value you are looking for, the value of alpha which minimises the function g

Manually integrating to get inverse Laplace transform

I wanted to compute the inverse Laplace transform manually without resorting to any library. Specifically, I wanted to compute a bilateral laplace inverse transform. I wanted to check my understanding and tried the following manually, but not able to match the answer. Where am I going wrong?
I want to compute laplace transform of 1/(s-a). I know the answer is eat. My attempt:
a = 2
t = 0.5
f = lambda s: 1/(s-a)
def g(u):
gammah=1
s = complex(real=gammah,imag=u)
return (f(s)).real*np.cos(s.imag*t) * 2*np.exp(s.real*t)/pi
import spicy as sp
import numpy as np
sp.integrate(g,0,np.inf,limit=10000)
gives me -0.9999999
but I know the answer is exp = 2.71...
The main error is mathematical. As Wikipedia says,
integration is done along the vertical line Re(s) = γ in the complex plane such that γ is greater than the real part of all singularities of F(s)
The function F(s) = 1/(s-a) has a singularity at a, which is 2 in your example. So γ needs to be greater than 2. For example, with γ=3 the output of quad is
(2.718278877362764, 2.911191228083254e-06)
as expected. By the, your import spicy etc can't possibly work, correct import syntax would be
from scipy.integrate import quad
# ....
quad(g, 0, np.inf, limit=10000)

How to get X- oder Y-Coordinate from Scipy mathematical function

When I create a simple mathematical function like..
f(X) = 2*X
using scipy.interpolate - how can I get the X-coordinate of a corresponding Y-coordinate?
Here is the scipy-function:
from scipy import interpolate
testfunc = scipy.interpolate.interp1d([1,2], [2,4], kind='linear')
I want to get the X-value belonging to Y = 4 (should be 2).
I tried:
testfunc.x(4)
Would it work to just do reverse interpolation?
x,y = ...
testfunc_inverse = scipy.interpolate.interp1d(y, x, kind='linear')
testfunc_inverse(4)
I may be missing the point here, however, if you follow the scipy.interpolate.interp1d example you will end up with two numpy arrays of equal length. Seems like you should be able to index the y array against the x array and get your answer. I don't know if you would consider this approach 'pythonic' but it works in this case.

Fourier Series from Discrete Fourier Transform

I'm trying to recreate a function from a discrete fourier transform. In Matlab it would be done like this:
function [y] = Fourier(dft,x)
n = length(dft);
y = cos(pi*(x+1)'*(0:n-1))*real(dft)+sin(pi*(x+1)'*(0:n-1))*imag(dft)
end
My attempt in Python is falling flat because I don't know how to add up all the coefficients correctly
def reconstruct(dft, x):
n = len(dft)
y = ([(coeff.real)*np.cos(np.pi*x*nn) + (coeff.imag)*np.cos(np.pi*x*nn) for coeff in dft for nn in range(0,n)])
But this isn't correct because I need to sum over n and add those sums together. Where am I off?
The equation I am trying to recreate is below:
You were running two nested loops instead of one. Try this:
y = ([(dft[nn].real)*np.cos(np.pi*x*nn) + (dft[nn].imag)*np.cos(np.pi*x*nn) for nn in range(0,n)])
You actually should not use a Python loop at all. You get more readable and much more efficient code if you vectorise the expression. Assuming dft is a complex-valued NumPy array, you could use
xn = x * np.arange(n)
y = dft.real * np.cos(xn) + dft.imag * np.sin(xn)
(Note that your Matlab code, your Python code and the formula you gave do three different things. The code I gave is closest to the Matlab code.)

Categories