pagan

5147 Reputation

23 Badges

17 years, 126 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 answers submitted by pagan

Instead of posting Matlab code to be "translated", perhaps you could state clearly what it is that you hope to accomplish in Maple?

Are you you trying to duplicate a way in which Matlab can overlay a currently displayed plot with new points?

If that's the case, then you could use a Plot Component Plot0, say. Just keep a Maple table (or, suboptimally a list) of the points generated so far. Each time through the Maple for-loop you can do all the following steps: Add a new point to the table. And then form a new listlist of all points computed so far. Then call plots:-pointplot using the updated list and assign to P. Then call DocumentTools:-SetProperty(Plot0,'value',P,'refresh') to update the Plot Component. There is a slight flash each time through the loop. But it gives the effect of a plot that is updating in time. The big difference between this and an animation is that the plot is updated precisely when each new individual point is calculated, in contrast to an animated plot sequence which can only be done after all points are computed.

An &+- tolerance is just a pretty-printed INTERVAL object.

> with(Tolerances):

> G:=proc(x,a,b)
> INTERVAL(x-a .. x+b);
> end proc:

> G(4.5,5,10); # producing 4.5 (-5 to +10)
7.00 +- 7.50
> op(%);
-0.5 .. 14.5

Of course, this doesn't help you enter in as a preadjusted bit of 2D Math input.

Some other responses produce "7" instead of "07" for the output month.

It's noted that you explicitly wrote you wanted the same day, a month ago, and not 30 days ago.

An earlier response using `mod` returns 0 as the output month when the input month is January (01).

> restart:

> G:=proc(x::string)
> local pt;
>   pt:=StringTools:-ParseTime("%Y-%m-%d",x);
>   if (pt:-month=3 and pt:-monthDay>28) or
>      (member(pt:-month,[5,7,10,12]) and
>       pt:-monthDay=31) then
>     error "no such day of the month";
>   end if;
>   convert(cat(
>       `if`(pt:-month=1,pt:-year-1,pt:-year),
>       "-",`if`(pt:-month<11 and pt:-month>1,0,NULL),
>       1+(pt:-month-2 mod 12),
>      "-",pt:-monthDay),string);
> end proc:

> StringTools:-FormatTime("%Y-%m-%d");
                          "2010-08-25"
> G(%);
                          "2010-07-25"
> G("2010-01-17");
                          "2009-12-17"
> G("2010-12-17");
                          "2010-11-17"
> (G@@12)("1976-06-13");
                          "1975-06-13"
> G("2010-03-30");
Error, (in G) no such day of the month

You could check that I have the exceptional cases correct.

You don't need to assign the values to `a` and `b`, in order to use the solution. For example:

> y1:=a^4+b-3=0:

> y2:=a^3+b^2+2=0:

> solution:=fsolve({y1, y2});

             {a = -1.402752934, b = -0.8719054433}

> eval(a+b^2, solution);

                         -0.6425338319

> eval([a,b], solution);

                 [-1.402752934, -0.8719054433]

> aval,bval := op(eval([a,b], solution));

                  -1.402752934, -0.8719054433

> aval, bval;
                  -1.402752934, -0.8719054433

> sin(eval(b, solution));

                         -0.7655562292

If you really want to, you can alternatively do assign(solution) and actually assign to `a` and `b`. But then it'd be more work to subsequently create new equations involving the symbolic names `a` and `b` instead of their assigned numeric values. (Ie, you'd have to unassign them.)

Since you mention "expanded", there is this.

F:=1 + Q*x^2 + P*x^3;
a:=x^2/L^2;
a*expand(F/a);
expand(%);

A little more extreme is this.

``(a)*expand(F/a);
expand(%);

An easy way is to simply call f() at a sequence of points in your intended range. Then form two separated collections, using that result. Both will be fodder for plots:-pointplot, as either listlists or 2byN Matrices.

A disadvantage with that approach is that you have to specify the sampling points. And so it takes away the ability of plot() to refine its grid as it sees fit, dynamically. Sometimes that is needed to get the nice smooth picture.

An alternative is to let plot() do its thing for just one of the two curves, but to store the data (produced incidentally) and then use that in a pointplot for the other curve. In this scenario, only one of the two curves will have to potentially suffer from using a pre-specified sampling grid. Here is an example.

f:=proc(t) [sin(t),10^10*cos(t)]; end proc:

F:=proc(t)
  global T;
  local res;
  res := f(t);
  T[t]:=res[2];
  res[1];
end proc:

plot(F,0..6);

plots:-pointplot(map([lhs,rhs],sort(op(eval(T)),(a,b)->lhs(a)<lhs(b))),connect,color=red);

If you want plot() to be able to dynamically adjust its sampling, for both curves, then I don't see how it can be done easily except by two calls to plot() and two full passes of calling f().

Who knows, though. Maybe there is some really simple solution that I'm overlooking.

I am not saying that `RootOf/sort` gets used here, but the order does match, in terms of how the result is sorted by its numeric coefficients. So perhaps `solve` is doing something similar.

I'll evaluate at k=1 below only because I choose to sort the numeric coefficients here, and not because I fail to recognize that other values of k would (obviously) affect things.

G:=solve(diff(x^6,x)=k,x);
evalf(eval([G],k=1)); # so, how is this order chosen?
map(evalf,[G]); # it is the same as this, btw
sort(%); # ok, it's clearly not just the usual `sort`
`RootOf/sort`(%);
showstat(`RootOf/sort`); showstat(`RootOf/sort1`);

Basically, it is something like r1,r3,r2,r4 (after a little more poking, and often in that order) from these:

> showstat(`RootOf/sort1`,16..19);

`RootOf/sort1` := proc(aa)
local r1, r2, r3, r4, F3, F4, c3, c4, u, r, i, a, tm;
       ...
  16   r1 := select(t -> Im(t[1]) = 0 and 0 <= Re(t[1]),a);
  17   r2 := select(t -> Im(t[1]) = 0 and Re(t[1]) < 0,a);
  18   r3 := select(t -> 0 < Im(t[1]),a);
  19   r4 := select(t -> Im(t[1]) < 0,a);
       ...
end proc

Is this something like your goal? You first asked how to get a row into the DropDownBox, but then later seemed to describe entries from a column.

with(Maplets:-Elements):

A:=Array(1..3,1..3,[[a,b,c],[d,e,f],[g,h,i]]):

f:=proc() local L,u;
L:=convert(A[2..,parse(Maplets:-Tools:-Get('colDDB'))],'list');
Maplets:-Tools:-Set('myDDB'('itemlist')=map(u->convert(u,'string'),L));
L; end proc:

mymaplet := Maplet([
["Update this drop box of column entries... ",
DropDownBox['myDDB'](map(u->convert(u,string),
convert(A[2..,op(1,rtable_dims(A)[2])],'list')))],
["...by selecting a column from this drop box: ",
DropDownBox['colDDB']([seq(i,i=rtable_dims(A)[2])],
'onchange'=Evaluate('TF'='f()'))],
[TextField['TF']()],
[Button("OK", Shutdown())]
]):

Maplets:-Display(mymaplet);

I also threw in a text box to show the items more clearly. But of course I don`t know what your Maplet will do with it all.

I suppose that you have some candidate form of the equation in mind (for which you know the placement of the parameters). See ?Statistics,Fit or ?Statistics,NonlinearFit or even ?CurveFitting

Use Array, not array. You can use ArrayTools:-Copy, or simply square-bracket indexing to do the copying or assignment. No, map is not really well-suited here.

Edit: now that I have time to type...

restart:
a:=Array(1..10,1..10):
b:=Array(1..10,[1,2,3,4,5,6,7,8,9,8]):
ArrayTools:-Copy(10,b,0,1,a,0,10);
a;

restart:
a:=Array(1..10,1..10):
b:=Array(1..10,[1,2,3,4,5,6,7,8,9,8]):
a[1]:=b: # or use a[1,1..] or a[1,1..10] or a[1,1..-1]
a;

Clearly the second way is simpler. The first way has an advantage of not creating any new Array object in the case that you only wanted to copy a sub-portion of b (which is not true for your example).

Do you know how to find the integral of exp(x)*sin(x)? If so, then you can rewrite sinh(x) by converting it to `exp` form.

For exp(x)*sin(x), if you are not familiar with the trick, you can do it twice by parts. After the first "by parts", you get a sum, the second piece of which is the integral of exp(x)*cos(x). So then you apply the "by parts" rule to that bit too. This ends up giving you,

Int(sin(x)*exp(x),x)

= -exp(x)*cos(x)-Int(-exp(x)*cos(x),x)

= -exp(x)*cos(x)+exp(x)*sin(x)-Int(sin(x)*exp(x),x)

Now, look at that last term! It's the same as the original problem. So you can "move it to the other side" of the equation, obtaining 2*Int(sin(x)*exp(x),x) on the LHS. Then divide both sides by 2.

You can use the same trick for Int(sin(x)*exp(-x),x), and thus you know how to do all bits of this

> convert(sinh(x),exp)*sin(x): expand(%);
                   1                  sin(x) 
                   - sin(x) exp(x) - --------
                   2                 2 exp(x)

If you can follow all that, then you should be able to do Int(exp(2*x)*sin(3*x),x) and thus also Int(sinh(2*x)*sin(3*x),x) using the same technique.

It looks like a false intermediate result is being returned when (at least some part of) the objective is evaluated and produces an non-real (imaginary or undefined) value.

If your expression is `e`, try this

simplify(e) assuming a>0, a<1, B>0, B<1, G>0, G<1;

Optimization[Interactive](%);

Alternatively, try using bounds just a little greater than zero and smaller than 1, like 0.001 and 0.999, to avoid parts of the unsimplified expression from producing a nonreal value upon evaluation at the boundaries.

Curiously, it seems to work ok for the 'modifiednewton method, with the unsimplifed objective and the full ranges.

> Optimization:-NLPSolve(e,a=0..1,B=0..1,G=0..1,initialpoint=[G=0.1],method=modifiednewton,
> maximize);
[0.750000000000000000,

[B = 1.0, G = 1.0, a = 1.0]]

But with the 'sqp' method it runs into trouble for the unsimplified expression. (So maybe that's the default used by the Assistant, if not by Maximize!?)

> Optimization:-NLPSolve(e,a=0..1,B=0..1,G=0..1,initialpoint=[G=0.1],method=sqp,
> maximize);
Warning, undefined value encountered
Error, (in Optimization:-NLPSolve) number expected for float[8] parameter, got HFloat(HFloat(undefined))+HFloat(HFloat(undefined))*I

> f:=simplify(e) assuming a>0, a<1, B>0, B<1, G>0, G<1:

> Optimization:-NLPSolve(f,a=0..1,B=0..1,G=0..1,initialpoint=[G=0.1],method=sqp,
> maximize);
[0.750000000900000074,

[B = 1.0, G = 1.0, a = 1.0]]

See here, perhaps.

One cheap and dirty trick is to rewrite your procedure EIG as a piecewise, or with conditionals inside it. If any of the arguments are not "within bounds" then EIG can be edited to return instead some arbitrary huge value that you just make up. That way, the minimum shouldn't be found as any point outside bounds. (For maximization, you use a large negative value.)

This can sometimes work OK when using nonlinearsimplex as the method, provided that you supply an initial point which is inside bounds (which you are already doing). The objective is no longer differentiable at the boundary, but in practice that aspect seems to not present many problems.

The alternative of using sqp as the method, say, has problems for operator objectives like your EIG. See here, which shows a workaround that involves handling of the objectivegradient but not of the constraintjacobian.

restart;

# Preben Alsholm's suggestion
G:=(1/2)*exp(sqrt(omega)*h/sqrt(nu)):
F:=1/2*exp(sqrt(omega/nu+m^2)*h):
combine(F/G):
convert(series(%,nu=0,3),polynom):
sol1:=G*%:

# another way
z:=sinh(sqrt(omega/nu+m^2)*h):
sol2:=convert(MultiSeries:-series(z,nu=0),polynom) assuming omega>0, h>0:

> expand(sol1-sol2);
0

plot(eval([z,sol2,sol1],[h=1/10,omega=3,m=2]),nu=0.001..0.02);
First 29 30 31 32 33 34 35 Last Page 31 of 48