nm

11413 Reputation

20 Badges

13 years, 72 days

MaplePrimes Activity


These are replies submitted by nm

@Kitonum 

thanks for all the answers. But I found a problem

Your method works for ln(x) when ln(x) is both in numerator and denominator.

But for sqrt(x), which I want to change to sqrt(abs(x)), it only works when sqrt() is in the numerator.  

expr:=sqrt(x);
applyrule(sqrt(t::anything)=sqrt(abs(t)), expr);

is OK. But not for:

expr:=1/sqrt(x);
applyrule(sqrt(t::anything)=sqrt(abs(t)), expr);

does not work. Since I do not know where the subexpresion will show up in the expression, this will be a problem. I do not know why applyrule works for both 1/ln(x) and ln(x), but only for sqrt(x) and not for 1/sqrt(x).

 

 

@vv 

Thanks. This looks better. But using these arbitray "a" and "b" makes it little hard to use.

I wrote a a Maple function based on paper "On Separation of Variables by C. P. Viazminsky". I am still debugging and testing it. But this is what I get using it. on the test functions I posted above

can not split arcsin(x)/(-x^2+1)^(1/2)/y^2
x*y = (x) * (y)
x^2*y+x^2 = (x^2) * (y+1)
2*x+1 = (2*x+1) * (1)
cos(2*x) = (cos(2*x)) * (1)
y = (1) * (y)
(x-1)/y = (x-1) * (1/y)
ln(y^2+1) = (1) * (ln(y^2+1))
can not split -x*y^2+y^2-x+1
can not split x^3*y+x^2
can not split 1/(x+y)
(1+x^(1/2))/(1+y^(1/2)) = (1+x^(1/2)) * (1/(1+y^(1/2)))
(-x^2*y^2-x^2+y^2+1)/x^2 = ((x^2-1)/x^2) * (-y^2-1)
3*x^2*y^2+2*x*y^2 = (3*x^2+2*x) * (y^2)
can not split 3*exp(2*x)+2*y
can not split (5*x^(1/2)-y)/x
can not split 2*x*y+3*x^2*exp(x^2)
can not split (y^2+x+1)^(1/2)
1 = (1) * (1)
can not split x*y+1
4*x^3*y-y = (4*x^3-1) * (y)
can not split exp(x^2)+2*x*y
can not split -(y-exp(x))/(x-2)
arcsin(x)/(-x^2+1)/y^2 = (arcsin(x)/(x^2-1)) * (-1/y^2)
can not split -(y-exp(x))/(x-2)
4*x^3*y-y = (4*x^3-1) * (y)
can not split (x^2*y+y)*y^3*exp(-x-y+1)*3^(-x-y)*(x^2*y-y)^(1/2)

The only problem is the last one. Based on the function is_separable(f,x,y) that I posted above, here is it again

is_separable:=proc(f,x,y)
  #checks if f(x,y) is separable to X(x)*Y(y) or not
  #but does not do the separation. The separation is done by
  #another function I have
  if diff(simplify(diff( simplify(ln(f)),x)),y) = 0 then
     return(true);
  else
     return(false);
  fi;
end proc:

The last function is supposed to be seperable.

is_separable((x^2*y+y)*y^3*exp(-x-y+1)*3^(-x-y)*sqrt(x^2*y-y),x,y);

true

Yet, the function I wrote does not separate it. my function also does not separate the first one, which is sqrt(x-1)*sqrt(x+1)/(sqrt(-x^2+1)*y^2); but your SplitX does. But since your use all these extra constants, it makes it hard for me to use now.

Thanks for all the help.

@John Fredsted 

hi. Your method also has same issue as I just mentioned below.

expr:=-y+4*x^3*y;
s,r := selectremove(z -> has(z,x) and has(z,y),expr):
``(simplify(select(has,r*expand(s),x)))*
``(simplify(remove(has,r*expand(s),x)));

It should be  y*(4x^3-1)

And

expr:=exp(x^2)+2*x*y;
s,r := selectremove(z -> has(z,x) and has(z,y),expr):
``(simplify(select(has,r*expand(s),x)))*
``(simplify(remove(has,r*expand(s),x)));

Which is also wrong.

Hard problem!

@Kitonum 

I tried your method, but unfortunately, it gives wrong results on number of cases. I tried both Splitting and Splitting1. Actually all methods shown in all the answers, do not all work on all cases. This is not an easy problem as it looks.

expr:=-y+4*x^3*y;
result := Splitting(expr,x,y);

It should be y*(4 x^3-1)

And

expr:=exp(x^2)+2*x*y;
r:=Splitting1(expr); 

The above can't be split.

 

@Carl Love 

" The syntax A:-B searches module A's exports for something named B. On the other hand, the B without a module prefix is just accessing a local "

Ah, but for newbies, it is not clear that A:-B means to search for only the exports of A. I just thought it mean just a naming convention to make it more clear which B is it, weather it is exported or not.  Also did not know if using B with prefix implies local

Good to know. I only been using modules for few days.

But this brings another follow up question.

What if parent has a local proc named foo(), and the child also has a local proc named foo(). Then how will the child call the parent local foo() proc if it wants (in addition to calling its own foo() when it wants) if one is not allowed to use the syntax parent:-foo() to tell Maple which foo() they want to call and without being forced to export the parent foo()? Here is an example

parent_module:=module()
 
 local child_module;
 local foo;

 export parent_entry;

 child_module:= module()
    export child_entry; 
    local foo;

    child_entry :=proc()
     foo(); #How to call the parent foo()??
    end proc;

    foo :=proc()
     print("in child foo");
    end proc;

  end module;

 #local
 foo :=proc()
   print("insider parent foo");
 end proc;

 #public
 parent_entry :=proc()
   child_module:-child_entry();
 end proc;
end module;

I can make the above a seperate question if needed.

thanks

@Preben Alsholm 

Thanks for both answers, Both works.

But I do not like to put the absolute path of child packages inside the $include, since I have to change this later if I move the folder somewhere else or if I want to send this package to someone to use?

So now I put all .mpl files in same folder and use relative path and add $include "child_package.mpl". 

But before loading the main package, I have to set the path, which is OK, since this is done outside the package.

 

@one man 

on my Maple nops gives an error. How come it worked for you? Which version do you have?

 

 

I am using Maple 2018. 

thanks.

@Carl Love 

I have not touched or changed anything. It was OK earlier today. I could do computation. It is only the menu items and help that was causing this error.

It seems something was causing it. The good news, is that I just rebooted the whole PC and now this error is gone !  I can start help OK now.

Something was causing it which I do not know what. But rebooting the PC fixed it.

I could delete this question in this case, or leave if it is of any it could happen for someone else or if it happens again for me. This is first time I've seen this problem with Maple 2018

@acer 

I think I either found a bug in the above function F, or I do not understand what it does when the input is not separable.

I gave it an expression which is not separable. It returns product of two expressions. But this is not separable.   How is one supposed to know if the returned value is the separation/split or may be it it same as the input written in different way? Here is an example

expr := -(y-exp(x))/(x-2);
F (expr, [x,y] );

I also found an expression which it can't separate

expr := 1-x+y^2-x*y^2;
#this can be split to (1-x)*(1+y^2)
F( expr, [x,y] );


And this one

expr:=(1-x^2+y^2-x^2*y^2)/(x^2);
#this can be split to 
fx:=(1-x^2)/x^2;
fy:=(1+y^2);
simplify(expr-(fx*fy));
F( expr, [x,y] );

This is not an easy problem!. I think Maple should have build-in function to do this.

I do not understand your code too well. Too advanced for me to change it. It will help if your function will return a list of the 2 split product, when it can separate them, or 2 empty lists if it can't separate them. This way a user would more easily check, like this

fx,fy := F(expr, [x,y]);

if fx={} or fy={} then
   print("can't separate them");
else
   print("separated them into two functions", fx, fy);
fi;

Thanks

   

@acer 

I used LibraryTools:-Save as you recommend. I was just asking if there was a different example you refered to. The whole documenation is really confusing in Maple. They do not spell things out very well for newbies. 

For example., in LibraryTools:-Save('name'), it does not say that it will save the contant of "name.mpl" to "name.mla" by default. I found this by trial and error. 

I ended doing this

restart;
read "my_package.mpl"; 
        #note that now Maple currentdir() is automatically 
        #set to where the worksheet is located. This seems to be
        #new in Maple 2018, which is good change.

my_package_name := cat( currentdir(),kernelopts(dirsep),"my_package.mla");

LibraryTools:-Create(my_package_name); 
          #this will create file my_package.mla 
          #in same folder as this worksheet

LibraryTools:-Save('my_package'); 
             #this will save content of "my_package.mpl" 
             #in "my_package.mla" file. This step was a 
             #little confusing. As name passed refers to
             #both the input (.mpl) and the (.mla) with same 

restart;
with(my_package);   #now this will work

#to update the package, after making changes to .mpl, do
restart;
read "my_package.mpl";
LibraryTools:-Save('my_package');

restart;
with(my_package);   #now this load the updated package


 

@acer 

Use LibraryTools:-Create to make a new .mla file. You only need to do that once.

Use LibraryTools:-Save to store the modules or procedure within that new archive file. You only need to do this after you make any change to the definitions.

(Do Not use the savelib command for the second step, of storing the pieces in the archive. It is too awkward and it's use error-prone for non-experts. Really.)

There's an example of all this in the Programming Manual. 

 

Would you know where in the programming manual this example is? Do you mean the programming guide?

I am now looking at the programming manual, 2018, downloaded from 

https://www.maplesoft.com/documentation_center/maple2018/ProgrammingGuide.pdf

And it uses savelib. not LibraryTools:-Save (but it uses LibraryTools:-Create) which is strange. On page 394:

Then on next page

 

@Carl Love 

I need to construct a symbolic expression, inside a local proc(). So one should make all the symbols that are part of the expresion local, so not to use a symbol which could be assigned globally.

Now, then I need to pass this expression to another proc() to do pattern matching. 

But I just found an easy workaround. I will pass the "x" and "C1" symbols in the call. That is all.

restart;
foo:=proc()
  local x,C1;
  boo(exp(C1+x),x,C1);
end proc;

boo:=proc(expr,x,C1)
  local a,b,c,la;
  patmatch(expr,a::anything*exp(b::anything*C1+c::anything),'la');
end proc:

And now it works.

 

@acer 

thanks. Your new version work. 

I myself do not like the inline `if`. I've seen such constructs used before, but I find it hard to read, since I like to see the explicit IF THEN ELSE, which makes it easier for me to see the logic. So I rewrote yours as follows

restart;
expr  := y(x)^2+diff(y(x),x,x)+g(y(x))+diff(y(x),x)^2+Int(f(x),x)+y(x)+y(x)*y(x)+y;
check := proc(expr::anything)
   local t,__y;
   t := subs(y(x)=__y(x),expr);
   
   if indets(t,{identical(y),'specfunc'(y)}) = {} then
      "OK";
   else
      "NOT OK";
   fi;

end proc:

check(expr);

I also added local __y;  I noticed you replaced the y(x) in the expression by __y(x). But there is always a chance that __y could have global value. Not likely, but possible.

Do you know if this is how dsolve does its parsing, or where to find how dsolve parses the input? I looked at dsolve using  showstat(:-dsolve); but hard for me to see where the parsing/validating of the input is done. I am sure dsolve parsing of input will be hundreds of lines long, as it has to check for so many variations.  I just do not know where it does that. 

But the above now works for me. 

Thanks for help.

 

@Fabio92 

thanks to all the answers. Yes, this does what I want. This is just for development. I first open the worksheet where the definitions are, then next open the testing worksheet.

Later, when finish development, I can do the library method. I am newbie and do not know how to do library stuff yet. So I work in worksheets now.

@acer 

"Using `has` to attempt this kind of thing, is not The Way, IMO"

You are right. I found that "has" fails on this

expr:=y(x)+g(y(x));
 

restart;
expr:=y(x)+g(y(x));
candidates:=indets(expr);
candidates:=select(has,candidates,y);
reject:=remove(u->[op(u)]=[x], candidates);
if nops(reject)<>0 then
   print("Not ok input");
else
   print("Ok input");
fi;

The above is wrong. The input  g(y(x)) is valid. Your method works on the above 

expr:=y(x)+g(y(x));
candidates:= indets(expr, 'specfunc'(y));
reject:=remove(u->[op(u)]=[x], candidates);
if nops(reject)<>0 then
   print("Not ok input");
else
   print("Ok input");
fi;

Only problem as I mentioned  before with indets is that it fails if input has "y" on its own. 

thanks.

First 68 69 70 71 72 73 74 Last Page 70 of 91