So far I have managed to find the particular solution to this equation for any given mass and drag coefficient. I have not however found a way to plot the solution or even evaluate the solution for a specific point. I really want to find a way to plot the solution.
from sympy import *
m = float(raw_input('Mass:\n> '))
g = 9.8
k = float(raw_input('Drag Coefficient:\n> '))
f = Function('f')
f1 = g * m
t = Symbol('t')
v = Function('v')
equation = dsolve(f1 - k * v(t) - m * Derivative(v(t)), 0)
C1 = Symbol('C1')
C1_ic = solve(equation.rhs.subs({t:0}),C1)[0]
equation = equation.subs({C1:C1_ic})
For completeness, you may also use Sympy's plot, which is probably more convenient if you want a "quick and dirty" plot.
plot(equation.rhs,(t,0,10))
Import these libraries (seaborn just makes the plots pretty).
from matplotlib import pyplot as plt
import seaborn as sns
import numpy as np
Then tack this onto the end. This will plot time, t, against velocity, v(t).
# make a numpy-ready function from the sympy results
func = lambdify(t, equation.rhs,'numpy')
xvals = np.arange(0,10,.1)
yvals = func(xvals)
# make figure
fig, ax = plt.subplots(1,1,subplot_kw=dict(aspect='equal'))
ax.plot(xvals, yvals)
ax.set_xlabel('t')
ax.set_ylabel('v(t)')
plt.show()
I get a plot like this for a mass of 2 and a drag coefficient of 2.
If I've understood correctly, you want to represent the right hand side of your solution, here's one of the multiple ways to do it:
from sympy import *
import numpy as np
import matplotlib.pyplot as plt
m = float(raw_input('Mass:\n> '))
g = 9.8
k = float(raw_input('Drag Coefficient:\n> '))
f = Function('f')
f1 = g * m
t = Symbol('t')
v = Function('v')
equation = dsolve(f1 - k * v(t) - m * Derivative(v(t)), 0)
C1 = Symbol('C1')
C1_ic = solve(equation.rhs.subs({t: 0}), C1)[0]
equation = equation.subs({C1: C1_ic})
t1 = np.arange(0.0, 50.0, 0.1)
y1 = [equation.subs({t: tt}).rhs for tt in t1]
plt.figure(1)
plt.plot(t1, y1)
plt.show()
Related
I have made the below in order to create a cube by giving different X, Y, Z values, but when I give for example (6,3,2) I don't receive 6 blocks on X-axis, 3 blocks on Y-axis, and 2 blocks on the Z-axis, but I received a cube 6x6x4, why?
import matplotlib.pyplot as plt
import numpy as np
def make(X,Y,Z):
x, y, z = np.indices((X,Y,Z))
cube2 = (x==0) & (y==0) & (z==0)
for i in range (X):
for j in range (Y):
for k in range(Z):
cube1 = (x==i) & (y==j) & (z==k)
cube2 = cube2|cube1
colors = np.ones(cube2.shape, dtype=object)
from matplotlib import cm
for i in range (X):
for j in range (Y):
for k in range(Z):
if 0<i<=3:
colors[i][j][k] = cm.gray(((i+j+k)/X),alpha=0.8)
elif 3<i<=6:
colors[i][j][k] = cm.winter(((i+j+k)/Y),alpha=0.8)
else:
colors[i][j][k] = cm.copper(((i+j+k)/Z),alpha=0.8)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.voxels(cube2, facecolors=colors, edgecolor=None)
plt.show()
make(6,3,2,)
I also need your help with something else. I have created a bezier line according to the code.
#bezier line
import numpy as np
import matplotlib.pyplot as plt
A = np.array([10,20])
B = np.array([15,8])
C = np.array([8,22])
A = A.reshape(2,1)
B = B.reshape(2,1)
C = C.reshape(2,1)
t = np.arange(0.0, 1.0, 0.1).reshape(1,-1)
P0 = A * t + (1 - t) * B
P1 = B * t + (1 - t) * C
Pfinal = P0 * t + (1 - t) * P1
x=np.transpose(Pfinal)
x1= x[:, 0]
print(x1)
plt.plot(x1)
Is it possible to implement this to the above first code in order to choose different colors instead of what I have done in the if statement? For example, on the Z axis at the right of this bezier line to have cm.winter colors, at the left cm.copper or something similar.
Your code produces the expected plots. I don't see a problem. This is not an answer but a means of showing you the plot I get with your code. What are you looking for?
make(6,3,2)
I keep getting error messages such as invalid syntax, or something is not defined.
here I defined the dependencies
import math #Basic math library
import numpy as np #Numpy -> tools for working with arrays
import matplotlib.pyplot as plt #Matplotlib -> tools for plotting
here I defined the constants
#CONSTANTS
pi = math.pi
omega_n = 30
xi = 0.05
beta = 0.1
here I defined the functions
O = (1/((1-beta**2)**2 + (2*xi*beta)**2)) #Capital Omega defined above
omega_d = omega_n*np.sqrt(1-xi**2) #Damped natural frequency
A = (2*xi*beta*np.cos(omega_n*t)*math.e**(-xi* omega_n* t)
C = 2*omega_n*(xi**2)*beta*math.e**(-xi*omega_n*t)
D = (1-beta**2)*np.sin(omega_d*t)
E = -2*xi*beta*np.cos(omega_d*t)
tmax = 60 #(sec) The max time
delta_t = 0.001 #(sec) The timestep
nPoints = tmax/delta_t #Number of equally spaced data points
t = np.linspace(0,tmax, int(nPoints)) # Time vector
ut = O* (A + omega_d + C) #Transientresponse
us = O* (D + E) #Steady-state response
rt= ut + us
plotting
#Plotting
fig = plt.figure()
axes = fig.add_axes([0.1,0.1,2,1.5])
axes.plot(t,rt,label='Respond ratio of a damped system')
axes.set_xlim([0,tmax])
axes.set_xlabel('Time (sec)')
axes.set_ylabel('Respond ratio')
axes.set_title('Respond ratio-time history')
axes.grid()
axes.legend()
plt.show()
There are several errors here. First, you're missing a bracket in this line:
A = (2*xi*beta*np.cos(omega_n*t)*math.e**(-xi* omega_n* t))
Then you're using the variable t in the same line but you haven't defined t yet. You're defining t after this line. Similarly, you need to define tmax/delta_t before using them in nPoints
I'm trying to plot the graphs of the following equation in Python.
Solution of the radial differential equation of a 2d quantum ring
The beta parameter is
This was my attempt
import numpy as np
from scipy.special import gamma, genlaguerre
import matplotlib.pyplot as plt
from scipy import exp, sqrt
m = 0.067*9.1*10E-31
R = 5E-9
r = np.linspace(0, 20E-9)
#Definição do parâmetro beta
def beta(gama):
flux = np.linspace(0,1.0)
beta = sqrt((m-flux)**2+(gama**4)/4)
return beta
def Rn(n,gama):
raiz = sqrt((gamma(n+1)/((2**beta(gama)) * gamma(n+beta(gama)+1))))
eval_g = genlaguerre((n,beta(gama)),((gama * r/R)**2/2))
exp_g = exp(-((gama * r/R)**2)/4)
return (1/R) * raiz * (gama * r/R)**beta(gama) * exp_g * eval_g
sol1 = Rn(0,1.5)
sol2 = Rn(0,2.0)
sol3 = Rn(0,2.5)
sol4 = Rn(0,3.0)
fig, ax = plt.subplots()
ax.plot(r/R, sol1, color = 'red', label = '$\gamma$ = 1.5')
ax.plot(r/R, sol2, color = 'green', label = '$\gamma$ = 2.0')
ax.plot(r/R, sol3, color = 'blue', label = '$\gamma$ = 2.5')
ax.plot(r/R, sol4, color = 'black', label = '$\gamma$ = 3.0')
ax.legend()
ax.set_xlabel('R/r')
ax.set_ylabel('$R_0(r)$')
erro using genlaguerre
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Here the link to the article
I'm not into this topic, but afaics there are at least the following mistakes (I assume setting silently n=0 was on purpose):
In opposite to the posted image of the beta function, you added a division by 4 into your function definition.
Correct version:
def beta(gama):
return np.sqrt((m-flux)**2+(gama**4))
That's no reason for distributed instead of fixed peaks but I tell what I see here.
Product instead of division because of lacking parantheses in definition of amplitude function:
Correct version:
def amplitude(gama):
return np.sqrt(gamma(1)/((2**beta(gama)*gamma(beta(gama)+1))))
In the definition of Rn function there's the introducing 1/R missing.
However, all this unfortunately does not change the peaks to happen at equal x positions...
Sorry! The radial wave function of the article is wrong! I made the calculations and found the correct answer. The following code is correct
import numpy as np
from scipy.special import genlaguerre, gamma
import numpy as np
import matplotlib.pyplot as plt
m = 0 # magnetic number
flux = 0 # Phi in eqn 8
R = 5 # nm
r = np.linspace(0, 6 * R)
rho = r / R
def R0(n, gama):
beta = np.sqrt((m - flux)**2 + gama**4/4)
return (gama/R*
np.sqrt(gamma(n+ 1) / ( 2**beta * gamma(n + beta + 1))) *
(gama * rho)**beta *
np.exp(-gama**2 * rho**2 / 4) *
genlaguerre(n, beta)(gama**2 * rho**2 / 2))
sol1 = R0(0, 1.5)
sol2 = R0(0, 2.0)
sol3 = R0(0, 2.5)
sol4 = R0(0, 3.0)
plt.plot(rho, sol1, rho, sol2, rho, sol3, rho, sol4)
plt.legend(['$\gamma = 1.5$', '$\gamma = 2$', '$\gamma = 2.5$', '$\gamma = 3$'])
plt.ylabel('$R_{0}(r)$')
plt.xlabel('$r/R$')
plt.show()
I'm trying to model Chau's Circuit in Python using matplotlib and scipy, which involves solving a system of ordinary differential equations.
This has been done in matlab, and I simply wanted to attempt the problem in python. The matlab code linked is a little confusing; the code on the left doesn't appear to have much relevance to solving the system of ode's that describe Chua's Circuit (page 3, equations (2)(3) and (4)), whilst the code on the right goes beyond that to modelling the circuit component by component.
I'm not familiar with scipy's odeint function so I used some of the examples from the scipy cookbook for guidance.
Can anyone help me troubleshoot my system; why do I get a graph looking like this:
As opposed to one looking like this?
My code is attached below:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def fV_1(V_1, G_a, G_b, V_b):
if V_1 < -V_b:
fV_1 = G_b*V_1+(G_b-G_a)*V_b
elif -V_b <= V_1 and V_1 <=V_b:
fV_1 = G_a*V_1
elif V_1 > V_b:
fV_1 = G_b*V_1+(G_a-G_b)*V_b
else:
print "Error!"
return fV_1
def ChuaDerivatives(state,t):
#unpack the state vector
V_1 = state[0]
V_2 = state[1]
I_3 = state[2]
#definition of constant parameters
L = 0.018 #H, or 18 mH
C_1 = 0.00000001 #F, or 10 nF
C_2 = 0.0000001 #F, or 100 nF
G_a = -0.000757576 #S, or -757.576 uS
G_b = -0.000409091 #S, or -409.091 uS
V_b = 1 #V (E)
G = 0.000550 #S, or 550 uS VARIABLE
#compute state derivatives
dV_1dt = (G/C_1)*(V_2-V_1)-(1/C_1)*fV_1(V_1, G_a, G_b, V_b)
dV_2dt = -(G/C_2)*(V_2-V_1)+(1/C_2)*I_3
dI_3dt = -(1/L)*V_2
#return state derivatives
return dV_1dt, dV_2dt, dI_3dt
#set up time series
state0 = [0.1, 0.1, 0.0001]
t = np.arange(0.0, 53.0, 0.1)
#populate state information
state = odeint(ChuaDerivatives, state0, t)
# do some fancy 3D plotting
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(state[:,0],state[:,1],state[:,2])
ax.set_xlabel('V_1')
ax.set_ylabel('V_2')
ax.set_zlabel('I_3')
plt.show()
So I managed to work it out for myself after some fiddling; I was interpreting the odeint function wrong; more careful reading of the docstring and starting from scratch to stop me following a difficult method solved it. Code below:
import numpy as np
import scipy.integrate as integrate
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#define universal variables
c0 = 15.6
c1 = 1.0
c2 = 28.0
m0 = -1.143
m1 = -0.714
#just a little extra, quite unimportant
def f(x):
f = m1*x+(m0-m1)/2.0*(abs(x+1.0)-abs(x-1.0))
return f
#the actual function calculating
def dH_dt(H, t=0):
return np.array([c0*(H[1]-H[0]-f(H[0])),
c1*(H[0]-H[1]+H[2]),
-c2*H[1]])
#computational time steps
t = np.linspace(0, 30, 1000)
#x, y, and z initial conditions
H0 = [0.7, 0.0, 0.0]
H, infodict = integrate.odeint(dH_dt, H0, t, full_output=True)
print infodict['message']
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(H[:,0], H[:,1], H[:,2])
plt.show()
Which gives me this:
I want to implement complex standard Gaussian noise in python or C. This figure shows what I want to implement.
And first I implement it in python, like this.
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import pylab as pl
size = 100000
BIN = 70
x = np.random.normal(0.0,1.0,size)
y = np.random.normal(0.0,1.0,size)
xhist = pl.hist(x,bins = BIN,range=(-3.5,3.5),normed = True)
yhist = pl.hist(y,bins = BIN,range=(-3.5,3.5),normed = True)
xmesh = np.arange(-3.5,3.5,0.1)
ymesh = np.arange(-3.5,3.5,0.1)
Z = np.zeros((BIN,BIN))
for i in range(BIN):
for j in range(BIN):
Z[i][j] = xhist[0][i] + yhist[0][j]
X,Y = np.meshgrid(xmesh,ymesh)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(X,Y,Z)
plt.show()
However, it is not standard complex Gaussian noise.
The output figure become:
I think Gaussian noises are additive, however, why it become so different?
I already tried to change the parts of code
x = np.random.normal(0.0,1.0,size)
y = np.random.normal(0.0,1.0,size)
to
r = np.random.normal(0.0,1.0,size)
theta = np.random.uniform(0.0,2*np.pi,size)
x = r * np.cos(theta)
y = r * np.sin(theta)
however, the result was same.
Please tell me the correct implementation or equation of bivariate standard Gaussian noise.
So sorry.It's my mistake.
Joint probability is defined by the product, not summation. I was a perfect fool!
So
Z[i][j] = xhist[0][i] + yhist[0][j]
term must become
Z[i][j] = xhist[0][i] * yhist[0][j]
And I checked
for i in range(BIN):
for j in range(BIN):
integral = integral + Z[i][j] * 0.01
will be 1.0.
So if we need complex standard Gaussian noise, we should do adding the real standard Gaussian noise to real part and imaginary part.
This is the graph for comparing.