Mathematica - Plotting the output of a function created directly from solve - plot

I've got some fairly long matrix algebra that I am trying to plot the outcome of. Nothing seems to show up on the axes, and I can't quite tell where the problem is. I successfully created a function from the output of solve using the tips here:
How to create a function directly from the output of Solve
But it just won't plot!
Here (briefly) is the code:
eqn = m.{1, r} == {t, 0}
sols1 = Solve[eqn, {t, r}]
m is a complex matrix
Here is the output:
{{t -> -((-1. cos[9.62458 s]^2 - (1. + 0. I) sin[9.62458 s]^2)/(
cos[9.62458 s] - (0. + 2.4087 I) sin[9.62458 s])),
r -> ((0. + 2.1913 I) sin[9.62458 s])/(
cos[9.62458 s] - (0. + 2.4087 I) sin[9.62458 s])}}
So far so good (except that Mathematica seems to have trouble with the whole cos^2 + sin^2 = 1 thing).
Then I try to plot the real part of t as a function of s:
Plot[Re[t /. sols1], {s, 0, 0.4}]
And I just get empty axes.
I try assigning the output to a function and plotting that way
f[s_] = t /. sols1[[1, 1]]
Plot[Re[f[s]], {s, 0, 0.4}]
And I still get an empty axis. I transcribed the function in Matlab where it plots just fine, so I know the solution is sound. I have to solve this for several matrices m which just get hairier and hairier, so transcribing to Matlab is not ideal. I want to plot right in Mathematica.
Any ideas?

Try using mathematica syntax. I.e. Sin in place of sin; same for cos:
In[1]:= sols1={
{t->-((-1. cos[9.62458 s]^2-(1.+0. I) sin[9.62458 s]^2)/(cos[9.62458 s]-(0.+2.4087 I) sin[9.62458 s]))
,r->((0.+2.1913 I) sin[9.62458 s])/(cos[9.62458 s]-(0.+2.4087 I) sin[9.62458 s])}
}/.{cos->Cos,sin->Sin}//FullSimplify//Chop
Out[1]= {{t->1./(Cos[9.62458 s]-(0. +2.4087 I) Sin[9.62458 s]),r->1/(-1.09921-(0. +0.45635 I) Cot[9.62458 s])}}
then e.g.
GraphicsColumn[Plot[t /. sols1 // #, {s, 0, .4}, PlotLabel -> #[t], Frame -> True] & /# {Re, Im, Abs[#]^2 &}]
should work well.

Related

Unable to plot solution of ODE in Maxima

Good time of the day!
Here is the code:
eq:'diff(x,t)=(exp(cos(t))-1)*x;
ode2(eq,x,t);
sol:ic1(%,t=1,x=-1);
/*---------------------*/
plot2d(
rhs(sol),
[t,-4*%pi, 4*%pi],
[y,-5,5],
[xtics,-4*%pi, 1*%pi, 4*%pi],
[ytics, false],
/*[yx_ratio , 0.6], */
[legend,"Solution."],
[xlabel, "t"], [ylabel, "x(t)"],
[style, [lines,1]],
[color, blue]
);
and here is the errors:
integrate: variable must not be a number; found: -12.56637061435917
What went wrong?
Thanks.
Here's a way to plot the solution sol which was found by ode2 and ic2 as you showed. First replace the integrate nouns with calls to quad_qags, a numerical quadrature function. I'll introduce a made-up variable name (a so-called gensym) to avoid confusion with the variable t.
(%i59) subst (nounify (integrate) =
lambda ([e, xx],
block ([u: gensym(string(xx))],
quad_qags (subst (xx = u, e), u, -4*%pi, xx)[1])),
rhs(sol));
(%o59) -%e^((-t)-quad_qags(%e^cos(t88373),t88373,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]
+quad_qags(%e^cos(t88336),t88336,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]+1)
Now I'll define a function foo1 with that result. I'll make a list of numerical values to see if it works right.
(%i60) foo1(t) := ''%;
(%o60) foo1(t):=-%e
^((-t)-quad_qags(%e^cos(t88373),t88373,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]
+quad_qags(%e^cos(t88336),t88336,-4*%pi,t,
epsrel = 1.0E-8,epsabs = 0.0,
limit = 200)[
1]+1)
(%i61) foo1(0.5);
(%o61) -1.648721270700128
(%i62) makelist (foo1(t), t, makelist (k, k, -10, 10));
(%o62) [-59874.14171519782,-22026.46579480672,
-8103.083927575384,-2980.957987041728,
-1096.633158428459,-403.4287934927351,
-148.4131591025766,-54.59815003314424,
-20.08553692318767,-7.38905609893065,-2.71828182845904,
-1.0,-0.3678794411714423,-0.1353352832366127,
-0.04978706836786394,-0.01831563888873418,
-0.006737946999085467,-0.002478752176666358,
-9.118819655545163E-4,-3.354626279025119E-4,
-1.234098040866796E-4]
Does %o62 look right to you? I'll assume it is okay. Next I'll define a function foo which calls foo1 defined before when the argument is a number, otherwise it just returns 0. This is a workaround for a bug in plot2d, which incorrectly determines that foo1 is not a function of t alone. Usually that workaround isn't needed, but it is needed in this case.
(%i63) foo(t) := if numberp(t) then foo1(t) else 0;
(%o63) foo(t):=if numberp(t) then foo1(t) else 0
Okay, now the function foo can be plotted!
(%i64) plot2d (foo, [t, -4*%pi, 4*%pi], [y, -5, 5]);
plot2d: some values were clipped.
(%o64) false
That takes about 30 seconds to plot -- calling quad_qags is relatively expensive.
it looks like ode2 does not know how to completely solve the problem, so the result contains an integral:
(%i6) display2d: false $
(%i7) eq:'diff(x,t)=(exp(cos(t))-1)*x;
(%o7) 'diff(x,t,1) = (%e^cos(t)-1)*x
(%i8) ode2(eq,x,t);
(%o8) x = %c*%e^('integrate(%e^cos(t),t)-t)
(%i9) sol:ic1(%,t=1,x=-1);
(%o9) x = -%e^((-%at('integrate(%e^cos(t),t),t = 1))
+'integrate(%e^cos(t),t)-t+1)
I tried it with contrib_ode also:
(%i12) load (contrib_ode);
(%o12) "/Users/dodier/tmp/maxima-code/share/contrib/diffequations/contrib_ode.mac"
(%i13) contrib_ode (eq, x, t);
(%o13) [x = %c*%e^('integrate(%e^cos(t),t)-t)]
So contrib_ode did not solve it completely either.
However the solution returned by ode2 (same for contrib_ode) appears to be a valid solution. I'll post a separate answer describing how to evaluate it numerically for plotting.

Second order delay differential equation in Julia

I'm new to Julia programming I managed to solve some 1st order DDE (Delay Differential Equations) and ODE. I now need to solve a second order delay differential equation but I didn't manage to find documentation about that (I previously used DifferentialEquations.jl).
The equation (where F is a function and τ the delay):
How can I do this?
Here is my code using the given information, it seems that the system stay at rest which is incorrect. I probably did something wrong.
function bc_model(du,u,h,p,t)
# [ u'(t), u''(t) ] = [ u[1], -u[1] + F(ud[0],u[0]) ] // off by one in julia A[0] -> A[1]
γ,σ,Q = p
ud = h(p, t-σ)[1]
du = [u[2], + Q^2*(γ/Q*tanh(ud)-u[1]) - u[2]]
end
u0 = [0.1, 0]
h(p, t) = u0
lags = [σ,0]
tspan = (0.0,σ*100.0)
alg = MethodOfSteps(Tsit5())
p = (γ,σ,Q,ω0)
prob = DDEProblem(bc_model,u0,h,tspan,p; constant_lags=lags)
sol = solve(prob,alg)
plot(sol)
The code is in fact working! It seems that it is my normalization constants that are not consistent. Thank you!
You get a state space of dimension 2, containing u = [u(t),u'(t)]. Consequently the return vector of the right-side function is [u'(t),u''(t)]. Then if ud is the delayed state [u(t-τ),u'(t-τ)] the right side function can be formulated as
[ u'(t), u''(t) ] = [ u[1], -u[1] + F(ud[0],u[0]) ]

Making a Star Triangle in SML

I have just started coding in SMLNJ and have been having some trouble making a program that returns a string in a triangular star pattern. For example triangle(5) should output:
*****
****
***
**
*
My code so far is:
fun triangle(x) =
if (x = 0) then "\n"
else
let
fun makeTriangle(n) =
if(n = 0) then "\n" else "*"^makeTriangle(n-1);
in
makeTriangle(x);
end
triangle(x-1)
I am getting the error "triangle.sml:9.3 Error: syntax error: inserting EQUALOP". Any help would be appreciated.
There are at least two issues with your code:
First, there is a simple operator precedence issue:
if(n = 0) then "\n" else "*"^makeTriangle(n-1)
parses as
(if(n = 0) then "\n" else "*") ^ makeTriangle(n-1)
rather than your intended
if(n = 0) then "\n" else ("*" ^ makeTriangle(n-1))
The solution is to put in the needed parentheses.
Another issue is the stray line triangle(x-1) at the bottom of the function. It is unrelated to the code above it. If your intention is to concatenate it to the result of the function call makeTriangle(x) then you would need to do the explicit concatenation. There really shouldn't be anything in your function definition after the end since that end terminates the else part.
A minor issue: since your function makeTriangle inserts "\n", your code (after fixed) will have two "\n" at the bottom of the triangle. If that isn't what you want, perhaps you can think about the basis case (n=0).
Since John already explained some of the issues with your code, and since this seems like an exercise, here are two ways you could solve it differently:
Recursively, using pattern matching:
fun repeat (0, _) = []
| repeat (n, x) = x :: repeat (n-1, x)
fun triangle 0 = ""
| triangle n = implode (repeat (n, #"*")) ^ "\n" ^ triangle (n-1)
There's a library function called List.tabulate of which repeat is a special case:
fun repeat (n, x) = List.tabulate (n, fn _ => x)
But actually, triangle itself fits pretty well within List.tabulate:
fun triangle n =
concat (List.tabulate (n, fn i => implode (repeat (15 - i, #"*")) ^ "\n"))

Why do i get this error - MATLAB

I have the image and the vector
a = imread('Lena.tiff');
v = [0,2,5,8,10,12,15,20,25];
and this M-file
function y = Funks(I, gama, c)
[m n] = size(I);
for i=1:m
for j=1:n
J(i, j) = (I(i, j) ^ gama) * c;
end
end
y = J;
imshow(y);
when I'm trying to do this:
f = Funks(a,v,2)
I am getting this error:
??? Error using ==> mpower
Integers can only be combined with integers of the same class, or scalar doubles.
Error in ==> Funks at 5
J(i, j) = (I(i, j) ^ gama) * c;
Can anybody help me, with this please?
The error is caused because you're trying to raise a number to a vector power. Translated (i.e. replacing formal arguments with actual arguments in the function call), it would be something like:
J(i, j) = (a(i, j) ^ [0,2,5,8,10,12,15,20,25]) * 2
Element-wise power .^ won't work either, because you'll try to "stuck" a vector into a scalar container.
Later edit: If you want to apply each gamma to your image, maybe this loop is more intuitive (though not the most efficient):
a = imread('Lena.tiff'); % Pics or GTFO
v = [0,2,5,8,10,12,15,20,25]; % Gamma (ar)ray -- this will burn any picture
f = cell(1, numel(v)); % Prepare container for your results
for k=1:numel(v)
f{k} = Funks(a, v(k), 2); % Save result from your function
end;
% (Afterwards you use cell array f for further processing)
Or you may take a look at the other (more efficient if maybe not clearer) solutions posted here.
Later(er?) edit: If your tiff file is CYMK, then the result of imread is a MxNx4 color matrix, which must be handled differently than usual (because it 3-dimensional).
There are two ways I would follow:
1) arrayfun
results = arrayfun(#(i) I(:).^gama(i)*c,1:numel(gama),'UniformOutput',false);
J = cellfun(#(x) reshape(x,size(I)),results,'UniformOutput',false);
2) bsxfun
results = bsxfun(#power,I(:),gama)*c;
results = num2cell(results,1);
J = cellfun(#(x) reshape(x,size(I)),results,'UniformOutput',false);
What you're trying to do makes no sense mathematically. You're trying to assign a vector to a number. Your problem is not the MATLAB programming, it's in the definition of what you're trying to do.
If you're trying to produce several images J, each of which corresponds to a certain gamma applied to the image, you should do it as follows:
function J = Funks(I, gama, c)
[m n] = size(I);
% get the number of images to produce
k = length(gama);
% Pre-allocate the output
J = zeros(m,n,k);
for i=1:m
for j=1:n
J(i, j, :) = (I(i, j) .^ gama) * c;
end
end
In the end you will get images J(:,:,1), J(:,:,2), etc.
If this is not what you want to do, then figure out your equations first.

"$" symbol in mathematica output

I am having some slight difficulty with the following code:
Lagrange[list_] :=
Module[{points = list, length, k, j, m, x, g},
length = Length[points];
k = length - 1;
f = Sum[points[[j + 1,2]]*Product[If[j != m, (x - points[[m + 1,1]])/
(points[[j + 1,1]] - points[[m + 1,1]]), 1], {m, 0, k}], {j, 0, k}];
g = FullSimplify[Expand[f]];
Return[f]]
The output I get is:
Out[101]= 0. -1.85698 (-1.5+x$26810) (-0.75+x$26810) (0. +x$26810) (0.75+x$26810)
+0.490717 (-1.5+x$26810) (-0.75+x$26810) (0. +x$26810) (1.5 +x$26810)
-0.490717 (-1.5+x$26810) (0. +x$26810) (0.75 +x$26810) (1.5 +x$26810)
+1.85698 (-0.75+x$26810) (0. +x$26810) (0.75 +x$26810) (1.5 +x$26810)
My concern is with these "$" symbols. I don't know what they mean, I can't find documentation on them, and they are preventing the plotting of this polynomial.
The $ in your output is from the unique variable generated by the lexical scoping of Module (see the More Information part of mathematica/ref/Module). This is why I made my LagrangePoly function accept the symbol that the polynomial is meant to be in. I used LagrangePoly[list_, var_:x], which defaults to the global symbol x.
A simple example of the problem is
In[1]:= Module[{x}, x]
Out[1]= x$583
The number in the "local" variable x$nnn comes from the global $ModuleNumber.
If you don't understand this, then you should probably read the tutorial Blocks Compared with Modules.
In your code, x is a local variable. However you are returning an expression containing x. The purpose of localized variables is that they shouldn't appear outside their context, which is the Module in this case.
Consider this simple example:
adder[x_] := Module[{y}, Return[x + y]]
adder[2] gives: 2 + y$1048
A good practice is to recognize that our function adder should actually itself return a function.
adder[x_] := Function[{y}, x + y]
twoAdder = adder[2];
twoAdder[3] gives: 5

Resources