How to compose function range in Python - python

So I wish to create a log(y) vs log(x) of the following function in python. I am not sure how the range (w) should be composed to get a good graph. For now I have left it blank.
import numpy as np
import matplotlib.pyplot as plt
w =
y = 1/(1+2.56e-8*(w)^2)
plt.plot(log(w),log(y));
Okay so now I have to do one more plot but its a little bit more complicated.
w = np.arange(1e3, 1e7, 1e3)
z = 1/ (((5.89824e-15 (w ** 4))+(1-2.56e-8 (w ** 2))) ** 0.5)
b = plt.loglog(w, z);
This give me an error:
z = 1/ (((5.89824e-15 (w ** 4))+(1-2.56e-8 (w ** 2))) ** 0.5)
TypeError: 'float' object is not callable
Never mind I fixed it.

You can use the numpy.arange function to get a numpy version of range. A reasonable range for this function is:
w = np.arange(1e3, 1e7, 1e3)
(That is, going from 1000 to 10000000 in steps of 1000). However, note that in order to make Python know you're trying to use exponentiation rather than the bitwise xor operator, you should change your line to:
y = 1/(1+2.56e-8*(w ** 2))
Then, if you make a log-log plot, you end up with:
plt.loglog(w, y)

Related

Creating a plot of a SymPy expression with a a equation with multiple variables [duplicate]

This question already has answers here:
Using Sympy Equations for Plotting
(2 answers)
Closed 4 months ago.
I have figured out how to make a equation with SymPy, however, I am not sure how to plot the relationship between two values. I keep getting an TypeError: Cannot convert expression to float whenever I write plt.plot(Rho , T). I have a code like this so far:
import matplotlib as plt
from sympy import init_session
init_session()
rho, X, Y, Z, T_9, T, T_8, m, n, Gamma = symbols('rho X Y Z T_9 T T_8 m n Gamma')
q_pp = (2.4 * 10**(4) * rho * X**2 / T_9**(2/3)) * exp((-3.380/T_9**(1/3)))
q_CNO = (4.4 * 10**(25) * rho * X* Z/ T_9**(2/3)) * exp((-15.228/T_9**(1/3)))
q_min = q_pp + q_CNO
simplify(q_min)
T_9 = T / (10**9)
Rho = (10**3)*(T_9**(1/3) / (24000 * X * exp(15.228/T_9**(1/3)) + (4.4*10**25) * Z * exp(3.38/T_9**(1/3)))) * exp(-18.608/ T_9**(1/3))
simplify(Rho)
plot_implicit(T, Rho)
Updated: I used SymPy plot to get new error, I updated the code to reflect what I currently have, TypeError: object of type 'Mul' has no len()
You need to provide values for the independent variable(s). For example, to plot an expression like y = x**2 - 1, I would do this:
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(0, 20) # Provide the range of the independent variable.
y = x**2 - 1 # Compute the dependent variable.
plt.plot(x, y)
In your case, you'll need to provide values for T I suppose, and it looks like there are several other unknowns too. Take a look at this question, answers to which show a SymPy plotting example.

Contradictiry values for the same calculation in python

Consider the following two results
import numpy as np
(1/21) * np.log( (1/21) / (3/21) * (3/21))
which results in
-0.14497725893921062
and the same calculation as follows
import numpy as np
x = 0.14285714285714285
y = 0.14285714285714285
xy = 0.047619047619047616
xy * np.log(xy / (x * y))
which results in
0.040347517161295414
Both calculations are same, but results has so much gap. What is the issue here?
And which one is recommended, if its not a subjective question?
Because multiplication and divison have same precedence at Python and Python reads them from left to right.
for example:
x, y, z = 2, 4, 8
these are completely different:
x / y * z == x / (y * z)
>>>False
left side is 4.0 and right side is 0.0625
ps:
Parentheses have the highest precedence and can be used to force an expression to evaluate in the order you want.

The arctangent of tangent x is not calculated precisely

I need tangent, arctangent functions for my Python program. I tried np.arctan and np.tan but observed a strange behaviour. In principle, the arctangent of tangent of some number is the number itself, but the code below doesn't give a precise value.
import numpy as np
x = 10
print(np.arctan(np.tan(x)))
When I change x to 2*x or 3*x, then the result is even more inaccurate.
I tried math.tan, math.atan but the result was the same.
Can someone please explain why it happens(which of the two functions is wrong), and under which condition one should be careful about using the arctangent and tangent functions?
three things to note:
in python (as in all programming languages i have ever looked at) trigonometric functions work with angles in radians i.e. the range [0, 2*pi) represents the 'full circle'
tan is periodic: tan(x) = tan(pi + x) (again note that this is in radians; in python tan(x) = tan(180 + x) will not be true!).
arctan returns a value in [-pi/2, pi/2).
in your example you fall back on the correct result in [-pi/2, pi/2):
import numpy as np
x = 10
print(np.arctan(np.tan(x))) # 0.575222039231
print(10 % (np.pi / 2)) # 0.5752220392306207
your function np.arctan(np.tan(x)) is equivalent to (the computationally less expensive)
def arctan_tan(x):
ret = x % np.pi
if ret > np.pi / 2:
ret -= np.pi
return ret

scipy.optimize.minimize two different outputs for the same(?) input

I have a function func(x). I want to know the x for func(x)-7=0. Because there is no exact real answer, I thought minimize would be a good idea.
from scipy.optimize import minimize
def func(x): # testing function which leads to the same behaviour
return (x * 5 + x * (1 - x) * (6-3*x) * 5)
def comp(x): # comparison function which should get zero
return abs(((func(x)) - 7))
x0 = 0.
x_real = minimize(comp, x0) # minimize comparison function to get x
print(x_real.x)
The last print gives me [ 0.7851167]. The following print...
print(comp(x_real.x))
print(comp(0.7851167))
...leads to different outputs:
[ 1.31290960e-08]
6.151420706146382e-09
Can someone explain me this behaviour?
EDIT: I think i understood your question wrong. Rounding the number as you did in the print statements obviously will result in some differences (which are pretty small (around 1e-9)).
To find all x, you should apply some global solution method or start from different intital point to find all local minimas(as seen in the plot).
The equation however has two solutions.
def func(x): # testing function which leads to the same behaviour
return (x * 5 + x * (1 - x) * (6-3*x) * 5)
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-0.1,1,100)
plt.plot(x, func(x)-7)
plt.plot(x, np.zeros(100))
plt.show()
The function:

Efficiently coding gradient of function

I'm currently trying to code this beastie in Python (using the numpy libraries). The lambda * w is supposed to be outside the summation.
Currently, I've coded the problem using a for loop, and a running total outside; however, this approach takes a long time.
My vectors for y, w, and x are very large - think 100,000s of elements. I was wondering whether there is a simpler way to vectorize the element instead using simple matrix operations instead of looping through the vector one element by another element.
This is my vectorized code:
xty = xtrain.T.dot(ytrain)
e = math.exp(-w_0.T.dot(xty))
gradient = (-xty*(e/1+e)-lambda_var*w_0)
If I understand your problem correctly, you might just have to bite the bullet and go with the loop:
import numpy as np
wave = 1e3
xs, ys, w = np.arange(1, 4), np.arange(4, 7), np.arange(7, 10)
eps = np.zeros(w.T.shape)
for x, y in zip(xs, ys):
eps += -y * np.exp(-y * w.T * x) * x / (1 + np.exp(-y * w.T * x))
print(eps + wave * w)
[ 7000. 8000. 9000.]

Categories