nm

8552 Reputation

19 Badges

12 years, 348 days

MaplePrimes Activity


These are replies submitted by nm

@Rouben Rostamian  

thanks. fixed it. I had 

pts:= map(X->eval({x,y},X),[cp]);

changed it to

pts:= map(X->eval([x,y],X),[cp]);

Because it was a set, maple changed the order on me in the middle without me noticing.

@acer 

I understand all of this. That an input of `*` could be expanded and they will become `+` and then factored, and the benifit will come from this. But I am not looking for such advanced things in my question due to where this function is used at this moment.

I simply want to pull a common factor term if possible from `+` expression. That is all. I added to my question that input will only need to be of type `+` to be more clear. 

@acer 

If there is something not clear in a question, people normally ask the poster to clarify things. There is not wrong about it. This happens all the time at stackexchange in comments below the question.

So if there was something not clear about the specification, you can simply ask for clarification before answering. 

I tried my best to explain the question, if there is still something not clear, I will try to make it more clear.

@acer 

I only need to find common factor when the input is of type `+`. If the input is already a product, i.e. type `*`, then I do not need to do anything with it.

The whole idea, is that if I have term such as x+x^2+y*x, I want to convert to product  x*(1+x+y) in order to process each operand one at a time, which will simply things. There are equations, So they have the form 

                     x+x^2+y*x=0

But when it is in the form

                    x*(1+x+y)=0

Then now the program can easily say x=0 or (1+x+y)=0.

If the input is already in the form `*` as in

              x^2*(x+x^3+x*y)=0

Then I do not need to find common factor. Since it is in product form already. All the examples I gave and all the initial description I showed, are of type `+` as you can see.

If you are saying I should have mentioned explicitly that input only needs to be `+` and nothing else, OK. I will add this now. But I thought this was clear, as common factor is done on type `+`. At least in traditional way one thinks about it.

@acer 

I am not convinced that your (current) code's accept/reject criteria match your prior descriptions.

why? I said first line the following

I am looking for a robust way to factor an expression (if applicable) to become    x^n*(rest)  as we do it by hand.

so the output of common_factor should be `*`, so I check if the result is `*` or not. Are you saying the check for denom(result)<>1 is not needed?  There was case where it did that, and I wanted to check for it:

expr:=diff(y(x),x)-(1+x^(1/2))/(1+y(x)^(1/2));
term:=y(x);
acer_V1_common_factor(term,expr);

But I see now your V2 fixed this;

expr:=diff(y(x),x)-(1+x^(1/2))/(1+y(x)^(1/2));
term:=y(x);
acer_V2_common_factor(term,expr);

But I thought to keep the check there as extra saftey. What is wrong with it?

I just saw this addition of your

Naturally that remark may not hold if you further edit it.

sorry, I have no idea what you are talking about here. I did not edit anything in the question. I simply cleaned up the testcases and put all tests into one function. If you can explain more what you mean that will help better understand what is the issue.

Can you explain why you added "incomplete question" tag to my question? What is incomplete about it?  Instead of doing all these things, why not explain to people simply what the issue you see in the question. If there something not clear, I can improve it. But adding side remarks like this and adding tag incomplete without any explaination is not helpful.

@acer 

But this case

 expr:=(x^2*y+x*y+x/y)/(y+p);

will not be even be used by common_factor. Becuase the program will only attempt to find a common_factor only on input which is not already of type `*`.

And the above is of type `*`. So I only need to worry about finding common factor on input which is not of type `*`. 

@J F Ogilvie 

Yes, you example gives Error, (in gcd/Freeze) arguments should be polynomials also. But actually for me, this is not a big deal, as I can simply trap this error and by pass it and just use the input in this case.

The main problem is when it changes the input to a much more complicated form, such as this

expr:=A-(1+x)/(1+y^(1/2));
term:=y;
common_factor(term,expr);

 

By hand, I would leave the expression as is as there is no common y(x) among the two terms.

It would be better if this would also throw the same error as the last one, becuase I would trap it and not use the result, but now the program does not now and it complicated the expression. 

I just thought of an idea! Simply add an extra check that the result is of type `*` but with denom=1 only. This will be able to detect such edge cases edges. If so, reject it and by pass. This with the trap should catch the two issues I see so far.

Will try it now on my main test program and see. Will take some hrs to finish. The test is running now...

@acer 

Unfortunately this did not work after testing it more. There are cases where it should have left the input as is, but it changed it to strange form for some reason which made the ode much more complicated that it was, and many other cases where it gives error that arguments should be polynomials.  I can handle the case when it throws a signal, as I can trap it and keep using the original input. But I can't handle the cases where the input becomes much more complicated like the first example below since the program does not know this happend.

 

When doing all these by hand, the result should be the input itself, as there is no common y(x) to pull out as can be seen.

As I mentioned in my question. The input can be any mathematical expression (actually they are all differential equations) but can be any valid differential equation, which can contain any mathematical functions and expressions.

restart;
common_factor := proc(x::algebraic, ee::algebraic)
  local p, d := gcd(ee, x^frontend(degree,[ee,x]),'p');
  d * p;
end proc:
print("*********************");
expr:=diff(y(x),x)-(1+x^(1/2))/(1+y(x)^(1/2));
term:=y(x);
common_factor(term,expr);
print("*********************");
expr:=diff(y(x),x) -(x-1)*y(x)^5/x^2/(-y(x)+2*y(x)^3);
term:=y(x);
common_factor(term,expr);
print("*********************");
expr:=3*y(x)+diff(y(x),x) - 2*x/exp(3*x);
term:=y(x);
common_factor(term,expr);

I'll try to implement a brute force parsing method for this by looking at each term and collect all terms one by one. and see if there is a common factor that way.

@dharr 

Thanks. Your method works for polynomials. But what I am looking for is for any general expression and any general term. For example, given expression y(x)^4*diff(y(x),x)^2+y(x)^2*diff(y(x),x)^2+y(x); and the term is y(x) then it should return y(x)^2*(2*diff(y(x), x)^2 + 1)  and for the same expression, if the term was diff(y(x),x) then it should return diff(y(x),x)^2*(y(x)^4+y(x)^2); instead.

I tried to make your method work by substitution but that does not work well. For example if I replace y(x) by then this mess up the diff(y(x),x) terms there and they become zero. I could workaround this by converting to D form first. I am working on it.

Such a simple problem, we do by hand so easily all the time (just pull common factor out), but it seems hard to do using CAS.  May be it needs  frontend or freeze/thaw like you said. will keep trying. 

@Carl Love 

Fyi;

Maple gives an error when I put the base class and the extending class under a module.

I want to have all the modules be in same name space. So I have a top most module, say which just acts a name space to put all my code below it. So when I put the animal base class (module) and also the dog class (module) inside A, now Maple complains.

restart;

A:=module()
   export animal:= module()
      option object;
      export data1;
      export move::static:= proc(_self, $)
             print("In Animal class. moving ....")
      end proc;
    end module; #end base class
 
    export dog:= module()
        option object(A:-animal);  #PROBLEM IS HERE
        local ModuleLoad:= proc()
            move::static:= proc(_self, $)
                print("In dog class. moving ....")
            end proc;
           return
        end proc;
        ModuleLoad()  
    end module; #end extending class

end module;

I had to make animal class and dog class export, to be able to do   Object(A:-dog) later on, otherwise, can't access it if it is local. But even if dog module was local, same error results.

Maple gives the error

    Error, (in A:-dog) `A` does not evaluate to a module

This means I can't use this set, if I can put these inside the top most module. I do not want these modules to be seen from outside without having the prefix A:- 

I tried few things to workaround it, but so far,. no success. The problem is when doing 

             option object(A:-animal);

Maple still does not see as module, since it is partially evaluating it and this is not complete yet. It looks like it does one pass only on the module.  If I use just option object(animal); then now Maple gives error 

Error, (in A:-dog) argument of option object(animal) must refer to another object

So it seems this setup only works when both class (base and extending) are top level module. But this would not work for me. I need everything to be roots under same root module A.

I should add that this limitation has nothing to do with your solution. The original example I showed will also not work if I put them inside a root module. It seems just a limitation in Maple in that it does not allow option(A:-module_name) inside module A. This means all the objects I use (and want to extend) must now be top level (not under a module), which could conflict with any user's global object happend to be named the same. This is too bad. I hope Maple can fix this limitation in future release. 

Maple 2021.2

@Carl Love 

Hello Carl. Thanks for the answer to the other question. I simply had no idea someone gave another answer to it. That is all.

Since Mapleprimes does not  provide notification telling one they had reply or a comment, how is one supposed to know?

In Stackexchange, when I login, I see in red marker that I have notifcation in my inbox. There is nothing like this in this forum. 

And I do not always remember to go check old questions or answers looking for if there is any replies.  Unless it happened to be on first page and I see it.

I will test your code there now and see how it works. I am sure it will work well.

Thanks again for your answer.

regards

@Mac Dude 

I must be overlooking something. But there is no "type extension" here. dog() call just returns a module. This module does not even share the attributes of the base class Animal. 

Buster:=Animal:-dog();
Buster:-move();
Buster:-data1;

Error, module does not export `data1`

While when doing   option object(animal); now the new object has access to all base class animal data and methods.

How is this method you showed any better than just making a separate dog class?  As in

dogClass:=module()
   option object;

       export move:=proc(_self,$)
         print("In dog class. moving ....");
       end proc;  
end module;


Buster1:=Object(dogClass);
Buster2:=Object(dogClass);
etc...

But I agree with you in that Maple is not a true OOP language. I now just use Object as a "record" in other langauges (or "struct"). Where I have common data in one place. Then pass this object from one call to another. Just like when one passes a struct between functions in C.

@dharr 

"I think you wanted print(p) in B."

Yes ofcourse. Last minute change, forgot to update. Now typo fixed. The image is still not expored to a file. 

I nerver used interface(plotdevice=ps, etc...) before.  I am following https://maplesoft.com/support/help/maple/view.aspx?path=plotsetup  where it says to use plotsetup.  

But I just tried your suggestion, and it still did not work I am afraid.   now A wil call B1.


 

restart;

currentdir("C:\\tmp\\TEST_MAPLE");
p:=DocumentTools[RunWorksheet]( "B1.mw" , [the_function=sin(x),the_variable=x]  ):
print("Back from calling worksheet B. Here is the result");
p;

"C:\tmp\TEST_MAPLE"

"Back from calling worksheet B. Here is the result"

"OK"

 


 

Download A.mw

This is B1.mw. tried interface(plotdevice=ps, plotoutput=filename );  and interface(plotdevice=postscript, plotoutput=filename );


 

Inputs

 

the_function:=0;

the_variable:=0;


full_file_name:=cat("C:\\tmp\\TEST_MAPLE\\tmp.ps");
interface(plotdevice=postscript, plotoutput=filename );
plot(the_function,the_variable=-2*Pi..2*Pi):
return "OK";

 


 

Download B1.mw

 

@Rouben Rostamian  

"The format of the font specification is defined in ?plot,options under the "font" entry. Your specification axesfont=[12,12] does not fit that specification. Maple does not complain about that in the worksheet mode."

I am getting these errors. May be we are using different versions? (not able to post an image)

plot(sin(x),x=0..2*Pi,axesfont=12);
Error, (in plot) expecting option [axesfont, axes_font] to be of type list but received 12


plot(sin(x),x=0..2*Pi,axesfont=[12,12]);  #works OK
 

 

@vv 

It is not that easy. The issue becomes what value of slope to choose? 

Compare 

restart;
f:= (3 - 2*x)*exp(5*x);
f1:= diff(f, x):
maxslope:=100:
ff:=piecewise(abs(f1) < maxslope, f, undefined):
plot(ff, x=0..2*Pi);

With the result if using slope=5000 say

This choice worked better for this function as it shows more relevent parts.  But I will try setting some large slope value and run the program and see how the plots look like as there are 10's of thousands of functions to plot.  This will take 1-2 days to finish. This looks like a good solution until Maple smart view becomes more smart :)

 

 

 

First 14 15 16 17 18 19 20 Last Page 16 of 71