How to do substitution of a function in mathematica - wolfram-mathematica

I have the expression D[f[x, y], x], and I want to substitute f[x,y] with x*y, I tried the following:
D[f[x, y], x] /. {f[x,y] -> x*y}
and
D[f[x, y], x] /. {f -> x*y}
But neither worked. Would appreciate your help! Thanks.

The FullForm of the derivative in your expression is
In[145]:= D[f[x,y],x]//FullForm
Out[145]//FullForm= Derivative[1,0][f][x,y]
This should explain why the first rule failed - there is no f[x,y] in your expression any more. The second rule failed because Derivative considers f to be a function, while you substitute it by an expression. What you can do is:
In[146]:= D[f[x,y],x]/.f->(#1*#2&)
Out[146]= y
Note that the parentheses around a pure function are essential, to avoid precedence - related bugs.
Alternatively, you could define your r.h.s through patterns:
In[148]:=
fn[x_,y_]:=x*y;
D[f[x,y],x]/.f->fn
Out[149]= y
HTH

Nothing new, just the way I usually think of it:
D[f[x, y], x] /. f -> Function[{x, y}, x y]
Out
y

You can also try Hold and Release or Defer etc.
Hold#D[f[x, y], x] /. {f[x, y] -> x*y}
D[x y, x]
Hold#D[f[x, y], x] /. {f[x, y] -> x*y} // Release
y

Related

Evaluating Output Function in Mathematica when input does not specify variables

I am evaluating a partial derivative
fx = D[m[x, y], x]
The output gives me an output in terms of x and y. I'm trying to evaluate the function using
fx1 = fx/.{x-> 1.0, y-> 2.0}
but keeps giving me an answer like
0.471328[1.0, 2.0]
But I only want the 0.471328
I can't even begin to guess what code you have written, and not shown, to get where you are, but
In[3]:= Head[0.471328[1.0, 2.0]]
Out[3]= 0.471328
will give you what you are asking for.
Let me show one correct way to do this:
m[x_, y_] := x^2 + y^2 + x y
fx[x_, y_] := D[m[x, y], x]
fx[x, y] /. {x -> 1.0, y -> 2.0}
(*
=> 4.
*)

Using the output of Solve

I had a math problem I solved like this:
In[1]:= Solve[2x(a-x)==0, x]
Out[1]= {{x->0}, {x->a}}
In[2]:= Integrate[2x(a-x), {x,0,a}]
Out[2]= (a^3)/3
In[3]:= Solve[(a^3)/3==a, a]
Out[3]= {{a->0}, {a->-Sqrt[3]}, {a->Sqrt[3]}}
My question is if I could rewrite this to compute it in one step, rather than having to manually input the result from the previous line. I could easily replace the integral used in step three with the Integrate command from step two. But what I can't figure out is how I would use the result from step 1 as the limits of integration in the integral.
You could combine step 1 and 2 by doing something like
Integrate[2 x (a - x), {x, ##}] & ## (x /. Solve[2 x (a - x) == 0, x]);
If you agree to delegate the choice of the (positive oriented) domain to Integrate, by means of using Clip or Boole:
In[77]:= Solve[
Integrate[
Clip[2 x (a - x), {0, Infinity}], {x, -Infinity, Infinity}] == a, a]
Out[77]= {{a -> 0}, {a -> Sqrt[3]}}
or
In[81]:= Solve[
Integrate[
2 x (a - x) Boole[2 x (a - x) > 0], {x, -Infinity, Infinity}] ==
a, a]
Out[81]= {{a -> 0}, {a -> Sqrt[3]}}
The reason only non-negative roots are found, is that Integrate will integrate from the smallest root to the largest root, i.e. from {x,0,a} for positive a and {x,a,0} for negative a.

Using `With` with a list of `Rules` - but without affecting the normal behaviour of `With`

Say I have a list of Rules
rules = {a -> b, c -> d};
which I use throughout a notebook. Then, at one point, it makes sense to want the rules to apply before any other evaluations take place in an expression. Normally if you want something like this you would use
In[2]:= With[{a=b,c=d}, expr[a,b,c,d]]
Out[2]= expr[b, b, d, d]
How can I take rules and insert it into the first argument of With?
Edit
BothSome solutions fail do all that I was looking for - but I should have emphasised this point a little more. See the bold part above.
For example, let's look at
rules = {a -> {1, 2}, c -> 1};
If I use these vaules in With, I get
In[10]:= With[{a={1,2},c=1}, Head/#{a,c}]
Out[10]= {List,Integer}
Some versions of WithRules yield
In[11]:= WithRules[rules, Head/#{a,c}]
Out[11]= {Symbol, Symbol}
(Actually, I didn't notice that Andrew's answer had the Attribute HoldRest - so it works just like I wanted.)
You want to use Hold to build up your With statement. Here is one way; there may be a simpler:
In[1]:= SetAttributes[WithRules, HoldRest]
In[2]:= WithRules[rules_, expr_] :=
With ## Append[Apply[Set, Hold#rules, {2}], Unevaluated[expr]]
Test it out:
In[3]:= f[args___] := Print[{args}]
In[4]:= rules = {a -> b, c -> d};
In[5]:= WithRules[rules, f[a, c]]
During evaluation of In[5]:= {b,d}
(I used Print so that any bug involving me accidentally evaluating expr too early would be made obvious.)
I have been using the following form of WithRules for a long time. Compared to the one posted by Andrew Moylan, it binds sequentially so that you can say e.g. WithRules[{a->b+1, b->2},expr] and get a expanded to 3:
SetAttributes[WithRules, HoldRest]
WithRules[rules_, expr_] := ReleaseHold#Module[{notSet}, Quiet[
With[{args = Reverse[rules /. Rule[a_, b_] -> notSet[a, b]]},
Fold[With[{#2}, #1] &, Hold#expr, args]] /. notSet -> Set,
With::lvw]]
This was also posted as an answer to an unrelated question, and as noted there, it has been discussed (at least) a couple of times on usenet:
A version of With that binds variables sequentially
Add syntax highlighting to own command
HTH
EDIT: Added a ReleaseHold, Hold pair to keep expr unevaluated until the rules have been applied.
One problem with Andrew's solution is that it maps the problem back to With, and that does not accept subscripted variables. So the following generates messages.
WithRules[{Subscript[x, 1] -> 2, Subscript[x, 2] -> 3},
Power[Subscript[x, 1], Subscript[x, 2]]]
Given that With performs syntactic replacement on its body, we can set WithRules alternatively as follows:
ClearAll[WithRules]; SetAttributes[WithRules, HoldRest];
WithRules[r : {(_Rule | _RuleDelayed) ..}, body_] :=
ReleaseHold[Hold[body] /. r]
Then
In[113]:= WithRules[{Subscript[x, 1] -> 2,
Subscript[x, 2] -> 3}, Subscript[x, 1]^Subscript[x, 2]]
Out[113]= 8
Edit: Addressing valid concerns raised by Leonid, the following version would be safe:
ClearAll[WithRules3]; SetAttributes[WithRules3, HoldRest];
WithRules3[r : {(_Rule | _RuleDelayed) ..}, body_] :=
Developer`ReplaceAllUnheld[Unevaluated[body], r]
Then
In[194]:= WithRules3[{Subscript[x, 1] -> 2, Subscript[x, 2] -> 3},
Subscript[x, 1]^Subscript[x, 2]]
Out[194]= 8
In[195]:= WithRules3[{x -> y}, f[y_] :> Function[x, x + y]]
Out[195]= f[y_] :> Function[x, x + y]
Edit 2: Even WithRules3 is not completely equivalent to Andrew's version:
In[206]:= WithRules3[{z -> 2}, f[y_] :> Function[x, x + y + z]]
Out[206]= f[y_] :> Function[x, x + y + z]
In[207]:= WithRules[{z -> 2}, f[y_] :> Function[x, x + y + z]]
Out[207]= f[y$_] :> Function[x$, x$ + y$ + 2]

Force function evaluation on declaration

I have a function f[x_,y_,z_]:=Limit[g[x+eps,y,z],eps->0]; and I plot f[x,y,z] in the next step. Earlier, I used to evaluate the limit and copy the expression in the definition of f. I tried to make it all in one step. However, the evaluation of the Limit is done only when I try to plot f. As a result, every time I change around the variables and replot, the limit is evaluated all over again (it takes about a min to evaluate, so it becomes annoying). I tried evaluating the limit first, and then doing f[x_,y_,z_]:=%. But that doesn't work either. How do I get the function to evaluate the limit upon declaration?
The function you need is logically called Evaluate and you can use it within the Plot command.
Here is a contrived example:
f[x_, y_, z_] := Limit[Multinomial[x, y, z], x -> 0]
Plot3D[ Evaluate[ f[x, y, z] ], {y, 1, 5}, {z, 1, 5}]
Addressing your follow-up question, perhaps all you seek is something like
ff = f[x, y, z]
Plot3D[ff, {y, 1, 5}, {z, 1, 5}]
or possibly merely
ClearAll[f, x, y, z]
f[x_, y_, z_] = Limit[Multinomial[x, y, z], x -> 0]
Plot3D[f[x, y, z], {y, 1, 5}, {z, 1, 5}]
It would be helpful if you would post a more complete version of your code.
An alternative to Mr Wizard's solution is that you can also put the Evaluate in the function's definition:
f[x_, y_, z_] := Evaluate[Limit[Multinomial[x, y, z], x->0]]
Plot3D[f[x, y, z], {y, 1, 5}, {z, 1, 5}]
You can compare the two versions with the one without an Evaluate by Timing the Plot.

How to expand the arithmetics of differential operators in 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

Resources