GSL solving ODE for a pendulum movement - c

I'm trying to solve a differential equation for a pendulum movement, given the pendulum initial angle (x), gravity acceleration (g), line length (l), and a time step (h). I've tried this one using Euler method and everything's alright. But now i am to use Runge-Kutta method implemented in GSL. I've tried to implement it learning from the gsl manual, but I'm stuck at one problem. The pendulum doesn't want to stop. Let's say that I start it with initial angle 1 rad, it always has it's peak tilt at 1 rad, no matter how many swings it already did. Here's the equation and the function i use to give it to GSL:
x''(t) + g/l*sin(x(t)) = 0
transforming it:
x''(t) = -g/l*sin(x(t))
and decomposing:
y(t) = x'(t)
y'(t) = -g/l*sin(x(t))
Here's the code snippet, if that's not enough i can post the whole program (it's not too long), but maybe here's the problem somewhere:
int func (double t, const double x[], double dxdt[], void *params){
double l = *(double*) params;
double g = *(double*) (params+sizeof(double));
dxdt[0] = x[1];
dxdt[1] = -g/l*sin(x[0]);
return GSL_SUCCESS;
}
The parameters g and l are passed correctly to the function, I've already checked that.

As Barton Chittenden noted in a comment, the pendulum should keep going in the absence of friction. This is expected.
As for why it slows and stops when you use the Euler method, that's touching on a subtle and interesting subject. A (ideal, friction-free) physical pendulum has the property that energy in the system is conserved. Different integration schemes preserve that property to different degrees. With some integration schemes, the energy in the system will grow, and the pendulum will swing progressively higher. With others, energy is lost, and the pendulum comes to a halt. The speed at which either of these happens depends partially on the order of the method; a more accurate method will often lose energy more slowly.
You can easily observe this by plotting the total energy in your system (potential + kinetic) for different integration schemes.
Finally, there is a whole fascinating sub-field of integration methods which preserve certain conserved quantities of a system like this, called symplectic methods.

Related

I'm trying to interpolate and find the minimum x of the interpolation in C (Possibly with secant method)

I want to create my own C function to interpolate some data points and find an accurate minimum (Overall project is audio frequency tuning, and I'm using the YIN algorithm which is working well). I am implementing this on a digital DSP K22F ARM chip, so I want to minimize floating point multiplies as much as possible to implement within the interrupt while the main function pushes to a display and #/b indicators.
I have gotten to the point where I need to interpolate I have implemented the algorithm, found the integer minimum, and now need to interpolate. Currently I am trying to parabolically interpolate using the 3 points I have. I have found one that works within a small margin of error Most interpolation functions seem to only be made between two points.
It seems as though the secant method on this page would work well for my application. However, I am at a loss for how to combine the 3 points with this 2 point method. Maybe I am going about this the wrong way?
Can someone help me implement the secant method of interpolation?
I found some example code that gets the exact same answer as my code.
Example code:
betterTau = minTau + (fc - fa) / (2 * (2 * fb - fc - fa));
My code:
newpoint = b + ((fa - fb)*(c-b).^2 - (fc - fb)*(b-a)^2) / ...
(2*((fa-fb)*(c-b)+(fc-fb)*(b-a)))
where the x point values are a, b, and c. The values of each point is fa, fb, and fc, respectively
Currently I am just simulating in MATLAB before I put it on the board which is why the syntax isn't C. Mathematically, I am not seeing how these two equations are equivalent.
Can someone explain to me how these two functions are equivalent?
Thank you in advance.

Following 3D Spiral Path

I would like to produce a realistic 3D demonstration of a ball rolling down a Conical Helix path. The reference that has helped me get close to a solution can be found here. [I am creating my solution in Actionscript 3, using Stage3D, but would be happy to have any suggested coding solutions in other languages, using other 3D frameworks, with which you may be more familiar.]
As I entered the title for my posting, the system pointed me to a wealth of "Questions that may already have your answer", and that was helpful, and I did check each of them out. Without wanting to hijack an existing thread, I should say that this oneincludes a good deal of very helpful commentary about the general subject, but does not get to the specific challenges I have been unable to resolve.
Using the cited reference, I am happy with this code snippet that traces the path I would like the ball to follow. [N.B. My reference, and most other math-based references, treat Z as being up-down; my usage, however, is the more usual 3D graphics of Y for up-down.]
This code is executed for each frame.
ft += 0.01; // Where ft is a global Number.
var n:Number = Math.pow (0.5, (0.15 * ft));
// Where s is a constant used to scale the overall path.
obj.moveTo (
(s * n * Math.cos (2.0 * ft)),
(s * n),
(s * n * Math.sin (2.0 * ft))
);
The ball follows a nice path, and owing to the lighting and other shader code, a very decent effect is viewed in the scene.
What is not good about my current implementation is that the ball does not appear to be rolling along that path as it moves from point to point. I am not using any physics engine, and am not seeking any solution dealing with collisions, but I would like the ball to correctly demonstrate what would be happening if the movement were due to the ball rolling down a track.
So, to make a little more clear the challenge, let's say that the ball is a billiard ball with the stripe and label for #15. In that case, the visual result should be that the number 15 should be turning head over heals, but, as you can probably surmise from the name of my obj.moveTo() function, that only results in changes in position of the 3D object, not its orientation.
That, finally, brings me to the specific question/request. I have been unable to discover what rotation changes must be synchronized with each positional change in order to correctly demonstrate the way the billiard ball would appear if it rolled from point 1 from point 2 along the path.
Part of the solution appears to be:
obj.setRotation ((Math.atan2 (Math.sin (ft), Math.cos (ft))), Vector3D.Y_AXIS);
but that is still not correct. I hope there is some well-known formula that I can add to my render code.

variable timestep and acceleration

To move objects with a variable time step I just have to do:
ship.position += ship.velocity * deltaTime;
But when I try this with:
ship.velocity += ship.power * deltaTime;
I get different results with different time steps. How can I fix this?
EDIT:
I am modelling an object falling to the ground on one axis with a single fixed force (gravity) acting on it.
ship.position = ship.position + ship.velocity * deltaTime + 0.5 * ship.power * deltaTime ^ 2;
ship.velocity += ship.power * deltaTime;
http://www.ugrad.math.ubc.ca/coursedoc/math101/notes/applications/velocity.html
The velocity part of your equations is correct and they must both be updated at every time step.
This all assumes that you have constant power (acceleration) over the deltaTime as pointed out by belisarius.
What you are doing (mathematically) is evaluating integrals. In the first case, the linear approximation is exact, as you have a linear relationship.
In the second case, you have at least a parabola, so your results are only approximate. You may get better results by using a smaller deltaTime, or by using the real integral equations, if available.
Edit
Brian's answer is right as long as the ship.power remains always constant, and you recalculate ship.velocity at each step. It is indeed the integral equation for a constant accelerated movement.
This is an inherent problem trying to integrate numerically. There will be an error. Lowering delta will give you more accurate results, but more computation is needed. If your power function is integrable, you could try that.
Your simulation is numerically solving the equation of motion for a single mass point. The time discretisation you are using is called "Euler method", and it is possible to show that it does not preserve energy (as the exact solution does in some way). A much better yet simple way of solving equations of motion is the "leapfrog integration".
You can use Verlet integration to calculate position and velocity of object. Acceleration you can calculate from a = m*F where m is mass and F is force. This is one of the easiest algorithm
In your code you use setInterval(moveBoxes,20) to update the boxes, and subsequently you use (new Date()).getTime()) to calculate deltaT. This is somewhat redundant, because you could have used the number 20 to calculate deltaT directly.
It is better write the code so that you use exacly the same value for deltaT during each time step. (In other words deltaT should not depend on the value of (new Date()).getTime())). This way your code becomes reproducible and it is easier for you to write unit tests.
Let us look at a situation where the browser has less CPU-time available for a short time interval. In this situation you want to avoid long term effects on the dynamics. One the lack of CPU-time is over you want the browser to return to a state that is unaffected by the short lack of CPU-time. You can achieve this by using the same value of deltaT in each time step.
By the way. I think that the following code
if(box.x < 0) {
box.x = 0;
box.vx *= -1;
}
Could be replaced with
if(box.x < 0) {
box.x *= -1 ;
box.vx *= -1;
}
Good luck with the project - and please include code samples in the first version of your question next time you ask :-)

mean and variance of image in single pass

am trying to calculate mean and variance using 3X3 window over image(hXw) in opencv...here is my code...is there any accuracy issues with this??or is there any other efficient method to do it in one pass.?
int pi,a,b;
for(i=1;i<h-1;i++)
{
for(j=1;j<w-1;j++)
{ int sq=0,sum=0;
double mean=0;
double var=0;
for(a=-1;a<=1;a++)
{
for(b=-1;b<=1;b++)
{
pi=data[(i+a)*step+(j+b)];
sq=pi*pi;
sum=sum+sq;
mean=mean+pi;
}
}
mean=mean/9;
double soa=mean*mean;//square of average
double aos=sum/9;//mean of squares
double var=aos-soa;//variance
}
}
With respect to computational efficiency I would recommend doing this in the Fourier domain instead of the time (image) domain using convolutions. Remember, a convolution is a simple multiplication in the Fourier domain. Just like in time series where the spectral density function is the variance decomposed as a function of frequency, one can extend this into two dimensions for an image. Should be much better than nested for-loops.
I don't have the code on me at the moment. but this technique has been used in algorithms like "fast template matching" for object detection or image registration.
That is a pretty well-researched topic, see e.g. this Wikipedia article on variance calculations.
One of the issues that sometimes gets mentioned is accumulated numerical errors; you need to decide if that may be an issue. If the values you compute over are similar in range that it may be less of an issue.
You should be fine even with floats over such a small number of pixels. Typically you need doubles if you're doing this kind of thing over an entire image.
You should better use image integrals for quick local mean and standard deviation calculation!
All you need in that case is to correctly calculate the boundaries of the mask window at each position of the image. It will be much more faster.
If you will need a sample code, please ask for that.

How to program a fractal?

I do not have any experience with programming fractals. Of course I've seen the famous Mandelbrot images and such.
Can you provide me with simple algorithms for fractals.
Programming language doesn't matter really, but I'm most familiar with actionscript, C#, Java.
I know that if I google fractals, I get a lot of (complicated) information but I would like to start with a simple algorithm and play with it.
Suggestions to improve on the basic algorithm are also welcome, like how to make them in those lovely colors and such.
Programming the Mandelbrot is easy.
My quick-n-dirty code is below (not guaranteed to be bug-free, but a good outline).
Here's the outline:
The Mandelbrot-set lies in the Complex-grid completely within a circle with radius 2.
So, start by scanning every point in that rectangular area.
Each point represents a Complex number (x + yi).
Iterate that complex number:
[new value] = [old-value]^2 + [original-value] while keeping track of two things:
1.) the number of iterations
2.) the distance of [new-value] from the origin.
If you reach the Maximum number of iterations, you're done.
If the distance from the origin is greater than 2, you're done.
When done, color the original pixel depending on the number of iterations you've done.
Then move on to the next pixel.
public void MBrot()
{
float epsilon = 0.0001; // The step size across the X and Y axis
float x;
float y;
int maxIterations = 10; // increasing this will give you a more detailed fractal
int maxColors = 256; // Change as appropriate for your display.
Complex Z;
Complex C;
int iterations;
for(x=-2; x<=2; x+= epsilon)
{
for(y=-2; y<=2; y+= epsilon)
{
iterations = 0;
C = new Complex(x, y);
Z = new Complex(0,0);
while(Complex.Abs(Z) < 2 && iterations < maxIterations)
{
Z = Z*Z + C;
iterations++;
}
Screen.Plot(x,y, iterations % maxColors); //depending on the number of iterations, color a pixel.
}
}
}
Some details left out are:
1.) Learn exactly what the Square of a Complex number is and how to calculate it.
2.) Figure out how to translate the (-2,2) rectangular region to screen coordinates.
You should indeed start with the Mandelbrot set, and understand what it really is.
The idea behind it is relatively simple. You start with a function of complex variable
f(z) = z2 + C
where z is a complex variable and C is a complex constant. Now you iterate it starting from z = 0, i.e. you compute z1 = f(0), z2 = f(z1), z3 = f(z2) and so on. The set of those constants C for which the sequence z1, z2, z3, ... is bounded, i.e. it does not go to infinity, is the Mandelbrot set (the black set in the figure on the Wikipedia page).
In practice, to draw the Mandelbrot set you should:
Choose a rectangle in the complex plane (say, from point -2-2i to point 2+2i).
Cover the rectangle with a suitable rectangular grid of points (say, 400x400 points), which will be mapped to pixels on your monitor.
For each point/pixel, let C be that point, compute, say, 20 terms of the corresponding iterated sequence z1, z2, z3, ... and check whether it "goes to infinity". In practice you can check, while iterating, if the absolute value of one of the 20 terms is greater than 2 (if one of the terms does, the subsequent terms are guaranteed to be unbounded). If some z_k does, the sequence "goes to infinity"; otherwise, you can consider it as bounded.
If the sequence corresponding to a certain point C is bounded, draw the corresponding pixel on the picture in black (for it belongs to the Mandelbrot set). Otherwise, draw it in another color. If you want to have fun and produce pretty plots, draw it in different colors depending on the magnitude of abs(20th term).
The astounding fact about fractals is how we can obtain a tremendously complex set (in particular, the frontier of the Mandelbrot set) from easy and apparently innocuous requirements.
Enjoy!
If complex numbers give you a headache, there is a broad range of fractals that can be formulated using an L-system. This requires a couple of layers interacting, but each is interesting in it own right.
First you need a turtle. Forward, Back, Left, Right, Pen-up, Pen-down. There are lots of fun shapes to be made with turtle graphics using turtle geometry even without an L-system driving it. Search for "LOGO graphics" or "Turtle graphics". A full LOGO system is in fact a Lisp programming environment using an unparenthesized Cambridge Polish syntax. But you don't have to go nearly that far to get some pretty pictures using the turtle concept.
Then you need a layer to execute an L-system. L-systems are related to Post-systems and Semi-Thue systems, and like virii, they straddle the border of Turing Completeness. The concept is string-rewriting. It can be implemented as a macro-expansion or a procedure set with extra controls to bound the recursion. If using macro-expansion (as in the example below), you will still need a procedure set to map symbols to turtle commands and a procedure to iterate through the string or array to run the encoded turtle program. For a bounded-recursion procedure set (eg.), you embed the turtle commands in the procedures and either add recursion-level checks to each procedure or factor it out to a handler function.
Here's an example of a Pythagoras' Tree in postscript using macro-expansion and a very abbreviated set of turtle commands. For some examples in python and mathematica, see my code golf challenge.
There is a great book called Chaos and Fractals that has simple example code at the end of each chapter that implements some fractal or other example. A long time ago when I read that book, I converted each sample program (in some Basic dialect) into a Java applet that runs on a web page. The applets are here: http://hewgill.com/chaos-and-fractals/
One of the samples is a simple Mandelbrot implementation.
Another excellent fractal to learn is the Sierpinski Triangle Fractal.
Basically, draw three corners of a triangle (an equilateral is preferred, but any triangle will work), then start a point P at one of those corners. Move P halfway to any of the 3 corners at random, and draw a point there. Again move P halfway towards any random corner, draw, and repeat.
You'd think the random motion would create a random result, but it really doesn't.
Reference: http://en.wikipedia.org/wiki/Sierpinski_triangle
The Sierpinski triangle and the Koch curve are special types of flame fractals. Flame fractals are a very generalized type of Iterated function system, since it uses non-linear functions.
An algorithm for IFS:es are as follows:
Start with a random point.
Repeat the following many times (a million at least, depending on final image size):
Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5.
Plot the new point on the screen.
If the point is outside the screen, choose randomly a new one inside the screen instead.
If you want nice colors, let the color depend on the last used transformation.
I would start with something simple, like a Koch Snowflake. It's a simple process of taking a line and transforming it, then repeating the process recursively until it looks neat-o.
Something super simple like taking 2 points (a line) and adding a 3rd point (making a corner), then repeating on each new section that's created.
fractal(p0, p1){
Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
fractal(p0,Pmid);
fractal(Pmid, p1);
}
I think you might not see fractals as an algorithm or something to program. Fractals is a concept! It is a mathematical concept of detailed pattern repeating itself.
Therefore you can create a fractal in many ways, using different approaches, as shown in the image below.
Choose an approach and then investigate how to implement it. These four examples were implemented using Marvin Framework. The source codes are available here
Here is a codepen that I wrote for the Mandelbrot fractal using plain javascript and HTML.
Hopefully it is easy to understand the code.
The most complicated part is scale and translate the coordinate systems. Also complicated is making the rainbow palette.
function mandel(x,y) {
var a=0; var b=0;
for (i = 0; i<250; ++i) {
// Complex z = z^2 + c
var t = a*a - b*b;
b = 2*a*b;
a = t;
a = a + x;
b = b + y;
var m = a*a + b*b;
if (m > 10) return i;
}
return 250;
}
The mandelbrot set is generated by repeatedly evaluating a function until it overflows (some defined limit), then checking how long it took you to overflow.
Pseudocode:
MAX_COUNT = 64 // if we haven't escaped to infinity after 64 iterations,
// then we're inside the mandelbrot set!!!
foreach (x-pixel)
foreach (y-pixel)
calculate x,y as mathematical coordinates from your pixel coordinates
value = (x, y)
count = 0
while value.absolutevalue < 1 billion and count < MAX_COUNT
value = value * value + (x, y)
count = count + 1
// the following should really be one statement, but I split it for clarity
if count == MAX_COUNT
pixel_at (x-pixel, y-pixel) = BLACK
else
pixel_at (x-pixel, y-pixel) = colors[count] // some color map.
Notes:
value is a complex number. a complex number (a+bi) is squared to give (aa-b*b+2*abi). You'll have to use a complex type, or include that calculation in your loop.
Sometimes I program fractals for fun and as a challenge. You can find them here. The code is written in Javascript using the P5.js library and can be read directly from the HTML source code.
For those I have seen the algorithms are quite simple, just find the core element and then repeat it over and over. I do it with recursive functions, but can be done differently.
People above are using finding midpoints for sierpinski and Koch, I'd much more recommend copying shapes, scaling them, and then translating them to achieve the "fractal" effect.
Pseudo-code in Java for sierpinski would look something like this:
public ShapeObject transform(ShapeObject originalCurve)
{
Make a copy of the original curve
Scale x and y to half of the original
make a copy of the copied shape, and translate it to the right so it touches the first copied shape
make a third shape that is a copy of the first copy, and translate it halfway between the first and second shape,and translate it up
Group the 3 new shapes into one
return the new shape
}

Resources