Robert Israel

6467 Reputation

21 Badges

15 years, 229 days
University of British Columbia
Associate Professor Emeritus
North York, Ontario, Canada

MaplePrimes Activity


These are replies submitted by Robert Israel

@barefoot1980 : An approximation might correspond to a limit where some of the parameters go to specified values, hopefully where an exact solution is known for those specified values.  For example, in your equation you could take x -> infinity, and one solution is approximately

> asympt(RootOf(-x^8*a^4 + 48*z^4 + 48*x^7*a + 8*z*x^6*a-1, a), x, 10);

(1/48-z^4)/x^7+1/288*z*(-1+48*z^4)/x^8-1/1728*z^2*(-1+48*z^4)/x^9+O(1/(x^10))

@barefoot1980 : An approximation might correspond to a limit where some of the parameters go to specified values, hopefully where an exact solution is known for those specified values.  For example, in your equation you could take x -> infinity, and one solution is approximately

> asympt(RootOf(-x^8*a^4 + 48*z^4 + 48*x^7*a + 8*z*x^6*a-1, a), x, 10);

(1/48-z^4)/x^7+1/288*z*(-1+48*z^4)/x^8-1/1728*z^2*(-1+48*z^4)/x^9+O(1/(x^10))

I would avoid the solution of using Typesetting[Settings] because this will cause problems if you try to communicate with somebody who doesn't use the same settings.  Rather than trying to remember all the complications of when you do or don't need an explicit multiplication (space or *), it's by far preferable to stick to a simple infallible rule: always use explicit multiplication. 

@blamm64 :

Q2: I deliberately left out the range option from my call to dsolve, so it is the sol(2) and not the dsolve that actually does the numeric solving and triggers the halt.

Q3: You could try rifsimp in the DEtools package.  For example: what is diff(x(t), t$3) in the system {diff(x(t), t) = x(t)*y(t), diff(y(t),t) = x(t) + y(t)}?

> sys := {diff(x(t), t) = x(t)*y(t), diff(y(t),t) = x(t) + y(t)};
   subs(DEtools[rifsimp](sys union {diff(x(t),t$3)=r(t)},
       [[r],[x,y]])[Solved],r(t));

x(t)*(y(t)^3+4*x(t)*y(t)+3*y(t)^2+x(t)+y(t))

Q4: For example

> plots[odeplot](sol, [t, fGrnd(t)], t = 0 .. t1);

@blamm64 :

Q2: I deliberately left out the range option from my call to dsolve, so it is the sol(2) and not the dsolve that actually does the numeric solving and triggers the halt.

Q3: You could try rifsimp in the DEtools package.  For example: what is diff(x(t), t$3) in the system {diff(x(t), t) = x(t)*y(t), diff(y(t),t) = x(t) + y(t)}?

> sys := {diff(x(t), t) = x(t)*y(t), diff(y(t),t) = x(t) + y(t)};
   subs(DEtools[rifsimp](sys union {diff(x(t),t$3)=r(t)},
       [[r],[x,y]])[Solved],r(t));

x(t)*(y(t)^3+4*x(t)*y(t)+3*y(t)^2+x(t)+y(t))

Q4: For example

> plots[odeplot](sol, [t, fGrnd(t)], t = 0 .. t1);

Actually MathWorld was not created "on the foundation of Mathematica".  It was started by Eric Weisstein on his own, and only later was acquired by Wolfram Research after Weisstein went to work for them.  For a summary of the history see http://mathworld.wolfram.com/about/faq.html#history

There's nothing wrong with G[0]: if G has not been assigned a value, it is a table reference, not a list element.  Even the C'(t) is OK in 2D Math input.  The one thing that is a problem is the C[ude], because C is also the name of the dependent variable.

I might add that the solution is implicit, and of course depends on an arbitrary parameter _C1.  An initial value is needed to pick out a particular solution.  But there is no hope for an explicit closed-form solution C(t) = (some expression in t).  If you want a numerical solution of the initial value problem, you can use dsolve with the numeric option.

For example:

> de:= eval((D(C))(t) = G[0]+.1*sqrt(C(t))-C(t)*n+C[ude]*n, 
         {n = 6, C[ude] = 417, G[0] = 83*1.7*1.2});
   S:= dsolve({de, C(0) = 0}, numeric);
   plots[odeplot](S, t = 0 .. 4);

There's nothing wrong with G[0]: if G has not been assigned a value, it is a table reference, not a list element.  Even the C'(t) is OK in 2D Math input.  The one thing that is a problem is the C[ude], because C is also the name of the dependent variable.

I might add that the solution is implicit, and of course depends on an arbitrary parameter _C1.  An initial value is needed to pick out a particular solution.  But there is no hope for an explicit closed-form solution C(t) = (some expression in t).  If you want a numerical solution of the initial value problem, you can use dsolve with the numeric option.

For example:

> de:= eval((D(C))(t) = G[0]+.1*sqrt(C(t))-C(t)*n+C[ude]*n, 
         {n = 6, C[ude] = 417, G[0] = 83*1.7*1.2});
   S:= dsolve({de, C(0) = 0}, numeric);
   plots[odeplot](S, t = 0 .. 4);

Perhaps it would help if you told us in words what this code is supposed to do.

<0,1> is not the radius, it is a unit vector u[r] in the direction away from the origin.  <-1,0> is not the angle theta, it is a unit vector u[theta] in the direction of increasing theta.  Perhaps a picture might help. The origin is O, the root point is B.

<0,1> is not the radius, it is a unit vector u[r] in the direction away from the origin.  <-1,0> is not the angle theta, it is a unit vector u[theta] in the direction of increasing theta.  Perhaps a picture might help. The origin is O, the root point is B.

@Wang Gaoteng : the reason I did it with two figures was that none of the plot devices worked well with the combined figure. 

You could remove the legend from A[1,1] (before the first plotsetup command) as follows:

> A[1,1]:= subs(op(indets(A[1,1],specfunc(anything,LEGEND)))=NULL,A[1,1]);

@Wang Gaoteng : the reason I did it with two figures was that none of the plot devices worked well with the combined figure. 

You could remove the legend from A[1,1] (before the first plotsetup command) as follows:

> A[1,1]:= subs(op(indets(A[1,1],specfunc(anything,LEGEND)))=NULL,A[1,1]);

It worked for me.  This is acer's file:

 

 

The assignment of the subscripted name as a partial derivative can be done programmatically.

 

The names of the mathematical function (Maple operator) and the variables (argument with which to differentiate) can be handled automatically, by making the declaration process into a Maple program. That way, one can declare as many such functions as one wants, repeatedly and easily.

 

I'm using the term "declaration" somewhat similar to the sense in PDEtools:-declare . By declaration I mean that a new name or syntax is devised to represent the partial differentiation of an existing operator with respect to one of its parameters. But I'm also keeping to Robert's key idea -- of using atomic identifiers (literal Maple names) to produce something more than just a displayed effect.

 

And the declared result can also be generated automatically as a new operator, without the need for manually re-interpretation of a returned function call as a new operator.

 

Because this worksheet involves code involving the underlying structure of objects there is a mix of 2D Math input and 1D Maple Notation input through the worksheet. Basically, the input portions used for visual demonstration are in 2D Math, and the programming is in 1D Maple Notation for explicit legibility.

 

First, we'll keep it simple and only use ` D `.

 

We want the declaration process to work whether f has already been defined or not. We'll demonstrate this by successfully forming f_x before assigning to f, and then by forming f_y afterwards.

 

restart:

Declare := proc(F,X,n)
  assign(cat(`#msub(mi("`,F,`"),mi("`,X,`"))`)=D[n](F));
end proc:

Declare(f,x,1);

(1)

f:=(x,y)->sin(x^2*y)+x:

T;

(2)

(3)

Declare(f,y,2);

(4)

 

Now, optionally implementing the partials using either ` diff ` or ` D ` (the default).

 

restart:

Declare := proc(F,X,n,{usediff::truefalse:=false},{varlist::list:=[]})
local mbit;
  if usediff then
     assign(cat(`#msub(mi("`,F,`"),mi("`,X,`"))`)
            = unapply(diff(F(op(varlist)),X),varlist) );
  else
     mbit:=`if`(type(X,name),"mi","mn");
     assign(cat(`#msub(mi("`,F,`"),`,mbit,`("`,X,`"))`)
            =D[n](F));
  end if;
end proc:

 

This works as before.

 

Declare(f, x, 1);

(5)

(6)

f:=(x,y)->sin(x^2*y)+x;

(7)

(8)

(9)

 

Now, using `diff` to get a "nicer" pretty-printed representation when f is not yet assigned.

 

We still want the process to work whether f has already been defined or not. We'll demonstrate this by successfully forming f_x before assigning to f, and by forming f_y afterwards.

 

unassign('f'):

Declare(f, x, 1, usediff, varlist=[x,y]);

(10)

(11)

f:=(x,y)->sin(x^2*y)+x;

(12)

(13)

Declare(f, y, 2, usediff, varlist=[x,y]);

(14)

(15)

 

We're not tied to x and y. We may choose another convention.

 

Declare(f, s, 1);
Declare(f, t, 2, usediff, varlist=[s,t]);

(16)

(17)

 

When using `D` (the default) we might also use a convention with numeric subscripts.

 

Declare(f, 1, 1);

(18)

(19)

unassign('g');

Declare(g, 2, 2);

(20)

(21)

g:=(v,w)->v*sqrt(v*w);

(22)

(23)

(24)

 

One reason to prefer `D` over the more nicely printed `diff` (in the situation that `f` is not yet assigned) is that `f` might get subsequently assigned as a procedure with conditionals And we'd want those handled robustly. This issue is basic to the D vs diff distinction, and isn't specific to this discussion on subscripted differential operators.

 

For the example below, `piecewise` would also work using either method and is a viable workaround. But for a more complicated procedure `f` containing even more conditional programming `D` may be a better choice. We can see the process run into trouble when using the `diff` approach here. The problems should not be unexpected. We really shouldn't be unapplying the derivative of a expression which is the result of a function application, just to get a differentiated operator. If one starts with an operator, then the generally best way to obtain the differentiated operator is to use `D`, which is supposed to be smarter and more generally careful. (Well, that's an ideal, anyway...)

 

Let's see an example of such a problem, using the coded apporach with `diff`. (Improved techniques are also possible, of course!)

 

unassign('f');

Declare(f, x, 1, usediff, varlist=[x,y]);

(25)

f:=proc(x,y)
      if x>0 then sin(x*y) else x^2*y end if;
   end proc:

Error, (in #msub(mi("f"),mi("x"))) invalid input: diff received 2, which is not valid for its 2nd argument

 

Declare(f, x, 1, usediff, varlist=[x,y]);

Error, (in f) cannot determine if this expression is true or false: 0 < x

 

 

So now we try with the default method, involving `D`.

 

unassign('f');

Declare(f, x, 1);

(26)

f:=proc(x,y)
      if x>0 then sin(x*y) else x^2*y end if;
   end proc:

(27)

Declare(f, x, 1);

(28)

(29)

 

The drawback of using `D` was that the declared partial derivatives didn't typeset as nicely when f was not yet assigned. So there's a fun exercise for another day: how can one extend the print mechanism so that D[1](f), etc, print as attractive partials, just like in text books? If we can do that task then we can get the better of both worlds: the better safety of D alongside standard textbook syntax. Of course the mechanism would have to be tied in to at least prior some declaration process, because for unassigned f the names of the presumed formal arguments of f are as yet unknown: there is no other way to know what name X is wanted for del f/del X. I suspect that `print/D` can be extended and set up to print D[1](f) as subscripted f_x within the program that handles the declaration of f_x as D[1](f).

 

 

 



Download atomicpartials.mw

 

First 11 12 13 14 15 16 17 Last Page 13 of 187