Multivariate Taylor series expansion in Mathematica - wolfram-mathematica

Mathematica seems to be missing a function for this, or I can't find it anyway.
The Series function can do expansion in succession for multiple variables, but it doesn't seem capable of doing a full multivariate expansion.
Does anyone know how to do this?
Thanks

This question is not clear to me. Do you mean something like this, where you get terms up to some specified total degree?
f[x_, y_] := Sin[x*y^2] + x^4*y - 3*x*Cos[y] - x^2*y^3
Normal[Series[f[x*t, y*t], {t, 0, 5}]] /. t -> 1
(*
-> -3*x + x^4*y + (5*x*y^2)/2 - x^2*y^3 - (x*y^4)/8
*)
Daniel Lichtblau

Related

Mathematica's puzzling interpretation of #^2 & /# Range[n]

I'm puzzled by Mathematica's responses to the following:
ClearAll[n]
#^2 & /# Range[n]
#^2 & /# Range[n] // StandardForm
It seems that even Mathematica (8.0) doesn't believe what it has just said:
#^2 & /# Range[5]
Range[5^2]
Any thoughts about what is happening?
Edit:
The original context for this question was the following. I had written
PrimeOmega[Range[n]] - PrimeNu[Range[n]]
and since n was going to be very large (2^50), I thought I might save time by rewriting it as:
PrimeOmega[#] - PrimeNu[#] &/#Range[n]
Thinking back, that probably wasn't such a good idea. (I could have used Module to 'compute' the Range only once.)
Since n is undefined, Range[n] evaluated to itself. Therefore, Map acts on it as on any other symbolic head, mapping your function on its elements - here it is just n
In[11]:= #^2 & /# someHead[n]
Out[11]= someHead[n^2]
EDIT
Addressing the question in your edit - for numeric n, Range evaluates to a list all right, and you get the expected result (which is, Range[5]^2. It is all about the order of evaluation. To get Range[5^2], you could have used #^2&/#Unevaluated[Range[5]], in which case everything happens just like for symbolic n above) . In fact, Range issues an error message on non-numeric input. Also, it is tangential to the question, but functions like #^2& are Listable, and you don't have to map them.
Slightly off topic, but you can improve the speed by redefining in terms of FactorInteger, which then is only called once per input.
f1[n_] := PrimeOmega[Range[n]] - PrimeNu[Range[n]]
f2[n_] := With[{fax=FactorInteger[#]}, Total[fax[[All,2]]]-Length[fax]]& /# Range[n]
Example:
In[27]:= Timing[pdiff1 = f1[2^20];]
Out[27]= {37.730264, Null}
In[28]:= Timing[pdiff2 = f2[2^20];]
Out[28]= {9.364576, Null}
In[29]:= pdiff1===pdiff2
Out[29]= True
Daniel Lichtblau

Complex Error Function in Mathematica

The complex error function w(z) is defined as e^(-x^2) erfc(-ix). The problem with using w(z) as defined above is that the erfc tends to explode out for larger x (complemented by the exponential going to 0 so everything stays small), so that Mathematica reverts to arbitrary precision calculations that make life VERY slow. The function is used in implementing the voigt profile - a line shape commonly used in spectroscopy and other related areas. Right now I'm reverting to calculating the lineshape once and using an interpolation to speed things up, however this doesn't let me alter the parameters of the lineshape (or fit to them) easily.
scipy has a nice and fast implementation of w(z) as scipy.special.wofz, and I was wondering if there is an equivalent in Mathematica.
The complex error function can be written in terms of the Hermite "polynomial" H_{-1}(x):
In[1]:= FullSimplify[2 HermiteH[-1,I x] == Sqrt[Pi] Exp[-x^2] Erfc[I x]]
Out[1]= True
And the evaluation does not suffer as many underflows and overflows
In[68]:= 2 HermiteH[-1, I x] /. x -> 100000.
Out[68]= 6.12323*10^-22 - 0.00001 I
In[69]:= Sqrt[Pi] E^-x^2 Erfc[I x] /. x -> 100000.
During evaluation of In[69]:= General::unfl: Underflow occurred in computation. >>
During evaluation of In[69]:= General::ovfl: Overflow occurred in computation. >>
Out[69]= Indeterminate
That said, some quick tests show that the evaluation speed of the Hermite function to be slower than that of the product of the exponential and error function...
A series expansion at infinity shows that the real and imaginary parts are of very different scales. I'd suggest computing them separately and not adding them. Below I use the first few terms of the series expansion to get the imaginary part.
In[186]:=
w[x_?NumericQ] := {N[Exp[-SetPrecision[x, 25]^2], 20],
N[(3 /(4 Sqrt[\[Pi]] x^5) + 1/(2 Sqrt[\[Pi]] x^3) + 1/(
Sqrt[\[Pi]] x))]}
In[187]:= w[11]
Out[187]= {2.8207700884601354011*10^-53, 0.05150453151309212}
In[188]:= w[1000]
Out[188]= {3.296831478088558579*10^-434295, 0.0005641898656429712}
Not sure how badly you want that very small real part. If you can drop it that will keep the numbers in a reasonable range. In some ranges (or if higher than machine precision is desired) you may want to use more terms from the expansion on that imaginary part.
Daniel Lichtblau
Wolfram Research
The real and imaginary parts of the complex error function on the real line can be explicitly and efficiently computed in Mathematica using Dawson integral:
In[9]:= Sqrt[Pi] Exp[-x^2] Erfc[I x] ==
E^-x^2 Sqrt[\[Pi]] - 2 I DawsonF[x] // FullSimplify
Out[9]= True
This is about 4 times faster than using HermiteH[-1,z].
In[10]:= w1[x_] := E^-x^2 Sqrt[\[Pi]] - 2 I DawsonF[x]
w2[x_] := 2 HermiteH[-1, I x]
In[15]:= AbsoluteTiming[w1 /# Range[-5.0, 5.0, 0.001];]
Out[15]= {2.3272327, Null}
In[16]:= AbsoluteTiming[w2 /# Range[-5.0, 5.0, 0.001];]
Out[16]= {10.2400239, Null}
A program in language C for the complex error function (aka the Faddeeva function) that can be run from Mathematica is also available in RooFit. Read the article by Karbach et al. arXiv:1407.0748 for more information.
Just wrap the C library libcerf.

How to store punch of equations / constants to solve for any element equation or numerical value

Lets say, that problems are fairly simple - something, that pre-degree theoretical physics student would solve. And student does the hardest part of the task - functional reading: parsing linguistically free form text, to get input and output variables and input variable values.
For example: a problem about kinematic equations, where there are variables {a,d,t,va,vf} and few functions that describe, how thy are dependent of each-other. So using skills acquired in playing fitting blocks where thy fit, you play with the equations to get the output variable you where looking for.
In any case, there are exactly 2 possible outputs you might want and thy are (with working example):
1) Equation for that variable
Physics[have_, find_] := Solve[Flatten[{
d == vf * t - (a * t^2) /2, (* etc. *)
have }], find]
Physics[True, {d}]
{{d -> (1/2)*(2*t*vf - a*t^2)}}
2) Exact or general numerical value for that variable
Physics[have_, find_] := Solve[Flatten[{
d == vf * t - (a * t^2) /2, (* etc. *)
have }], find]
Physics[{t == 9.7, vf == -104.98, a == -9.8}, {d}]
{{d->-557.265}}
I am not sure, that I am approaching the problem correctly.
I think that I would probably prefer an approach like
In[1]:= Physics[find_, have_:{}] := Solve[
{d == vf*t - (a*t^2)/2 (* , etc *)} /. have, find]
In[2]:= Physics[d]
Out[2]= {{d -> 1/2 (-a t^2 + 2 t vf)}}
In[2]:= Physics[d, {t -> 9.7, vf -> -104.98, a -> -9.8}]
Out[2]= {{d -> -557.265}}
Where the have variables are given as a list of replacement rules.
As an aside, in these types of physics problems, a nice thing to do is define your physical constants like
N[g] = -9.8;
which produces a NValues for g. Then
N[tf] = 9.7;N[vf] = -104.98;
Physics[d, {t -> tf, vf -> vf, a -> g}]
%//N
produces
{{d->1/2 (-g tf^2+2 tf vf)}}
{{d->-557.265}}
Let me show some advanges of Simon's approach:
You are at least approaching this problem reasonably. I see a fine general purpose function and I see you're getting results, which is what matters primarily. There is no 'correct' solution, since there might be a large range of acceptable solutions. In some scenario's some solutions may be preferred over others, for instance because of performance, while that might be the other way around in other scenarios.
The only slight problem I have with your example is the dubious parametername 'have'.
Why do you think this would be a wrong approach?

Problem performing a substitution in a multiple derivative

I have a basic problem in Mathematica which has puzzled me for a while. I want to take the m'th derivative of x*Exp[t*x], then evaluate this at x=0. But the following does not work correct. Please share your thoughts.
D[x*Exp[t*x], {x, m}] /. x -> 0
Also what does the error mean
General::ivar: 0 is not a valid variable.
Edit: my previous example (D[Exp[t*x], {x, m}] /. x -> 0) was trivial. So I made it harder. :)
My question is: how to force it to do the derivative evaluation first, then do substitution.
As pointed out by others, (in general) Mathematica does not know how to take the derivative an arbitrary number of times, even if you specify that number is a positive integer.
This means that the D[expr,{x,m}] command remains unevaluated and then when you set x->0, it's now trying to take the derivative with respect to a constant, which yields the error message.
In general, what you want is the m'th derivative of the function evaluated at zero.
This can be written as
Derivative[m][Function[x,x Exp[t x]]][0]
or
Derivative[m][# Exp[t #]&][0]
You then get the table of coefficients
In[2]:= Table[%, {m, 1, 10}]
Out[2]= {1, 2 t, 3 t^2, 4 t^3, 5 t^4, 6 t^5, 7 t^6, 8 t^7, 9 t^8, 10 t^9}
But a little more thought shows that you really just want the m'th term in the series, so SeriesCoefficient does what you want:
In[3]:= SeriesCoefficient[x*Exp[t*x], {x, 0, m}]
Out[3]= Piecewise[{{t^(-1 + m)/(-1 + m)!, m >= 1}}, 0]
The final output is the general form of the m'th derivative. The PieceWise is not really necessary, since the expression actually holds for all non-negative integers.
Thanks to your update, it's clear what's happening here. Mathematica doesn't actually calculate the derivative; you then replace x with 0, and it ends up looking at this:
D[Exp[t*0],{0,m}]
which obviously is going to run into problems, since 0 isn't a variable.
I'll assume that you want the mth partial derivative of that function w.r.t. x. The t variable suggests that it might be a second independent variable.
It's easy enough to do without Mathematica: D[Exp[t*x], {x, m}] = t^m Exp[t*x]
And if you evaluate the limit as x approaches zero, you get t^m, since lim(Exp[t*x]) = 1. Right?
Update: Let's try it for x*exp(t*x)
the mth partial derivative w.r.t. x is easily had from Wolfram Alpha:
t^(m-1)*exp(t*x)(t*x + m)
So if x = 0 you get m*t^(m-1).
Q.E.D.
Let's see what is happening with a little more detail:
When you write:
D[Sin[x], {x, 1}]
you get an expression in with x in it
Cos[x]
That is because the x in the {x,1} part matches the x in the Sin[x] part, and so Mma understands that you want to make the derivative for that symbol.
But this x, does NOT act as a Block variable for that statement, isolating its meaning from any other x you have in your program, so it enables the chain rule. For example:
In[85]:= z=x^2;
D[Sin[z],{x,1}]
Out[86]= 2 x Cos[x^2]
See? That's perfect! But there is a price.
The price is that the symbols inside the derivative get evaluated as the derivative is taken, and that is spoiling your code.
Of course there are a lot of tricks to get around this. Some have already been mentioned. From my point of view, one clear way to undertand what is happening is:
f[x_] := x*Exp[t*x];
g[y_, m_] := D[f[x], {x, m}] /. x -> y;
{g[p, 2], g[0, 1]}
Out:
{2 E^(p t) t + E^(p t) p t^2, 1}
HTH!

How do I make this substitution in Mathematica?

I'm just getting started with Mathematica, and I've got what must be a pretty basic question about making substitutions but I can't get it to work.
I'd like to find the Euler-Lagrange equations for a functional of the function phi[x,y] and then make a substitution for the function phi[x,y]
If I enter the following:
VariationalD[tau*phi[x, y]^2 - 2*phi[x, y]^4 + phi[x, y]^6 + Dot[D[phi[x, y], {{x, y}}], D[phi[x, y, {{x, y}}]]], phi[x, y], {x, y}]
I get
Plus[Times[2,tau,phi[x,y]],Times[-8,Power[phi[x,y],3]],Times[6,Power[phi[x,y],5]],Times[-2,Plus[Derivative[0,2][phi][x,y],Derivative[2,0][phi][x,y]]]]
Now if I try % /. phi[x,y] -> phi0[x,y] + psi[x,y] it makes the substitution for all the polynomial terms, but not for the Derivative terms.
How do I force the substitution into those functions?
I agree with all of what rcollyer says, but I think his final solution might be a little opaque.
The simplest rule that I could come up with (which is the basically the same as rcollyer's) is
{phi[x__] :> phi0[x] + psi[x], f_[phi][x__] :> f[phi0][x] + f[psi][x]}
or something with less possible side effects is
{phi[x__] :> phi0[x] + psi[x], Derivative[n__][phi][x__] :> Derivative[n][phi0][x] + Derivative[n][psi][x]}
It would be a lot easier if Derivative had a Default property (compare Default[Times] with Default[Derivative]). It should be something like Default[Derivative] := Sequence[] but unfortunately that doesn't play nice with the pattern matching.
Getting back to your question, you probably want to define something like
VariationalD[expr_, sym_, var_] := Module[{
vRule = {sym[x__] :> sym[x] + var[x],
Derivative[n__][sym][x__] :> Derivative[n][sym][x] + Derivative[n][var][x]}},
(expr /. vRule) - expr]
Where the variation var of the symbol sym is assumed to be small. Of course what you then need to do is series expand around var=0 and only keep the linear part. Then use integration by parts on any term which has derivatives of var. All of which should be included in the above module.
First, you misplaced a ] in your second derivative term, it should read D[phi[x, y], {{x, y}}]] not D[phi[x, y, {{x, y}}]]].
That said, replacement in Mathematica can be tricky, as has been pointed out in other questions. That isn't to say it is impossible, just requires some work. In this case, the problem comes in in that phi[x,y] is different from Derivative[2, 0][phi][x, y]. So, your pattern won't match the derivative term. The simplest thing to do is to add the rule
Derivative[a__][phi][x__]:> Derivative[a][phi0][x] + Derivative[a][psi][x]
to your list of replacement rules. Three things to note: 1) I use ReplaceDelayed so that both types of derivatives will match without writing multiple rules, 2) since I can use patterns, I named them so that I can refer to them on the RHS of the rule, and 3) I used a double underscore when defining a and x which will match one or more items in a sequence.
Of course, that isn't the most satisfying way to approach the problem, as it will require you to write two rules every time you wish to this sort of replacement. It turns out a more general approach is surprisingly difficult to accomplish, and I'll have to get back to you on it.
Edit: This requires a double replacement, as follows
<result> /. phi -> phi0 + psi /. a_[b__][c__] :> Through[Distribute[a[b]][c]]
Distribute ensures that the derivative works correctly with Plus, and Through does the same with the function args c. The key is that the Head of Derivative[2, 0][phi][x, y] is Derivative[2, 0][phi], hence the several levels of square brackets in the rule.

Resources