Plot sine wave (degrees) - python

We're supposed to plot the sine wave with the help of Matplotlib but in degrees.
First we're supposed to get every sin(x) from 0-360 degrees, every ten degrees.
I'm a beginner, would really appreciate the help.
def getsin():
for i in range(0,361,10):
y=math.sin(math.radians(i))
sinvalue.append(round(y,3)
sinvalue=[]
getsin()
x=np.linspace(0,360,37)
plot.plot(x,sinvalue)
plot.xlabel("x, degrees")
plot.ylabel("sin(x)")
plot.show()

Your code is almost OK (you missed a closing parenthesis on line sinvalue.append(round(y,3)), but it can be perfected.
E.g., it's usually considered bad practice updating a global variable (I mean sinvalue) from inside a function... I don't say that it should never be done, I say that it should be avoided as far as possible.
A more common pattern is to have the function to return a value...
def getsin():
sines = []
for i in range(0,361,10):
y=math.sin(math.radians(i))
sines.append(round(y,3))
return sines
Why I say this is better? Compare
sinvalue=[]
getsin()
with
sinvalue = getsin()
At least in my opinion, the second version is waaay better because it makes clear what is happening, now sinvalue is clearly the result of getting the sines...

Related

solving a Non- linear first order differential equation and getting a break in the plot

I am trying to solve the elliptical differential equation using fourth-order runge-kutta method in python.
After execution, I get a very small part of the actual plot that should be obtained and alongside with it an error saying that:
"RuntimeWarning: invalid value encountered in double_scalars"
import numpy as np
import matplotlib.pyplot as plt
#Define constants
g=9.8
L=1.04
#Define the differential Function
def fun(y,x):
return-(2*(g/L)*(np.cos(y)-np.cos(np.pi/6)))**(1/2)
#Define variable arrays
x=np.zeros(1000)
y=np.zeros(1000)
y[0]=np.pi/6
dx=0.5
#Runge-Kutta Method
for i in range(len(y)-1):
k1=fun(x[i],y[i])
k2=fun(x[i]+dx/2, y[i]+dx*k1/2)
k3=fun(x[i]+dx/2, y[i]+dx*k2/2)
k4=fun(x[i]+dx, y[i]+dx*k3)
y[i+1]=y[i]+dx/6*(k1+2*k2+2*k3+k4)
x[i+1]=x[i]+dx
#print(y)
#print(x)
plt.plot(x,y)
plt.xlabel('Time')
plt.ylabel('Theta')
plt.grid()
And the graph I obtain is something like,
My question is why am I getting the error message? Thanks for helping!
Several points that lead to this behavior. First, you switched the order of the arguments in the ODE function, probably to make it compatible with odeint. Use the tfirst=True optional argument to avoid that and have the independent variable always first.
The actual source of the error is the term
(np.cos(y)-np.cos(np.pi/6)))**(1/2)
remember that in your version y has the value x[i], so that at some point the expression under the root becomes negative.
If you correct the first point, you will probably still encounter the second error as the exact solution moves parabolically towards the fixed point, so that the stages of RK4 are likely to overshoot. One can fix that by providing a sufficiently secured square root function,
def softroot(x): return x/max(1e-12,abs(x))**0.5
#Define the differential Function
def fun(x,y):
return -(2*(g/L)*softroot(np.cos(y)-np.cos(np.pi/6)))
#Define variable arrays
dx=0.01
x=np.arange(0,1,dx)
y=np.zeros(x.shape)
y[0]=np.pi/6
...
results in a plot
as the solution already starts in the fixed point. Shifting the initial point a little down to y[0]=np.pi/6-1e-8 produces a jump to the fixed point below.

numpy: arange include endpoint

I need to transfer some Matlab code into P. I got stuck at a numpy.arange I use to set points continuously on the arc of circle with a given angle (in radians).
I got this far (example for points on x-axis):
def sensor_data_arc_x():
theta = np.arange(0, angle/2, 2*np.pi/360)
return np.multiply(radius, np.cos(np.transpose(theta)))
I know numpy.arange does not include the endpoint, although the Matlab equivalent does; the array is always one element short, which is messing up my further computations.
Is there an way to include the endpoint?
I recommend that you work through a tutorial on for loops -- the information you need is there, as well as other hints on using controlled iteration. To solve your immediate need, simply increase your upper bound by one loop increment:
inc = 2*np.pi/360
theta = np.arange(0, angle/2 + inc, inc)

Python: fsolve near asymptotic region

For E=0.46732451 and t=1.07589765 I am trying to solve for the upper limit of the integral t= \int_{0}^{z} 1/sqrt(2*(0.46732451-z**2)), I plotted this function and it looks like this .
Around t=1 it kind of asymptotes.
I have the following code
import numpy as np
from scipy import integrate
from scipy.optimize import fsolve
def fg(z_up,t,E):
def h(z,E):
return 1/(np.sqrt(2*(E-z**2)))
b, err = integrate.quad(h, 0, z_up,args=(E))
return b-t
x0 = 0.1
print fsolve(fg, x0, args=(1.07589765, 0.46732451))[0]
But this code just outputs the guess value, no matter what I put, so I am guessing it has something to do with the fact that the curve asymptotes there. I should note that this code works for other values of t which are away from the asymptotic region.
Can anyone help me resolve this?
Thanks
EDIT After playing around for a while, I solved the problem, but it's kind of a patchwork, it only works for similar problems not in general (or does it?)
I made the following changes: the maximum value that z can attain is sqrt(0.46732451), so I set x0=0.5*np.sqrt(0.46732451) and set factor anywhere between 0.1 to 1, and out pops the correct answer. I don't have an explanation for this, perhaps someone who is an expert in this matter can help?
You should use bisect instead, as it handles nan without problems:
print bisect(fg, 0.4, 0.7, args=(1.07589765, 0.46732451))
Here 0.4 and 0.7 are taken as an example but you can generalize this for almost any diverging integral by using 0 and let's say 1e12 as the limits.
However, I'm not sure I understand what you really want to do... if you want to find the limit at which the integral diverges, cf. your
I am trying to solve for the upper limit of the integral
then it's simply for z_up -> \sqrt{E} \approx 0,683611374...
So to find the (approximate) numerical value of the integral you just have to decrease z_up from that value until quad stops giving a nan...

Scipy LSQSphereBivariateSpline : hanging, and how to choose knots?

I'm working on some python code to interpolate irregular data onto a 180° lat x 360° lon spherical grid. The code is currently hanging when I call the following:
def geo_interp(lats,lons,data,grid_size_deg):
deg2rad = pi/180.
new_lats = np.linspace(grid_size_deg, 180, 180) * deg2rad
new_lons = np.linspace(grid_size_deg, 360, 360) * deg2rad
knotst, knotsp = new_lats.copy(), new_lons.copy()
knotst[0] += .0001
knotst[-1] -= .0001
knotsp[0] += .0001
knotsp[-1] -= .0001
lut = LSQSphereBivariateSpline(lats.ravel(),lons.ravel(),data.T.ravel(),knotst,knotsp)
data_interp = lut(new_lats, new_lons)
return data_interp
The arrays I'm using as arguments when I call the above subroutine all fit the requirements of LSQSphereBivariateSpline as listed in the documentation. When I run it, it takes much longer than I feel like it should take to process a 180x360 dataset.
When I run the script with python -m trace --trace, the last line of output before nothing happens for a long time is
fitpack2.py(1025): w=w, eps=eps)
As far as I can tell, line 1025 of fitpack2.py is in a comment, which is even more confusing.
So my questions are:
1. Is there a way to tell if it's hanging or just very slow?
2. If it's hanging, how might I fix it?
The only thing I can think of is that I have no idea what I'm doing as far as choosing knots. Is there a good way to choose those? I just went with the grid I'll be interpolating to later, since the example in the doc seemed to be an arbitrary grid.
UPDATE: It finally finished after about 3 hours but the "interpolated data" looked like random noise. Also, if this is relevant, as far as I can tell LSQSphereBivariateSpline is the only function I can use for this because my lats and lons are not strictly increasing.
Also, I should add that when it finished it output the following warning: Warning (from warnings module):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/scipy/interpolate/fitpack2.py", line 1029
warnings.warn(message)
UserWarning:
WARNING. The coefficients of the spline returned have been computed as the
minimal norm least-squares solution of a (numerically) rank
deficient system (deficiency=16336, rank=48650). Especially if the rank
deficiency, which is computed by 6+(nt-8)*(np-7)+ier, is large,
the results may be inaccurate. They could also seriously depend on
the value of eps.
SOLUTION: I had far too many knots, causing both the glacial pace and the useless results.

Lattice paths algorithm does not finish running for 20 X 20 grid

I wrote the following code in python to solve
problem 15 from Project Euler:
grid_size = 2
def get_paths(node):
global paths
if node[0] >= grid_size and node[1] >= grid_size:
paths += 1
return
else:
if node[0]<grid_size+1 and node[1] < grid_size+1:
get_paths((node[0]+1,node[1]))
get_paths((node[0],node[1]+1))
return paths
def euler():
print get_paths((0,0))
paths = 0
if __name__ == '__main__':
euler()
Although it runs quite well for a 2 X 2 grid, it's been running for hours for a 20 X 20 grid. How can I optimise the code so that it can run on larger grids?
Is it a kind of breadth first search problem? (It seems so to me.)
How can I measure the complexity of my solution in its current form?
You might want to look into the maths behind this problem. It's not necessary to actually iterate through all routes. (In fact, you'll never make the 1 minute mark like that).
I can post a hint but won't do so unless you ask for it, since I wouldn't want to spoil it for you.
Edit:
Yes, the algorithm you're using will never really be optimal since there's no way to reduce the search space of your problem. This means that (as pg1989 stated) you'll have to look into alternative means of solving this problem.
As sverre said looking over here might give a nudge in the right direction:
http://en.wikipedia.org/wiki/Binomial_coefficient
A direct solution may be found here (warning, big spoiler):
http://www.joaoff.com/2008/01/20/a-square-grid-path-problem/
Your algorithm is exponential, but only because you are re-evaluating get_paths with the same input many times. Adding Memoization to it will make it run in time. Also, you'll need to get rid of the global variable, and use return values instead. See also Dynamic Programming for a similar idea.
When solving problems on Project Euler, think about the math behind the problem for a long time before starting to code. This problem can be solved without any code whatsoever.
We're trying to count the number of ways through a grid. If you observe that the number of moves down and right do not change regardless of the path, then you only need to worry about the order in which you move down and right. So in the 2x2 case, the following combinations work:
DDRR
DRDR
RDRD
RRDD
RDDR
DRRD
Notice that if we pick where we put the R moves, the placement of the D moves is determined. So really we only have to choose, from the 4 movement slots available, which get the R moves. Can you think of a mathematical operation that does this?
Probably not the way the project Euler guys wanted this problem to be solved but the answer is just the central binomial coefficient of a 20x20 grid.
Using the formula provided at the wiki article you get:
from math import factorial, pow
grid = 20
print int(factorial(2 * grid) / pow(factorial(grid), 2))
The key is not to make your algorithm run faster, as it will (potentially) run in exponential time, no matter how fast each step is.
It is probably better to find another way of computing the answer. Using your (expensive, but correct) solution as a comparison for small values is probably a sanity-preserver during the algorithm optimization effort.
This question provides some good insight into optimization. The code is in c# but the algorithms are applicable. Watch out for spoilers, though.
Project Euler #15
It can be solved by simple observation of the pattern for small grids, and determining a straightforward formula for larger grids. There are over 100 billion paths for a 20x20 grid and any iterative solution will take too long to compute.
Here's my solution:
memo = {(0, 1) : 1, (1, 0) : 1}
def get_pathways(x, y):
if (x, y) in memo : return memo[(x, y)]
pathways = 0
if 0 in (x, y):
pathways = 1
else:
pathways = get_pathways(x-1, y) + get_pathways(x, y-1)
memo[(x, y)] = pathways
return pathways
enjoy :)

Categories

Resources