plot surface of cusp catastrophe (with gnuplot) - plot

Is it possible to plot the surface of the Cusp Catastrophe with Gnuplot? Here's a comparable plot.
The catastrophe is mathematically described by: V = x^4 + a*x^2 + b*x (Wikipedia, see above)
The surface is describes by: 0 = a + b*y – y^3
I'm a gnu plot beginner, so I'd be really grateful for an example with source code.
(I study psychology and I need this plot for an essay about a clinical theory: the cusp catastrophe is used to describe changes of mood, that seem to appear more sudden and disruptive for depressive patients, compared to healthy persons.)

I think the best way would be to generate a table of roots of the equation (outside of gnuplot) and then plot the table with splot. But you can get an approximation to what you want in gnuplot by trying
a=b=1
set para
set iso 30
set pm3d at s
set urange [-10:10]
set hidd
set view 47,192
splot a + u*v - b * v**3, u, v

Related

Determining when there is a decrease in the rate of change

I have created plots of heart rate recovery against time, using ggplot2.
I have noticed them seem to have an inflection point where the heart rate levels off. I was looking to ask if there is a way of determining this inflection point for each subject, using R studio instead of doing it manually myself?
This is the script for plots:
ggplot(data = f, aes(x=Seconds, y=Heart.Rate, group=ID, colour=ID + geom_point() + geom_line()
You should write a script to calculate the change in Y divided by change in X. This is basically derivative of y wrt x. In a distance versus time curve this gives you velocity. Often a sudden change will create an easily discernable peak or inflection in the derivative curve. This should be simple to calculate as well. It's just the difference in 2 consecutive y points divided by the difference in their corresponding x values. You can then plot this new curve and see what it looks like. You will have to start at point 2 since there is no earlier value for point 1.

drawing the graph of a function f(x) = x^3 - 6x^2 + 9x - 4 in d3.js

I am back at college learning maths and I want to try and use some this knowledge to create some svg with d3.js.
If I have a function f(x) = x^3 - 3x^2 + 3x - 1
I would take the following steps:
Find the x intercepts for when y = 0
Find the y intercept when x = 0
Find the stationary points when dy\dx = 0
I would then have 2 x values from point 3 to plug into the original equation.
I would then draw a nature table do judge the flow of the graph or curve.
Plot the known points from the above and sketch the graph.
Translating what I would do on pen and paper into code instructions is what I really could do with any sort of advice on the following:
How can I programmatically factorise point 1 of the above to find the x-intercepts for when y = 0. I honestly do not know where to even start.
How would I programmatically find dy/dx and the values for the stationary points.
If I actually get this far then what should I use in d3 to join the points on the graph.
Your other "steps" have nothing to do with d3 or plotting.
Find the x intercepts for when y = 0
This is root finding. Look for algorithms to help with this.
Find the y intercept when x = 0
Easy: substitute to get y = 1.
Find the stationary points when dy\dx = 0
Take the first derivative to get 3x^2 - 12x + 9 and repeat the root finding step. Easy to get using quadratic equation.
I would then have 2 x values from point 3 to plug into the original
equation. I would then draw a nature table do judge the flow of the
graph or curve. Plot the known points from the above and sketch the
graph.
I would just draw the curve. Pick a range for x and go.
It's great to learn d3. You'll end up with something like this:
https://maurizzzio.github.io/function-plot/
For a cubic polynomial, there are closed formulas available to find all the particular points that you want (https://en.wikipedia.org/wiki/Cubic_function), and it is a sound approach to determine them.
Anyway, you will have to plot the smooth curve, which means that you will need to compute close enough points and draw a polyline that joins them.
Doing this, you are actually performing the first steps of numerical root isolation, with such an accuracy that the approximate and exact roots will be practically undistinguishable.
So an easy combined solution is to draw the curve as a polyline and find the intersections with the X axis as well as extrema using this polyline representation, rather than by means of more sophisticated methods.
This approach works for any continuous curve and is very easy to implement. So you actually draw the curve to find particular points rather than conversely as is done by analytical methods.
For best results on complicated curves, you can adapt the point density based on the local curvature, but this is another story.

Generating rolling hills of different height and width like Tiny Wings?

How can I generate rolling hills of different height and width like Tiny Wings? Right now I'm using sin() but it obviously generates uniform hills repeating forever and ever.
What's the secret?
Thanks!
Certainly not a procedural generation expert - but you could try additively combining multiple randomly generate sin/cos functions with different periods. The more you add, the more random seeming it will be.
Something like this.
Simplex noise, or any other 2d noise function that looks the way you like.
If you're set on accomplishing this with sine waves to create this variation, here's a basic overview of how to manipulate the sine function:
Say you have an x axis, a y axis, and a sine wave y = sin(x)
y = sin(x * 0.5) makes the sine wave cross the x axis half as often (frequency)
y = 0.5 * sin(x) makes the sine wave reach a height half as high (amplitude)
y = 0.5 + sin(x) moves the central axis of the sine wave up the y axis by 0.5 (translation / offset)
Using these three properties, you can construct a wide variety of different looking waves.
Now, the trick is you'll have to overlay these waves to create variation over time. An easy way to do this is to just add the waves together,
y = sin(x * 0.5) + 0.5 * sin(x) + (0.5 + sin(x))
Or, you could define different waves over a specific subset of the x axis, and create a piecewise function. This may be more controllable / art-directable:
y = {
sin(x * 0.5) for x in (0, 5],
0.5 * sin(x) for x in (5, 10],
0.5 + sin(x) for x in (10, 5] }
However, f you try this, you'll notice this produces discontinuities in your wave. You should investigate different blending options (look up linear blending first) to see if you can create smooth transitions between these piecewise functions.
BUT, in my opinion, you should also investigate spline curves and see if they would accomplish what you want. Splines are well documented part of graphics and game programming, so it would be easy to implement (or grab someone else's code), and might provide a more intuitive way to author your levels (Generate a random set of points representing knots/control points, and pass a spline through it).

Conversion between RGB and RYB color spaces

I am currently trying to convert colours between RGB (red, green, blue) colour space and RYB (red, yellow, blue) colour space and back again.
Based on the details in the following paper, I am able to convert from RYB to RGB using trilinear interpolation - where the parametric weightings (s, t, u) are the RYB colors, and the vertices of the cube are 3d points in RGB space.
Paint Inspired Color Mixing and Compositing for Visualisation - Gossett and Chen - Section 2.1 - Realization Details
My difficulties are in reversing the conversion process.
A second paper references the use of this technique and also indicates that the reverse conversion was achieved using Newton's Method. But provides no further details. This would probably indicate root finding in solving the trilinear interpolation equations.
On the Transfer of Painting Style to Photographic Images through Attention to Colour Contrast - Xiaoyan Zhang; Constable, M.; Ying He;
Before I expand on this question with the equations, has anybody seen, or solved this in a language such as Java/C/C++/C#?
My current approach is to take the forward equations of the trilinear interpolation (RYB to RGB), expand and rearrange to provide 3 simultaneous equations for 3 unknowns (the parametric weightings: s, t, and u) then work out how to find the roots using the Newton-Raphson method. Am I going about this in the right way?
I managed to solve it in the end.
Take the equations for a trilinear interpolation:
wikipedia
Edit: Wikipedia revision at the time
Substitute the first equations into the last, the expand and collect the coefficients for:
Xd, Yd, Zd, XdYd, XdZd, YdZd, ZdYdZd and the constant.
Then find the partial differentiation of the equation in each of the 3 dimensions each in respect to Xd, Yd and Zd. Use these new equations to populate the (3x3) Jacobian matrix and then use Newton's method to solve in software.
Newton-Raphson Method
I found this JavaScript implementation of RYB->RGB conversion based on cubic splines. Here is my Lua port (all values lie in the interval 0-1):
local ryb2rgb = function( R, Y, B )
local R, Y, B = R*R*(3-R-R), Y*Y*(3-Y-Y), B*B*(3-B-B)
return 1.0 + B * ( R * (0.337 + Y * -0.137) + (-0.837 + Y * -0.163) ),
1.0 + B * ( -0.627 + Y * 0.287) + R * (-1.0 + Y * (0.5 + B * -0.693) - B * (-0.627) ),
1.0 + B * (-0.4 + Y * 0.6) - Y + R * ( -1.0 + B * (0.9 + Y * -1.1) + Y )
end
Here is a category on UIColor that does the same thing, returning elements between RGB, RYB, and CMYK. Further, you can mix any number of colors in the respective color space (they mix differently, of course, depending).
https://github.com/ddelruss/UIColor-Mixing

Cubic spline extrapolation

I have a nice cubic spline code but it is for interpolation only. I need to extrapolate just a little into the future. Does anyone know of a good source of code, not a library, for doing this?
This is the code I wrote in basic (now ASM) for interpolation.
You don't need new code for that.
To extrapolate the spline you can extrapolate the parameters of the first and last spline.
Depending on your existing code/library that might not be possible without modifying the code. In that case just prepend/append two other points to the beginning/end of your list of points. You can get those two points by linearily interpolating between the first/last two points.
Be careful: Depending on the original meaning of the points that extrapolation might be completely inappropriate, especially when it comes to statistical data. In that case you should consider using regression analysis.
For simplicity, I'm going to represent a cubic Bezier curve
as 4 points (A, B, C, D),
where A and D are the endpoints of the curve,
and B and C are the "control handle points".
(The actual curve usually does not touch the control handle points).
See "Don Lancaster's Guru's Lair Cubic Spline Library"
for ways to convert this representation of a cubic Bezier curve
into other popular representations.
interpolation
Given one cubic Bezier curve (P0, P1, P2, P3),
we use De Casteljau's algorithm
to chop a Bezier curve into
a left half and a right half.
This is super-easy even on a microcontroller that doesn't have a "multiply" instruction,
because it only requires calculating a few averages until we get a midpoint:
P0
F0 := average(P0, P1)
P1 S0 := average(F0, F1)
F1 := average(P1, P2) Midpoint := average(S0, S1)
P2 S1 := average(F1, F2)
F2 := average(P2, P3)
P3
The entire Bezier curve is (P0, P1, P2, P3).
The left half of that entire Bezier curve is the Bezier curve (P0, F0, S0, M).
The right half of that entire Bezier curve is the Bezier curve (M, S1, F2, P3).
Many microcontrollers continue to divide each curve up
into smaller and smaller little curves
until each piece is small enough to approximate with
a straight line.
But we want to go the other way -- extrapolate out to a bigger curve.
extrapolation
Given either the left half or the right half,
we can run this in reverse to recover the original curve.
Let's imagine that we forgot the original points P1, P2, P3.
Given the left half of a Bezier curve (P0, F0, S0, M),
we can extrapolate to the right with:
S1 := M + (M - S0)
F1 := S0 + (S0 - F0)
P1 := F0 + (F0 - P0)
then use those values to calculate
F2 := S1 + (S1 - F1)
P2 := F1 + (F1 - P1)
and finally
P3 := F2 + (F2 - P2)
to extrapolate and recover the extrapolated Bazier curve (P0, P1, P2, P3).
details
The extrapolated curve (P0, P1, P2, P3)
passes through every point in the original curve
(P0, F0, S0, M) --
in particular, starting at P0 and passing through the midpoint M --
and keeps on going until it reaches P3.
We can always extrapolate from any 4 points (P0, F0, S0, M),
whether or not those 4 points were originally calculated
as the left half (or right half) of some larger Bezier spline.
I'm sure you already know this, but just for clarity:
Midpoint = average(F0, F1)
means "find the Midpoint exactly halfway between points F0 and F1",
or in other words,
Midpoint.x = (F0.x + F1.x)/2
Midpoint.y = (F0.y + F1.y)/2
Midpoint.z = (F0.z + F1.z)/2
The expression
S1 := M + (M - S0)
means "Given a line segment, with one end at S0, and the midpoint at M,
start at S0 and run in a straight line past M until you reach the other end at S1",
or in other words
(unless you have a decent vector library) 3 lines of code
S1.x := M.x + (M.x - S0.x)
S1.y := M.y + (M.y - S0.y)
S1.z := M.z + (M.z - S0.z)
.
(If you're doing 2D, skip all the "z" stuff -- it's always zero).
You'll really have to expand that question a little. Also, "cubic spline" is a very wide term.
If you're interested in splines, I can heartly reccomend Carl de Boors "A Practical Guide to Splines". It is however a little mathematically oriented, but it has code examples included (they can be downloaded from the author's home page). Googling and wikiing for "cubic spline" can bring up some examples, maybe even in particular languages - another thing to add to the question (if you're looking for code).
If you're interested in extrapolation and curve fitting, googling those could help. Matlab package has a very nice curve fitting toolbox. Wikipedia has some links to useful references
Really, it is too wide a question, to even start guessing an answer.
Also, could you explain what exactly are you trying to do ? What kind of data ? Anything ?
Edit1: Here, try this: you may find something useful in here - link
Generally for spline interpolation you use a variable t to interpolate over the line. As long as 0 <= t <= 1 you're interpolating. However, when t < 0 or t > 1 you're simply extrapolating the spline.
You need to write better requirements for requested code. Splines are usually used for interpolation of some unknown or complex function by using of some fixed data set. If you want to have an estimate of function's value outside of boundaries of this data set then you shouldn't use splines.
If your spline is function defined in the place where you really want to evaluate your value (cubic, but not piecewise-cubic) then you already can evaluate that value.
If you want to have ability to evaluate your spline outside of interpolation range, but leave it as piecewise-cubic function with the same values inside of interpolation range then you should extend spline range by some nodes, and add some logic of evaluation values at the new nodes (for example you want to have your spline be not only a continuous function, but also have some number of first derivatives be also continuous functions)
Really I suggest you to use some algorithm more suitable for extrapolation, like usage of Lagrange polynomial if everything you really need is single value not very far from points of original data set.

Resources