acer

32348 Reputation

29 Badges

19 years, 329 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@Carl Love Great.

So I suppose you could add that to the `ModuleLoad`.

Perhaps the `ModuleApply` could accept anything, and return the first argument if it were not of the new type `RealIntervals`.

@student_md 

The fancy GUI table cannot be converted to LaTeX, though it is possible to generate some lengthy XML. Doing anything with all that in LaTeX would likely be very difficult.

The easiest thing would be just to convert the 2-column Matrix to LaTeX, which produces \begin{array} ... \end{array}. If you needed to you could substitute "tabular" for "array" in the LaTeX string generated.

Below, I strip out the left- and right square brackets.

I notice that the Maple LaTeX command is mis-treating floats, when handling the Matrix. So it turns 1.2345e-11 into 0.000000000012345 which is not nice. So I'll include some patch-ups involving float notations. (Goodness, it'd probably be easier to write a better Matrix-to-LaTeX export from scratch. Oh well.)

restart:

n:=1:
m:=2:  
E:= 1.75*10^(3):  
l:=10:  
II:=10^(3):  
v:=10:  
M:=10:  
a:=0.1:  
g:=9.8:  
tf:=10:

w1:=sqrt(E*II/m)*(Pi/l)^2:
a_0:=Pi*a/(w1^2*l):
m_0:=M/(m*l):
v_0:=v/w1:
delta:=4*m*g*l^4/E*II*Pi^5:
tau:=w1*t:

p:=sin(v_0*tau)*sin(v_0*tau):
h:=sin(v_0*tau)*cos(v_0*tau):
z:=2:

M:= tau -> 1+2*m_0*sin(v_0*tau)*sin(v_0*tau):
C:=tau -> 2*m_0*(v_0*tau)*sin(v_0*tau)*cos(v_0*tau):

K:=tau ->1-2*m_0*v_0^2*sin(v_0*tau)*sin(v_0*tau)+2*m_0*a_0*cos(v_0*tau)*sin(v_0*tau):
f:=tau -> m_0*Pi/2+m_0*v_0^2*p*z-m_0*a_0*h*z:
X:=x(t):   
  
sys:= delta*(M(t)*diff~(X, t$2)+C(t)*diff~(X, t))+K(t)*X=f(t):

IC:=x(0)=0,D(x)(0)=0: # or you can define any Initial conditions
sys1:={sys,IC}:

numSol:=dsolve(sys1,numeric,method=rkf45, range=0..1, output=listprocedure):

xx := eval(x(t), numSol):

V1 := Vector([seq(0.1..1, 0.1)]):

V2 := map(xx, V1):

M := <V1|evalf[5](V2)>;

Matrix(10, 2, {(1, 1) = .1, (1, 2) = 0.2870700000e-10, (2, 1) = .2, (2, 2) = 0.1152100000e-9, (3, 1) = .3, (3, 2) = 0.2593600000e-9, (4, 1) = .4, (4, 2) = 0.4607600000e-9, (5, 1) = .5, (5, 2) = 0.7194100000e-9, (6, 1) = .6, (6, 2) = 0.1035700000e-8, (7, 1) = .7, (7, 2) = 0.1409400000e-8, (8, 1) = .8, (8, 2) = 0.1840100000e-8, (9, 1) = .9, (9, 2) = 0.2327700000e-8, (10, 1) = 1.0, (10, 2) = 0.2871800000e-8})

with(StringTools):

SubstituteAll(Substitute(Substitute(latex(M,'output'='string'),
                                    "\\left[ ",""),"\\right]",""),"`","");

" \begin {array}{cc}  0.1&{ 2.8707\times 10^{-11}}\\ \noalign{\medskip} 0.2& 0.00000000011521\\ \noalign{\medskip} 0.3& 0.00000000025936\\ \noalign{\medskip} 0.4& 0.00000000046076\\ \noalign{\medskip} 0.5& 0.00000000071941\\ \noalign{\medskip} 0.6& 0.0000000010357\\ \noalign{\medskip} 0.7& 0.0000000014094\\ \noalign{\medskip} 0.8& 0.0000000018401\\ \noalign{\medskip} 0.9& 0.0000000023277\\ \noalign{\medskip} 1.0& 0.0000000028718\end {array}  "

 

M := <map[2](nprintf,"%.2g",V1)|map[2](nprintf,"%.5g",V2)>;

Matrix(10, 2, {(1, 1) = `0.1`, (1, 2) = `2.8707e-11`, (2, 1) = `0.2`, (2, 2) = `1.1521e-10`, (3, 1) = `0.3`, (3, 2) = `2.5936e-10`, (4, 1) = `0.4`, (4, 2) = `4.6076e-10`, (5, 1) = `0.5`, (5, 2) = `7.1941e-10`, (6, 1) = `0.6`, (6, 2) = `1.0357e-09`, (7, 1) = `0.7`, (7, 2) = `1.4094e-09`, (8, 1) = `0.8`, (8, 2) = `1.8401e-09`, (9, 1) = `0.9`, (9, 2) = `2.3277e-09`, (10, 1) = `1`, (10, 2) = `2.8718e-09`})

with(StringTools):

SubstituteAll(Substitute(Substitute(latex(M,'output'='string'),
                                    "\\left[ ",""),"\\right]",""),"`","");

" \begin {array}{cc} \mbox {{\tt 0.1}}&\mbox {{\tt 2.8707e-11}}\\ \noalign{\medskip}\mbox {{\tt 0.2}}&\mbox {{\tt 1.1521e-10}}\\ \noalign{\medskip}\mbox {{\tt 0.3}}&\mbox {{\tt 2.5936e-10}}\\ \noalign{\medskip}\mbox {{\tt 0.4}}&\mbox {{\tt 4.6076e-10}}\\ \noalign{\medskip}\mbox {{\tt 0.5}}&\mbox {{\tt 7.1941e-10}}\\ \noalign{\medskip}\mbox {{\tt 0.6}}&\mbox {{\tt 1.0357e-09}}\\ \noalign{\medskip}\mbox {{\tt 0.7}}&\mbox {{\tt 1.4094e-09}}\\ \noalign{\medskip}\mbox {{\tt 0.8}}&\mbox {{\tt 1.8401e-09}}\\ \noalign{\medskip}\mbox {{\tt 0.9}}&\mbox {{\tt 2.3277e-09}}\\ \noalign{\medskip}\mbox {{\tt 1}}&\mbox {{\tt 2.8718e-09}}\end {array}  "

SubstituteAll(SubstituteAll(Substitute(Substitute(latex(M,'output'='string'),
                                    "\\left[ ",""),"\\right]",""),"`",""),"\\tt","");

" \begin {array}{cc} \mbox {{ 0.1}}&\mbox {{ 2.8707e-11}}\\ \noalign{\medskip}\mbox {{ 0.2}}&\mbox {{ 1.1521e-10}}\\ \noalign{\medskip}\mbox {{ 0.3}}&\mbox {{ 2.5936e-10}}\\ \noalign{\medskip}\mbox {{ 0.4}}&\mbox {{ 4.6076e-10}}\\ \noalign{\medskip}\mbox {{ 0.5}}&\mbox {{ 7.1941e-10}}\\ \noalign{\medskip}\mbox {{ 0.6}}&\mbox {{ 1.0357e-09}}\\ \noalign{\medskip}\mbox {{ 0.7}}&\mbox {{ 1.4094e-09}}\\ \noalign{\medskip}\mbox {{ 0.8}}&\mbox {{ 1.8401e-09}}\\ \noalign{\medskip}\mbox {{ 0.9}}&\mbox {{ 2.3277e-09}}\\ \noalign{\medskip}\mbox {{ 1}}&\mbox {{ 2.8718e-09}}\end {array}  "

 

Download student_md_question_2_acc.mw

 

@Carl Love Vote up.

I think that the extension mechanism requires an actual procedure, which can be wrapped around an appliable module. (It's also possible that you tried that as a second attempt, but neglected to clear the remembered result.)

restart;

kernelopts(version);

`Maple 2018.0, X86 64 LINUX, Mar 9 2018, Build ID 1298750`

 

SimplifyIntervals:= module()
local
   x::identical(x),
   ModuleLoad:= ()->
      TypeTools:-AddType( #recursive type: put base cases 1st!
         'RealIntervals',
         Or(
            specfunc(RealRange),
            set(realcons),
            'specop'('RealIntervals', {`intersect`, `union`, `minus`})
         )
      ),
   Deconstruct:= (IN::RealIntervals)->
      if IN::specfunc(RealRange) then convert(x::IN, relation)
      elif IN::set(realcons) then Or((x =~ IN)[])
      elif IN::`minus` then And(thisproc(op(1,IN)), Not(thisproc(op(2,IN))))
      else `if`(IN::`union`, Or, And)(map(thisproc, [op(IN)])[])
      fi,   
   ModuleApply:= proc(IN::RealIntervals)
   local pts, ints;
      (pts,ints):= selectremove(type, [solve(Deconstruct(IN), x)], realcons);
      `union`(sort(ints, key= (p-> `if`(op(1,p)::realcons, op(1,p), op([1,1],p))))[])
            union {pts[]}       
   end proc
;
   ModuleLoad()
end module:

 

expr := (((RealRange(-infinity, 1) intersect RealRange(Open(-1), infinity))
           minus RealRange(-1/3, 1/3)) minus {0}) union {-2,2};

`union`(`minus`(`minus`(`intersect`(RealRange(-infinity, 1), RealRange(Open(-1), infinity)), RealRange(-1/3, 1/3)), {0}), {-2, 2})

 

`simplify/intervals` := SimplifyIntervals:
forget(simplify);

 

simplify(expr, intervals); # Does not use the appliable module

`union`(`minus`(`minus`(`intersect`(RealRange(-infinity, 1), RealRange(Open(-1), infinity)), RealRange(-1/3, 1/3)), {0}), {-2, 2})

 

`simplify/intervals` := proc() SimplifyIntervals(args); end proc:
forget(simplify);

 

simplify(expr, intervals); # Uses the procedure

`union`(RealRange(Open(-1), Open(-1/3)), RealRange(Open(1/3), 1), {-2, 2})

 

Download simplify_intervals.mw

How about uploading a worksheet that let's us explicitly see (or experiment with) your example?

@Spirithaunter After making the replacements I suggested throughout I no longer see that error message at all.

Spirithaunter_01.mw

Please upload a worksheet that reproduces the problem.

@vv I tried to give the OP some advice about not using unapply (and a procedure call) when an expression would serve. That is enough to avoid the problem.

But the originally exhibited problem is deeper, I think. In the examples below, what is the essential difference between Vectors boo and rah? Why does mapping eval across rah have such an effect, while applying rtable_eval (to rah, or V, or anything in sight, with or without its inplace option) does not have a similar effect?

I agree with you that the construction was unusual. It seems like advice might include: don't unapply a Vector and then subsequently change that Vector's entries.

restart;

kernelopts(version);

`Maple 2018.0, X86 64 LINUX, Mar 9 2018, Build ID 1298750`

V := Vector(2);

Vector(2, {(1) = 0, (2) = 0})

f := unapply(V, t);

f := proc (t) options operator, arrow; Vector(2, {(1) = 0, (2) = 0}) end proc

V[1] := t^2;
V[2] := t^3;

t^2

t^3

rah:=f();

Vector(2, {(1) = t^2, (2) = t^3})

lprint(eval(rah,1));

Vector[column](2, {1 = t^2, 2 = t^3}, datatype = anything, storage = rectangular, order = Fortran_order, shape = [])

K := unapply(rah,t);

K := proc (t) options operator, arrow; Vector[column](1 .. 2, {1 = t^2, 2 = t^3}, datatype = anything, storage = rectangular, order = Fortran_order, subtype = Vector[column]) end proc

K(3); # like the OP's problem

Vector(2, {(1) = t^2, (2) = t^3})

boo := map(eval,rah);

Vector(2, {(1) = t^2, (2) = t^3})

lprint(eval(boo,1));

Vector[column](2, {1 = t^2, 2 = t^3}, datatype = anything, storage = rectangular, order = Fortran_order, shape = [])

L:=unapply(boo, t);

proc (t) options operator, arrow; rtable(1 .. 2, {1 = t^2, 2 = t^3}, datatype = anything, subtype = Vector[column], storage = rectangular, order = Fortran_order) end proc

L(3);

Vector(2, {(1) = 9, (2) = 27})

lprint(eval(K,1));

proc (t) options operator, arrow; Vector(2, {(1) = t^2, (2) = t^3}) end proc

lprint(eval(L,1));

proc (t) options operator, arrow; rtable(1 .. 2, {1 = t^2, 2 = t^3}, datatype = anything, subtype = Vector[column], storage = rectangular, order = Fortran_order) end proc

 

Download Vector_unapply_oddity.mw

@student_md Suppose you have an expression already, involving the global name t. And then you construct a procedure (operaotr) using just the arrow notation directly. The parameter t of the procedure (operator) is different from the global name t inside the expression. They look the same, but they are quite distinct. When the procedure is called it uses the value of it argument wherever that name is used in the body of the procedure. But in the following example the parameter t does not occur in the expression (since that contains just the global name t).

restart;

expr := t^2;

                        2
               expr := t 

p := t -> expr;

            p := t -> expr

p(2.1);

                    2
                   t 

This is a frequently asked question. Here are some ways to make it work. Note that :-t is a useful syntax for referring to the global name t, and distinguish it from a parameter or local name t.

expr := t^2;

                            2
                   expr := t 

r := unapply(expr, t);

                             2
                  r := t -> t 

r(2.1);

                      4.41

s := subs(dummy = expr, t->dummy);

                              2
                   s := t -> t 

s(2.1);

                      4.41

w := t -> eval(expr, :-t = t);

          w := t -> eval(expr, :-t = t)

w(2.1);

                      4.41

As you can see, unapply provides one convenient way to construct a procedure from an expression.

Try not to overuse unapply. It can be inefficient to have a procedure F that calls unapply each time you call F. Another way is to use 2-argument eval to evaluate an expression at a value for a name. Eg,

expr := sin(x)*exp(x):
eval(expr, x=2.1);
                                 7.049114358

Also, never bother to create a procedure with unapply if you're only going to just call it with a name for its argument. You may as well just use the expression. Eg, here's something I see now and then,

restart;
expr := sin(x)*exp(x):

f := unapply(expr, x):
plot(f(x), x=0..Pi);   # this is silly, if it's the only time f is used.

plot(expr, x=0..Pi);   # one could just as easily do this

Also, don't try and use a function call on the left-hand-side of an assignment statement, unless you really know what you're doing. That was part of your original difficulty in your Question. That's complicated.

And so you could avoid the original problem simply by following the advice to not create a procedure (with some parameter name) and then only use it with a function call to the same unassigned name, or the advice to not assign to a function call.

This adjustment makes it almost identical to my answer.

restart;
C :=[[0,1/11],[1/11,1/9],[1/9, 1/7],[1/3,1/2],[1/2,1]]:
C1:=map(t->x>=t[1] and x<=t[2], C):
op(map(`[]`@op,[solve(`or`(C1[]))]));

               [0, 1/7], [1/3, 1]

@student_md Yes, the MatrixSystem is not linear in the c[i] so it makes no sense to try and use GenerateMatrix (let alone linsolve or LinearSolve).

Even if it were linear for another example, its a mistake to re-assign to lowercase b since that's being used for the x-range lower endpoint.

ps. Did you edit the original Question and remove material?

I see that Kitonum already gave essentially the same answer, while I was still typing. The only difference being that I converted the RealRange results from solve into lists (just to match the OP's input of a sequence of lists).

Note: RealRange can prettyprint like a list. I don't know whether the OP prefers lists, or is not aware of the RealRange structure.

So, another variation, if say we started with a sequence of RealRange rather than a sequence of lists.

restart;

C :=map(RealRange@op,[[0,1/11],[1/11,1/9],[1/9, 1/7],[1/3,1/2],[1/2,1]])[];

                 /   1 \           /1   1\           /1  1\  
   C := RealRange|0, --|, RealRange|--, -|, RealRange|-, -|, 
                 \   11/           \11  9/           \9  7/  

              /1  1\           /1   \
     RealRange|-, -|, RealRange|-, 1|
              \3  2/           \2   /

solve(Or(op(map(r->convert(__dum::r,relation),[C]))));

                         /   1\           /1   \
                RealRange|0, -|, RealRange|-, 1|
                         \   7/           \3   /

@student_md Obtaining the min and max depends on the kind of plot, yes.

If you upload an example with a different kind of plot or coloring scheme then we can show you how its data can be handled to get a corresponding colorbar.

@minhthien2016 I edited my Answer to illustrate that.

I suggest that you tell us what shading/coloring scheme you want to accomplish.

For example, would you be content with shading by hue, as the (z-value) height changed?  Eg,

num_sol:-plot3d(x=0..1, t=0..1, shading=zhue, grid=[79,179], style=surface);

num_sol:-plot3d(x=0..1, t=0..15, shading=zhue, grid=[79,879], style=surface);

And here is a variant where the burden is not on the user to specify the z-height contour values up front.

I consider that as a useful case. It's never quite satisfying when a nifty use of contour plots requires the user to figure out in advance what contour values to use. It's nice that we can force the values, but many users will prefer the system try and do it.

I've been wanting this for some time, and realized that I can now get it easily by ripping it out of the hover-over contour label substructures that plots:-contourplot now produces. (It's a little weird that I didn't think of this earlier, as I've used the info in those new substructures for other cool things.) I've never liked the idea of averaging the values obtained by substituting CURVE x-y data points into the formula.

And the contours on the upper 3D surface are rendered by the GUI from the CONTOURS substructure rather than from CURVE substructures (which very often look jagged and either too thick or too thin, alongside a surface).

In summary: the precise contour values are the same for the 2D density + contour plot as they are in both 3D surfaces. And the color shading is also exactly the same.

These plots look much better in the actual Maple GUI than they do when rendered inline by this site's backend.

restart;

# Allow `contourplot` to choose the z-heights for contours.
#

C2D:=plots:-contourplot(sin(x)*y^2, x=-Pi..Pi,y =-1..1,
                        color=black, contourlabels=true):

 

# Grab the z-heights used from the contour-label hover-over substructure.
# This is nicer than kludging an average of substitutions of the CURVE points.

Clist:=[map[2](op,1,indets(C2D,specfunc(anything,_HOVERCONTENT)))[]];

[-.777, -.555, -.333, -.111, .111, .333, .555, .777]

# Standalone 3D surface, with same contour values.
#
# Re-use that z-heights list in `contours` options. This makes the
# GUI responsible for rendering the 3D contours purely from a terse
# CONTOURS substructure, and that looks much better tightly next to
# the rendered surface than would any CURVEs transformed from 2D up
# to the surface.
#

P := plots:-contourplot3d(sin(x)*y^2, x=-Pi..Pi, y=-1..1,
            contours=Clist,
            thickness=1,
            colorscheme=["zgradient",
                         ["Red","Orange","Yellow","Green","Cyan","Blue","Magenta"]]):
P := subsindets(P,specfunc(anything,STYLE),()->STYLE(PATCHCONTOUR));

# Standalone 2D densityplot, with same contour values and shading.
#
# Here is the 2D filled contour plot.
#

plots:-display(
  PLOT(op([1],P),STYLE(PATCHNOGRID)),
  C2D
);

# And now, combine 3D, with all same z-heights for contours.
#

zval := -1.1:  # choice of height of horizontal surface
lowerP := subsop([1,3]=Matrix(op(2,op([1,3],P)), zval, datatype=float[8]), P):

plots:-display(
  P,
  lowerP,
  plottools:-transform((x,y)->[x,y,-1.1])(C2D)
);

 

Download 2d_3d_filled_contours.mw

 

First 237 238 239 240 241 242 243 Last Page 239 of 592