Module caution: In 'Show' occurs where it is probably not going to be evaluated before going out of scope - plot

I have tried to make my own Manipulate module that draws numerical trajectories in 2D space depending on 1 parameter.
The problem is that I have this caution in title for every variable in Show.
I understand that it is related to some dynamic functionality, but I still don't know how to get rid of it.
Also, it will be great if I can get rid of the local variable name (k$8245) in output of this module.
MyManipulatePlot2D[list_, opts : OptionsPattern[]] :=
Module[{mv, pr, rt, constPlots, k},
{rt, mv, pr} = Dimensions[list];
constPlots = Table[ListPlot[list[[i,;;, 1 ;; 2]], opts], {i, rt}];
Manipulate[
Show[constPlots[[k]]], {k, 1, rt, 1}]
]
P.S. I don't want to take Manipulate out of the Module, because in my code this function is way more complex and it actually draws trajectories depending on 2 parameters.
Right here if someone is interested
MyManipulatePlot2D[list_, opts : OptionsPattern[]] :=
Module[{rt, mv1, pr, constPlots, k1, mv2, i, k2, pointsPlot},
{rt, mv1, mv2, pr} = Dimensions[list];
constPlots =
Table[ListPlot[
ArrayReshape[list[[;; , i, ;; , ;;]], {rt*mv2, pr}][[;; ,
1 ;; 2]], PlotStyle -> ColorData[97, "ColorList"][[2]],
opts], {i, mv1}];
pointsPlot = list[[;; , ;; , ;; , 1 ;; 2]];
pointsPlot = ArrayReshape[pointsPlot, {rt, mv1, mv2, 1, 2}];
Manipulate[
Show[{constPlots[[k1]],
ListPlot[pointsPlot[[;; , k1, k2]],
PlotLegends ->
Placed[ToString[{list[[1, k1, k2, 3]], list[[1, k1, k2, 4]]}],
Top]]}], {k1, 1, mv1, 1}, {k2, 1, mv2, 1}]
]
I have tried experementing with Evaluate funtion but it didn't work out.

You can fix the k$8245 problem by using Block instead of Module, or you can use a label "k" as below. k$8245 is the module's local variable name so it is showing as expected, even though not what you want. No other problems observed.
MyManipulatePlot2D[list_, opts : OptionsPattern[]] :=
Module[{mv, pr, rt, constPlots, k}, {rt, mv, pr} = Dimensions[list];
constPlots = Table[ListPlot[list[[i, ;; , 1 ;; 2]], opts], {i, rt}];
Manipulate[Show[constPlots[[k]]], {{k, 1, "k"}, 1, rt, 1}]]
The second manipulate just errors disasterously.

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.

Find number of successes from a list of terms/goals

I have written the following predicate exactly/2 that succeeds if exactly N of the numbers in the list L are equal to 1:
:- pred exactly(int, list(int)).
:- mode exactly(in, in) is semidet.
:- mode exactly(out, in) is det.
exactly(N, L) :-
length(filter(pred(X::in) is semidet :- (X = 1), L), N).
For example, the call exactly(X, [1, 0, 0, 1, 0, 1]) will bind X to 3.
I want to create something similar, but for predicates: I want to write a predicate that succeeds if exactly N goals from the list L are successful.
For example, the call exactly(X, [true, false, member(1, [1, 2, 3]), member(0, [1, 2, 3])]) should bind X to 2.
Actually, this can be done, as shown by this code:
:- module exactly.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module int.
:- import_module list.
main(!IO) :-
Test1 = list_member(1, [1, 2, 3]),
Test2 = list_member(0, [1, 2, 3]),
Tests = [Test1, Test2],
exactly(N, Tests),
io.write_line(N, !IO).
:- pred exactly(int::out, list((pred))::in(list_skel((pred) is semidet)))
is det.
exactly(0, []).
exactly(N, [Test | Tests]) :-
exactly(NTail, Tests),
( if Test then
N = NTail + 1
else
N = NTail
).
:- pred list_member(T::in, list(T)::in) is semidet.
list_member(E, L) :-
list.member(E, L).
The predicate list_member tells the compiler which mode of
list.member you want to call. As for true and false, you would
need to define predicates of those names as well. (By default,
they exist as goals only.)

How to transform a custom datatype to arrays of arrays

I'm new to Julia and I have some difficulties with the programming with types approach.
I wanted to load a 3D mesh from a file to practice and I have made some custom types to store it.
Here are my types:
struct Vertex
x::Number
y::Number
z::Number
Vertex(x::Number, y::Number, z::Number) = new(x, y, z)
Vertex(t::Tuple{Number, Number, Number}) = new(t[1], t[2], t[3])
Vertex(x::Number, y::Number) = new(x, y, 0)
Vertex(t::Tuple{Number, Number}) = new(t[1], t[2], 0)
Vertex(x::Number) = new(x, 0, 0)
Vertex(t::Tuple{Number}) = new(t[1], 0, 0)
Vertex() = new(0, 0, 0)
Vertex(t::Tuple{}) = new(0, 0, 0)
end
struct Mesh
t::Vector{Vertex} # List of triangles
f::Vector{Vertex} # List of faces
n::Vector{Vertex} # List of normals
Mesh(t::Vertex, f::Vertex) = new([t], [f], [])
Mesh(t::Vector{Vertex}, f::Vector{Vertex}, n::Vector{Vertex}) = new(t, f, n)
Mesh(t::Vector{Vertex}, f::Vector{Vertex}, n::Vector) = new(t, f, n)
Mesh(t::Vector, f::Vector, n::Vector) = new(t, f, n)
#Mesh(t::Triangle) = new([t], [])
#Mesh(t::Vector{Triangle}) = new(t, [])
end
I can effectively load a mesh in my Mesh type.
Now, I would like to plot it using the method plot_trisurf from PyPlot. However, this method expect an array of arrays and I'm not sure my way of doing it is the right way:
function plotMesh(M)
Xv = map(e -> e.x, M.t[:])
Yv = map(e -> e.x, M.t[:])
Zv = map(e -> e.x, M.t[:])
Fv = map(e -> (e.x, e.y, e.z), M.f[:])
plot_trisurf(Xv, Yv, Zv, triangles=Fv, alpha=1)
gca()[:projection] = "3d"
end
Q:
The Xv, Yv, Zv doesn't feel right at the moment,
and the Fv do not work at all. [Corrected -> see Edit]
What it the best way of doing this?
Is my type design correct? or should I change it to something more suitable?
Thanks
[edit]
After some more tests I finally managed to make it work, however I'm still not sure if it is the best way to do things in Julia nor if my type system is a good one.
function plotMesh(M::Mesh)
Xv = map(e -> e.x, M.t[:])
Yv = map(e -> e.y, M.t[:])
Zv = map(e -> e.z, M.t[:])
Fv = map(e -> [Int(e.x)-1, Int(e.y)-1, Int(e.z)-1], M.f[:])
print(size(Xv))
print(size(Fv))
plot_trisurf(Xv, Yv, Zv, triangles=Fv)
gca()[:projection] = "3d"
end
First 3D plot in Julia
[edit]
The vertices and normals are (in general) floats and the faces are integers.
The object I'm using is bunny.obj
and my code for loading the object in the structures is:
function read_obj(filename::String)
v = []
f = []
n = []
tof(x) = parse(Float64, x)
open(filename) do file
for line in eachline(file)
l = split(line, ' ')
if l[1] ∈ ["v", "f", "n"]
values = (tof(l[2]), tof(l[3]), tof(l[4]))
if l[1] == "v"
push!(v, Vertex(values))
elseif l[1] == "f"
faces = (Int(values[1]), Int(values[2]), Int(values[3]))
push!(f, Vertex(faces))
elseif l[1] == "n"
push!(n, Vertex(values))
end
end
end
end
return Mesh(v, f, n)
end
My way of loading the object is surely not the best way of doing it. If you have any material to improve my skills feel free to share :)
First I would change the definition of Vertex like this (it seems below you require entries to be integers, if not, you can change Integer to Number)
struct Vertex{T<:Integer}
x::T
y::T
z::T
end
Vertex(x::T=0, y::T=zero(T)) where {T<:Integer} = Vertex(x,y,zero(T))
Vertex(t::Tuple) = Vertex(t...)
Next in Mesh you can use StructArrays.jl package like this (this way you can easily access fields of Vertex as vectors):
using StructArrays
struct Mesh{S<:StructArray, T}
t::S
f::S
n::S
function Mesh(t::Vector{T}, f::Vector{T}, n::Vector{T}) where {T<:Vertex}
st, sf, sn = StructArray(t), StructArray(f), StructArray(n)
new{typeof(st), T}(st, sf, sn)
end
end
Mesh(t::T, f::T) where {T<:Vertex} = Mesh([t], [f], T[])
now you can define the plotting function for example as:
function plotMesh(M::Mesh{S, T}) where {S,T}
Fv = eachrow([M.f.x M.f.y M.f.z] .- one(T))
print(size(M.t.x))
print(size(Fv))
plot_trisurf(M.t.x, M.t.y, M.t.z, triangles=Fv)
gca()[:projection] = "3d"
end
Note 1: All codes make sure that all the structures operate on concrete types so that the code will be faster than using abstract types (like Number). Also I make sure that all entries have the same type.
Note 2: I have written this from my head as you did not provide data to test the code against (so please let me know if anything fails in this code). Strictly speaking you do not have to use StructArrays.jl to achieve the goal, but I hope that you will agree that using them gives you a more readable code.

How to use reverse Scaling function with error bars in mathematica?

I have data which I would like to plot along with the corresponding error bars:
{{{54927.7, -1.91044}, ErrorBar[38.2664, 0.0538982]},
{{55320.9, -1.97673}, ErrorBar[45.3592, 0.101486]},
{{55671.4, -2.15716}, ErrorBar[41.2234, 0.0258249]},
{{56032.9, -2.15957}, ErrorBar[38.8805, 0.0191277]},
{{56410.6, -2.14289}, ErrorBar[41.5501, 0.0189911]},
{{56787.2, -2.19703}, ErrorBar[38.1972, 0.00632055]},
{{57137.5, -2.1839}, ErrorBar[35.6098, 0.0084108]},
{{57493.3, -2.19994}, ErrorBar[38.0298, 0.00651633]},
{{57859.5, -2.19687}, ErrorBar[40.9682, 0.00658857]}}
I can use the "ErrorListPlot" function in *Mathematica just fine, however if I would like to reverse the y axis scale with the function "ScalingFunctions->"Reverse" " the error bars do not get plotted along with the data.....any suggestions on how to fix this?
Similar to this question. Some messing around to get the ticks looking right.
Needs["ErrorBarPlots`"]
data = {
{{54927.7, -1.91044}, ErrorBar[38.2664, 0.0538982]},
{{55320.9, -1.97673}, ErrorBar[45.3592, 0.101486]},
{{55671.4, -2.15716}, ErrorBar[41.2234, 0.0258249]},
{{56032.9, -2.15957}, ErrorBar[38.8805, 0.0191277]},
{{56410.6, -2.14289}, ErrorBar[41.5501, 0.0189911]},
{{56787.2, -2.19703}, ErrorBar[38.1972, 0.00632055]},
{{57137.5, -2.18390}, ErrorBar[35.6098, 0.0084108]},
{{57493.3, -2.19994}, ErrorBar[38.0298, 0.00651633]},
{{57859.5, -2.19687}, ErrorBar[40.9682, 0.00658857]}};
data[[All, 1, 2]] = -data[[All, 1, 2]];
ep = ErrorListPlot[data];
newTicks = AbsoluteOptions[ep, Ticks][[1, 2, 2]] /.
{x1_, x2_, x3_, x4_} :> If[x1 == x2,
{x1, NumberForm[-x2, {3, 2}], {0.014, 0}, x4},
{x1, x2, {0.007, 0}, x4}];
newTicks = newTicks /. {
GrayLevel[0.] -> GrayLevel[0.5],
AbsoluteThickness[0.25] -> AbsoluteThickness[0.18],
AbsoluteThickness[0.125] -> AbsoluteThickness[0.08]};
ErrorListPlot[data, Ticks -> {Automatic, newTicks}]
Needs["ErrorBarPlots`"]
data = {
{{54927.7, -1.91044}, ErrorBar[38.2664, 0.0538982]},
{{55320.9, -1.97673}, ErrorBar[45.3592, 0.101486]},
{{55671.4, -2.15716}, ErrorBar[41.2234, 0.0258249]},
{{56032.9, -2.15957}, ErrorBar[38.8805, 0.0191277]},
{{56410.6, -2.14289}, ErrorBar[41.5501, 0.0189911]},
{{56787.2, -2.19703}, ErrorBar[38.1972, 0.00632055]},
{{57137.5, -2.18390}, ErrorBar[35.6098, 0.0084108]},
{{57493.3, -2.19994}, ErrorBar[38.0298, 0.00651633]},
{{57859.5, -2.19687}, ErrorBar[40.9682, 0.00658857]}};
(* Invert the error bars, visible in InputForm *)
ep = InputForm[ErrorListPlot[data]] /.
{Line[{{a_, b_}, {c_, d_}}] :> Line[{{a, -b}, {c, -d}}],
Line[{Offset[e_, {f_, g_}], Offset[h_, {i_, j_}]}] :>
Line[{Offset[e, {f, -g}], Offset[h, {i, -j}]}]};
(* Discard the InputForm wrapper *)
ep2 = First[ep];
Show[ErrorListPlot[data, ScalingFunctions -> "Reverse"],
Delete[ep2, Most#First#Position[ep2, Point]]]

Return the index for a list from a list in Erlang

I've been practicing using recursion to define the index in Erlang. Here I need to implement a function to return the index for a list from a list.
eg.
([2, 4, 4], [1, 1, 2, 4, 4, 3, 4 ]) ----> 2
([1, 3], [5, 2, 2, 3, 1, 3, 5]) ----> 4
([1], [3, 2, a, {1, 1}, 1] ----> 4
Here is my code:
-module(project).
-export([index/2]).
index([X|XS],[_]) -> index([X|XS],[_],1).
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
I modified and coded logically but it still can not being compiled. I hope someone who can help me with it. Thanks!
Just for fun, here is an implementation that is not written a very clean way, but illustrates the techniques I think you are looking for. Note there are two basic states: "checking" and "matching".
-module(sublistmatch).
-export([check/2]).
check(Segment, List) ->
SegLen = length(Segment),
ListLen = length(List),
Index = 1,
check(Segment, List, SegLen, ListLen, Index).
check(S, S, _, _, I) ->
{ok, I};
check(_, _, SL, LL, _) when SL >= LL ->
nomatch;
check(S = [H|Ss], [H|Ls], SL, LL, I) ->
case matches(Ss, Ls) of
true -> {ok, I};
false -> check(S, Ls, SL, LL - 1, I + 1)
end;
check(S, [_|L], SL, LL, I) ->
check(S, L, SL, LL - 1, I + 1).
matches([H|S], [H|L]) -> matches(S, L);
matches([], _) -> true;
matches(_, _) -> false.
Note that this depends on knowing the lengths of both the segment you are checking for, and the current length of the remaining list to check. Consider why this is necessary. Also consider how using the utility function matches/2 gives us a natural place to explore whether an option matches, and backtracks if it does not.
In real programs you would use the standard library functions such as lists:prefix/2, lists:suffix/2, or sets:is_subset/2, or maybe some key or member operation over a gb_tree, dict, map or array depending on the situation.
To Compile the code you have to change it to:
-module(project).
-export([index/2]).
%%index([X|XS],[_]) -> index([X|XS],[_],1).
index([X|XS],List) -> index([X|XS],List,1).
%% you shuld not pass '_' as parameter it's will be marked as unbound
index(_,[],_) -> [];
index([X|XS],[X|_], ACC) -> ACC;
%%index([X|XS],[_|rest],ACC) ->index([X|XS],rest,ACC+1).
index([X|XS],[_|Rest],ACC) ->index([X|XS],Rest,ACC+1).
%% rest is an atom, it's not the case you need to use here.
%%Variables should start with upper case letter.
This code will compiled but wrong results as some cases.

Resources