(*Fourier series coefficients of a rectangular pulse signal
by Nasser M. Abbasi
version April 12 2009*)
Manipulate[
(
currentPulses =
makePulseTrainDutyCycle[t0, 1, range, dutyCycle/100, 1];
fourierCoeffLines = getMag[t0, 1, range, dutyCycle/100., nCoeff];
currentMag = ListPlot[fourierCoeffLines,
Evaluate[plotOptions],
FillingStyle -> If[thickLines, Thick, Thin],
PlotLabel -> Style["Fourier coefficient magnitude", 12],
PlotRange -> {Automatic, {-.5, 1.2}},
Ticks -> {Automatic, {-.5, 0, .5, 1}},
Axes -> {True, False},
Epilog ->
Text[ numIt[fourierCoeffLines[[nCoeff, 2]], 4, 2, 10], {0,
fourierCoeffLines[[nCoeff, 2]]}, {0, -1}]];
If[joinPlot && nCoeff > 1,
currentMag =
Show[currentMag,
Plot[Interpolation[fourierCoeffLines, InterpolationOrder -> 1][
x], {x, -(nCoeff - 1), (nCoeff - 1)},
PlotRange -> {Automatic, {-.5, 1}}, PlotStyle -> Red]]];
fourierCoeffPhaseLines =
getPhase[t0, 1, range, dutyCycle/100., nCoeff];
currentPhase = ListPlot[fourierCoeffPhaseLines,
Evaluate[plotOptions],
FillingStyle -> If[thickLines, Thick, Thin],
PlotLabel -> Style["Fourier coefficient phase", 12],
PlotRange -> {Automatic, {-Pi, Pi}},
Ticks -> {Automatic, {-Pi, Pi}}];
If[joinPlot && nCoeff > 1,
currentPhase =
Show[currentPhase,
Plot[Interpolation[fourierCoeffPhaseLines,
InterpolationOrder -> 1][x], {x, -(nCoeff - 1), (nCoeff - 1)},
PlotRange -> {Automatic, {-Pi, Pi}}, PlotStyle -> Red]]];
Grid[{
{Framed@Plot[0, {x, -range, range},
Evaluate[pulsePlotOptions],
PlotLabel -> Style["pulse train", 12],
PlotRange -> {{-range, range}, {0, 1.2}},
AxesLabel -> {Row[{Style["t", Italic], Style[" (sec)", 10]}],
None},
Ticks -> {Automatic, {0, 1}},
Epilog -> {If[thickLines, Thick, Thin], Red, currentPulses}],
Column[{Framed@currentMag, Framed@currentPhase}]}
}, Spacings -> 1, Alignment -> Center]
),
Item[Row[{
Column[{
Framed@Column[{Style["time delay (sec)", 10],
Control[{ {t0, .25, ""}, 0, 1., .05, ImageSize -> Tiny,
Appearance -> "Labeled"}]}],
Framed@Column[{Style["duty cycle percentage", 10],
Control[{ {dutyCycle, 30, ""}, 0, 100, .1,
ImageSize -> Tiny, Appearance -> "Labeled"}]}]
}],
Column[{
Framed@Column[{Style["number of Fourier coefficients", 10],
Control[{ {nCoeff, 8, ""}, 1, 30, 1, ImageSize -> Tiny,
Appearance -> "Labeled"}]}],
Framed@Column[{Style["time range (sec)", 10],
Control[{ {range, 4, ""}, 1, 8, .1, ImageSize -> Tiny,
Appearance -> "Labeled"}]}]
}],
Column[{
Framed@Column[{Style["join plot ", 10],
Control[{ {joinPlot, True, ""}, {True, False},
ControlType -> Checkbox}]}],
Framed@
Column[{Style["thick lines ", 10],
Control[{ {thickLines, True, ""}, {True, False},
ControlType -> Checkbox}]}]
}]
}, Alignment -> Top], ControlPlacement -> Top],
Control[{ {currentPulses, 0}, ControlType -> None}],
Control[{ {x, 0}, ControlType -> None}],
Control[{ {currentCoeff, 0}, ControlType -> None}],
Control[{ {currentMag, 0}, ControlType -> None}],
Control[{ {currentPhase, 0}, ControlType -> None}],
Control[{ {fourierCoeffLines, 0}, ControlType -> None}],
Control[{ {fourierCoeffPhaseLines, 0}, ControlType -> None}],
Control[{ {pulsePlotOptions, 0}, ControlType -> None}],
Control[{ {imageSize, 260}, ControlType -> None}],
Control[{ {pulseAspectRatio, 1.55}, ControlType -> None}],
Control[{ {aspectRatio, .6}, ControlType -> None}],
TrackedSymbols :> {t0, dutyCycle, range, nCoeff, joinPlot,
thickLines},
AutorunSequencing -> {1, 2, 3},
Initialization :>
{
pulsePlotOptions = {ImageMargins -> 1,
ImagePadding -> {{20, 40}, {20, 20}},
AspectRatio -> pulseAspectRatio, PlotStyle -> {Thin, Red},
TicksStyle -> Directive[10], ImageSize -> imageSize};
plotOptions = {Filling -> Axis, ImageMargins -> 1,
ImagePadding -> {{10, 15}, {10, 10}},
AspectRatio -> aspectRatio, PlotStyle -> {Thin, Red},
TicksStyle -> Directive[10], ImageSize -> imageSize,
AxesLabel -> {Style["n", Italic, 10], None}};
(*-----------------------------*)
(* formats a number *)
(*-----------------------------*)
numIt[v_, s1_, s2_, fontSize_] := Module[{},
Style[
ToString[
AccountingForm[Chop[v], {s1, s2}, NumberPadding -> {" ", "0"},
NumberSigns -> {"-", ""}]], fontSize]
];
(*-----------------------------*)
(* decide on phase signa *)
(*-----------------------------*)
getPhase[n_, cn_, t0_, period_] := Module[{phase},
If[n == 0, Return[0]];
If[cn == 0, Return[0]];
If[t0 == 0, Return[If[cn < 0, Sign[n]*Pi, 0]]];
phase = -n*(2 Pi)/period t0;
If[cn >= 0 && Abs[phase] > 0, Return[Mod[phase, Sign[phase]*Pi]],
Return[0]];
phase = -n*(2 Pi)/period t0 + Sign[n]*Pi;
If[Abs[phase] > 0, Return[Mod[phase, Sign[phase]*Pi]],
Return[Sign[n]*Pi]];
];
(*-----------------------------*)
(* find the magnitude of cn *)
(*-----------------------------*)
getMag[t0_?NumericQ, period_?NumericQ, range_?NumericQ,
dutyCycle_?NumericQ, nCoeff_Integer] := Module[{data, n, h = 1},
data = {{0, h*dutyCycle}};
data =
Append[List@
Reverse@Table[{n,
Abs[h*dutyCycle*Sinc[Pi*n*dutyCycle]*
Exp[-I*2*Pi/period*n*t0]]}, {n, -1, -(nCoeff - 1), -1}],
data];
data =
Append[data,
Table[{n,
Abs[h*dutyCycle*Sinc[Pi*n*dutyCycle]*
Exp[-I*2*Pi/period*n*t0]]}, {n, 1, nCoeff - 1, 1}]];
Chop@Flatten[data, 1]
];
(*-----------------------------*)
(* find the phase of cn *)
(*-----------------------------*)
getPhase[delay_?NumericQ, period_?NumericQ, range_?NumericQ,
dutyCycle_?NumericQ, nCoeff_Integer] := Module[{data, n, t0},
t0 = Mod[delay, period];
data = {{0, 0}};
data =
Append[List@
Reverse@Table[{n,
getPhase[n, Sinc[Pi n dutyCycle], t0,
period]}, {n, -1, -(nCoeff - 1), -1}], data];
data =
Append[data,
Table[{n, getPhase[n, Sinc[Pi n dutyCycle], t0, period]}, {n,
1, nCoeff - 1, 1}]];
Chop@Flatten[data, 1]
];
(*-----------------------------*)
(* build the pulse train *)
(*-----------------------------*)
makePulseTrainDutyCycle[delay_?NumericQ, period_?NumericQ,
range_?NumericQ, dutyCycle_?NumericQ, h_?NumericQ] :=
Module[{allPulses, tao = period*dutyCycle},
getForwardPulses[] :=
Module[{n, z, ok = True, pulse, forwardPulses = {}, more, t0},
t0 = Mod[delay, period];
n = 0;
more = True;
While[more,
{
z = t0 + n*period;
If[z > range, more = False,
{
pulse =
Line[{ {z - tao/2, 0}, {z - tao/2, h}, {z + tao/2,
h}, {z + tao/2, 0}}];
forwardPulses = Append[forwardPulses, pulse];
n = n + 1;
}]
}
];
forwardPulses
];
getBackPulses[] :=
Module[{n, z, ok = True, pulse, backPulses = {}, more, t0},
t0 = Mod[delay, period];
n = 0;
more = True;
While[more,
{
z = -(period - t0) - n*period;
If[Abs[z] > range, more = False,
{
pulse =
Line[{ {z + tao/2, 0}, {z + tao/2, h}, {z - tao/2,
h}, {z - tao/2, 0}}];
backPulses = Append[backPulses, pulse];
n = n + 1;
}]
}
];
backPulses
];
allPulses = getForwardPulses[];
allPulses = Append[allPulses, getBackPulses[]]
];
}
]