nm

11643 Reputation

20 Badges

13 years, 144 days

MaplePrimes Activity


These are replies submitted by nm

@Preben Alsholm 

Thanks, I did not know about 

frontend(solve,[eq,A],[{`=`}]);

I do not think I want to replace solve with isolate. I had cases where isolate did not do as well as solve in all case.

But do you recommend then changing solve to use frontend in front of it as you show? I am not sure now what the ramification of doing this. Will solve still work the same as before, but without the auto simplication part? If that is the only difference, then I will switch to using frontend(solve...) but since I never used it before like this, I need to first find out if it will have any negative effects in other cases or not.

 

 

@Rouben Rostamian  

You are "misleading" Maple into looking at the ODE as one of the d'Alembert type. 

but it is d'Alembert ode. Maple itself says so

restart;
ode:=diff(y(x),x)=sqrt(1+x+y(x)):
DEtools:-odeadvisor(ode)

Another point, is that surely Maple will not have given a solution using a method if the method is not applicable to the ODE?

Maple ode solver is the best in the industry, and will not just use the wrong method on an ode and give wrong solutions without any checking internally that the method is applicable to the ode.

 don't impose the dalembert requirement.  

I am not imposing anything. When the advisor gives the types of the ode, then a user can select which method to apply. Without this, Maple internally chooses one. 

restart;
ode:=diff(y(x),x)=sqrt(1+x+y(x)):
DEtools:-odeadvisor(ode);
dsolve(ode);

sol:=DEtools:-dalembertsol(ode);
sol:=DEtools:-genhomosol(ode);

 

 

If one tries to tell Maple to use a method not applicable to the ode, it will produce no solutions as expected. But it can't just make up ones.

ode:=diff(y(x),x)=sqrt(1+x+y(x)):
DEtools:-abelsol(ode)

fyi, ,I found a workaround.

restart;
ode:=diff(y(x),x)=x*(y(x)^2-1)^(2/3);
sol:=DEtools:-exactsol(ode);
odetest(sol,ode);

diff(y(x), x) = x*(y(x)^2-1)^(2/3)

{-(1/2)*(y(x)^2-1)^(2/3)*x^2/((y(x)-1)^(2/3)*(y(x)+1)^(2/3))+Intat(1/((_a-1)^(2/3)*(_a+1)^(2/3)), _a = y(x))+_C1 = 0}

0

 

Download workaround.mw

@Carl Love 

Yes, the first and second trivial solutions y=1, and y=-1 do verify the original ode ofcourse.

But the third solution from the your cubed ode did not verify the original before cubing it. It does verify the cubed ode.

btw, you have small typo  

odetest~(sol);

should be 

odetest~(sol,ode);

my code:

restart;
original_ode:=diff(y(x),x)=x*(y(x)^2-1)^(2/3);
ode:= diff(y(x),x)^3 = x^3*(y(x)^2-1)^2;
sol:= [dsolve(ode)];
odetest~(sol,ode);  #verifies all 3 for the cubed ode

odetest(sol[1],original_ode);  #verifies (trivial sol)
odetest(sol[2],original_ode);  #verifies (trivial sol)
odetest(sol[3],original_ode);  #does not verify

I tried your method on simpler ode. Cubing the ode gives 3 solutions, and one general solution of these is expected to verify the original ode.  Here is an example below. But in the above example, we see that the third general solution from the cubed ode did not verify the original ode. So that is still a problem.

original_ode:=diff(y(x),x)=x^(2/3);
cubed_ode:=diff(y(x),x)^3=x^2;
dsolve(original_ode);
sol:=[dsolve(cubed_ode)];
odetest(sol[1],original_ode);  #verifies OK (general solution)
odetest(sol[2],original_ode);
odetest(sol[3],original_ode);

@Axel Vogt 

Thanks for the workaround. Although it helped in few verifications that failed earlier to verify, I found cases where it still fail. Here is an example below.

I really think Maple's odetest with series method should be much improved for series solutions. It is supposed to verify series solution. A user should not have to go through all of this to verify a series solution to an ODE, specially if the solution is Maple's own solution.
 

interface(version);

`Standard Worksheet Interface, Maple 2022.1, Windows 10, May 26 2022 Build ID 1619613`

restart;

Example 7

 

Order:=6;  
ode:=x^2*diff(y(x), x$2) + (cos(x)-1)*diff(y(x), x) + exp(x)*y(x) = 0;
sol:=dsolve(ode,y(x),type='series',x=0): # simplify(%):
sol1:=eval(%, _C2=0):
sol2:=eval(%%, _C1=0):
'rhs(sol1)+rhs(sol2)= rhs(sol)';
is(%);

6

x^2*(diff(diff(y(x), x), x))+(cos(x)-1)*(diff(y(x), x))+exp(x)*y(x) = 0

rhs(sol1)+rhs(sol2) = rhs(sol)

true

rhs(sol1):
Y:= unapply(%, x):
eval(lhs(ode), y=Y):
MultiSeries:-asympt(%, x);
#convert(%,polynom);

Error, (in simpl/min) complex argument to max/min: -13/2+1/2*I*3^(1/2)

rhs(sol2):
Y:= unapply(%, x):
eval(lhs(ode), y=Y):
MultiSeries:-asympt(%, x);
#convert(%,polynom);

Error, (in simpl/min) complex argument to max/min: -13/2-1/2*I*3^(1/2)

 


 

Download method_not_verified_for_all.mw

 

@vv 

"It is obvious that the result of odetest cannot be 0, because sol is a truncated series."

Humm. But odetest in this case knows this is series solution, so it is not comparing it with an exact solution,

It knows the order (which is same). I've used odtest to verify my series solution to ode for years.

Then how do you explain that odetest works on thousands of cases of series solutions and give zero, except for only few (for reasons I do not know).
 

restart;

Order:=6;
ode:=(4*x^2+16*x+17)*diff(y(x),x$2)=8*y(x);
sol:=dsolve(ode,y(x),type='series',x=-2);
odetest(sol,ode,'series','point'=-2);

6

(4*x^2+16*x+17)*(diff(diff(y(x), x), x)) = 8*y(x)

y(x) = series(y(-2)+(D(y))(-2)*(x+2)+(4*y(-2))*(x+2)^2+((4/3)*(D(y))(-2))*(x+2)^3-((16/15)*(D(y))(-2))*(x+2)^5+O((x+2)^6),x = -2,6)

0

restart;

Order:=6;
ode:=12*x^2*(1+x)*diff(y(x),x$2)+x*(11+35*x+3*x^2)*diff(y(x),x)-(1-10*x-5*x^2)*y(x)=0;
sol:=dsolve(ode,y(x),type='series',x=0);
odetest(sol,ode,'series','point'=0);

6

12*x^2*(1+x)*(diff(diff(y(x), x), x))+x*(3*x^2+35*x+11)*(diff(y(x), x))-(-5*x^2-10*x+1)*y(x) = 0

y(x) = _C1*(series(1-x+(7/8)*x^2-(19/24)*x^3+(283/384)*x^4-(1339/1920)*x^5+O(x^6),x,6))/x^(1/4)+_C2*x^(1/3)*(series(1-x+(28/31)*x^2-(1111/1333)*x^3+(57493/73315)*x^4-(3668716/4912105)*x^5+O(x^6),x,6))

0

restart;

Order:=6;
ode:=10*x^2*(1+x+2*x^2)*diff(y(x),x$2)+x*(13+13*x+66*x^2)*diff(y(x),x)-(1+4*x+10*x^2)*y(x)=0;
sol:=dsolve(ode,y(x),type='series',x=0);
odetest(sol,ode,'series','point'=0);

6

10*x^2*(2*x^2+x+1)*(diff(diff(y(x), x), x))+x*(66*x^2+13*x+13)*(diff(y(x), x))-(10*x^2+4*x+1)*y(x) = 0

y(x) = _C1*(series(1+x+(14/13)*x^2-(556/897)*x^3-(5314/9867)*x^4+(2092186/2121405)*x^5+O(x^6),x,6))/x^(1/2)+_C2*x^(1/5)*(series(1+(3/17)*x-(7/153)*x^2-(547/5661)*x^3+(26942/266067)*x^4+(200432/3991005)*x^5+O(x^6),x,6))

0

Order:=6;
ode:=2*x^2*(3+x)*diff(y(x),x$2)+x*(1+5*x)*diff(y(x),x)+(1+x)*y(x)=0;
sol:=dsolve(ode,y(x),type='series',x=0);
odetest(sol,ode,'series','point'=0);

6

2*x^2*(3+x)*(diff(diff(y(x), x), x))+x*(1+5*x)*(diff(y(x), x))+(1+x)*y(x) = 0

y(x) = _C1*x^(1/3)*(series(1-(4/9)*x+(14/81)*x^2-(140/2187)*x^3+(455/19683)*x^4-(1456/177147)*x^5+O(x^6),x,6))+_C2*x^(1/2)*(series(1-(3/7)*x+(15/91)*x^2-(15/247)*x^3+(27/1235)*x^4-(297/38285)*x^5+O(x^6),x,6))

0

 


 

Download series_ode_test_work_examples.mw

@Joe Riel 

Thanks,. But this solution is like having external separate module. The methods in that module are no longer part of the object and can't access private data in the object.  

I came up with a workaround. I am not too unhappy with it. It allowes me to split methods into separate name spaces and still have everything part of the object. It uses manual naming convention.

I put methods that I want to put under different name space in different files called   name_space.mpl   and then from the object, call these methods using   name_space__method1() and name_space__method2() and so on  

In the object module itself, I add 

$include  "name_space.mpl" 
 

Here is an example


----------------- file  A.mpl ----------
restart;

A:=module() 
    option object; 
    local name::string:="";  

    export ModuleCopy::static:= proc( self, proto, name::string, $)          
         self:-name := name;
    end proc;

$include  "B.mpl"  
$include  "C.mpl"  

    export process_1::static:=proc(_self,$)
       if name="me" then
           _self:-B__process();
       else
          _self:-C__process();
       fi;
    end proc;
    
end module; 

--------- file B.mpl ------
     local B__process::static:=proc(_self,$)
           print("in B__process ",_self:-name);
           _self:-B__do_more_processing();
    end proc;

     local B__do_more_processing::static:=proc(_self,$)
          #.......
    end proc;

    #any local method in this file must start with B__ prefix

--------- file C.mpl ------
     local C__process::static:=proc(_self,$)
           print("in C__process ",_self:-name);
    end proc;

    #any local method in this file must start with C__ prefix

 

So I just have to stick to this convention and I think it will work out. Again, the purpose of this is to help me manage large number of methods into separate spaces but at the same time keep everything as part of one object. I tested this on a much larger example I have and it is working well so far.   The methods in B.mpl and C.mpl are part of the object and behave the same exact way as other private methods. Just in different files now and have naming convention that match the file name.

Not perfect, but I see no other alternative other than having everything in one large name space which is not good.

 

@Joe Riel 

 use the Object procedure to copy an object

If there is no constructor defined for an object, and I have only data members in the object (no methods). So the object is like a Record.

I find that copy(object) behaves the same as Object(o).  I see no difference. Here is an example

A:=module()
  option object;
  export name:="me";
  export id:=100;
  export b := Array(2..3,-1..1,[[1,2,3],[4,5,6]]);
end module;

o:=Object(A)

And now I want to make copy of this object . This works

o2:=copy(o);
o2:-b;

And this also works

o3:=Object(A,o);
o3:-b

But since there is no constructor defined, does Maple then in the second case above, copies all the data members from to new object? 

Why would one use the new_object:=Object(A,old_object); call if new_object:=copy(old_object) works the same? 

Thanks

@epostma 

"Unfortunately, this is a known limitation in the current versions of Maple. "

Here we are, 4 years later and this limitation is still there.

This is sad.

Maplesoft is busy making lots of clickable GUI apps that runs on the cloud for high school students but have no time to fix such a basic fundamental  limitation in its product?

Can not put an object module inside another module? This is not important enough to fix?

Clearly Maplesoft is not serious about OOP.  The documentation on OOP is terrible in the help pages and missing so many examples. I guess no time to make examples. 

Will check again in 4 years. And I bet that this problem will still be there.

@Joe Riel 

What were you intending? 

Just trying things. Wanted to see if I can make a copy of the object that way instead of using Object() onb it. When I was dealing with this problem:

https://mapleprimes.com/questions/234356-Passing--The-Object-Itself-To-One-Of

@Joe Riel 

Thanks. That worked. May be future version of Maple will allow one to use overload directly with _self as it is more convenient than having to make separate named proc for each constructor with an extra call for each which might cause an error if one calls the wrong proc when there are many different constructors. But this works for now.

Here is a full example

restart;

person:=module()
    option object;
    local name::string:="";
    local age::integer:=99;

    local constructor_1::static:=proc( _self, proto::person, the_name::string, $ )         
         name:= the_name;
    end proc;

    local constructor_2::static:=proc( _self,proto::person,the_name::string,the_age::integer,$ )
         name:= the_name;
         age:= the_age;
    end proc;

    export ModuleCopy::static:= overload( 
    [
       proc(_self,proto::person,the_name::string,$) option overload;
            constructor_1(_passed);
       end proc,

       proc(_self,proto::person,the_name::string, age::integer,$) option overload;
            constructor_2(_passed);
       end proc
    ]);

end module;


p:=Object(person,"me");
p:=Object(person,"me",20);

                  p := Object<<2950173059488>>
                  p := Object<<2950173046176>>


About what you said:

I assume this occurs because the procedures in the list passed to overload are not exports of the module

But I thought that since the ModuleCopy itself is export, and it overloads the procs, then the procs will be automatically exported? That would be the logical effect. 

Otherwise how does it work in this case (also using overload) if the procs inside overload are not also exported?

restart;
person:=module()
    option object;
    local name::string:="";
    local age::integer:=99;    

    export ModuleCopy::static:= overload( 
    [
       proc(_self,proto::person,the_name::string,$) option overload;
            _self:-name := the_name;
       end proc,

       proc(_self,proto::person,the_name::string, the_age::integer,$) option overload;
            _self:-name := the_name;
            _self:-age := the_age;
       end proc
    ]);

end module;
               person := Object<<2950170753120>>

p:=Object(person,"me");
p:=Object(person,"me",20);

The above works. Only difference is using _self:-name vs. just name

I think the sematics of when to use  _self and when one does not have to use it are still not clear in Maple. At least to me. Documenation are almost non existent on this. Only mention in all the official Maple documentation about _self is just one line. That is all I could find. 

@Joe Riel 

I think I found new bug. Your solution works OK, but it does not work in different setup I tried, different from the one I show above.

Do you prefer I ask new question on it (since it is new setup) or should I ask it here?

@mmcdara 

Obtaining the exact solution, then trying series on it does not always work. It depends on the solution. Here is just one example. I have many more where Maple can't solve since the expansion is around irregular singlular point. 

Order:=6; 
ode:=t*(t-2)^2*diff(diff(y(t),t),t)+t*diff(y(t),t)+y(t) = 0;
expansion_point:=2;
sol:=dsolve(ode,y(t),type='series',t=expansion_point);

No solution. Using series on the exact solution does not work, since Maple can't compute series expansion at singular point t=2

sol:=dsolve(ode,y(t));
series(rhs(sol), t=2)

This needs to be solved directly using asymptotic methods. Maple does not support this now for dsolve.

 

@tomleslie 

You did not read the question carefully. 

I do not have 2 examples. I only have one.

And I have posted the worksheet and a plain text version of it. The link is at the bottom of my post. So I have no idea why you say that I should post the worksheet when it is there.

The first ode you see is a screen shot of the maple help page to show that the syntax using series worked. That was not an example of mine. It is just screen shot of the help page to show that the syntax in help page worked but gives error when I used it.

@C_R 

Thanks for checking. I did not do "import of 2021 preferences" when installing. I prefer to explictly set the preference each time I install new Maple, so I know each time what I am doing and what I did set. 

But I do not see why this should affect things?.

After maple comes up I set the option to use separate engine. Exit Maple. When I start maple again, this setting is gone and now it is back to share the engine. I am sure I am not the only one who see this problem. I am on windows 10. May be Maple is saving the setting to some location different than where it reads it again next time it starts?

Does your windows 10 start menu show "maple 2022 shared server" for the icon like I show in the screen shot? I wonder if this has anything to do with it.

Currently to solve this, I put a big yellow sticky note on the corner of my computer monitor which says to change this setting each time I start Maple so I do not forget.

First 31 32 33 34 35 36 37 Last Page 33 of 90