How do I write an Euler function in Mathematica? - math

I programmed a Euler function but misread the instructions, so now I have to make a new one, but I can't figure it out.
I have made the following automatic Euler function.
f[x_, y_] := -x y^2;
x0 = 0;
y0 = 2;
xend = 2;
steps = 20;
h = (xend - x0)/steps // N;
x = x0;
y = y0;
eulerlist = {{x, y}};
For[i = 1, i <= steps, y = f[x, y]*h + y;
x = x + h;
eulerlist = Append[eulerlist, {x, y}];
i++
]
Print[eulerlist]
But it just generates the list I have specified.
I would like to have a Euler function which is able to generate this form:
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
I don't seem to get any further.

It is not clear what you are asking, but if what you want is to be able to input
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
and get
{{0,2},{0.1,2.},{0.2,1.96},{0.3,1.88317},{0.4,1.77678},{0.5,1.6505},{0.6,1.51429},{0.7,1.37671},{0.8,1.24404},{0.9,1.12023},{1.,1.00728},{1.1,0.905822},{1.2,0.815565},{1.3,0.735748},{1.4,0.665376},{1.5,0.603394},{1.6,0.548781},{1.7,0.500596},{1.8,0.457994},{1.9,0.420238},{2.,0.386684}}
Then you need to write a function definition like this:
Euler[y0_, f_, {x0_, xend_}, steps_Integer?Positive] := (* body *)
Notice the underscores to denote patterns, the := to denote delayed evaluation and the pattern specification Integer?Positive.
As for the body of the function -- oh my goodness could you have picked a less Mathematica-style approach? Perhaps not. Procedural loops and Append are almost never the best way to do anything in Mathematica.
Here is a better solution.
Euler[y_, y0_, f_, {x_, x0_, xend_}, steps_Integer?Positive] :=
With[{h = N[(xend - x0)/steps], ff = Function[{x, y}, f]},
NestList[{#[[1]] + h, ff[#[[1]], #[[2]]]*h + #[[2]]} &, {x0, y0},
steps]]
Euler[y, 2, -x y^2, {x, 0, 2}, 20]
{{0, 2}, {0.1, 2.}, {0.2, 1.96}, {0.3, 1.88317}, {0.4,
1.77678}, {0.5, 1.6505}, {0.6, 1.51429}, {0.7, 1.37671}, {0.8,
1.24404}, {0.9, 1.12023}, {1., 1.00728}, {1.1, 0.905822}, {1.2,
0.815565}, {1.3, 0.735748}, {1.4, 0.665376}, {1.5, 0.603394}, {1.6,
0.548781}, {1.7, 0.500596}, {1.8, 0.457994}, {1.9, 0.420238}, {2.,
0.386684}}
If you want something that outputs Euler[y, 2, -x y^2, {x, 0, 2}, 20], then typing it into the notebook is the quickest method.

Related

No output on ParametricPlot

I'm solving and plotting the equations of motion for the double pendulum using Mathematica's NDSolve.
I've successfully plotted the Angular position using a standard plot. But when I come to use the parametric plot for the position of each mass. I get no errors but simply no plot.
eqn1 = 2 th''[t] + Sin[th[t] - ph[t]] (ph'[t])^2 + Cos[th[t] - ph[t]] (ph''[t]) + (2 g/l) Sin[th[t]]
eqn2 = ph''[t] + Sin[th[t] - ph[t]] (th'[t])^2 + Cos[th[t] - ph[t]] (th''[t]) + (g/l) Sin[th[t]]
eqnA = eqn1 /. {g -> 10, l -> 1}
eqnB = eqn2 /. {g -> 10, l -> 1}
sol = NDSolve[{eqnA == 0, eqnB == 0, th[0] == 0.859, th'[0] == 0, ph[0] == 0.437, ph'[0] == 0}, {th, ph}, {t, 0, 10}]
Plot[{th[t], ph[t]} /. sol, {t, 0, 10}]
r1 = {lSin[th[t]] + lSin[ph[t]], -lCos[th[t]] - lCos[ph[t]]} /. {l -> 1, g -> 10}
ParametricPlot[r1 /. sol, {t, 0, 10}]
Replace
r1 = {lSin[th[t]] + lSin[ph[t]], -lCos[th[t]] - lCos[ph[t]]} /. {l->1, g->10}
with
r1 = {l*Sin[th[t]] + l*Sin[ph[t]], -l*Cos[th[t]] - l*Cos[ph[t]]} /. {l->1, g->10}
and your ParametricPlot should appear.
One useful trick you might remember, when any plot doesn't appear you can try replacing the plot with Table and see what it shows. Often the table of data provides the needed hint about why the plot isn't appearing.

How to calculate the convolution of a function with itself multiple times in Wolfram?

Excuse me I am new to Wolfram. I have seen people asking questions about how to do convolution of a function with itself in Wolfram. However, I wonder how to do it multiple times in a loop. That is to say I want to do f20* i.e. f*f*f*f*....f totaling 20 f. How to implement it?
Here is my thinking. Of course do not work....
f[x_] := Piecewise[{{0.1`, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g = f;
n = 19;
For[i = 1, i <= n, i++, g = Convolve[f[x], g, x, y]]; Plot[
g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Could anybody help me?
My new code after revising agentp's code
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0,x > 10}}];
n = 19;
res = NestList[Convolve[#, f[x], x, y] /. y -> x &, f[x], n];
Plot[res, {x, -10, (n + 1)*10 + 10}, PlotRange -> All,PlotPoints -> 1000]
My buggy image
maybe this?
Nest[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 3]
If that's not right maybe show what you get by hand for n=2 or 3.
res = NestList[ Convolve[#, f[x], x, y] /. y -> x &, f[x] , 10];
Plot[res, {x, 0, 100}, PlotRange -> All]
this gets very slow with n, I don't have the patience to run it out to 20.
Your approach is nearly working. You just have to
make sure to copy f by value before entering the loop, because otherwise you face infinite recursion.
Assign the result of Convolve to a function which takes a parameter.
This is the code with the mentioned changes:
f[x_] := Piecewise[{{0.1, x >= 0 && x <= 10}, {0, x < 0}, {0, x > 10}}];
g[x_] = f[x];
n = 20;
For[i = 1, i <= n, i++, g[y_] = Convolve[f[x], g[x], x, y]];
Plot[g[x], {x, -10, n*10 + 10}, PlotRange -> All]
Edit: While this works, agentp's answer is more consise and i suspect also faster.

Mathematica: Unusual piecewise plot issue

Hello and thanks in advance,
I came upon an issue trying to plot a piecewise function in Mathematica. When entered directly into the Plot function, the piecewise did NOT plot. However, when I defined the piecewise as a variable, it did plot. Why is this issue occurring and can I still join my plot? (I would like to join it by setting exclusions to none)
The following is my code: (I define a Maxwell strain function and am trying to model the plastic deformation of a polymer over multiple stress cycles)
z = 2*10^10;
h = 10^12;
MaxwellStrain[s_, t_] := s/z + (s*t)/h;
stress = {0, 10^7, -10^7, 5*10^6, 10^7, -5*10^6};
time = {0, 100, 200, 300, 400, 500};
strainList = Join[{0}, Table[MaxwellStrain[stress[[i + 1]], t - time[[i]]], {i, 1, 5}]];
Plot[
Piecewise[
Table[{
Total[strainList[[1 ;; i + 1]]], time[[i]] < t < time[[i + 1]]},
{i, 1, 5}
],
Exclusions -> none]
,
{t, 0, 500}
]
x = Piecewise[
Table[{
Total[strainList[[1 ;; i + 1]]], time[[i]] < t < time[[i + 1]]},
{i, 1, 5}
],
Exclusions -> none]
Plot[x, {t, 0, 500}]
The following is my output: (first plot doesn't show, the second does)
output:
Thank you for the help,
SV

Mathematica: Filling under an infinite function

Mathematica: Filling an infinitely deep potential well
Comment: The proper page for Mathematica questions is this one
I would like to visualize a potential well for a particle in a box in Mathematica similar to the second picture from Wikipedia here.
I have defined my function piecewise
(*Length of the box*)
L = 4;
(*Infinitly deep potential well between 0 and L*)
V[x_] := Piecewise[{
{\[Infinity], x <= 0},
{0, 0 < x < L},
{\[Infinity], L <= x}}]
and would like to obtain a plot function which gives a filled area where the potential goes to infinity.
Unfortunately my tries end up in shaded areas between the "zero region" of the potential, while I would like to have the shading in the infinity region.
Table[Plot[V[x], {x, -5, 10},
Filling -> f], {f, {Top, Bottom, Axis, 0.3}}]
The problem is that Infinity is too much for plot. So let's just give it some other big number. But to prevent it from rescaling the y axis we need to be specific with the upper plot range
Block[{\[Infinity] = 1*^1},
Plot[V[x], {x, -5, 10}, Filling -> Bottom,
PlotRange -> {Automatic, 1}]
]
Alternatively you could plot V[x]/.\[Infinity]->1*^1 instead of Block but I like Block's way better
Just give it values instead of infinity:
(*Length of the box*)L = 4;
(*Infinitly deep potential well between 0 and L*)
V[x_] := Piecewise[{{1, x <= 0}, {0, 0 < x < L}, {1, L <= x}}]
Plot[V[x], {x, -5, 10}, Filling -> Bottom]
Another way using graphic primitives:
wellLeft = 0;
leftBorder = wellLeft - 1;
rightBorder = L + 1;
wellRight = L;
top = 5;
Graphics[{
Hue[0.67, 0.6, 0.6],
Opacity[0.2],
Rectangle[{leftBorder, 0}, {wellLeft, top}],
Rectangle[{wellRight, 0}, {rightBorder, top}]
}, Axes -> True]

Problem with Euler angles from YZX Rotation Matrix

I've gotten stuck getting my euler angles out my rotation matrix.
My conventions are:
Left-handed (x right, z back, y up)
YZX
Left handed angle rotation
My rotation matrix is built up from Euler angles like (from my code):
var xRotationMatrix = $M([
[1, 0, 0, 0],
[0, cx, -sx, 0],
[0, sx, cx, 0],
[0, 0, 0, 1]
]);
var yRotationMatrix = $M([
[ cy, 0, sy, 0],
[ 0, 1, 0, 0],
[-sy, 0, cy, 0],
[ 0, 0, 0, 1]
]);
var zRotationMatrix = $M([
[cz, -sz, 0, 0],
[sz, cz, 0, 0],
[ 0, 0, 1, 0],
[ 0, 0, 0, 1]
]);
Which results in a final rotation matrix as:
R(YZX) = | cy.cz, -cy.sz.cx + sy.sx, cy.sz.sx + sy.cx, 0|
| sz, cz.cx, -cz.sx, 0|
|-sy.cz, sy.sz.cx + cy.sx, -sy.sz.sx + cy.cx, 0|
| 0, 0, 0, 1|
I'm calculating my euler angles back from this matrix using this code:
this.anglesFromMatrix = function(m) {
var y = 0, x = 0, z = 0;
if (m.e(2, 1) > 0.999) {
y = Math.atan2(m.e(1, 3), m.e(3, 3));
z = Math.PI / 2;
x = 0;
} else if (m.e(2, 1) < -0.999) {
y = Math.atan2(m.e(1, 3), m.e(3, 3));
z = -Math.PI / 2;
x = 0;
} else {
y = Math.atan2(-m.e(3, 1), -m.e(1, 1));
x = Math.atan2(-m.e(2, 3), m.e(2, 2));
z = Math.asin(m.e(2, 1));
}
return {theta: this.deg(x), phi: this.deg(y), psi: this.deg(z)};
};
I've done the maths backwards and forwards a few times, but I can't see what's wrong. Any help would hugely appreciated.
Your matrix and euler angles aren't consistent. It looks like you should be using
y = Math.atan2(-m.e(3, 1), m.e(1, 1));
instead of
y = Math.atan2(-m.e(3, 1), -m.e(1, 1));
for the general case (the else branch).
I said "looks like" because -- what language is this? I'm assuming you have the indexing correct for this language. Are you sure about atan2? There is no single convention for atan2. In some programming languages the sine term is the first argument, in others, the cosine term is the first argument.
The last and most important branch of the anglesFromMatrix function has a small sign error but otherwise works correctly. Use
y = Math.atan2(-m.e(3, 1), m.e(1, 1))
since only m.e(3, 1) of m.e(1, 1) = cy.cz and m.e(3, 1) = -sy.cz should be inverted. I haven't checked the other branches for errors.
Beware that since sz = m.e(2, 1) has two solutions, the angles (x, y, z) used to construct the matrix m might not be the same as the angles (rx, ry, rz) returned by anglesFromMatrix(m). Instead we can test that the matrix rm constructed from (rx, ry, rz) does indeed equal m.
I worked on this problem extensively to come up with the correct angles for a given matrix. The problem in the math comes from the inability to determine a precise value for the SIN since -SIN(x) = SIN(-x) and this will affect the other values of the matrix. The solution I came up with comes up with two equally valid solutions out of eight possible solutions. I used a standard Z . Y . X matrix form but it should be adaptable to any matrix. Start by findng the three angles from: X = atan(m32,m33): Y = -asin(m31) : Z = atan(m21,m11) : Then create angles X' = -sign(X)*PI+X : Y'= sign(Y)*PI-Y : Z = -sign(Z)*pi+Z . Using these angles create eight set of angle groups : XYZ : X'YZ : XYZ' : X'YZ' : X'Y'Z' : XY'Z' : X'Y'Z : XY'Z
Use these set to create the eight corresponding matrixes. Then do a sum of the difference between the unknown matrix and each matrix. This is a sum of each element of the unknown minus the same element of the test matrix. After doing this, two of the sums will be zero and those matrixes will represent the solution angles to the original matrix. This works for all possible angle combinations including 0's. As 0's are introduced, more of the eight test matrixes become valid. At 0,0,0 they all become idenity matrixes!
Hope this helps, it worked very well for my application.
Bruce
update
After finding problems with Y = -90 or 90 degrees in the solution above. I came up with this solution that seems to reproduce the matrix at all values!
X = if(or(m31=1,m31=-1),0,atan(m33+1e-24,m32))
Y = -asin(m31)
Z = if(or(m31=1,m31=-1),-atan2(m22,m12),atan2(m11+1e-24,m21))
I went the long way around to find this solution, but it wa very enlightening :o)
Hope this helps!
Bruce

Resources