nm

11558 Reputation

20 Badges

13 years, 135 days

MaplePrimes Activity


These are replies submitted by nm

@acer 

Yes, this helped reduce verbosity in this example, but still due to not able to use "zero or more" method in general with structured type, I find I still need to duplicate things.

Let me give a much simpler example than the above. 

Suppose we want to match  anything*sin(anything)  by making a structured type for this expression.

Since I can't use zero or more, I find I have to duplicate the type using Or or {}.

One time for anything*sin(anything) when anything is not 1, and one for sin(anything) for the case when factor is default 1. Here is an example

TypeTools:-AddType('my_type', {  '`*`'({rational,specfunc(sin)}),   specfunc(sin)   } );
type(2*sin(x),my_type);
type(sin(x),my_type);

The above structured type now matches both cases. Because the first part looks for `*` type and the second one looks for sin(x) on its own. So I had to make separate type for when the leading factor is default 1. Same thing for powers if present like in the example I posted in original post.

I know ofcourse that 2*sin(x) has type `*`  and sin(x) is not type `*` that is why it does not work. Which is completely understandble from point of view of a strong type system. But for finding subexpressions, it means one have to make many types to capture each possible case, while with pattern matching (which does not use structured types), one can, using only one pattern, match a much larger class of subexpressions.

In Mathematica, using the zero or more method for pattern:

type = n_.*Sin[_];
MatchQ[Sin[x], type]
MatchQ[2*Sin[x], type]

And both above gives True match since first one, n_. says zero or more. No need to duplicate things.

I can do the same thing above using Maple's patmatch easily as follows

my_pattern:='n::anything*sin(b::anything)';
patmatch(2*sin(x),my_pattern,'la'); la;
patmatch(sin(x),my_pattern,'la'); la;

But I can't do similar thing with structured type. That is why I think patterns are more flexible for finding subexpressions and for expressions transformation, but everyone here says to avoid patmatch in Maple and use structured types.

@tomleslie 

You should read the question before answering.

I know everything you said and I mentioned that in the question itself. 

I simply was asking if there is a way to do a select or select like function that starts at top level and go down. I currently do a type check first and if that fail, then call select.

 

 

 

@ecterrab 

I actually tried identical(x) as you can see from my post. The problem is that I had {} in there. That is why it did not work.  This is what I tried (copied from my post)

expr:=sin(x)+cos(x)*exp(x)+x*tan(x)*f(x)+x+y;
type_1:={function,typefunc(mathfunc)};
type_2:={symbol,identical(x)};
lis:=indets(expr,  Or( And(type_1),  And(type_2) ))

The above did not work. it gives

Changed the code to remove the {} now it works

expr:=sin(x)+cos(x)*exp(x)+x*tan(x)*f(x)+x+y;
type_1:=function,typefunc(mathfunc);
type_2:=symbol,identical(x);
lis:=indets(expr,  Or( And(type_1),  And(type_2) ))

So I was close (but no cigar). But because I used a list instead of expression sequence, it did not work.

 

@ecterrab 

Thanks, this works. I got confused since I thought I have to have a Maple type in there. And  identical(x) is not a "type" in Maple sense? (as in integer, function, real, symbol, etc...). But good one can supply this. I did not know that before.

 

@Kitonum 

But this adds the symbol x even it does not exist!

 

expr:=sin(x)+cos(x)*exp(x)+tan(x)*f(x);
indets(expr, function) union {x};

gives

Which is wrong.

 

@Thomas Richard 

Thanks, I understand that when x=0 it works. But this is basically verifiying the solution at one location when x=0 only. 

If you just supply ode as the 2nd argument to odetest, it will return 0 as expected. So it‘s the list [ode,ic] that makes trouble here.

This is not the case for me, using Maple 2021.1. 

restart;
ode:=diff(y(x),x)-y(x) = x*y(x)^(1/2):
ic:= y(0)=4:
maple_sol:=dsolve([ode,ic],'explicit'):
odetest( maple_sol,ode);
maple_sol:=dsolve([ode,ic],'implicit'):
odetest( maple_sol,ode);

Both give non-zero above.

Only time it gives zero, if I remove ic altogother from dsolve itsef. Now it gives zero for both cases

restart;
ode:=diff(y(x),x)-y(x) = x*y(x)^(1/2):
ic:= y(0)=4:
maple_sol:=dsolve(ode,'explicit'):
odetest( maple_sol,ode);
maple_sol:=dsolve(ode,'implicit'):
odetest( maple_sol,ode);

zero for both. 

So yes, it is using IC which makes odetest not verify the (now) particular solution. It can only verify the general solution for the ODE.

@Thomas Richard 

Sorry, I am confused. Why are you evaluating the_diff_1  at x=0?  should it not be valid for all x?  

To make sure we are on same page, and I am reading this correctly, when typing this

restart;
ode:=diff(y(x),x)-y(x) = x*y(x)^(1/2):
ic:= y(0)=4:
maple_sol:=dsolve([ode,ic],'implicit');
the_diff_1:=odetest( (lhs-rhs)(maple_sol)=0,[ode,ic])

  

The first entry in the list above is the difference odetest found when verifying the ode itself, and the second entry in the list above is the difference for IC, which is zero.  Correct? i.e the order in the output above, is the same order as in the input, which is [ode,ic].

So Maple verified that the  solution satisfies the IC ok, but not the ode itself, because the first entry is not zero.

But why did you then tell it to evaluate the first entry in the_diff_1 at x=0?  that is my question. Should not this difference be zero for all x, if the solution is valid and not at specific x? 

 

@Katatonia 

to do plots of derivatives, you could do

restart;
g:=x->x-exp(-x);
plot(diff(g(x),x),x=-2..10);
f:=x->2*x+5;
plot(diff(g(x)*f(x),x),x=-2..10)

 

You can see help for plot for more options.  

@Rouben Rostamian  

Thanks. Yes, that is what I basically did. But this is really a manual solution (similar to how one will do it by hand, which is what I did first when I noticed there is ln on both sides of the equation).

I am hoping there might be a more direct way to tell dsolve to do this, via some option or a method I am overlooking.  

@vv 

wow. I never seen such a bug before in Maple.

ps. could someone please make a bug report on this to Maplesoft (SCR?) I do not know how to do this.

(I will change now all my code to use (lhs-rhs)(mysol) = 0 when using odetest.)

thanks.

@Carl Love 

You are right. When I removed the flat option, now both methods give the same output.  So all is OK now. 

 

@Carl Love 

I got a chance to do little  testing. I compared your method with Edgardo's. I found case where they give different output.    Here is the code

restart;
Carl:= expr-> 
    local rad:= anything^fraction;
    subsindets(expr, And(`*`, satisfies(e-> andmap(membertype,[rad, {specop(exp), specop(exp)^anything}],{op(e)}))),
        e-> local d:= ilcm(map2(op, [2,2], indets(e, rad))[]); G(e) #simplify((e^d)^(1/d))
   ):

Edgardo:=expr->subsindets[flat](expr, And(`*`, satisfies(u -> andmap(membertype, [Or(exp(anything), exp(anything)^(-1)), anything^fraction], [op(u)]))), G): 

I changed the operation to just `G` to make it more clear where it is applied and to compare. 

I used this example on the above two procedures to see if they give same result

expr:=exp(sqrt(exp(exp(z)*sqrt(h))))*1/(exp(z)*sqrt(h));
Carl(expr);
Edgardo(expr);

I think what happens is this: Edgardo's method treated the whole numerator exp(sqrt(exp(exp(z)*sqrt(h)))) as say and so the whole input becomes like   A*(exp(z)*sqrt(h))^(-1)  and this pattern matched, so it applied G once to the whole input and stopped.

Your method seems to start from inside out. It found the inner exp(z)*sqrt(h) hidden inside there, applied G to it, then looking outside, it also found the same pattern again and applied G again on the whole thing as shown above.

My cases will not hit such complicated possibilities anyway, but thought to point this out. I am not sure which one is considered the correct output as it might be a matter of interpretation.

Thanks for the help.

 

 

 

 

@ecterrab 

For that reason I mentioned "note that denominators are represented as negative powers". You seem to have not noticed the comment. It is at the beginning of my previous reply. It is the same reply where you missed the example.

I did not miss it. I knew the reason. I just did not know how in Maple to handle it in one call/type as you showed now. It is the same issue in Mathematica, but there I use the command Alternatives. I did not know how to do it in Maple, since I am not as familar with it.

This language is remarkably flexible and expressive,

It is  yes. But not everyone has 40 years experience programming in Maple as you do :)  also, Maple help pages lack many non trivial examples to help someone learn from. Even the Maple programming manual do not have any such detailed examples.Only this, on page 122 of the 2020  version

That is it. 

Thanks for the new version of the code that handles both numerator and denomanitaor at same time. I will test it in my main code later today. 

@Carl Love 

Thanks. I also could not get your method to work on subexpression which happened to be in the denominator

expr:=a*exp(z)*sqrt(h)+exp(z)*sqrt(h)+1/(3*exp(z)*sqrt(h));

It finds the first 2 and transforms them correctly, but not the third one. I did not know how to combine both into one type as I mentioned in the above reply I just made. 

 

@ecterrab 

No. I showed - in the reply you are replying to - how to match that pattern for "any number of operands, 2, 3, or other",

Sorry, I overlooked this new version you had there. I was concentrating on the earlier version you showed using 

u::`&*`(anything $ 2)

You are right, the new version works for any  number. But I could not make it work when the pattern is in the denominator. So I ended up having to run it two times. One for the numerator and one for the denominator. May be there is a better way, but this is what I could find so far. Here is an example

restart;
expr:=a*exp(z1)*sqrt(h1)+exp(z2)*sqrt(h2)+1/(exp(z3)*sqrt(h3));

Your code changes the first two term above, but not the third, because the pattern is in the denominator.  (different type, in Maple talk). So I changed it as follows, by doing 2 passes

restart;
expr:=a*exp(z1)*sqrt(h1)+exp(z2)*sqrt(h2)+1/(exp(z3)*sqrt(h3));
expr:=subsindets[flat](expr, And(`*`, satisfies(u -> andmap(membertype, [exp(anything),  anything^(fraction)],[op(numer(u))]))), e->G(e));
expr:=subsindets[flat](expr, And(`*`, satisfies(u -> andmap(membertype, [exp(anything),  anything^(fraction)],[op(denom(u))]))), e->1/G(denom(e)));

The first pass changes the subexpression in numerator, second passes for the denominator.

I did not know how to make a type that combines both together.  But the above works OK for me now. 

Someone should write a Maple book on just these operations and methods and techniques, as Maple help have very little examples to learn from and no Maple books  I know about even talk about such topics.

 

 

First 36 37 38 39 40 41 42 Last Page 38 of 90