nm

8552 Reputation

19 Badges

12 years, 354 days

MaplePrimes Activity


These are replies submitted by nm

@Carl Love 

I understand what you are saying, I need to learn more about hastype. 

But I do not know now if hastype can do what I want. With patmatch, it can not only detect the pattern, but also give me the specfic values that makes up the pattern it matched.

For example, if I want to detect   ( a1* x^a2 * y^a3 )^a4   Where a1,a2,a3,a4 are things that be different in different cases. Then I can do 

restart;
expr:=(3*x^7*y^(-1/2))^(3/4);
patmatch( expr, a0::anything * (a1::anything*x^a2::anything*y^a3::anything)^a4::anything,'la');
assign(la);

And now not only the expression is detected, but I also can look at the specific values

a0;
a1;
a2;
a3;
a4;

    3^(3/4)
   1  
   7
   -1/2
   3/4

And then decide in the code if I want to do something different based on these values. These values can be different each time as the input can be anything.

I do not know if hastype can do all this now as I just found about it. if it can, will start using it.,

@tomleslie 

Thanks.

This seems to work on tests I did so far. I need to test it more.

I had to slightly change it to make it accept more variations that I wanted and rewrite it in more traditional  Maple style as I find the terse Maple coding style very hard for me to read. I also like to use proc(), so that sometimes I can add extra local variables if needed internally and for debugging, and this makes it easier.

Here is what I have so far

restart;
expr:=[sin(x)*(x*y)^(1/3),
       sin(x)+(x*y)^(1/6),
       sin(x)*sqrt(x/y)+3,
       10+sin(x)*sqrt(a*y*x)+3*x,
       sqrt(x)/sin(x)*sqrt(y*x^2)+3*x];

f:=proc(ex)
   if type(ex,`+`) then
      g~([op( ex)]);
   else
      [op(ex)];
   fi;
end proc;

g:=proc(ex)
   if type(ex,`*`) then
      op(ex);
   else
      ex;
   fi;
end proc;

getMatch:= proc(expr,x,y)
    if ormap( patmatch, f(expr),(a1::anything*x^a2::anything*y^a3::anything)^c::nonunit(radnum),'la') then
       printf("Pattern Match with c=%a\n", eval(c, la));
    else
       printf("No Match\n")
    fi;
end proc;

And now

seq(getMatch(expr[i],x,y),i=1..nops(expr))

Pattern Match with c=1/3
Pattern Match with c=1/6
Pattern Match with c=1/2
Pattern Match with c=1/2
Pattern Match with c=1/2

 

 

@Carl Love 

+1 for hastype, I did not know about it. Will see if it can do everything patmatch can do. I like patmatch, except as I said, I have to repeat the code for different operator each time. At least 3 times to cover all cases.

@tomleslie 

+1 for the ormap. I did not know about it. But I am afraid your method does not work for general expression. For example 

                    sin(x)*(x*y)^(1/3)+3

Now it does not match. The input expression can be anything as I mentioned in my question and my reply to Carl above. The idea is that I need to detect a pattern inside a larger expression, which can be as complicated as one wants. 

 

@Carl Love 

Nothing wrong with using has() in this case. But I was just making a simple example. (if has() can do everything patmatch can, then patmatch would not be needed :)  So may be this can be considered as an exercise to do with has() did but using patmatch instead.

For example, suppose I want to detect for  radical with power between say 1/6 and 1/3, as in

 sin(x)*(x*y)^(1/3)  or sin(x)+(x*y)^(1/6)

Then I would write 

restart;
expr:= sin(x)*(x*y)^(1/3);
if patmatch(expr,a::anything*(b::anything*x*y)^(c::anything),'la') then
    print("Pattern match");
    assign(la);
    if c >= 1/6 and c<= 1/3 then
       print("found pattern");
    else
       print("did not find pattern");
    fi;
 else
   print("did not find pattern");
 fi;

 

And would have to do it again using

if patmatch(expr,a::anything+(b::anything*x*y)^(c::anything),'la') then

Actually, it gets worst. If I want to ckeck for SOMETHING +*  my_pattern +* SOMETHING which is most general.I'd have to make 3 cases, not just 2

if patmatch(expr,a::anything+(b::anything*x*y)^(c::anything)+d::anything,'la') then
...
if patmatch(expr,a::anything+(b::anything*x*y)^(c::anything)*d::anything,'la') then
...
if patmatch(expr,a::anything*(b::anything*x*y)^(c::anything)+d::anything,'la') then
...

So, yes has() works in the example I posted, but this was just a simple example. I still want to use patmatch and tell Maple that the operator between the terms can be  * or + without having to duplicate code for each case, that is why I asked.

 

@DJJerome1976 

Maple is weak in this area.

It does not even have a function that returns the real domain of a function, similar to Mathematica's  https://reference.wolfram.com/language/ref/FunctionDomain.html

Maple can give one a list of singularties, sure, and using icont() or using discont() on the real line. But this is only half the story. 

Maple needs the equivlant of Mathematic'a FunctionDomain, which was introduced almost 6 years ago by now.

May be Maple in the next version will have something like this. This must be hard to implement, else Maplesoft would have such a function by now I would think.

@ecterrab 

"Anyway, for the example you indcate, in my opinion the degree is 1, not 2, since it is linear in the highest derivative"

I think the degree is 2 and not 1, since the powers have to be integers on all derivative first before deciding:

This is how I learned it at school. Any way, thanks again for the link and the help.

@ecterrab 

Thanks. But I can't figure how to use it to tell me for example that  (1+diff(y(x),x)^2)^(3/2) = diff(y(x),x$2) has degee 2. I do not understand what a differential polynomial or a differential ideal or a differential polynomial ring is or how to make them from the ODE.These are a little advanced topics for me, I have not studied these yet.

 

 

@Rouben Rostamian  

I am sorry, I do not understand why you said that the degree is not defined for the first example you show.

The first one has degree one, since the power on the highest derivative is one. Using Carl's code given in answer below confirms:

ode:= diff(x(t),t$2)+sin(x(t))=0;
ODEdegree(ode);

           1

The degree becomes 2 in this case

ode:= diff(x(t),t$2)^2+sin(x(t))=0;
ODEdegree(ode);

    2

@Rouben Rostamian  

 

https://en.wikipedia.org/wiki/Degree_of_a_differential_equation

"In mathematics, the degree of a differential equation is the power of its highest derivative, after the equation has been made rational and integral in all of its derivatives"

I need to find this during parsing of ODE to help me decide if I can solve it or not.

@Thomas Richard 

thanks. But it is strange, that Maple, being the best CAS in ODE's does not have a buildin function to find the degree of an ODE in addition to the order.

May be this is something Maplesoft could add for the next release.

First, you do not need to write “c://Users//hello//Documents//h.m”. it is either “c:/Users/hello/Documents/h.m” or  “c:\\Users\\hello\\Documents\\h.m”

But have you tried to open h.m  yourself from outside Maple? does it work? And have you tried to check what security there are on the folder itself?

@Carl Love 

There is still a case which is given a problem. This is what Maple returns solutions as sequence of lists. Here is example


 

restart;

depvars:= (pde::{algebraic, `=`(algebraic), {set,list}(algebraic, `=`(algebraic))})->
   indets(
      indets(convert(pde, diff), specfunc(diff)),
      And(typefunc(name, name), Not(typefunc({mathfunc, identical(diff)})))
   ):

is_solution_trivial:= (pde, sol::{`=`, set(`=`),`function`})->
   evalb(eval(`if`(sol::set, sol, {sol}), depvars(pde)=~ 0) = {0=0}):


pde:= diff(u(x,t),t)= u(x,t)*(1-u(x,t))+ diff(u(x,t),x$2):
sol:={PDEtools:-TWSolutions(pde,u(x,t))};
is_solution_trivial(pde,sol)

{{u(x, t) = 1}, {u(x, t) = (1/4)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = (1/4)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh((5/12)*t+(1/12)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t+(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = -(1/4)*tanh((5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh((5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}}

Error, invalid input: is_solution_trivial expects its 2nd argument, sol, to be of type {`=`, function, set(`=`)}, but received {{u(x, t) = 1}, {u(x, t) = (1/4)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = (1/4)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*t ... )*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}}

sol

{u(x, t) = 1}, {u(x, t) = (1/4)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = (1/4)*tanh((5/12)*t+(1/12)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t+(1/12)*6^(1/2)*x+_C1)+1/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh((5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)^2-(1/2)*tanh(-(5/12)*t-((1/12)*I)*6^(1/2)*x+_C1)+3/4}, {u(x, t) = -(1/4)*tanh((5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)^2+(1/2)*tanh((5/12)*t+((1/12)*I)*6^(1/2)*x+_C1)+3/4}

convert([sol],`sequence`)

Error, unrecognized conversion: sequence

 


 

Download bug_june_25_2019_2.mw

I had to put {} around the result, since it is sequence, in order to make it a list.  But now it becomes a list of lists, and this is why it gives an error. I'll see if I can find a work around for this case.

 

 

@Carl Love 

Hello; I found a small bug. Sometimes pdsolve returns a solution which of type 'function', and hence your is_solution_trivial function now fails on it. Here is an example


 

restart;

unassign('u,x,t');
depvars:= (pde::{algebraic, `=`(algebraic), {set,list}(algebraic, `=`(algebraic))})->
   indets(
      indets(convert(pde, diff), specfunc(diff)),
      And(typefunc(name, name), Not(typefunc({mathfunc, identical(diff)})))
   );

is_solution_trivial:= (pde, sol::{`=`, set(`=`)})->
   evalb(eval(`if`(sol::set, sol, {sol}), depvars(pde)=~ 0) = {0=0});

pde:= diff(u(x,t),t)-diff(u(x,t),x,x,t)+4*u(x,t)*diff(u(x,t),x)=3*diff(u(x,t),x)*diff(u(x,t),x$2)+u(x,t)*diff(u(x,t),x$3);
sol:=pdsolve(pde,u(x,t));

is_solution_trivial(pde,sol)

proc (pde::{algebraic, `=`(algebraic), ({list, set})(algebraic, `=`(algebraic))}) options operator, arrow; indets(indets(convert(pde, diff), specfunc(diff)), And(typefunc(name, name), Not(typefunc({mathfunc, identical(diff)})))) end proc

proc (pde, sol::{`=`, set(`=`)}) options operator, arrow; evalb(eval(`if`(sol::set, sol, {sol}), `~`[:-`=`](depvars(pde), ` $`, 0)) = {0 = 0}) end proc

diff(u(x, t), t)-(diff(diff(diff(u(x, t), t), x), x))+4*u(x, t)*(diff(u(x, t), x)) = 3*(diff(u(x, t), x))*(diff(diff(u(x, t), x), x))+u(x, t)*(diff(diff(diff(u(x, t), x), x), x))

PDESolStruc(u(x, t) = _F1(x)*_F2(t), [{diff(_F2(t), t) = _c[2]*_F2(t)^2, diff(diff(diff(_F1(x), x), x), x) = -(diff(diff(_F1(x), x), x)-_F1(x))*_c[2]/_F1(x)-(diff(_F1(x), x))*(3*(diff(diff(_F1(x), x), x))-4*_F1(x))/_F1(x)}])

Error, invalid input: is_solution_trivial expects its 2nd argument, sol, to be of type {`=`, set(`=`)}, but received PDESolStruc(u(x, t) = _F1(x)*_F2(t), [{diff(_F2(t), t) = _c[2]*_F2(t)^2, diff(diff(diff(_F1(x), x), x), x) = -(diff(diff(_F1(x), x), x)-_F1(x))*_c[2]/_F1(x)-(diff(_F1(x), x))*(3*(diff(diff(_F1(x), x), x))-4*_F1(x))/_F1(x)}])

whattype(sol)

function

 


 

Download bug_june_25_2019.mw

I add `function` as one of allowed types to accept, and now it seems to work OK. I hope this was the correct way to fix this.

 


 

restart;

depvars:= (pde::{algebraic, `=`(algebraic), {set,list}(algebraic, `=`(algebraic))})->
   indets(
      indets(convert(pde, diff), specfunc(diff)),
      And(typefunc(name, name), Not(typefunc({mathfunc, identical(diff)})))
   ):

is_solution_trivial:= (pde, sol::{`=`, set(`=`),`function`})->
   evalb(eval(`if`(sol::set, sol, {sol}), depvars(pde)=~ 0) = {0=0}):

pde:= diff(u(x,t),t)-diff(u(x,t),x,x,t)+4*u(x,t)*diff(u(x,t),x)=3*diff(u(x,t),x)*diff(u(x,t),x$2)+u(x,t)*diff(u(x,t),x$3):
sol:=pdsolve(pde,u(x,t));

is_solution_trivial(pde,sol)

PDESolStruc(u(x, t) = _F1(x)*_F2(t), [{diff(_F2(t), t) = _c[2]*_F2(t)^2, diff(diff(diff(_F1(x), x), x), x) = -(diff(diff(_F1(x), x), x)-_F1(x))*_c[2]/_F1(x)-(diff(_F1(x), x))*(3*(diff(diff(_F1(x), x), x))-4*_F1(x))/_F1(x)}])

false

 


 

Download bug_june_25_2019_fixed.mw

 

Maple 2019.1

 

@Carl Love 

Thanks. Your functions worked very well. Verified on Maple 2019.1

First 41 42 43 44 45 46 47 Last Page 43 of 71