Search code examples
matlabplotodepiecewiseperiodicity

Solving and plotting a piecewise ODE


I have a function dφ/dt = γ - F(φ) (where F(φ) -- a is -periodic function) and the graph of the function F(φ).

I need to create a program that outputs 6 plots of φ(t) for different values of γ (γ = 0.1, 0.5, 0.95, 1.05, 2, 5), and t∈[0,100].

Here is the definition of the F(φ) function:

      -φ/a - π/a,    if φ ∈ [-π, -π + a]
      -1,            if φ ∈ [-π + a, - a] 
F(φ) = φ/a,          if φ ∈ [- a, a]
       1,            if φ ∈ [a, π - a]
      -φ/a + π/a,    if φ ∈ [π - a, π]
                 ^ F(φ)
                 |
                 |1   ______
                 |   /|     \
                 |  / |      \
                 | /  |       \      φ
__-π_______-a____|/___|________\π____>
   \        |   /|0    a
    \       |  / |
     \      | /  |
      \     |/   |
       ¯¯¯¯¯¯    |-1

My problem is I don't know what inputs to give ode45 in terms of the bounds and the initial condition. What I do know is that the evolution of φ(t) must be continuous.

This is the code for case of γ = 0.1:

hold on;
df1dt = @(t,f1) 0.1 - f1 - 3.14;
df2dt = @(t,f2)- 1;
df3dt = @(t,f3) 0.1 + f3;
df4dt = @(t,f4)+1;
df5dt = @(t,f5) 0.1 - f5 + 3.14;
[T1,Y1] = ode45(df1dt, ...);
[T2,Y2] = ode45(df2dt, ...);
[T3,Y3] = ode45(df3dt, ...);
[T4,Y4] = ode45(df4dt, ...);
[T5,Y5] = ode45(df5dt, ...);
plot(T1,Y1);
plot(T2,Y2);
plot(T3,Y3);
plot(T4,Y4);
plot(T5,Y5);
hold off; 
title('\gamma = 0.1')

Solution

  • Let us first define F(φ,a):

    function out = F(p, a)
    phi = mod(p,2*pi);
    out = (0      <= phi & phi < a     ).*(phi/a) ...
        + (a      <= phi & phi < pi-a  ).*(1) ...
        + (pi-a   <= phi & phi < pi+a  ).*(-phi/a + pi/a) ...
        + (pi+a   <= phi & phi < 2*pi-a).*(-1) ...
        + (2*pi-a <= phi & phi < 2*pi  ).*(phi/a - 2*pi/a);
    end
    

    Which for some example inputs gives: enter image description here

    using the plotting code:

    x = linspace(-3*pi, 3*pi, 200);
    a = pi/6;
    
    figure(); plot(x,F(x, a));
    xlim([-3*pi,3*pi]);
    xticks(-3*pi:pi:3*pi);
    xticklabels((-3:3)+ "\pi");
    grid on; grid minor
    ax = gca;
    ax.XAxis.MinorTick = 'on';
    ax.XAxis.MinorTickValues = ax.XAxis.Limits(1):pi/6:ax.XAxis.Limits(2);
    

    From there you don't need to bother with the ranges anymore, and simply call ode45:

    % Preparations:
    a = pi/6;
    g = [0.1, 0.5, 0.95, 1.05, 2, 5]; % γ
    phi0 = 0; % you need to specify the correct initial condition (!)
    tStart = 0;
    tEnd = 100;
    % Calling the solver:
    [t, phi] = arrayfun(@(x)ode45(@(t,p)x-F(p,a), [tStart, tEnd], phi0), g, 'UniformOutput', false);
    % Plotting:
    plotData = [t; phi];
    figure(); plot(plotData{:});
    legend("γ=" + g, 'Location', 'northwest');
    

    Resulting in:

    enter image description here