# Return exact solution in one variable from Series as an option

I have a module which expands many functions, depending on expansion order input parameters. Here's an MRE:

ExpandFuncs[xorder_, yorder_] :=
Block[{func1, func2, exp1, exp2},
func1 = 1/Sin[x+y];
func2 = 1/Cos[x+y];
exp1 = Normal[Series[func1,{x, 0, xorder}, {y, 0, yorder}]];
exp2 = Normal[Series[func2,{x, 0, xorder}, {y, 0, yorder}]];
Return[{exp1, exp2}];
]


Sometimes, however, I'd like to get the functions to only expand in y and return the exact solution in x. Is there a straightforward way to do this without introducing a bunch of If statements? In practice, my module is working with many functions, so introducing exceptions would be a hassle. Is there some way to give Series an argument like Infinity for the expansion order? (I've looked but not found anything like that).

You can define the following function expandFunc which takes two arguments, the first is a list of variables, the second is a list of orders to expand in (with Infinity corresponding to "no expansion"):

expandFunc[vars_, orders_] := Function[{f},
Series[f,
Sequence @@ If[#2 == \[Infinity], Nothing, {#1, 0, #2}] & @@@
Transpose[{vars, orders}]
]
]


Simple usage example (note that I do not define it with Normal)

expandFunc[{x, y}, {1, \[Infinity]}][1/Sin[x + y]]
(* SeriesData[x, 0, {
Csc[y], -Cot[y] Csc[y]}, 0, 2, 1] *)


Your code can be rewritten with expandFunc as

ExpandFuncs[xorder_, yorder_] :=
Block[{func1, func2, exp1, exp2},
func1 = 1/Sin[x + y];
func2 = 1/Cos[x + y];
exp1 = Normal@expandFunc[{x, y}, {xorder, yorder}][func1];
exp2 = Normal@expandFunc[{x, y}, {xorder, yorder}][func2];
Return[{exp1, exp2}];]


## Update

I just thought of the solution of filtering any argument with Infinity as an order specification out of a call to a function mySeries which then just calls Series with the "valid" arguments. This also allows options to be passed.

Options[mySeries] = Options[Series];
mySeries[expr_, limits__, opts : OptionsPattern[]] := Module[
{finiteLimits = {limits} /. {_, _, \[Infinity]} :> Nothing},
Series[expr, Sequence @@ finiteLimits,
Sequence @@ FilterRules[{opts}, Options[Series]]]
]


Taking the example for Assumptions from the documentation of Series:

mySeries[ArcCos[x], {x, 1, 1}, Assumptions -> (x > 1)]
(* SeriesData[x, 1, {Complex[0, 1] 2^Rational[1, 2]}, 1, 3, 2] *)

• This is perfect! thank you! – David Jul 10 '20 at 19:39