How to expand the arithmetics of differential operators in mathematica - wolfram-mathematica

For example, I want mma to expand out the following differential operator
(1+d/dx+x*d2/dy2)^2*(1+y*d/dy)^2
I found Nest is not good enough to do this sort of things.

A bit dated, but see
http://library.wolfram.com/infocenter/Conferences/325/
The section "Some noncommutative algebraic manipulation" gives a few ways to go about this.
The first example, defining a function called differentialOperate, is probably best suited for your purposes.
---edit, reedited---
Here is the code I use. Probably it is (still) missing a few refinements. It is taken from a couple of examples in the notebook mentioned above.
I will define and use an auxiliary predicate, scalarQ. This gives the flexibility of declaring entities other than explicit numerical values to be scalar.
I define a noncommutative multiplication, called ncTimes. Ideally I would just use NonCommutativeMultiply, but Iwas not able to get the pattern matching to behave the way I wanted with respect to zero or one argument forms, or pulling out scalars. (Less technical explanation: it's mojo was more powerful than mine.)
scalarQ[a_?NumericQ] := True
scalarQ[_] := False
ncTimes[] := 1
ncTimes[a_] := a
ncTimes[a_, ncTimes[b_, c], d_] := ncTimes[a, b, c, d]
ncTimes[a_, x_ + y_, b_] := ncTimes[a, x, b] + ncTimes[a, y, b]
ncTimes[a_, i_?scalarQ*c_, b_] := i*ncTimes[a, c, b]
ncTimes[a_, i_?scalarQ, b___] := i*ncTimes[a, b]
differentialOperate[a_, expr_] /; FreeQ[a, D] := a*expr
differentialOperate[L1_ + L2_, expr_] :=
differentialOperate[L1, expr] + differentialOperate[L2, expr]
differentialOperate[a_*L_, expr_] /; FreeQ[a, D] :=
a*differentialOperate[L, expr]
differentialOperate[a : HoldPattern[D[] &], expr_] := a[expr]
differentialOperate[ncTimes[L1, L2_], expr_] :=
Expand[differentialOperate[L1, differentialOperate[L2, expr]]]
differentialOperate[L1_^n_Integer, expr_] /; n > 1 :=
Nest[Expand[differentialOperate[L1, #]] &, expr, n]
In[15]:= ddvar[x_, n_: 1] := D[#, {x, n}] &
Here are some of your examples, both from post and comments.
In[17]:= diffop =
ncTimes[(1 + ddvar[x] + ncTimes[x, ddvar[y, 2]])^2, (1 +
ncTimes[y, ddvar[y]])^2]
Out[17]= ncTimes[(1 + (D[#1, {x, 1}] & ) +
ncTimes[x, D[#1, {y, 2}] & ])^2,
(1 + ncTimes[y, D[#1, {y, 1}] & ])^2]
Apply this operator to f[x,y].
In[25]:= differentialOperate[diffop, f[x, y]]
Out[25]= f[x, y] + 3*y*Derivative[0, 1][f][x, y] +
9*Derivative[0, 2][f][x, y] +
18*x*Derivative[0, 2][f][x, y] + y^2*Derivative[0, 2][f][x, y] +
7*y*Derivative[0, 3][f][x, y] + 14*x*y*Derivative[0, 3][f][x, y] +
25*x^2*Derivative[0, 4][f][x, y] + y^2*Derivative[0, 4][f][x, y] +
2*x*y^2*Derivative[0, 4][f][x, y] +
11*x^2*y*Derivative[0, 5][f][x, y] +
x^2*y^2*Derivative[0, 6][f][x, y] + 2*Derivative[1, 0][f][x, y] +
6*y*Derivative[1, 1][f][x, y] + 18*x*Derivative[1, 2][f][x, y] +
2*y^2*Derivative[1, 2][f][x, y] +
14*x*y*Derivative[1, 3][f][x, y] +
2*x*y^2*Derivative[1, 4][f][x, y] + Derivative[2, 0][f][x, y] +
3*y*Derivative[2, 1][f][x, y] + y^2*Derivative[2, 2][f][x, y]
Those edge cases.
In[26]:= differentialOperate[ncTimes[1, 1], f[t]]
Out[26]= f[t]
We can declare a symbol to be scalar.
In[28]:= scalarQ[a] ^= True;
Now it will get pulled out as a simple multiplier.
In[29]:= differentialOperate[ncTimes[a, b], f[t]]
Out[29]= a b f[t]
---end edit---
Daniel Lichtblau
Wolfram Research

Related

Passing a function to a module without specifying its arguments

I want to write a
Module Arg[f_,n_]
that takes a function f (having <=n arguments) and a natural number n and outputs the n-th argument of the function f.
As an example, suppose that f is defined by
f[a_,b_]=a^2+b^2.
Then,
Arg[f[s,t],1]
should be s;
while
Arg[f[u,v],2]
should be v.
My question is whether this is possible. If so, what should I write in the place of "???" below?
Arg[f_,n_] := Module[{}, ??? ]
Note that I don't want to specify a_ and b_ in the definition of Arg like
Arg[f_,a_,b_,n_]
EDIT: "Arg" is just my name for the module not the internal function Arg of Mathematica.
Perhaps
SetAttributes[arg, HoldFirst];
arg[f_[x___], n_] := {x}[[n]]
f[a_, b_] := a^2 + b^2.
arg[f[arg[f[s, t], 1], t], 1]
arg[f[s, t], 2]
(*
-> s
-> t
*)
arg[ArcTan[f[Cos#Sin#x, x], t], 1]
(*
-> x^2. + Cos[Sin[x]]^2
*)
Assuming your second example should give u, this should do the job:
ClearAll[arg];
SetAttributes[arg, HoldFirst];
arg[g_, n_] := Module[
{tmp, ret},
Unprotect[Part];
tmp = Attributes[Part];
SetAttributes[Part, HoldFirst];
ret = Part[g, n];
ClearAttributes[Part, HoldFirst];
SetAttributes[Part, tmp];
Protect[Part];
ret
]
so that
f[a_, b_] = a^2 + b^2.;
arg[f[s, t], 1]
gives s.
This is very heavy-handed though, so I expect someone will find something better soon enough.
This is a bit better (doesn't redefine built-in functions even temporarily):
ClearAll[arg2];
SetAttributes[arg2, HoldFirst];
arg2[g_, n_] := Hold[g][[1, n]]

How to "embed" Piecewise in NDSolve in Mathematica

I am using NDSolve to solve a non-linear partial differential
equation.
I'd like one of the variables (Kvar) to be a function
of the time step currently being solved and hence and using
Piecewise.
Mathematica generates an error message saying:
SetDelayed::write: Tag Real in 0.05[t_] is Protected. >>
NDSolve::deqn: Equation or list of equations expected instead of
$Failed in the first argument ....
ReplaceAll::reps: ....
I haven't included the entire error message for ease of reading.
My code is as follows:
Needs["VectorAnalysis`"]
Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"];
Clear[Eq4, EvapThickFilm, h, S, G, E1, K1, D1, VR, M, R]
Eq4[h_, {S_, G_, E1_, K1_, D1_, VR_, M_, R_}] := \!\(
\*SubscriptBox[\(\[PartialD]\), \(t\)]h\) +
Div[-h^3 G Grad[h] +
h^3 S Grad[Laplacian[h]] + (VR E1^2 h^3)/(D1 (h + K1)^3)
Grad[h] + M (h/(1 + h))^2 Grad[h]] + E1/(
h + K1) + (R/6) D[D[(h^2/(1 + h)), x] h^3, x] == 0;
SetCoordinates[Cartesian[x, y, z]];
EvapThickFilm[S_, G_, E1_, K1_, D1_, VR_, M_, R_] :=
Eq4[h[x, y, t], {S, G, E1, K1, D1, VR, M, R}];
TraditionalForm[EvapThickFilm[S, G, E1, K1, D1, VR, M, R]];
And the second cell where I am trying to implement Piecewise in NDSolve:
L = 318; TMax = 7.0;
Off[NDSolve::mxsst];
(*Ktemp = Array[0.001+0.001#^2&,13]*)
hSol = h /. NDSolve[{
(*S,G,E,K,D,VR,M*)
Kvar[t_] := Piecewise[{{0.01, t <= 4}, {0.05, t > 4}}],
EvapThickFilm[1, 3, 0.1, Kvar[t], 0.01, 0.1, 0, 160],
h[0, y, t] == h[L, y, t],
h[x, 0, t] == h[x, L, t],
(*h[x,y,0] == 1.1+Cos[x] Sin[2y] *)
h[x, y, 0] ==
1 + (-0.25 Cos[2 \[Pi] x/L] - 0.25 Sin[2 \[Pi] x/L]) Cos[
2 \[Pi] y/L]
},
h,
{x, 0, L},
{y, 0, L},
{t, 0, TMax}
][[1]]
hGrid = InterpolatingFunctionGrid[hSol];
PS: I am sorry but the first cell block doesn't display so well here. And thanks to not having enough "reputation", I can't post images.
The error message occurs when using the NDSolve cell block.
Define the function Kvar outside of a set of equations in NDSolve, like
Off[NDSolve::mxsst];
(*Ktemp=Array[0.001+0.001#^2&,13]*)
Kvar[t_] := Piecewise[{{0.01, t <= 4}, {0.05, t > 4}}];
hSol = ...
and remove it from the list in NDSolve, so that it starts as NDSolve[{(*S,G,E,K,D,VR,M*)EvapThickFilm[..., and it will work. It gives warnings, but those are related to possible singularities in your equation.
Also, your original error indicates that your Kvar was assigned a value of 0.05. So, add Clear[Kvar] before anything else in the second cell.

how to implement an integration rule ?

Suppose I've checked the identity below, how to implement it in Mathematica ?
(* {\[Alpha] \[Element] Reals, \[Beta] \[Element] Reals, \[Mu] \[Element] Reals, \[Sigma] > 0} *)
Integrate[CDF[NormalDistribution[0, 1], \[Alpha] + \[Beta] x] PDF[
NormalDistribution[\[Mu], \[Sigma]],
x], {x, -\[Infinity], \[Infinity]}] -> CDF[NormalDistribution[0, 1], (\[Alpha] +
\[Beta] \[Mu])/Sqrt[1 + \[Beta]^2 \[Sigma]^2]]
Most ways to do what you request would probably involve adding rules to built-in functions (such as Integrate, CDF, PDF, etc), which may not be a good option. Here is a slightly softer way, using the Block trick - based macro:
ClearAll[withIntegrationRule];
SetAttributes[withIntegrationRule, HoldAll];
withIntegrationRule[code_] :=
Block[{CDF, PDF, Integrate, NormalDistribution},
Integrate[
CDF[NormalDistribution[0, 1], \[Alpha]_ + \[Beta]_ x_] PDF[
NormalDistribution[\[Mu]_, \[Sigma]_], x_], {x_, -\[Infinity], \[Infinity]}] :=
CDF[NormalDistribution[0, 1], (\[Alpha] + \[Beta] \[Mu])/
Sqrt[1 + \[Beta]^2 \[Sigma]^2]];
code];
Here is how we can use it:
In[27]:=
withIntegrationRule[a=Integrate[CDF[NormalDistribution[0,1],\[Alpha]+\[Beta] x]
PDF[NormalDistribution[\[Mu],\[Sigma]],x],{x,-\[Infinity],\[Infinity]}]];
a
Out[28]= 1/2 Erfc[-((\[Alpha]+\[Beta] \[Mu])/(Sqrt[2] Sqrt[1+\[Beta]^2 \[Sigma]^2]))]
When our rule does not match, it will still work, automatically switching to the normal evaluation route:
In[36]:=
Block[{$Assumptions = \[Alpha]>0&&\[Beta]==0&&\[Mu]>0&&\[Sigma]>0},
withIntegrationRule[b=Integrate[CDF[NormalDistribution[0,1],\[Alpha]+\[Beta] x]
PDF[NormalDistribution[\[Mu],\[Sigma]],x],{x,0,\[Infinity]}]]]
Out[36]= 1/4 (1+Erf[\[Alpha]/Sqrt[2]]) (1+Erf[\[Mu]/(Sqrt[2] \[Sigma])])
where I set \[Alpha] to 0 in assumptions to make the integration possible in a closed form.
Another alternative may be to implement your own special-purpose integrator.

Finding the Fixed Points of an Iterative Map

I need to find fixed points of iterative map x[n] == 1/2 x[n-1]^2 - Mu.
My approach:
Subscript[g, n_ ][Mu_, x_] := Nest[0.5 * x^2 - Mu, x, n]
fixedPoints[n_] := Solve[Subscript[g, n][Mu, x] == x, x]
Plot[
Evaluate[{x,
Table[Subscript[g, 1][Mu, x], {Mu, 0.5, 4, 0.5}]}
], {x, 0, 0.5}, Frame -> True]
I'll change notation slightly (mostly so I myself can understand it). You might want something like this.
y[n_, mu_, x_] := Nest[#^2/2 - mu &, x, n]
fixedPoints[n_] := Solve[y[n, mu, x] == x, x]
The salient feature is that the "function" being nested now really is a function, in correct format.
Example:
fixedPoints[2]
Out[18]= {{x -> -1 - Sqrt[-3 + 2*mu]},
{x -> -1 + Sqrt[-3 + 2*mu]},
{x -> 1 - Sqrt[ 1 + 2*mu]},
{x -> 1 + Sqrt[ 1 + 2*mu]}}
Daniel Lichtblau
First of all, there is an error in your approach. Nest takes a pure function. Also I would use exact input, i.e. 1/2 instead of 0.5 since Solve is a symbolic rather than numeric solver.
Subscript[g, n_Integer][Mu_, x_] := Nest[Function[z, 1/2 z^2 - Mu], x, n]
Then
In[17]:= fixedPoints[1]
Out[17]= {{x -> 1 - Sqrt[1 + 2 Mu]}, {x -> 1 + Sqrt[1 + 2 Mu]}}
A side note:
Look what happens when you start very near to a fixed point (weird :) :
f[z_, Mu_, n_] := Abs[N#Nest[1/2 #^2 - Mu &, z, n] - z]
g[mu_] := f[1 + Sqrt[1 + 2*mu] - mu 10^-8, mu, 10^4]
Plot[g[mu], {mu, 0, 3}, PlotRange -> {0, 7}]
Edit
In fact, it seems you have an autosimilar structure there:

How to ask mathematica to compute higher order derivatives evaluated at 0

I have a function, let's say for example,
D[x^2*Exp[x^2], {x, 6}] /. x -> 0
And I want to replace 6 by a general integer n,
Or cases like the following:
Limit[Limit[D[D[x /((-1 + x) (1 - y) (-1 + x + x y)), {x, 3}], {y, 5}], {x -> 0}], {y -> 0}]
And I want to replace 3 and 5 by a general integer m and n respectively.
How to solve these two kinds of problems in general in mma?
Many thanks.
Can use SeriesCoefficient, sometimes.
InputForm[n! * SeriesCoefficient[x^2*Exp[x^2], {x,0,n}]]
Out[21]//InputForm=
n!*Piecewise[{{Gamma[n/2]^(-1), Mod[n, 2] == 0 && n >= 2}}, 0]
InputForm[mncoeff = m!*n! *
SeriesCoefficient[x/((-1+x)*(1-y)*(-1+x+x*y)), {x,0,m}, {y,0,n}]]
Out[22]//InputForm=
m!*n!*Piecewise[{{-1 + Binomial[m, 1 + n]*Hypergeometric2F1[1, -1 - n, m - n,
-1], m >= 1 && n > -1}}, 0]
Good luck extracting limits for m, n integer, in this second case.
Daniel Lichtblau
Wolfram Research
No sure if this is what you want, but you may try:
D[x^2*Exp[x^2], {x, n}] /. n -> 4 /. x -> 0
Another way:
f[x0_, n_] := n! SeriesCoefficient[x^2*Exp[x^2], {x, x0, n}]
f[0,4]
24
And of course, in the same line, for your other question:
f[m_, n_] :=
Limit[Limit[
D[D[x/((-1 + x) (1 - y) (-1 + x + x y)), {x, m}], {y, n}], {x ->
0}], {y -> 0}]
These answers don't give you an explicit form for the derivatives, though.

Resources