I have an array and an equation.
I want to plug in all array values into the equation and save it.
What I've tried until now:
import math
import numpy as np
Z_F0=376.73
Epsilon=3.66
wl_range = [np.arange(0.1, 50, 0.1)]
wl_array = np.array(wl_range)
multiplied_array = 6+(2*math.pi*6)*math.exp(-1*(30.666/wl_array)**0.7528)
print(multiplied_array)
Or I've tried multiplied_array = np.vectorize(6+(2*math.pi*6)...)
But I get the
only size-1 arrays can be converted to Python scalars
error.
You don't need math, numpy has pi and exp. pi would have worked with math, as it is just a constant. But the content of your exponential is a vector, so you need to use numpy for that.
There are situations where math is faster (when you don't vectorize), as numpy has higher overhead checking for the dimensions of your input.
import numpy as np
Z_F0=376.73
Epsilon=3.66
wl_range = [np.arange(0.1, 50, 0.1)]
wl_array = np.array(wl_range)
multiplied_array = 6+(2*np.pi*6)*np.exp(-1*(30.666/wl_array)**0.7528)
print(multiplied_array)
output:
[ 6. 6. 6. 6. 6.00000001 6.00000015
6.00000127 6.00000656 6.00002459 6.00007283 6.00018111 6.00039369
6.0007699 6.00138329 6.00231952 6.00367362 6.00554684 6.00804354
6.01126831 6.01532348 6.020307 6.02631085 6.03341981 6.04171066
6.0512517 6.06210249 6.07431393 6.08792837 6.10297998 6.11949516
6.13749297 6.15698571 6.17797939 6.20047433 6.22446568 6.24994393
6.27689541 6.30530278 6.33514546 6.36640006 6.39904075 6.43303963
6.46836702 6.50499181 6.54288169 6.58200341 6.62232297 6.66380586
6.70641722 6.75012196 6.79488494 6.84067111 6.88744554 6.93517359
6.98382097 7.03335377 7.08373859 7.13494255 7.18693331 7.23967918
7.29314908 7.34731259 7.40213999 7.45760222 7.51367097 7.5703186 ...
math.exp() only works with a scalar argument x. If you use numpy.exp() then the equation should work.
Related
I am trying to write a code that calculates an integral from zero to pi. But it gives an error which I do not understand how to fix. Thank you for your time.
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,300.1,0.1)
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
As is pointed out in the top comment:
Energy.shape == (2980,), but x.shape == (1000,)
so reduce the number of elements in Energy or increase np.cos(x).
Since energy is just a numpy arrage i reduced it to size=1000.
In order to fix this they need to be the same size, so this ,for example, works:
import numpy as np
from math import pi,cos
vtheta=np.linspace(0.0,pi,1000)
def my_function(x):
Energy = np.arange(2.1,102.1,0.1) #<-- changed 300.1 to 102.1
return ((1.0)/(Energy-1+np.cos(x)))
print (my_function(vtheta).sum())
This is the result (with the above):
39.39900748229355
Lets say I have the following function:
def f(x):
return log(3*exp(3*x) + 7*exp(7*x))
I want to do two things:
1) plot the function over a range of x-values
2) find the root of the function using the Newton method from scipy
My problem is that it seems that plotting is best done with a numpy array x=np.linspace(-2,2,1000), but then evaluating the function results in erros TypeError: only size-1 arrays can be converted to Python scalars. I can fix this by simply changing log and exp to np.log and np.exp, respectively.
But doing so then makes scipy.optimize.newton unhappy.
It seems like I need to define the function twice, once for use in plotting (with np. ...) and once for optimizing in the form given above.
I can't imagine that this is actually the case. Any hints would be greatly appreciated.
Seems legit, you just need to use numpy functions instead of base math functions:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
%matplotlib inline
def f(x):
return np.log(3*np.exp(3*x) + 7*np.exp(7*x))
x = np.linspace(-2,2,1000)
y = f(x)
plt.scatter(x, y)
optimize.root(f, 1)
I use pyculib to perform 3D FFT on a matrix in Anaconda 3.5. I just followed the example code posted in the website. But I found something interesting and don't understand why.
Performing a 3D FFT on matrix with pyculib is correct only when using numpy.arange to create the matrix.
Here is the code:
from pyculib.fft.binding import Plan, CUFFT_C2C
import numpy as np
from numba import cuda
data = np.random.rand(26, 256, 256).astype(np.complex64)
orig = data.copy()
d_data = cuda.to_device(data)
fftplan = Plan.three(CUFFT_C2C, *data.shape)
fftplan.forward(d_data, d_data)
fftplan.inverse(d_data, d_data)
d_data.copy_to_host(data)
result = data / n
np.allclose(orig, result.real)
Finally, it turns out to be False. And the difference between orig and result is not a small number, not negligible.
I tried some other data sets (not random numbers), and get the some wrong results.
Also, I test without inverse FFT:
from pyculib.fft.binding import Plan, CUFFT_C2C
import numpy as np
from numba import cuda
from scipy.fftpack import fftn,ifftn
data = np.random.rand(26,256,256).astype(np.complex64)
orig = data.copy()
orig_fft = fftn(orig)
d_data = cuda.to_device(data)
fftplan = Plan.three(CUFFT_C2C, *data.shape)
fftplan.forward(d_data, d_data)
d_data.copy_to_host(data)
np.allclose(orig_fft, data)
The result is also wrong.
The test code on website, they use numpy.arange to create the matrix. And I tried:
n = 26*256*256
data = np.arange(n, dtype=np.complex64).reshape(26,256,256)
And the FFT result of this matrix is right.
Could anyone help to point out why?
I don't use CUDA, but I think your problem is numerical in nature. The difference lies in the two data sets you are using. random.rand has dynamic range of 0-1, and arange 0-26*256*256. The FFT attempts to resolve spatial frequency components on the order of range of values / number of points. For arange, this becomes unity, and the FFT is numerically accurate. For rand, this is 1/26*256*256 ~ 5.8e-7.
Just running FFT/IFFT on your numpy arrays without using CUDA shows similar differences.
I'm trying to solve a long equation using sympy solve. This is a simplified version of the equation but the issue is the same.
This code works fine:
import numpy as np
import sympy as sy
coupons = [0.504452818664, 0.486892427806, 0.47758800215, 100.468050176]
rate = sy.Symbol('rate')
rate_final = (sy.solve(100 - (rate*coupons[0]+rate*coupons[1]+rate*coupons[2]+rate*coupons[3]),rate))
print rate_final
rate-final is [0.980998226948197].
But when Ι try to use numpy.dot inside the equation, it gives an empty list as a result.
import numpy as np
import sympy as sy
coupons = [0.504452818664, 0.486892427806, 0.47758800215, 100.468050176]
rate = sy.Symbol('rate')
rate_final = (sy.solve(100 - np.dot(rate,coupons[:]),rate))
print rate_final
rate_final is [].
Is there something wrong with my code or sympy.solve won't work if np.dot() is inside the equation?
A dot product of scalar rate and vector coupons hardly makes sense. You only get an element-wise multiplication of rate and each element. However, you can do this:
import numpy as np
import sympy as sy
coupons = np.array([0.504452818664, 0.486892427806, 0.47758800215, 100.468050176])
rate = sy.Symbol('rate')
rate_final = sy.solve(100 - np.sum(rate * coupons), rate)
print(rate_final)
Is there a built-in Numpy function to convert a complex number in polar form, a magnitude and an angle (degrees) to one in real and imaginary components?
Clearly I could write my own but it seems like the type of thing for which there is an optimised version included in some module?
More specifically, I have an array of magnitudes and an array of angles:
>>> a
array([1, 1, 1, 1, 1])
>>> b
array([120, 121, 120, 120, 121])
And what I would like is:
>>> c
[(-0.5+0.8660254038j),(-0.515038074+0.8571673007j),(-0.5+0.8660254038j),(-0.5+0.8660254038j),(-0.515038074+0.8571673007j)]
There isn't a function to do exactly what you want, but there is angle, which does the hardest part. So, for example, one could define two functions:
def P2R(radii, angles):
return radii * exp(1j*angles)
def R2P(x):
return abs(x), angle(x)
These functions are using radians for input and output, and for degrees, one would need to do the conversion to radians in both functions.
In the numpy reference there's a section on handling complex numbers, and this is where the function you're looking for would be listed (so since they're not there, I don't think they exist within numpy).
There's an error in the previous answer that uses numpy.vectorize - cmath.rect is not a module that can be imported. Numpy also provides the deg2rad function that provides a cleaner piece of code for the angle conversion. Another version of that code could be:
import numpy as np
from cmath import rect
nprect = np.vectorize(rect)
c = nprect(a, np.deg2rad(b))
The code uses numpy's vectorize function to return a numpy style version of the standard library's cmath.rect function that can be applied element wise across numpy arrays.
I used cmath with itertools:
from cmath import rect,pi
from itertools import imap
b = b*pi/180 # convert from deg to rad
c = [x for x in imap(rect,a,b)]
import numpy as np
import cmath.rect
nprect = np.vectorize(rect)
c = nprect(a,b*np.pi/180)
tom10 answer works fine... you can also expand the Euler's formula to:
def P2R(A, phi):
return A * ( np.cos(phi) + np.sin(phi)*1j )