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.
While trying to make a program for hidden markov models, I did the simplest assumption for the initial HMM of the Baum-Welch algorithm : put everything as a uniform distribution. That is,
A[i][j] = 1/statenumber;
B[i][j] = 1/observationnumber;
P[i] = 1/statenumber;
up to a logarithm to avoid underflowing. It has the benefit of not requiring to check for normalization.
But so far, I've run into the algorithm not actually doing much. The emission matrix changes at the first iteration, but not after that, and the transition matrix and initialization vector do not evolve at all. It seems to be that the gamma matrix does not change at all.
At first I thought it was my algorithm not working out too well, but after trying it on some other HMM libraries, I seem get the same type of results.
Is it impossible to converge to the correct HMM using such an initialization, and what is the ideal method to initialize those arrays?
The Baum Welch algorithm won't work with a uniform initial distribution -- the updates will be degenerate. Try to randomize it instead.
I would like to interpolate a 3D scalar function f(x, y, z). I have coded up a 3D linear interpolation algorithm (http://en.wikipedia.org/wiki/Trilinear_interpolation). This was not so bad.
However, I would like something more sophisticated, e.g. 3D cubic splines. Are there any open source, easy-to-use, publicly available code for interpolating a 3D scalar? I would prefer to use C, but Fortran would be OK as well. I would like to stay away from Matlab.
I have seen similar questions asked here:
Interpolating a scalar field in a 3D space
and
What are some good libraries for 3D interpolation?
The second one was OK with Matlab, which I am not.
As for the first one, the main suggestion was Shepard's method. I am curious how accurate Shepard's method is. For instance, in the case of a uniform grid, one can apply Shepard's method only to nearby grid points, and in that case does it tend to be more accurate than linear interpolation or cubic splines? I imagine not, but wasn't 100% sure, and if in fact it is not better, then I would prefer to find code using something like splines if any such codes are available.
Take a look at Geometric Tools for Interpolation:
templated C++ for tricubic, uniform B-splines, and much more.
(einspline, a C library for B-splines in 1d 2d 3d,
seems to be dormant in 2013; the author doesn't answer emails.
Also, it's C; C++ templates would reduce code bloat for interpolating
floats, colors, vecs ...)
I haven't used either of these.
On Inverse distance weighting
a.k.a. Shepard's method, you can take any number of neighbors: in 3d, 2^3 or 3^3 or 4^3 ...
A general problem is "sagging" — see the plot in the link.
"Accuracy" of any interpolation method is really hard to measure: what's "golden",
for what class of data / what noise ?
And you have two measures, error at the data and smoothness, to trade off
— for
photo enlargement
three:
aliasing, blurring and edge halos.
There's some theory on spline interpolation of band-limited functions, but afaik none at all for IDW.
Added:
What about the
bullseye effect ?
IDW is a terrible choice in almost every case.
It assumes that all of your input data points are local minimums or maximums!
Well, IDW can have peaks above nearby data points, if there are high peaks far away.
For example in 1d,
IDW( [0 0] [1 0] [2 y] ) = y/7 at x = 1/2.
But IDW weights ~ 1 / distance may be too spiky, fall off too fast, for some tasks.
Interpolation methods and kernels have to be chosen to fit specific data and noise — an art.
The bspline-fortran library does 2d-6d b-spline interpolation for data on a regular grid. It is written in modern Fortran (there is a basic subroutine interface and also an object-oriented interface).
vspline is a FOSS C++ template library for b-spline processing. It's dimension-agnostic, so you can use it for 3D data. It's focus is on efficiently processing large raster data sets with multithreaded SIMD code. If you're concerned about precision, it can use long doubles for calculations and has extremely precise precomputed constants for maximum fidelity.
I am looking to implement a resampling algorithm for a 2D array(it could be grayscale image or some 2D array of floating point values).
The steps involved in this particular operation are:
Given a 2D array, I first downsample it to size of 8x8 or 16x16, using some down-sampling method(preferably with a preceeding anti-aliasing filtering).
Some nuemrical operation on this.
Then upsample it back to its original size by doing, bilinear interpolation.
As a prototype I coded it as shown below in Octave. It gives decent results. I am looking to get some reference on C implementation.
fid = fopen("anti_vig_gain_map.txt","r");
fid2 = fopen("ds_us_anti_vig_gain_map.txt","w");
for i=1:1968
for j=1:2592
map(i,j) = fscanf(fid,'%f\n',1);
end
end
%downsample
ds_map = imresize(map,[8 8],'linear');
%% some processing on ds_map
%upsample
us_map = imresize(ds_map,[1968 2592],'linear');
I tried to see the code in imresize.m but it gets complicated after sometime and could not extract C code out of it.
Any pointers to reference C code for bilinear interpolation to perform the upsampling.
Also looking to get some pointers for the the anti-aliasing filter and down-sampling method using bilinear method.
I think what you are looking for is contained in the NetPBM suite. Specifically, pamscale which handles both up and down sampling with multiple possible filtering schemes for both directions. The code is both well-written and self-contained.
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
}