An archived instance of discourse for discussion in undergraduate Real and Numerical Analysis.

# Animating a harmonic osciallator

mark

So project four looks pretty tricky. It might be nice to have a similar problem that you folks can work on together as a team and discuss fully. Towards that end, try to generate an animation of a harmonic oscillator. I guess it should look something like so:

I guess the equations should look something like
$$x'' = -x; \: \: x(0)=0 \: \text{ and } \: x'(0)=v_0.$$

Professor.Membrane

The solution for this equation w/o regard to initial conditions is:
$x(t) = c_{1}\cos t + c_{2}\sin t$
We need $x(0) = 0$. It follows that $c_{1} = 0$.

Note that $x'(0) = c_{2}\cos t = v_{0}$
IT follows that $c_{2} = v_{0}$.

Hence $x(t) = v_{0}\sin t$.

mark

@Professor.Membrane That is the analytic solution to the equation. More importantly, how do we find the solution numerically? This is important because $\theta''=-\sin(\theta)$, as in our project, has no analytic solution.

djett

Excuse my plebeian knowledge of animation software, but how exactly do we implement ImageMagick to be used in Python script? I downloaded one of the first responses for a Google search for "ImageMagick animation" but I'm unsure of how to utilize it..

mark

@djett ImageMagick is a separate command line program. The idea, as I described it in the project, is to generate a sequence of frames that are saved to your hard drive in PNG format. You then execute the convert command from the terminal command line. Note that convert is a separate program and should be on your terminal path once you've installed ImageMagick. It is not executed from within Python.

Having said that, it is possible to execute it from with Python using the matplotlib.animation module. I'm not sure how much of a pain that is to set up but I'll have a look.

djett

@Professor.Membrane Is your $v_{0}$ the initial speed of the ball? Sort of synonymous to the initial angular velocity $s_{0}$ we need to find for the pendulum?

hjoseph

I've got everything done but I am currently using a seed of 4 because when I try to seed random with a string I get an error saying that I cannot cast a string array to an integer. Is there something I must do that is not shown in the example to be able to seed with a string array?

mark

@hjoseph Well, that is weird. The following works for me no problem:

from random import seed, random
seed("audrey")
random()

And it produces 0.7943768054253341 every time. You?

hjoseph

Thanks @mark,

For me:

seed("Harris")
s0 = 0.2+randn()/4
y0=[0,s0]
t= np.linspace(0,37.5,100)

gives the following:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
mtrand.pyx in mtrand.RandomState.seed (numpy\random\mtrand\mtrand.c:8615)()

TypeError: 'str' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-26-156918e835bf> in <module>()
----> 1 seed("Harris")
2 s0 = 0.2+randn()/4
3 y0=[0,s0]
4 t= np.linspace(0,37.5,100)

mtrand.pyx in mtrand.RandomState.seed (numpy\random\mtrand\mtrand.c:8897)()

TypeError: Cannot cast array from dtype('<U6') to dtype('int64') according to the rule 'safe'
mark

@hjoseph Well, I don't know what to tell you. That works for me. I'll be looking forward to seeing what happends tomorrow!

gbrock

So, just to make sure I'm doing this right, the idea is to:
1) run the code provided for us in the lab. The first part of odeint's output from this is an array of the x-values for this harmonic oscillator,
2) run that array through interp1d to generate a function that we then...
3) ...run through brentq to figure out where a root is,
4) rerun the code from part 1, but only from 0 to wherever the root is, giving us another (shorter) array of x-values for this harmonic oscillator across only one period,
5) use some loops to save images of these x-values on the line thing,
6) put it together to make a pretty picture?

mark

@gbrock I believe that's about correct. A couple of points might be a little more clear.

3) By "a" root I guess we want "the" second smallest, positive value of $t$ such that $\theta(t)=0$, since that's when the pendulum is on the way back through it's initial position.

4) Correct - we rerun the code from zero to the root we just found. This should certainly be an interval of shorter time duration. We can make the length of the array any length that we want, however. We might choose to make the length longer so that we generate a smoother animation.

Shia

Would it work if you used single quotes instead of double quotes? ('Harris' in place of "Harris")

djett

I was able to generate a pendulum animation, but since I used the same convert command in the command prompt (convert -delay 1 pic*.png -loop 0 anim.gif), when I ran the animation, it combined the Earth&Mars gif with the pendulum. To fix this, I assume I can just change the very last part of that convert command (anim.gif to something like pend.gif) so it is unique. Does that sound about right?

mark

@djett When I use convert like this, I typically create a directory dedicated for the purpose of creating the animation. On Mac OS or Unix, you can execute rm *.png to delete all the PNG files in the directory.

Invictus

The command looks for anything with a file name of pic and a number so it'll use whatever pngs are in the file you are looking in.