Featured Post

One case where an "expansion beyond all orders" may be needed is investigating the asymptotic behavior of the difference of two functions with coinciding dominant series.

We are interested in the asymptotic behavior of F(z) for large positive z:

h1 := proc (z) options operator, arrow; hypergeom([1/2], [5/4, 3/2, 7/4], z) end proc; h2 := proc (z) options operator, arrow; (3/4)*sqrt(2*Pi)*hypergeom([1/4], [3/4, 5/4, 3/2], z)/(GAMMA(3/4)*z^(1/4)) end proc; F := proc (z) options operator, arrow; h1(z)-h2(z)+(3/8)*sqrt(Pi)/sqrt(z) end proc

series does not succeed:

series(F(z), z = infinity, 20)

O((1/z)^(23/3))*exp(3/(1/z)^(1/3))

(1)

The reason is that the dominant terms containing the factor exp(3*z^(1/3)) in the two hypergeometric functions cancel exactly, and we have to look for the subdominant terms.

The order of the leading terms can be found from DETools:-formal_sol:

deq1 := FunctionAdvisor(DE, h1(z), f(z))[2, 1]

diff(diff(diff(diff(f(z), z), z), z), z) = -(15/2)*(diff(diff(diff(f(z), z), z), z))/z-(195/16)*(diff(diff(f(z), z), z))/z^2+(1/32)*(32*z-105)*(diff(f(z), z))/z^3+(1/2)*f(z)/z^3

(2)

DETools:-formal_sol(deq1, f(z), z = infinity, order = 0)

[(1/z)^(1/2), -exp(-3/(-1/z)^(1/3))/z, -exp(3*(-1)^(1/3)/(-1/z)^(1/3))/z, -exp(-3*(-1)^(2/3)/(-1/z)^(1/3))/z]

(3)

As expected, one of the solutions (the third one for positive z) contains the exp(3*z^(1/3)) factor, the leading term being of the order exp(3*z^(1/3))/z.

Another, subdominant, solution is algebraic and, in fact, is a series containing only one term, as 1/z^(1/2) is an exact solution. It will turn out that the algebraic part in F(z) also cancels out.

Thus we have to look for the subsubdominant terms, which contain decaying exponentials. We will accomplish this by applying the steepest descent method to the integral representations of h1(z) and h2(z).

ms := convert([h1(z), h2(z)], MeijerG)

[(3/32)*Pi*2^(1/2)*MeijerG([[1/2], []], [[0], [-1/4, -1/2, -3/4]], -z), (3/32)*2^(1/2)*Pi*MeijerG([[3/4], []], [[0], [1/4, -1/4, -1/2]], -z)/z^(1/4)]

(4)

m2g := proc (m, y) local a, b, c, d; a, b := op(op(1, m)); c, d := op(op(2, m)); -((1/2)*I)*mul(`~`[GAMMA](`~`[`-`](1+y, a)))*mul(`~`[GAMMA](`~`[`-`](c, y)))*op(3, m)^y/(Pi*mul(`~`[GAMMA](`~`[`-`](b, y)))*mul(`~`[GAMMA](`~`[`-`](1+y, d)))) end proc

gs := applyrule(conditional(e::anything, _op(0, e) = MeijerG) = 'm2g(e, y)', ms)

[-((3/64)*I)*2^(1/2)*GAMMA(1/2+y)*GAMMA(-y)*(-z)^y/(GAMMA(5/4+y)*GAMMA(3/2+y)*GAMMA(7/4+y)), -((3/64)*I)*2^(1/2)*GAMMA(1/4+y)*GAMMA(-y)*(-z)^y/(z^(1/4)*GAMMA(3/4+y)*GAMMA(5/4+y)*GAMMA(3/2+y))]

(5)

gs[2] := combine(eval(gs[2], [1/z^(1/4) = exp(I*Pi*(1/4))/(-z)^(1/4), y = y+1/4]), power)

-((3/64)*I)*GAMMA(1/2+y)*((1/2)*2^(1/2)+((1/2)*I)*2^(1/2))*(-z)^y*GAMMA(-1/4-y)*2^(1/2)/(GAMMA(1+y)*GAMMA(3/2+y)*GAMMA(7/4+y))

(6)

h1(z) and h2(z)are the integrals of gs[1] and of gs[2] over the same path, which is a loop encircling the poles ofGAMMA(-y) and of GAMMA(-1/4-y). Now a standard technique is to extend the integration contour far to the left, while still keeping both endpoints at "+infinity". Then the arguments of the gamma functions can be made large everywhere on the integration path, and the gamma functions can be replaced by their asymptotic approximations.

When moving the contour, we have to take into account the pole of the integrand at y = -1/2. The other poles of GAMMA(1/2+y) will be cancelled by the zeros of 1/GAMMA(3/2+y), which is why the algebraic part of the expansion will contain the single term of the order 1/z^(1/2).

This is the negative of the third term in F(z):

`assuming`([simplify((2*Pi*I)*residue(gs[1]-gs[2], y = -1/2))], [z > 0])

-(3/8)*Pi^(1/2)/z^(1/2)

(7)

Expanding the gamma functions produces terms containing exp(-I*Pi*y) and exp(I*Pi*y)

`assuming`([simplify(convert(MultiSeries:-series((gs[1]-gs[2])/z^y, y = -infinity, 1), polynom))], [z > 0]); collect(convert(%, exp), exp)

(-3/64-(3/64)*I)*(-1/y)^(1/2)*exp(-3*(ln(-y)-1)*y)*exp(-I*Pi*y)/(y^3*Pi^(1/2))+(3/64-(3/64)*I)*(-1/y)^(1/2)*exp(-3*(ln(-y)-1)*y)*exp(I*Pi*y)/(y^3*Pi^(1/2))

(8)

As we shall see, those terms have saddle points y0(z) = exp(`&+-`((1/3)*(2*Pi*I)))*z^(1/3) located in the left half-plane and contribute exponentially small factors exp(3*y0(z)). The terms for which the saddle point would be located at y = z^(1/3) have cancelled out, thus cancelling the exponentially large contributions. Another possible way to achieve the same result was to write h1(z)-h2(z) as a single Meijer G-function -(3/32)*MeijerG([[1/2], []], [[-1/4, 0], [-3/4, -1/2]], z).

We write the first term above in the form g(y)*exp(f(y)):

f := proc (z, y) options operator, arrow; -3*y*(ln(-y)-1)-I*Pi*y+y*ln(z) end proc

g := proc (y) options operator, arrow; (-3/64-(3/64)*I)*sqrt(-1/y)/(sqrt(Pi)*y^3) end proc

diff(f(z, y), y)

-3*ln(-y)-I*Pi+ln(z)

(9)

For this to become zero, we need argument(-y) = -(1/3)*Pi, and thus y = exp((1/3)*(2*I)*Pi)*z^(1/3). We can visualize the paths where the imaginary part of f(z, y) stays constant. The path of the steepest descent is the one that goes through the saddle point in the direction exp(I*Pi*(1/3)); the blue color indicates smaller values of the real part of f(z, y):

y0 := proc (z) options operator, arrow; exp(((2/3)*I)*Pi)*z^(1/3) end proc

(proc () local z; z := 2; plots:-display(plots:-contourplot(Re(f(z, u+I*v)), u = -5 .. 5, v = -5 .. 5, contours = ([seq])(Re(f(z, y0(z)))+i, i = -30 .. 6, 6), filledregions, coloring = [blue, red], grid = [100, 100]), plots:-implicitplot(Im(f(z, u+I*v)-f(z, y0(z))), u = -5 .. 5, v = -5 .. 5, gridrefine = 5, color = green), plot([cos((1/3)*Pi)*xi+Re(y0(z)), sin((1/3)*Pi)*xi+Im(y0(z)), xi = -3 .. 3], linestyle = dot, color = white), axes = boxed) end proc)()

 

The real part of f(z, y) has a maximum along this path at y0(z).

`assuming`([(`@`(`@`(simplify, evalc), series))(f(z, y0(z)+exp(I*Pi*(1/3))*xi), xi = 0, 3)], [z > 0]); quad := convert(%, polynom)

series((3/2)*(-1+I*3^(1/2))*z^(1/3)-((3/2)/z^(1/3))*xi^2+O(xi^3),xi,3)

(10)

Now we can compute the lead asymptotic term contributed by the saddle point y0(z):

lt1 := `assuming`([(`@`(simplify, evalc))(g(y0(z))*exp(I*Pi*(1/3))*(int(exp(quad), xi = -infinity .. infinity)))], [z > 0])

-(1/64)*exp(-(3/2)*z^(1/3))*3^(1/2)*((-1+I)*cos((3/2)*z^(1/3)*3^(1/2))+(-1-I)*sin((3/2)*z^(1/3)*3^(1/2)))*2^(1/2)/z

(11)

We repeat the same procedure for the second term of the integrand.

f := proc (z, y) options operator, arrow; -3*y*(ln(-y)-1)+I*Pi*y+y*ln(z) end proc

g := proc (y) options operator, arrow; (3/64-(3/64)*I)*sqrt(-1/y)/(sqrt(Pi)*y^3) end proc

diff(f(z, y), y)

-3*ln(-y)+I*Pi+ln(z)

(12)

y0 := proc (z) options operator, arrow; exp(-((2/3)*I)*Pi)*z^(1/3) end proc

The direction should be chosen as exp((1/3)*(2*I)*Pi) to be consistent with the direction of the integration contour, which goes from the lower to the upper half-plane.

lterm := proc (gy, fy, eq, dir) options operator, arrow; (eval(gy*exp(fy), eq))*dir*sqrt(-2*Pi/((eval(diff(fy, `$`(y, 2)), eq))*dir^2)) end proc

lt2 := `assuming`([(`@`(simplify, evalc))(lterm(g(y), f(z, y), y = y0(z), exp((1/3)*(2*I)*Pi)))], [z > 0])

(1/64)*exp(-(3/2)*z^(1/3))*((1+I)*cos((3/2)*z^(1/3)*3^(1/2))+(1-I)*sin((3/2)*z^(1/3)*3^(1/2)))*3^(1/2)*2^(1/2)/z

(13)

Combining the two results yields the leading term of F(z). The next terms can be obtained by expanding gs[1] and gs[2] to higher orders.

Fasympt := unapply(simplify(lt1+lt2), z)

proc (z) options operator, arrow; (1/32)*exp(-(3/2)*z^(1/3))*3^(1/2)*2^(1/2)*(cos((3/2)*z^(1/3)*3^(1/2))+sin((3/2)*z^(1/3)*3^(1/2)))/z end proc

(14)

(proc () Digits := 50; plot(`~`[`*`](exp((3/2)*z^(1/3)), [F(z), Fasympt(z)]), z = 1000 .. 10000, linestyle = [solid, dot], thickness = [1, 5], axes = frame) end proc)()

 

Download steep.mw

Featured Post

Just a simple little worksheet to see if I have enough propane to heat my house for the rest of the winter.


 

Do I have enough propane for the winter?

NULL

I've taken some measurements from my propane tank throughout the winter.  Now we can use Maple to see if we have enough to last the rest of the winter.

``

a := [["nov 27, 2017", 73.5], ["dec 9, 2017", 72], ["dec 16, 2017", 69], ["dec 31, 2017", 62], ["jan 12, 2018", 60], ["jan 19, 2018", 56], ["jan 26, 2018", 54], ["feb 4,2018", 51]]

[["nov 27, 2017", 73.5], ["dec 9, 2017", 72], ["dec 16, 2017", 69], ["dec 31, 2017", 62], ["jan 12, 2018", 60], ["jan 19, 2018", 56], ["jan 26, 2018", 54], ["feb 4,2018", 51]]

(1)

with(Finance)  ``

pts := [seq([DayCount(a[1, 1], a[i, 1]), a[i, 2]], i = 1 .. nops(a))]

[[0, 73.5], [12, 72], [19, 69], [34, 62], [46, 60], [53, 56], [60, 54], [69, 51]]

(2)

with(plots)

listplot(pts)

 

Adding a 30% and 20% level to the graph.  We probably shouldn't be too worried about the cold in June so DayCount("Nov 27, 2017", "Jun 1, 2018") = 186 we'll extend these reference lines out to 186.

plot({pts, [[0, 20], [186, 20]], [[0, 30], [186, 30]]}, view = [default, 0 .. 80])

 

 

30% is the recommended level your propane company wants you to fill up at.  The technician who installed the tank said 20% is all right.  It's up to you if you want to go to 10% but if you run out of propane the company has to come in and do a leak test on your system which is an added cost you don't want.  So let's predict at what point we need to start worrying about filling up our propane tank.  To do that, of course, all we need is a forecast line.  For that we'll just calculate a best fit.

 

a1 := [seq(DayCount(a[1, 1], a[i, 1]), i = 1 .. nops(a))]

[0, 12, 19, 34, 46, 53, 60, 69]

(3)

a2 := a[() .. (), 2]

[73.5, 72, 69, 62, 60, 56, 54, 51]

(4)

X := convert(a1, Vector)

Y := convert(a2, Vector)

with(Statistics)

L1 := LinearFit([1, x], X, Y, x)

HFloat(74.79237702730747)-HFloat(0.34416046490941915)*x

(5)

Plotting it all together

plot({L1, pts, [[0, 20], [186, 20]], [[0, 30], [186, 30]]}, x = 0 .. 200, y = 0 .. 80, labels = ["Days", ""], tickmarks = [default, [seq(10*i = cat(10*i, "%"), i = 1 .. 8)]])

 

Projecting the line to 30% we get

solve(L1 = 30)

130.1496877

(6)

AdvanceDate(a[1, 1], trunc(solve(L1 = 30)))

Record(monthDay = 6, month = 4, year = 2018, format = "%B %e, %Y", ModulePrint = proc (m) Finance:-FormatDate(m) end proc)

(7)

April is still a bit chilly so maybe if we wait until 20%, of course it's getting warmer all this time so our usage should go down.  

AdvanceDate(a[1, 1], trunc(solve(L1 = 20)))

Record(monthDay = 5, month = (), year = 2018, format = "%B %e, %Y", ModulePrint = proc (m) Finance:-FormatDate(m) end proc)

(8)

It isn't warm enough to turn off the furnace yet but it looks like we'll have enough to get us into the warm months

AdvanceDate(a[1, 1], trunc(solve(L1 = 10)))

Record(monthDay = 3, month = 6, year = 2018, format = "%B %e, %Y", ModulePrint = proc (m) Finance:-FormatDate(m) end proc)

(9)

We'll hit 10% well into late spring and almost right into summer of course it's a rough estimate however it looks like we won't have to fill up during the high price winter season.  I can tell my wife to relax, we should have enough propane for the winter.

 

 

NULL


 

Download Propane_usage-.mw



how i can simplify....

Maple 2017 asked by torabi 35 Yesterday

simplify ln(x) function

Maple asked by panke 25 February 18