nm

11353 Reputation

20 Badges

13 years, 14 days

MaplePrimes Activity


These are replies submitted by nm

@Carl Love 

The way I understand it, is that the degree of the ODE is the degree of highest order
derivative in the ODE when the ODE can be written as a polynomial in derivatives.

If the ODE can not be written as polynomial in the derivatives, then the degree is not defined.

The hard part of this, is to see if the ODE can be written as polynominal in derivatives or not.
(May be Maple has some build in functions to help with this algebra part?)

In a polynomial, all powers must be integers.

Examples
---------
1)  y'= y^(1/2)  

In this, the ODE is allreay a polynomial in derivatives. since it can be written as

      (y')^n = f(x,y)
      
Where n=1. So degree is 1. We do not care above y^(1/2) since that has no derivatives of y(x) in it.

2) y''+ (y')^(1/2) =y.

This is not a polynomial in derivatives. Since powers on all the derivatives are not all integers.      
     
If we can rewrite the above as polynomial (y'')^n + (y')^m = f(x,y) where n,m are integers, then n will be the degree.

<corrected. Thanks to Rouben Rostamian >

For this one, writing it as y'(1/2) = y-y'' and squaring both sides gives

               y' = y^2 -2 y y'' +(y'')^(2)

Now all powers on derivatives are integers.  Power on highest derivative is 2. Hence degree is 2.

3)   (1+ y')^(3/2)  = y''.  

This is Not a polynomial in the derivatives. But squaring both sides gives

         (1+y')^3 = (y'')^2
         1+ 3 y' + 3 (y')^2 + (y')^3 = (y'')^2
         
Now it is a polynomial in derivatives since all powers on each derivative is an integer.
Looking at result, we now find the power on the highest derivative. It is 2. Hence degree is 2.

@Carl Love 

fyi. I found a bug. 

ode:=diff(y(x),x) = x^(1/2);
ODEdegree(ode)

gives 2. But It is clear the degree of the ODE is 1.

@tomleslie 

"You (as author) have control over the order of arguments in the function call, so why use an order that you do not want? "

 

Not everyone works alone. Imagine you are working in a team and looking at others code on the same project.

Having keyword arguments be placed in between positional arguments can be just a little confusing when reading others code as one have to look at required argument.

Imagine a proc that takes many more arguments with mixed positional and keyword.

I always prefer the language itself to enforce something than rely on some convention or something to remember as code is written.

 

@Daniel Skoog 

Thanks. Should the file Visualization.mm  have Data := module() in it and the file Data.mm (after renaming) also have Data := module()

Also, for something meant to be used to learn from, there is NO readme.txt file anywhere, telling one what to  call to make this run. So after I did read("RandomnessTests.mpl") I was saying to myself, ok. Now what do I do? Do I need to make another call to something? 

Maplesoft should be a little bit more effort on this, as these meant to be code to learn from.

@Carl Love 

 

Maplesoft no longer sells this product from its web site

https://www.maplesoft.com/products/toolboxes/IDE/

I actually bought this product from Maple when it came out. Tried it for few days, could never figure how to use it or make it work, it seems to be based on Eclipse.

Called customer support and explained this to them, and they were nice enough to agree to refund my money.

 

@Carl Love 

"Your command subs(sol, ode) is total nonsense because sol is an implicit solution"

yes, I overlooked this, since I was using code to verify   explicit solutions I had and did not pay good attention.

I will remove it now.

@Carl Love 

"if you really actually don't care about a0, let me know"

Maple automatically sometimes does this. For example:

expr:=sin(x)+sqrt(3*x*y);

Maple returns

After more testing, It seems the general pattern which will cover all cases is

               a0 * ( a1 * x ^ a2  OPERATOR a3 * y ^ a4 ) ^ a5  + a6 

Where a0,a1,a2,a3,a4,a5,a6 can be some values and OPERATOR is either +,*,/,- This accounts to everything I tried so far. The following is the notebook. 

If all of this can be done by hastype (in addition to being able to know the values of a_i above, which is important, that that will good to see and I am sure useful for many others. What I have below seems to work for me so far and I am sure it can be improved more.
 

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

foo:=proc(expr,x,y)
  #looks for expression f(x,y) inside radical anywhere.
  local a0,a1,a2,a3,a4,a5,a6;  
  if patmatch(expr, a0::anything*(a1::anything*x^a2::anything * a3::anything*y^a4::anything)^a5::nonunit(radnum)+a6::anything,'la') or
     patmatch(expr, a0::anything*(a1::anything*x^a2::anything + a3::anything*y^a4::anything)^a5::nonunit(radnum)+a6::anything,'la') or
     patmatch(expr, a0::anything^((a1::anything*x^a2::anything + a3::anything*y^a4::anything)^a5::nonunit(radnum))+a6::anything,'la') or
     patmatch(expr, a0::anything^((a1::anything*x^a2::anything * a3::anything*y^a4::anything)^a5::nonunit(radnum))+a6::anything,'la')
then
        print("matched");
  else
        print("did not match");
  fi;
end proc:
seq(foo(expr[i],x,y),i=1..nops(expr))

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

"matched"

 

 

Download parsing.mw

 

@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.

 

 

First 61 62 63 64 65 66 67 Last Page 63 of 91