NDSolve not returning the expected solution

I'm trying to simulate a simple circuit with Mathematica. The equation of the circuit is $R \dfrac{dQ}{dt} + \dfrac{Q(t)}{C} = f_{sig}(t)$.

This is the definition of $f_{sign}$, and the function seems to work, since the plot is good.

newfSign[t_] :=
If[OddQ[Floor[t/τ]], 1/2*Subscript[V, max] (Cos[2*π *β*t/τ] + 1), Subscript[V, max]] This is the definition of the solution:

s = NDSolve[{R*Q'[t] + Q[t]/C2 == newfSign[t], Q == 0}, Q, {t, 0, 4 τ}]

And I try to plot it with this command:

Plot[Q[t]/C2 /. s, {t, 0, 4 τ}, PlotRange -> All]

Getting this result, which is not what would be expected, given the forcing function $f_{sign}$. Those are the values I'm using:

Subscript[V, max] = 5
β = 10
τ = 500*10^-6
R = 2000
C2 = 0.22*10^-6

Am I missing something?

• Please include the values for all your variables – Dr. belisarius Sep 3 '14 at 22:32
• Added just now. – Matteo Pompili Sep 4 '14 at 9:06
• It could be helpful to look at the difference of this solution with a solution for a f_sig(t) with a constant value of Subscript[V, max]. Also try to increase the PrecisionGoal parameter in case the effect of the inhomogeneity is very small and PlotPoints for the Plot of the solution. I would also suggest to try it with fixed step size (Method -> {"FixedStep", Method->...} , see doc) with a sufficiently small step size, maybe 10^-6 or smaller to ensure that the automatic determination of the step size is not the problem. – DaveStrider Sep 4 '14 at 11:26

The problem is that NDSolve is not HoldAll or HoldFirst. Therefore the differential equation is evaluated symbolically before it is passed to NDSolve. Thus the differential equation that NDSolve sees is

{R*Q'[t] + Q[t]/C2 == newfSign[t], Q == 0}
(* {4.54545*10^6 Q[t] + 2000 Derivative[Q][t] == 5, Q == 0}  *)

The reason that one does not see the If[OddQ.. bit of code is that OddQ always returns False if the argument is not an odd integer. The symbolic expression Floor[t / τ] is not an odd integer.

The fix, explained in What are the most common pitfalls awaiting new users? is to use ?NumericQ:

ClearAll[newfSign];

newfSign[t_?NumericQ] :=
If[OddQ[Floor[t/\[Tau]]],
1/2*Subscript[V, max] (Cos[2*\[Pi]*\[Beta]*t/\[Tau]] + 1),
Subscript[V, max]]

One way to make sure that a rapidly oscillating integrand is sampled enough is to limit the step size to be less than a quarter period using the MaxStepSize option:

s = NDSolve[{R*Q'[t] + Q[t]/C2 == newfSign[t], Q == 0},
Q, {t, 0, 4 τ}, MaxStepSize -> 1/(4*β/τ)]

Plot[Q[t]/C2 /. s, {t, 0, 4 τ}, PlotRange -> Full] For me it looks like the OddQ function behaves unexpected

If it is replaced by

OddQ2[n_] := If[Mod[n, 2] == 1, True, False]

then

s = NDSolve[{R*Q'[t] + Q[t]/C2 == newfSign[t], Q == 0}, Q, {t, 0, 4 \[Tau]}]
Plot[Q[t]/C2 /. s, {t, 0, 4 \[Tau]}, PlotRange -> Full]

outputs As I stated in my comment, for functions with fast oscillations there are sometimes problems with automatic step size evaluation.

using

s = NDSolve[{R*Q'[t] + Q[t]/C2 == newfSign[t], Q == 0}, Q, {t, 0, 4 \[Tau]}, Method -> {"FixedStep", Method -> "ExplicitRungeKutta"}, "StartingStepSize" -> 10^-7, WorkingPrecision -> 10, MaxSteps -> 100000]

you get which looks more reasonable.

I' curious why the OddQ function behaves like this and hope anyone has an idea.