10
$\begingroup$

Personally, I feel the design of FourierSeries/FourierSinSeries/FourierCosSeries/FourierTrigSeries not convenient enough because:

  1. They can't give general formula of series as output, one must set a specific integer as the order of series.

  2. One cannot define the domain to be expanded in a convenient way. What if I want to expand a function $f(x)$ in e.g. $x\in(2,10)$?

Can we make them more handy?

$\endgroup$
12
$\begingroup$

For the reasons mentioned above, I wrote the following "shell" for these functions:

(* Weak test for singularity *)
findSingular[coe_, k_, assump___] := 
 Piecewise[{{{}, # === k}}, #] &[
  k /. Union@Solve[{assump, Denominator@Together@coe == 0, k ∈ Integers}, k]]

generalTerm[expr_, {t_, a_, b_}, n_: C][coefunc_, termfunc_, assump___] := 
 With[{generalCoe = coefunc[expr, {t, a, b}, \[FormalK]]}, 
  With[{singularity = findSingular[generalCoe, \[FormalK], assump]}, 
   Piecewise[{{generalCoe, And @@ (\[FormalK] != # & /@ singularity)}, 
      Sequence @@ ({coefunc[expr, {t, a, b}, #], \[FormalK] == #} & /@ 
         singularity)}] termfunc[{t, a, b}, \[FormalK]]]]

summation[lowerbound_, upperbound_] := 
 HoldForm@Sum[#, {\[FormalK], lowerbound, upperbound}] &

trans[old_, new_, var_] := First@RescalingTransform[{new}, {old}][{var}]

easyFourierSinCoefficient[expr_, {t_, a_, b_}, k_] := 
 FourierSinCoefficient[expr /. t -> trans[{a, b}, {0, Pi}, t], t, k] /. 
  t -> trans[{0, Pi}, {a, b}, t]

Block[{t, a, b, k},
  easySinTerm[{t_, a_, b_}, k_] = Sin[k t] /. t -> trans[{0, Pi}, {a, b}, t] // Simplify];

easyFourierSinSeries[expr_, {t_, a_, b_}, n_: C] := 
 summation[1, n]@
  generalTerm[expr, {t, a, b}][easyFourierSinCoefficient, easySinTerm, \[FormalK] > 0]

easyFourierCoefficient[expr_, {t_, a_, b_}, k_] := 
 FourierCoefficient[expr /. t -> trans[{a, b}, {-Pi, Pi}, t], t, k] /. 
  t -> trans[{-Pi, Pi}, {a, b}, t]

Block[{t, a, b, k},
  easyTerm[{t_, a_, b_}, k_] = 
   Exp[I k t] /. t -> trans[{-Pi, Pi}, {a, b}, t] // Simplify];

easyFourierSeries[expr_, {t_, a_, b_}, n_: C] := 
 summation[-n, n]@
  PiecewiseExpand@
   Piecewise[{{generalTerm[expr, {t, a, b}][easyFourierCoefficient, 
       easyTerm], \[FormalK] != 0}}, 
    easyFourierCoefficient[expr, {t, a, b}, 0] easyTerm[{t, a, b}, 0]]

easyFourierCosCoefficient[expr_, {t_, a_, b_}, k_] := 
 FourierCosCoefficient[expr /. t -> trans[{a, b}, {0, Pi}, t], t, k] /. 
  t -> trans[{0, Pi}, {a, b}, t]

Block[{t, a, b, k},
  easyCosTerm[{t_, a_, b_}, k_] = Cos[k t] /. t -> trans[{0, Pi}, {a, b}, t] // Simplify];

easyFourierCosSeries[expr_, {t_, a_, b_}, n_: C] := 
 easyFourierCosCoefficient[expr, {t, a, b}, 0]/2 + 
  summation[1, n]@
   generalTerm[expr, {t, a, b}][easyFourierCosCoefficient, easyCosTerm, \[FormalK] > 0]

Block[{t, a, b, k},
  easyTrigTerm[{t_, a_, b_}, 
    k_] = {Cos[k t], Sin[k t]} /. t -> trans[{-Pi, Pi}, {a, b}, t] // Simplify];

easyFourierTrigSeries[expr_, {t_, a_, b_}, n_: C] := 
 easyFourierCoefficient[expr, {t, a, b}, 0] + 
  summation[1, n]@
   Collect[Simplify[
     generalTerm[expr, {t, a, b}][easyFourierCoefficient, 
        ExpToTrig@easyTerm@## &, \[FormalK] != 
         0] /. {{\[FormalK] -> \[FormalK]}, {\[FormalK] -> -\[FormalK]}} // 
      Total, \[FormalK] > 0 && \[FormalK] ∈ Integers], (Cos | Sin)[_]]

I'm still in v9 so choose HoldForm rather than Inactivate to hold Sum.

The usage of these functions are simple and straightforward. For example, suppose I want to expand

$$ f(x)=\left\{ \begin{array}{ll} x & -\frac{1}{2}\leq x<0 \\ 1 & 0\leq x<\frac{1}{2} \\ -1 & \frac{1}{2}\leq x<\frac{3}{2} \\ \end{array}\right.$$

in $-\frac{1}{2}<x<\frac{3}{2}$ with Fourier sine series, then I just need to write

expr = Piecewise[{{x, -1/2 <= x < 0}, {1, 0 <= x < 1/2}, {-1, 1/2 <= x < 3/2}}]
series = easyFourierSinSeries[expr, {x, -1/2, 3/2}]

Mathematica graphics

If you want to plot or do numeric calculation with the result, just replace C with a specific integer and ReleaseHold:

Plot[{expr, series /. C -> 24 // ReleaseHold} // Evaluate, {x, -1/2, 3/2}, 
 PlotRange -> All]

Mathematica graphics

$\endgroup$
  • $\begingroup$ Thanks, the built-in functions are indeed kind of hard to remember so I usually rescale arguments by hand before using them... $\endgroup$ – Jens Jul 1 '17 at 16:05
  • $\begingroup$ These procedures are really very helpful. Thanks for this work. (+1) $\endgroup$ – user36273 Jul 2 '17 at 13:22
  • $\begingroup$ Please be careful in handling these procedures! For example: f = Piecewise[{{x Sin[x], 0 <= x <= 2 Pi}}] , series = easyFourierSinSeries[f, {x, 0, 2 Pi}] /. C -> 5 // ReleaseHold $\endgroup$ – user36273 Jul 2 '17 at 17:51
  • $\begingroup$ @rewi OK, the problem is harder than I expected… The core issue is that we don't have a general function for obtaining singularity (see discussion here for more information). Anyway, I've modified the code to make the shell more general, have a look. $\endgroup$ – xzczd Jul 2 '17 at 20:21
  • $\begingroup$ Fantastic! The above example is now properly calculated, furthermore, I have also given difficult examples, e.g. Phase control; it works. $\endgroup$ – user36273 Jul 2 '17 at 21:15
6
$\begingroup$

Regarding the above Piecewise[ ] function:

Piecewise[{{x, -1/2 <= x < 0}, {1, 0 <= x < 1/2}, {-1, 1/2 <= x < 3/2}}]

There is another package (FS.m) that can compute the Fourier series of this type of function. It is located at https://arxiv.org/src/0806.0150v3/anc/FS.m (Most of the package was written long before FourierCoefficient[ ], etc. came along).

You can read in the package with something like << "C:\someDir\FS.m"

If all you want is a nicely-formatted expression for the Fourier series, then use formatSeries:

formatSeries[x, {x, 1, -1}, {-1/2, 0, 1/2, 3/2}, n]

If you don't care about the formatting, but instead just want expressions for the coefficients in terms of n, along with a graph of the function and 10 terms of its Fourier series, then use fSeries:

coeffs = fSeries[x, {x, 1, -1}, {-1/2, 0, 1/2, 3/2}, n, 10]

fSeries returns a list of three items:

coeffs = { aZeroOver2 , an , bn }

aZeroOver2 is the constant term; an and bn are the expressions for the nth cosine and sine terms.

I often find it easier to specify piecewise-continuous functions with a list of (x, y) pairs at endpoints, corners, and jumps:

xyPairs = { {-1/2, -1/2}, {0, 0}, {0, 1}, {1/2, 1}, {1/2, -1}, {3/2, -1} }

formatSeries and fSeries can also work with these (x, y) pairs:

formatSeries[x, xyPairs, n]

fSeries[x, xyPairs, n, 10]

In the above example, the period is $p = 3/2 - (-1/2) = 2$, so $2\pi/p = \pi$, so the Fourier series is

a0/2 + Sum[an * Cos[n Pi x] + bn * Sin[n Pi x], {n, 1, Infinity}]

The following plots the sum of 10 terms of the series over a larger interval that includes three periods:

Plot[coeffs[[1]] + Sum[(coeffs[[2]])*Cos[n Pi x] + (coeffs[[3]])*Sin[n Pi x], {n, 1, 10}], {x, -1/2 - 2, 3/2 + 2}]
$\endgroup$
  • $\begingroup$ Happy to see another answer! Then, I think it's worth pointing out that 1. formatSeries can actually handle Piecewise directly, one just needs to make the second argument a List: formatSeries[x, List@Piecewise[{{x, -1/2 <= x < 0}, {1, 0 <= x < 1/2}, {-1, 1/2 <= x < 3/2}}] , {-1/2, 3/2}, n] (Well, I think this design isn't that convenient and can be improved.) 2. This package currently has trouble in handling some edge cases e.g. formatSeries[x, {x Sin[x]}, {0, 2 Pi}, n] $\endgroup$ – xzczd Jul 19 '17 at 4:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.