acer

32363 Reputation

29 Badges

19 years, 332 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

The usual way to handle this is to utilize the global name on the lhs of the equation. Utilizing single right-quotes protects against the case that the global name might have been assigned a number.

restart

plots:-setoptions(size=[400,200]);

ecdf := proc(S, {color::string:="blue", thickness::posint:=1})
  local i;
  local N   := numelems(S):
  local M   := sort(S):
  local opt := [':-color'=color, ':-thickness'=thickness]:
  plots:-display(
    plot([ seq(op([[M[i], (i-1)/N], [M[i], i/N], [M[i+1], i/N]]), i=1..N-1) ], opt[])
    , plot([ [M[N], (N-1)/N], [M[N], 1] ], opt[])
    , plot([ [M[N], 1], [(max+(max-min)*0.2)(S), 1] ], opt[], linestyle=3)
    , plot([ [M[1], 0], [(min-(max-min)*0.2)(S), 0] ], opt[], linestyle=3)
  )
end proc:

S := Statistics:-Sample(Uniform(0, 1), 10):

ecdf(S)

ecdf(S, color="red", thickness=3)

color := 99; thickness := -4;

99

-4

ecdf(S, 'color'="green", 'thickness'=5)

 

Download ecdf_ac.mw

Now let's check,

maplemint(ecdf);
Procedure ecdf( S, { color::string := "blue", thickness::posint := 1 } ) 
  These names were used as global names but were not declared:  linestyle
  These local variables were used but never assigned a value:  i

Aha. That's informing us that we should also be cautious about the (unprotected) global name linestyle. We should also single left-quote that in the procedure's code, ie. replace with 'linestyle'. Otherwise it'd break if we assigned some values to the global name.

restart

with(LinearAlgebra)

A := `<,>`(`<|>`(-2*`&omega;__0`^2, `&omega;__0`^2), `<|>`(`&omega;__0`^2, -`&omega;__0`^2))

AA := subs(`&omega;__0` = 3, A)

Matrix(%id = 36893628142202658316)

evalf([Eigenvectors(AA)])

[Vector[column](%id = 36893628142202646388), Matrix(%id = 36893628142202638332)]

NULL

S := AA+3.43769410*IdentityMatrix(2)

Matrix(%id = 36893628142202635196)


Suppose you thought that you'd compute the RREF of S.

When you get to this stage below, what would you do? Would you state
that the bottom row was effectively all zero? Or would you divide
by the diagonal entry -1.728...e-9 to get a 1 on the diagonal?

This is an example of why it's not appropriate to utilize exact linear-algebra
algorithms for floating-point examples.

LUDecomposition(S, output = U)

Matrix(%id = 36893628142202633860)


Maple knows that it should not estimate the rank of floating-point Matrix S
using some inappropriate approach such as counting the non-zero rows
of an ill-computed RREF. Instead, it will consider how many singular-values
of S are close enough to its largest singular value.

Rank(S)

1

NULL


Let's compute the null-space of S. Maple will do this by utilizing a singular-value
decomposition, to get singular-vectors.

NullSpace(S); map(proc (V) options operator, arrow; V/V[2] end proc, %)

{Vector[column](%id = 36893628142202623748)}


In short, floating-point linear-algebra is done with different (suitable) algorithms.
The algorithms for exact linear-algebra are not all appropriate for floating-point
problems. (This distinction holds for other areas of math, not just linear-algebra.)

See also Computation section here. See also Rank in terms of singular values
section of the same page.
 

Download evcalc_ac.mw

Here is one way, using assumptions and the generated inert integral form. Note that it avoids doing,
     PDF(Dist, t) assuming 0 < t, t < 2

You could, of course, programmatically generate the sequence of conditions and `assuming` calls, given just the splitting points [0,2]. That would be straightforward and easy.

restart

kernelopts(version)

with(Statistics)

`Maple 2023.2, X86 64 LINUX, Nov 24 2023, Build ID 1762575`

fx1 := piecewise(t < -1, 0, And(t >= -1, t <= 1), 2*sqrt(-t^2+1)/Pi, t > 1, 0)

fx2 := piecewise(t < -1, 0, And(t >= -1, t <= 1), 2*sqrt(-t^2+1)/Pi, t > 1, 0)

X1 := RandomVariable(Distribution(PDF = unapply(fx1, t)))

X2 := RandomVariable(Distribution(PDF = unapply(fx2, t)))

Dist := abs(X1-X2)

ans :=

piecewise(t<0,
          `assuming`([simplify(value(PDF(Dist, t, inert)))], [ t<0 ]),
          t>0 and t<2,
          `assuming`([simplify(value(PDF(Dist, t, inert)))], [ t>0 and t<2 ]),
          t>2,
          `assuming`([simplify(value(PDF(Dist, t, inert)))], [ t>2 ])
         );

ans := piecewise(t < 0, 0, 0 < t and t < 2, (4*((t^2+4)*EllipticE((-2+t)/(t+2))-4*EllipticK((-2+t)/(t+2))*t))*(t+2)/(3*Pi^2), 2 < t, 0)

evalf(eval(ans,t=1.3));

.2558978187

PDF(Dist, 13/10, numeric);

.2558978190

plot(x->PDF(Dist, x, numeric), 0 .. 2, style=point,
     thickness=3, numpoints=15, size=[500,200]);

plot(ans, t=0 .. 2,
     thickness=3, size=[500,200]);

Download AbsDiff_ac.mw

Your Document contains a comment, "It sure looks like the righthand and lefthand sides of each expression are the same." [emphasis, mine]

You've printed simplify(result), and indeed both side of that are the same. You're visually comparing the two sides after simplify, but your code compares them without simplifying.

You can achieve your goal here with, say,
    result := simplify(eval(subs({x = sols[i]}, 'diff(x, t)' = A . x)))

evs_equal_ac.mw

Note that it can happen (in some other, possibly rare, example) that two expressions F,G can simplify to different forms even though simplify(F-G) becomes zero. In that case you can more strongly test simplify of the difference, ie. rhs-lhs.

From the main menubar,

  Insert -> Section

In my Maple 2024, a keyboard acceleration for that is Ctrl .   (Control period)

If the mouse focus in inside a Section then this action inserts a subsection below the cursor focus.

The following finds a solution with both fsolve (at reduced Digits) and DirectSearch, using procedures that return unevaluated if passed (only) symbolic arguments.

I used Maple 2023 (as did you, I believe).

shooting_question_ac.mw

It's impossible to state exactly which mistakes you've made, since you haven't attached your actual worksheet or full code. (In future Questions, you could do that using the green up-arrow in the Mapleprimes editor's menubar.)

But three kinds of potential problem appear in what you've shown:

1) You may have used = (equals sign) instead of := (colon equals)
   when assigning to y .  The former forms an equation, while the latter
   does an assignment.

2) You appear to have square brackets in the definition of y. Those kind of
   brackets denote lists in Maple. Only round brackets are expression delimiters/groups.

3) Your y expression has f__c, f__m with double underscores, but your parameter-values
   list appears to have f_c, f_m with just one underscore. Those need to
   match, for substitution.

 

y := (1 + M*cos(2*Pi*f__m*t))*A*sin(2*Pi*f__c*t)

(1+M*cos(2*Pi*f__m*t))*A*sin(2*Pi*f__c*t)

plot( eval(y, [ M = 0.5, A = 1, f__m = 2, f__c = 10]),
     t = 0 .. 1,
     gridlines,
     size = [600,400]);

Download pl_syntax_01.mw

restart;

with(Statistics):

r := sqrt(RandomVariable(Uniform(0,1))):

x := cos(RandomVariable(Uniform(0, 2*Pi))):

PDF(r, t) assuming t>0, t<1;

2*t

PDF(x, t) assuming t>-1, t<1;

1/(Pi*(-t^2+1)^(1/2))

PDF(x*r, t) assuming t>-1, t<0;

2*(-t^2+1)^(1/2)/Pi

PDF(x*r, t) assuming t>0, t<1;

2*(-t^2+1)^(1/2)/Pi

PDF(x*r, t) assuming t<-1;

0

PDF(x*r, t) assuming t>1;

0

Download rv_pdf_prod_ex.mw

The above four choices of assumptions handle all real t, for PDF(x*r, t). It's straightforward to combine the pieces into a piecewise.

I mentioned in your previous Question thread that I wonder whether it really is necessary to change all your module exports/locals, etc, just to get it to work in Grid.

When I want to avoid typing out the long-form names of module members I take one of the following two approaches. Neither of these ever involves utilizing use, which I dislike and find problematic.

1) Utilize uses instead, per procedure. Yes, I might have lots of procedures, but I only need to write the uses line once at each beginning, and I still find it far easier than using a long form each time I want to call a member.

restart;

A := module()

  export main_entry:=proc()
     B:-foo();
  end proc;

  local some_very_long_name:= module() #NOTICE, now local
        export toX:=proc(n::integer)::integer;
              n+1;
        end proc;
  end module;

  local B:= module()
     export foo:=proc()
         uses toX=some_very_long_name:-toX;

         toX(1);
     end proc;
  end module;

end module:

A:-main_entry()

2

Download mod_uses.mw

2) Utilize a $define directive (only once per file), in a source text file that I read. The code to use would look like,

    read "nm_mod.mpl";  # or omit this altogether if I had stored it in a .mla archive
    A:-main_entry();

and the test file contains, say,

$define TOX some_very_long_name:-toX

A := module()

  export main_entry:=proc()
     B:-foo();
  end proc;

  local some_very_long_name:= module() #NOTICE, now local
        export toX:=proc(n::integer)::integer;
              n+1;
        end proc;
  end module;

  local B:= module()
     export foo:=proc()
         TOX(1);
     end proc;
  end module;

end module:

$undef TOX

You only need to call rand(...) once, and then you can utilize its returned procedure many times. (There are other ways, but if you're intent on using rand...)

Also, your approach to compute the cumulative sum repeatedly adds all the way from the start, for each i=1..N, which is relatively inefficient. It repeats each previous step's work, and so has a higher than necessary order of computational complexity.

restart;
randomize():
R := rand(1..6):
N := 10^2:
y := [ seq(R(), i = 1..N) ]:
Y :=  map(yy->ifelse(yy<=3,-1,1), y):
C := Statistics:-CumulativeSum(Y):
plot([$N],C);

There are more efficient ways to accomplish this. But this should get you started.

You can compare timings for just the cumulative sum computation. (I haven't made lots of other possible speedups; just focusing on that difference.)

restart;
randomize():
R := rand(1..6):
N := 10^4:
y := [ seq(R(), i = 1..N) ]:
Y :=  map(yy->ifelse(yy<=3,-1,1), y):

CodeTools:-Usage([ seq(add(Y[ .. i]), i = 1..N) ]):
memory used=1.23GiB, alloc change=45.16MiB, cpu time=4.64s, real time=4.64s, gc time=278.23ms

CodeTools:-Usage(Statistics:-CumulativeSum(Y)):
memory used=246.43KiB, alloc change=0 bytes, cpu time=1000.00us, real time=1000.00us, gc time=0ns

LinearAlgebra:-Norm(Vector[column](%)-Vector[column](%%));
                               0.

The performance gaps widens as N increases.

If you are supposed to write your own routine for computing the cumulative sum then please let us know. At the ith step you just need to add the previous step's (i-1)th sum to the ith y entry.

Your code calls eval like this,

   eval(M, [:-alpha=alpha, :-gamma = gamma, :-mu = mu, :-lambda=lambda, :-B[1]=B__1, :-B[2]=B__2],:-beta[0]=beta__0)

but the closing right bracket is in the wrong place, ie. before beta[0]=beta__0. So you're invalidly calling eval with three arguments. That's what the error message tells you, too. It should be,

   eval(M, [:-alpha=alpha, :-gamma = gamma, :-mu = mu, :-lambda=lambda, :-B[1]=B__1, :-B[2]=B__2,:-beta[0]=beta__0])

Also, you're code tries to substitute for global :-gamma, which you've declared local at the top-level.

Also, some parts of your expression might take either very large/very small values, when done computed at hardware precision. You can force use of "software" floats instead of hardware double-precision. And you might also want to experiment with how much (if any) increased working precision might benefit the accuracy.

You might also need to adjust your hard-coded view, in the plot3d call in procedure G.

plot1_ac.mw

ps. One of the useful ideas behind having such a G procedure is that you can just call it with numeric arguments and get a single plot. That's easier to debug and figure out than is a whole Explore call. Focus on getting a/any good result from G. Then, when that works (at all!) try Explore.

Please check for mistakes. I may have misunderstood, and I wrote it quickly.

The basic idea is that if you can get at the allowed functions (of the Xi names) then you could freeze those function calls. The resulting (frozen) placeholder names might then be added to the set of Xi names and done altogether with the methodology for handling your first bullet point cases.

If you have some particular allowed "functions" in mind then you could adjust the typefunc
specification below, changing from name to something else (eg. identical(...), or other...)

restart;

 

H := proc(expr, S) local K,SS,temp;
  K := typefunc(identical(S[]),name);
  SS := freeze~(indets(expr, K)) union S;
  temp := subsindets(expr, K, freeze);
  ormap(s->type(expr, linear(s)), SS)
   and
  andmap(s->type(temp, And(polynom(anything,s),
                           satisfies(t->degree(t,s)<2))), SS);
end proc:

 

H( a*f(X1, X2)*g(X4) + b*X3*g(X4) + c*X1 + d*X1*X2,
   {X1,X2,X3,X4} );

true

H( a*b + c,
   {X1,X2,X3,X4} );

false

H( a*f(X1, X2)*g(X4)^2 + b*X3*g(X4) + c*X1 + d*X1*X2,
   {X1,X2,X3,X4} );

false

H( a*f(X1, X2)*g(X4) + b*X3^4*g(X4) + c*X1 + d*X1*X2,
   {X1,X2,X3,X4} );

false

H( a*f(X1, X2)*g(X4) + b*X3*g(X4) + c^2*X1 + d*X1*X2*X3*X4,
   {X1,X2,X3,X4} );

true

H( a*b*X3 + c^2*X1 + d*X1*X2*X3*X4,
   {X1,X2,X3,X4} );

true

H( a*b*X3^4 + c^2*X1 + d*X1*X2*X3*X4,
   {X1,X2,X3,X4} );

false

H( a*b + c^2*X1,
   {X1,X2,X3,X4} );

true

Download typefunc_ex.mw

restart;

kernelopts(version);

`Maple 2024.2, X86 64 LINUX, Oct 29 2024, Build ID 1872373`

A := module()
  local DEBUG_MSG::truefalse:=false;
  export work_proc:=proc(n::integer)
     print("My flag is ",DEBUG_MSG);
  end proc;
end module:

kernelopts(opaquemodules=false):

Grid:-Set(0,A:-work_proc,'A:-DEBUG_MSG');
Grid:-Run(0,A:-work_proc,[ 0 ]);
Grid:-Wait();

"My flag is ", false

A:-DEBUG_MSG := true:

Grid:-Set(0,A:-work_proc,'A:-DEBUG_MSG');
Grid:-Run(0,A:-work_proc,[ 0 ]);
Grid:-Wait();

"My flag is ", true


Download grid_set_module_local.mw

Yes, it is a bug.  If x is real then at least one of the pair is satisfied.

A developer might classify it as a "weakness".

I couldn't get it with a single is call and unrestricted real x (or equivalent) and the point is that ideally that would be possible.

restart;

S := cos(x) + sqrt(1-sin(x)^2) = 0, cos(x) - sqrt(1-sin(x)^2) = 0;

cos(x)+(1-sin(x)^2)^(1/2) = 0, cos(x)-(1-sin(x)^2)^(1/2) = 0

I wasn't able to merge these assumptions into a single `is` call (say, using
`Or`, including adding x::real, etc).

is(Or(S)) assuming cos(x)<=0;
is(Or(S)) assuming cos(x)>=0;

true

true

I also couldn't "merge" this pair (even with the abs converted to signum or piecewise).

is(Or(C + abs(C) = 0, C - abs(C) = 0)) assuming C>=0;
is(Or(C + abs(C) = 0, C - abs(C) = 0)) assuming C<=0;

true

true

Download is_trig_01.mw

You might guess that I have a hunch that an underlying problem is with combining such pairs, rather than just internal problems with trig handling...

A helping prod, that happens to work:

is(x*y*z = 0) assuming Or(x=0,z=0);

             true

I suppose that `solve` could be leveraged to get that Or() construction programmatically. Multiple results from solve can be taken as Or, and individual results within that can be taken as And (or just themselves if a singleton sequence).

I like nm's Answer.

First 7 8 9 10 11 12 13 Last Page 9 of 336