acer

21403 Reputation

29 Badges

15 years, 111 days

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Such graphs can become unmanageable when they get too wide, as nesting deepens.

You might consider a vertical orientation, on grounds of practical visibility.

On that note, and in a similar vein for displaying the nested structure of an expression, there is the dismantle command. (Much of it now implemented in a Library module, which can be viewed as source.) That is just a plaintext way of presenting the tree.

dismantle( (x+1)/(x-1)^2+sqrt((exp(-x^2)-1)/(x+1)) );                                

SUM(5)
   PROD(5)
      SUM(5)
         NAME(4): x
         INTPOS(2): 1
         INTPOS(2): 1
         INTPOS(2): 1
      INTPOS(2): 1
      SUM(5)
         NAME(4): x
         INTPOS(2): 1
         INTNEG(2): -1
         INTPOS(2): 1
      INTNEG(2): -2
   INTPOS(2): 1
   PROD(3)
      PROD(5)
         SUM(5)
            FUNCTION(3)
               NAME(4): exp #[protected, _syslib]
               EXPSEQ(2)
                  SUM(3)
                     PROD(3)
                        NAME(4): x
                        INTPOS(2): 2
                     INTNEG(2): -1
            INTPOS(2): 1
            INTNEG(2): -1
            INTPOS(2): 1
         INTPOS(2): 1
         SUM(5)
            NAME(4): x
            INTPOS(2): 1
            INTPOS(2): 1
            INTPOS(2): 1
         INTNEG(2): -1
      RATIONAL(3): 1/2
         INTPOS(2): 1
         INTPOS(2): 2
   INTPOS(2): 1

@J F Ogilvie Yes, the call to `simplify` prevents the crash (for those posint values of j).

I put in the `unapply` to gain speed, by preventing potentially expensive discontinuity checks on the integrand.

I had edited my response above, to indicate that I'd submit a bug report. The crash is due in part to the handling of the special functions, I believe. It is a regression bug.

@vv If the source is copied to text file then applying the `mint` utility may be as useful as using the `read` command. It covers more syntax issues in general.

The `mint` facility is part of what Startup Code regions utilize as syntax checkker, but with less flexibility as to controllong mint's options.

If the code in the worksheet is edited to be a string then that can be sent programmatically to external mint (similar to what's done in an old Post of mine).

I don't bother with the weaker `maplemint` command, even when it can be used.

@AHSAN From your comments so far I don't see that you really need these explicit symbolic representations of the roots. I don't see why you cannot solve numerically, later on when a and b take numeric values. It's also possible that numeric rootfinding might incur less numeric roundoff error than evaluation of the large explicit symbolic roots -- for given numeric a and b.

But recollections of having the same general conversation make me think that I should give up now on my arguments.

@nm Is there a box from which more examples will come later, or could you characterize the class of examples up front?

evala(Normal(expr));

                  2 /   (3/2)                 \
                 y  \3 y      x + sin(x) y + 1/

frontend(factor, [expr, y^(1/2)], [{`+`,`*`},{y^(1/2)}]);

                  2 /   (3/2)                 \
                 y  \3 y      x + sin(x) y + 1/

Could you also explain explicitly why that is better than, say,

evala(Factor(expr));

                  (7/2) /     sin(x)       1    \
               3 y      |x + -------- + --------|
                        |       (1/2)      (3/2)|
                        \    3 y        3 y     /

@AHSAN Yes, the unsimplified roots are very large symbolic expressions.

You can simplify them, which in this case reduces their size considerably.  help.ac1_ac.mw

What do you plan on doing with these symbolic roots? If you intend on (eventually) doing further computations that involve numerical evaluation at values of the parameters (a,b,c) then you might be better off waiting until that time and then doing numeric root-finding instead.

@J F Ogilvie I did not state that there was no crash, with the integrand left unsimplified following instantiation at those positive integer values for j.

I pointed out that, following instantiation at those positive integer values for j, the integrand simplifies into an expression containing only elementary functions (exp, and arithmetic operations). That is related to why the numeric integration succeeded in the code in my Answer.

@mmcdara  No worries. One could also add,

op(0,I), [op(I)];

              Complex, [1]

op(0, 2.1), [op(2.1)];

             Float, [21, -1]

@J F Ogilvie In case you had not noticed, for each of the concrete integer values of j=1..5 that call to simplify turns the integrand into an expression with only elementary functions (ie. exp but not GAMMA or LaguerreL).

I have not tracked down what all the causes of crashing are here, when the integrand is not simplified and still contains the special functions.

[edit] I now know what is the direct cause, and will submit a bug report.

@mmcdara You can also see the Help page for topic Complex. It wasn't clear to me whether you wanted details on that as well as on I.

And the DAG internal structure COMPLEX is mentioned in the Appendix to the Programming Guide.

I don't quite see why you'd find disassemble more to the mark than dismantle here (unless you needed to programmatically manipulate the DAG type results). Each to his own, I suppose.

(You might also be interested in the Float and SFloat constructors, if you're digging around.)

@rlopez In the original the name `a` is buried within a proc, so naturally Explore doesnt see it.

My solutions made the a name literally present as part of the first argument passed.

One of my suggestions was to use the expression a*x+y , just as you had it. In that case Explore replaces nonparameter assigned `a` with its value in what it stores in the Components . (Having `a` as a parameter is also possible, as you did.)

Here are four ways to adjust your example so that the earlier value assigned to name a is re-used in the earlier exploration, even following reassignment to a.

I am leaving out simple mechanism of simply having the execution group that calls Explore also do the desired assignent to a. In that case you could just rexecute that group, recreating the exploration while reassigning a as wanted.

The next four ways involve being able to immediately manipulate the Sliders in each of the explorations, without reinvoking Explore, and have them respect the value of a when the explorations were created.

1) Use uneval quotes and an eval call, so that the call f(x,y) evaluates and produces the returned expression in which the current value of a has replaced the instance(s) of a.  Explore_problem_ac1.mw

2) Use an expression rather than a procedure, to define f.  In recent Maple versions the assigned name a in the expression will get resolved to its value when Explore is/was called.  Explore_problem_ac2.mw

3) Call Explore on a procedure call of a procedure that takes a as an additional argument. (It works for the same reason as 2) above.) You could alter your procedure f, but since that might be awkward for you I show how you can create a wrapping procedure FExplore_problem_ac3.mw 

4) It's inefficient to F, and better to rewrite f. So here it is with rewritten f instead. You may find this the simplest way.  Explore_problem_ac4.mw

I suppose that the example you attached in a Reply to Carl's Answer might be merely a toy example, and that you actual work might be more involved. If, say, some more involved procedure f cannot be invoked with arguments nonnumeric x and y (due to conditionals needing to resolve, etc) then approaches 1) and 2) may well not work for you and 4) might need Explore(plot('f'(x, y, a)), y = 0 .. 10) instead.

@vv There will always be further examples requiring further work. In anything.

More problematic is something like  (x+sin(x))*_C2  since "sorting" wrt its first term is a problem.

restart;
F := proc(Sol,Cbase::name,cbase::name)
  local Cnames,cnames,csol,K,k,S,t;
  Cnames := indets(Sol,suffixed(Cbase, posint));
  if nargs=3 then
    S := [seq(Cbase||k=cbase[k],k=1..nops(Cnames))];
    cnames := map(rhs, S);
  else
    S := [];
    cnames := Cnames;
  end if;
  csol := subs(S,Sol);
  K := indets(csol,
              And(`*`,satisfies(u->ormap(type,[op(u)],
                                         {identical(cnames[]),
                                          identical(cnames[])^anything}))));
  for k in K do
    t:=remove(type,[op(k)],
              {identical(op(cnames)),identical(op(cnames))^anything,
               And(`+`,Not(polynom)),`+`^anything,function^(rational)});
    sort(k,t);
  end do;
  return csol;
end proc:

sol := y(x) = _C1*x*sin(2*ln(x))+x*cos(2*ln(x))/sin(x)*_C2:
F(sol, _C);
                                     _C2 x cos(2 ln(x))
         y(x) = _C1 x sin(2 ln(x)) + ------------------
                                           sin(x)      

# more irritating, and even shorter
#sol := x*(x+sin(x))*sin(x)^p*cos(2*ln(x))/(x+cos(x))*_C2^2;
sol := (x+sin(x))*_C2;
                    sol := (x + sin(x)) _C2

F(sol, _C); # oof
                        (x + sin(x)) _C2

@vv The probability isn't very low, as evinced by the fact that the OP has already run amok of inadvertant/undesired ordering even in his generated results containing the _Cn names.

My scheme in the other thread has been adjusted for your example there. Other adjustments are also possible. I aver that a suitable approach for obtaining a desired manner of ordering of terms in output is to have a programmatic mechanism for forcing the reordering (if such a thing is generally possible -- it might not be).

[edit] Thanks for changing the names to which things were assigned. Those assignments were not necessary for my counterexample, so I changed them too.
Using a local name c is possible, as long as no other process resorts any of the results, which might be unlikely. But having escaped locals, with further manipulations being programmatically awkward (and breakable by resorting) is somewhat dodgy -- a bit like asking for difficulties later. But maybe it's the most generally applicable solution.

@vv Thanks. This too can be accomodated.

Here one can use a modified procedure to correct this example too, following misordering.

sol := y(x) = _C1*x*sin(2*ln(x))+_C2*x*cos(2*ln(x))/(x+sin(x)):
bad := sort(sol, [_C1, _C2]):

lprint(sol);
  y(x) = x*sin(2*ln(x))*_C1+1/(x+sin(x))*x*cos(2*ln(x))*_C2

F := proc(Sol,Cbase::name,cbase::name)
  local Cnames,cnames,csol,K,k,S;
  Cnames := indets(Sol,suffixed(Cbase, posint));
  if nargs=3 then
    S := [seq(Cbase||k=cbase[k],k=1..nops(Cnames))];
    cnames := map(rhs, S);
  else
    S := [];
    cnames := Cnames;
  end if;
  csol := subs(S,Sol);
  K := indets(csol,
              And(`*`,satisfies(u->ormap(member,cnames,[op(u)]))));
  for k in K do
    sort(k,remove(type,remove(type,[op(k)],`+`^anything),identical(op(cnames))));
  end do;
  return csol;
end proc:

F(bad, _C):

lprint(%);
  y(x) = _C1*x*sin(2*ln(x))+1/(x+sin(x))*_C2*x*cos(2*ln(x))
Revisions to the mechanism can be made in an ongoing way. But I really think that the key to getting the desired sorting of subexpressions in the output is to have a mechanism for forcing the reordering even in the face of kernel uniquification of an undesired reordering.
3 4 5 6 7 8 9 Last Page 5 of 450