pagan

5147 Reputation

23 Badges

17 years, 122 days

 

 

"A map that tried to pin down a sheep trail was just credible,

 but it was an optimistic map that tried to fix a the path made by the wind,

 or a path made across the grass by the shadow of flying birds."

                                                                 - _A Walk through H_, Peter Greenaway

 

MaplePrimes Activity


These are replies submitted by pagan

I don't know a way to prohibit such so-called side-effects on the named arguments. There are Library routines which rely on it.

If it's worth anything to you, there are a couple of ways to ensure that your given example can continue to work.

> restart:

> f := proc(x::uneval)
> x := 7;
> print(x);
> end proc:

> f(y);
                                       y
 
> y;
                                       7
 
> f(y);
                                       y
 
> y;
                                       7

> restart:

> f := proc(x)
> x := 7;
> print(x);
> end proc:

> f(evaln(y));
                                       y
 
> y;
                                       7
 
> f(evaln(y));
                                       y
 
> y;
                                       7

> restart:

> f := proc(x)
> x := 7;
> print(x);
> end proc:

> f('y');
                                       y
 
> y;
                                       7
 
> f('y');
                                       y
 
> y;
                                       7

Thanks. I was quickly reusing earlier commands, and didn't notice that I'd left it in.

Thanks. I was quickly reusing earlier commands, and didn't notice that I'd left it in.

You can play with it, to get as many as ten or as few as five digits accurate instead of eight.

The idea, implicit in previous replies I think, is that a plain ol' power series approximation will do poorly for large t, while an asymptotic expansion to finitely many terms may do poorly near t=zero. (Also, Maple may have trouble with `asympt` for an order of more than 11.) So you could produce both, and use whichever is appropriate for a given t.

> Digits:=15:
> interface(warnlevel=0): # suppress Maximize evaluation count warnings
>
> eq:=v*t=(S0-St)+Km*ln(S0/St):
> s:=solve(eq,St);
                                           -v t + S0
                                    S0 exp(---------)
                                              Km
                      s := LambertW(-----------------) Km
                                           Km
 
>
> sx:=eval(s,[Km=11,S0=1,v=1]);
                                                t
                  sx := 11 LambertW(1/11 exp(- ---- + 1/11))
                                                11
 
>
# Looks monotonic, esp. near 10, so local optimization might be ok
> seq([i,Optimization:-Maximize(abs(sx-convert(series(sx,t,i),polynom)),
>                               t=0..10)[1]],i=10..17);
                            -7                               -6
[10, 0.174286148877700004 10  ], [11, 0.187880306930529998 10  ],
 
                                -7                               -8
    [12, 0.332243676689270000 10  ], [13, 0.428905852769310033 10  ],
 
                                -8                               -9
    [14, 0.266615915039121999 10  ], [15, 0.250101221720579981 10  ],
 
                                -9                               -10
    [16, 0.108400122247518005 10  ], [17, 0.351468733142219981 10   ]
 
>
# Looks monotonic, esp. near 10, so local optimization might be ok
> seq([i,Optimization:-Maximize(abs(sx-convert(asympt(sx,t,i),polynom)),
>                               t=10..20)[1]],i=7..11);
                           -7                              -8
[7, 0.393885631688799989 10  ], [8, 0.351354781298090012 10  ],
 
                               -9                               -10
    [9, 0.320926635148609976 10  ], [10, 0.298644869777180028 10   ],
 
                                -11
    [11, 0.282385415574599993 10   ]
 
>
# A candidate, for 8 digits of (absolute) accuracy,
# so that absolute error is less than 1.0*10^(-8).
> W := piecewise(t>=0 and t<=10, convert(series(sx,t,13),polynom),
>                t>10, convert(asympt(sx,t,8),polynom));
     {
     {               11   2     11    3      143     4       2629      5
W := { 1 - 1/12 t + ---- t  - ------ t  + --------- t  + ------------ t
     {              3456      165888      286654464      206391214080
     {
 
           24013       6         27599        7         1245277        8
     - -------------- t  + ----------------- t  + ------------------- t
       59440669655040      19972065004093440      7669272961571880960
 
              34830169         9           293852581           10
     - ---------------------- t  - -------------------------- t
       9939377758197157724160      14312703971803907122790400
 
                4557032279           11             34350637123            12
     + ---------------------------- t   - ------------------------------- t
       2061029371939762625681817600       1187152918237303272392726937600
 
    , 0 <= t and t <= 10
 
                               2                  3                   4
    exp(1/11)         exp(1/11)          exp(1/11)           exp(1/11)
    ---------- - 1/11 ---------- + 3/242 ---------- - 8/3993 ----------
          1/11              2/11               3/11                4/11
    exp(t)            exp(t)             exp(t)              exp(t)
 
                       5                   6                       7
        125   exp(1/11)      54   exp(1/11)      16807    exp(1/11)
     + ------ ---------- - ------ ---------- + ---------- ---------- , 10 < t
       351384       5/11   805255       6/11   1275523920       7/11
              exp(t)              exp(t)                  exp(t)
 
>
> Digits:=100:
> Optimization:-Maximize(abs(sx-W),t=0..20)[1]:
> evalf[10](%);
                                              -8
                               0.4289057483 10
 
>
> plot(sx-W,t=0..50);
 
  ************+-10--+--+*******20************30*************40*************50
0 +          AA       AAA
  +           A      AA
  +            A    A
  +            A   AA
-1e-09         A   A
  +            A   A
  +             A AA
  +             A A
-2e-09          A A
  +             A A
  +             A A
  +             AA
  +             AA
-3e-09          AA
  +             AA
  +             AA
  +              A
  +              A
-4e-09           A
  +              A

Now, you said that you wanted to be able to evaluate these series approximations "on paper". I'm not sure if you mean that literally. I set Maple's working precision to 15, during most of the above. Are you going to have a calculator or other program capable of 15 decimal digits available? How about a compiled language such as C, supporting double-precision floating-point computation? Or will you do it on paper?

Did you really want exact rationals in those curtailed series approximations,? Because the numer or denom of the coefficients in those might have more that 15 places, posing a practical problem for your subsequent calculation. Or will you want to evaluate to, say, 15 decimal digits right now, in Maple (using evalf[15])?

You can play with it, to get as many as ten or as few as five digits accurate instead of eight.

The idea, implicit in previous replies I think, is that a plain ol' power series approximation will do poorly for large t, while an asymptotic expansion to finitely many terms may do poorly near t=zero. (Also, Maple may have trouble with `asympt` for an order of more than 11.) So you could produce both, and use whichever is appropriate for a given t.

> Digits:=15:
> interface(warnlevel=0): # suppress Maximize evaluation count warnings
>
> eq:=v*t=(S0-St)+Km*ln(S0/St):
> s:=solve(eq,St);
                                           -v t + S0
                                    S0 exp(---------)
                                              Km
                      s := LambertW(-----------------) Km
                                           Km
 
>
> sx:=eval(s,[Km=11,S0=1,v=1]);
                                                t
                  sx := 11 LambertW(1/11 exp(- ---- + 1/11))
                                                11
 
>
# Looks monotonic, esp. near 10, so local optimization might be ok
> seq([i,Optimization:-Maximize(abs(sx-convert(series(sx,t,i),polynom)),
>                               t=0..10)[1]],i=10..17);
                            -7                               -6
[10, 0.174286148877700004 10  ], [11, 0.187880306930529998 10  ],
 
                                -7                               -8
    [12, 0.332243676689270000 10  ], [13, 0.428905852769310033 10  ],
 
                                -8                               -9
    [14, 0.266615915039121999 10  ], [15, 0.250101221720579981 10  ],
 
                                -9                               -10
    [16, 0.108400122247518005 10  ], [17, 0.351468733142219981 10   ]
 
>
# Looks monotonic, esp. near 10, so local optimization might be ok
> seq([i,Optimization:-Maximize(abs(sx-convert(asympt(sx,t,i),polynom)),
>                               t=10..20)[1]],i=7..11);
                           -7                              -8
[7, 0.393885631688799989 10  ], [8, 0.351354781298090012 10  ],
 
                               -9                               -10
    [9, 0.320926635148609976 10  ], [10, 0.298644869777180028 10   ],
 
                                -11
    [11, 0.282385415574599993 10   ]
 
>
# A candidate, for 8 digits of (absolute) accuracy,
# so that absolute error is less than 1.0*10^(-8).
> W := piecewise(t>=0 and t<=10, convert(series(sx,t,13),polynom),
>                t>10, convert(asympt(sx,t,8),polynom));
     {
     {               11   2     11    3      143     4       2629      5
W := { 1 - 1/12 t + ---- t  - ------ t  + --------- t  + ------------ t
     {              3456      165888      286654464      206391214080
     {
 
           24013       6         27599        7         1245277        8
     - -------------- t  + ----------------- t  + ------------------- t
       59440669655040      19972065004093440      7669272961571880960
 
              34830169         9           293852581           10
     - ---------------------- t  - -------------------------- t
       9939377758197157724160      14312703971803907122790400
 
                4557032279           11             34350637123            12
     + ---------------------------- t   - ------------------------------- t
       2061029371939762625681817600       1187152918237303272392726937600
 
    , 0 <= t and t <= 10
 
                               2                  3                   4
    exp(1/11)         exp(1/11)          exp(1/11)           exp(1/11)
    ---------- - 1/11 ---------- + 3/242 ---------- - 8/3993 ----------
          1/11              2/11               3/11                4/11
    exp(t)            exp(t)             exp(t)              exp(t)
 
                       5                   6                       7
        125   exp(1/11)      54   exp(1/11)      16807    exp(1/11)
     + ------ ---------- - ------ ---------- + ---------- ---------- , 10 < t
       351384       5/11   805255       6/11   1275523920       7/11
              exp(t)              exp(t)                  exp(t)
 
>
> Digits:=100:
> Optimization:-Maximize(abs(sx-W),t=0..20)[1]:
> evalf[10](%);
                                              -8
                               0.4289057483 10
 
>
> plot(sx-W,t=0..50);
 
  ************+-10--+--+*******20************30*************40*************50
0 +          AA       AAA
  +           A      AA
  +            A    A
  +            A   AA
-1e-09         A   A
  +            A   A
  +             A AA
  +             A A
-2e-09          A A
  +             A A
  +             A A
  +             AA
  +             AA
-3e-09          AA
  +             AA
  +             AA
  +              A
  +              A
-4e-09           A
  +              A

Now, you said that you wanted to be able to evaluate these series approximations "on paper". I'm not sure if you mean that literally. I set Maple's working precision to 15, during most of the above. Are you going to have a calculator or other program capable of 15 decimal digits available? How about a compiled language such as C, supporting double-precision floating-point computation? Or will you do it on paper?

Did you really want exact rationals in those curtailed series approximations,? Because the numer or denom of the coefficients in those might have more that 15 places, posing a practical problem for your subsequent calculation. Or will you want to evaluate to, say, 15 decimal digits right now, in Maple (using evalf[15])?

How accurate do you want it to be, when you plug in values?

If you know values for S0, Km, and v then you might be able to get a formula with guaranteed accuracy (within a stated bound) over a specified interval for t. You might be able to use the numapprox package for that, but don't rule out asympt.

If you just try a chopped power series, or even an asymptotic series, then the error will depend on S0, Km, and v (and hence could be large in principal, as we don't have ranges for those yet).

So it seems sensible to ask: what's the target accuracy? What are the parameter values?

How accurate do you want it to be, when you plug in values?

If you know values for S0, Km, and v then you might be able to get a formula with guaranteed accuracy (within a stated bound) over a specified interval for t. You might be able to use the numapprox package for that, but don't rule out asympt.

If you just try a chopped power series, or even an asymptotic series, then the error will depend on S0, Km, and v (and hence could be large in principal, as we don't have ranges for those yet).

So it seems sensible to ask: what's the target accuracy? What are the parameter values?

Get rid of the with(plots). You could keep it, but I suggest using the long form name plots:-inequal instead, wherever used. But if you keep it, then it has to be on its own, outside of a Do() call. It certainly should not be used in an attempt to set the value of the Plot0 component, which you presently have as Do(%Plot0=with(plots)). That doesn't make sense.

Your might want to put your code in procedures at some point, and with() won't work "properly" there either.

I suggest putting all your code into procedures defined outside the Action-when-clicked part of the Button Components. Just make it regular code, visible right there in your Document. It makes it easier to debug and develop. When it's finished and ready, then you can just add a few calls to those procedures inside the code section of the Components (and hide the code in an autoexecute, collapsed Block of your Document).

For example, suppose you move the code presently in the "Run Tutor" button into a visible proc named RunTutorproc.

RunTutorproc:=proc()
  DocumentTools:-Do(%Plot0 = plots:-inequal({x + 3*y <=200,
    2*x + 2*y <= 300, y <= 60, x >=0, y >=0}, x = -400..400,
    y = -400..400, optionsfeasible=(color=red),
    optionsexcluded=(color=white, thickness=4)));
end proc:

And you could add lots more into that proc body, of course. And then you can simply put a call

  RunTutorproc();

inside the Button's Action-when-clicked area. It's just a suggestion to make your development easier.

Get rid of the with(plots). You could keep it, but I suggest using the long form name plots:-inequal instead, wherever used. But if you keep it, then it has to be on its own, outside of a Do() call. It certainly should not be used in an attempt to set the value of the Plot0 component, which you presently have as Do(%Plot0=with(plots)). That doesn't make sense.

Your might want to put your code in procedures at some point, and with() won't work "properly" there either.

I suggest putting all your code into procedures defined outside the Action-when-clicked part of the Button Components. Just make it regular code, visible right there in your Document. It makes it easier to debug and develop. When it's finished and ready, then you can just add a few calls to those procedures inside the code section of the Components (and hide the code in an autoexecute, collapsed Block of your Document).

For example, suppose you move the code presently in the "Run Tutor" button into a visible proc named RunTutorproc.

RunTutorproc:=proc()
  DocumentTools:-Do(%Plot0 = plots:-inequal({x + 3*y <=200,
    2*x + 2*y <= 300, y <= 60, x >=0, y >=0}, x = -400..400,
    y = -400..400, optionsfeasible=(color=red),
    optionsexcluded=(color=white, thickness=4)));
end proc:

And you could add lots more into that proc body, of course. And then you can simply put a call

  RunTutorproc();

inside the Button's Action-when-clicked area. It's just a suggestion to make your development easier.

> restart:

> with(Statistics,Fit,NonlinearFit):
> with(LinearAlgebra,DotProduct,Rank):
> with(Student[LinearAlgebra],Rank): # clobbers previous Rank binding

> bind();
LinearAlgebra:-DotProduct, Statistics:-Fit, Statistics:-NonlinearFit,
 
    Student:-LinearAlgebra:-Rank
 
> LL:=P->select(x->eval(parse(x))=eval(P[x]),
>       [op({op(convert([bind()],`global`))}
>       intersect convert({exports(P)},`global`))]):

> LL(Statistics);
                              [Fit, NonlinearFit]
 
> LL(LinearAlgebra);
                                 [DotProduct]
 
> LL(Student[LinearAlgebra]);
                                    [Rank]

> unwith(Student[LinearAlgebra],Rank); # reverting to previous Rank binding

> LL(LinearAlgebra);
                              [Rank, DotProduct]
> restart:

> with(Statistics,Fit,NonlinearFit):
> with(LinearAlgebra,DotProduct,Rank):
> with(Student[LinearAlgebra],Rank): # clobbers previous Rank binding

> bind();
LinearAlgebra:-DotProduct, Statistics:-Fit, Statistics:-NonlinearFit,
 
    Student:-LinearAlgebra:-Rank
 
> LL:=P->select(x->eval(parse(x))=eval(P[x]),
>       [op({op(convert([bind()],`global`))}
>       intersect convert({exports(P)},`global`))]):

> LL(Statistics);
                              [Fit, NonlinearFit]
 
> LL(LinearAlgebra);
                                 [DotProduct]
 
> LL(Student[LinearAlgebra]);
                                    [Rank]

> unwith(Student[LinearAlgebra],Rank); # reverting to previous Rank binding

> LL(LinearAlgebra);
                              [Rank, DotProduct]

I think that it may not be a bug.

The `sort` routines appears to be following part of the rules of ordering according to the value of setsort. The pattern that for the default kernelopts(setsort)=1 is that the integers are are put into an order before the floats. That is documented on the ?setsort help page.

The ?sort help page could be more clear about it. It might be that `sort` is still sorting groups by ascending magnitude by default, at all setsort values, but is using setsort to prioritize the order in which integers and floats are put.

Launching Maple with --setsort=6 will get an alternate treatment of integers and floats. (Using setsort=7 may also get it.)

> kernelopts(setsort); # normal default launch
                                       1

> a:=[[1,3.4],[1,5],[1,2.7],[1,16]];
                  a := [[1, 3.4], [1, 5], [1, 2.7], [1, 16]]
 
> sort(a);
                     [[1, 5], [1, 16], [1, 2.7], [1, 3.4]]

And in a new session,

linux% maple13.01 -s --setsort=6

> kernelopts(setsort);
                                       6

> a:=[[1,3.4],[1,5],[1,2.7],[1,16]];
                  a := [[1, 3.4], [1, 5], [1, 2.7], [1, 16]]
 
> sort(a);
                     [[1, 2.7], [1, 3.4], [1, 5], [1, 16]]

It looks as if it deliberately accords with the ?setsort help. It doesn't look like an overlooked compiler warning to me.

I think that it may not be a bug.

The `sort` routines appears to be following part of the rules of ordering according to the value of setsort. The pattern that for the default kernelopts(setsort)=1 is that the integers are are put into an order before the floats. That is documented on the ?setsort help page.

The ?sort help page could be more clear about it. It might be that `sort` is still sorting groups by ascending magnitude by default, at all setsort values, but is using setsort to prioritize the order in which integers and floats are put.

Launching Maple with --setsort=6 will get an alternate treatment of integers and floats. (Using setsort=7 may also get it.)

> kernelopts(setsort); # normal default launch
                                       1

> a:=[[1,3.4],[1,5],[1,2.7],[1,16]];
                  a := [[1, 3.4], [1, 5], [1, 2.7], [1, 16]]
 
> sort(a);
                     [[1, 5], [1, 16], [1, 2.7], [1, 3.4]]

And in a new session,

linux% maple13.01 -s --setsort=6

> kernelopts(setsort);
                                       6

> a:=[[1,3.4],[1,5],[1,2.7],[1,16]];
                  a := [[1, 3.4], [1, 5], [1, 2.7], [1, 16]]
 
> sort(a);
                     [[1, 2.7], [1, 3.4], [1, 5], [1, 16]]

It looks as if it deliberately accords with the ?setsort help. It doesn't look like an overlooked compiler warning to me.

That is a good point!

But (purely for the sake of correctness) it is not true for all setsort settings. Eg, --setsort=7 as a launcher option. Of course, that is not the default, and most people will never run Maple with it changed.

While sort(a) gets the desired effect for pure integers under default setsort, it doesn't order by magnitude of the second entry, for a mix of floats and integers . For some tasks, this might matter.

# Maple 13.01

> a:=[[1,3.4],[1,5]];
                            a := [[1, 3.4], [1, 5]]
 
> sort(a);
                              [[1, 5], [1, 3.4]]

That is a good point!

But (purely for the sake of correctness) it is not true for all setsort settings. Eg, --setsort=7 as a launcher option. Of course, that is not the default, and most people will never run Maple with it changed.

While sort(a) gets the desired effect for pure integers under default setsort, it doesn't order by magnitude of the second entry, for a mix of floats and integers . For some tasks, this might matter.

# Maple 13.01

> a:=[[1,3.4],[1,5]];
                            a := [[1, 3.4], [1, 5]]
 
> sort(a);
                              [[1, 5], [1, 3.4]]
First 44 45 46 47 48 49 50 Last Page 46 of 81