classdef simpleOscillator
    %SIMPLEOSCILLATOR A class that models a simple harmonic oscillator
    %   This class models a one-dimensional simple harmonic oscillator. The
    %   two properties mass and springConstant are the two parameters that
    %   completely specify this system. The trajectory of this system is  
    %   completely determined by the initial position and the initial
    %   velocity. Given the initial conditions, The DYNAMICS method returns
    %   the final position after a given time interval. The EVOLUTION
    %   method calls the DYNAMICS method iteratively to evolve the
    %   system over a given period of time with a given time step. It also
    %   plots the position vs time graph.
    
    % Copyright 2020 The MathWorks, Inc. 
    
    properties (SetAccess = private, GetAccess = protected)
        mass 
        springConstant
    end
    
    methods
        function obj = simpleOscillator(m,k)
            obj.mass = m;
            obj.springConstant = k;
        end
        
        function omega = angularFrequency(obj)
            omega = sqrt(obj.springConstant/obj.mass);
        end
        
        function amp = amplitude(obj,initialPosition,initialVelocity)
            amp = sqrt(initialPosition^2 + (initialVelocity/obj.angularFrequency)^2);
        end
        
        function phi = phase(obj,initialPosition,initialVelocity)
            phi = atan2(obj.angularFrequency*initialPosition,initialVelocity);
        end
        
        function finalPosition = dynamics(obj,initialPosition,initialVelocity,timeInterval)
            finalPosition = obj.amplitude(initialPosition, initialVelocity)...
                *sin(obj.angularFrequency*timeInterval + obj.phase(initialPosition,initialVelocity));
        end
        
        function [time,position] = evolution(obj,initialPosition,initialVelocity,timeInterval,timeStep)
            numSteps = floor(timeInterval/timeStep);
            position = zeros(numSteps + 1,1);
            time = zeros(numSteps + 1,1);
            position(1) = initialPosition;
            for i = 1:numSteps
                position(i+1) = obj.dynamics(initialPosition,initialVelocity,i*timeStep);
                time(i+1) = i*timeStep;
            end
        end
    end
end

