## Chapter 2Design of the ode solver program

This gives high level view of my diﬀerential equations solver program which is in development for academic use. The program design is based on top-down modular design.

There are a number of public API’s. The main API is dsolve(). But there are other API’s such as for ﬁnding eigenvalues and eigenvectors.

This diagram shows the top level design

The following is the pseudo code of the dsolve() procedure. This is one of main calls into the main module for solving a single diﬀerential equation. It returns back all solutions found.

dsolve:=proc(ode,y(x),IC,hint::string)

-- This CALL validates the ode itself. IC are validated by each separate
-- module below this throws parse error if any fail
ode_MGR:-parse_ode(ode);
ode_order := ode_MGR:-:-get_ode_order(ode);

-- parse and validate IC. This throws error if any fails
IF ode_order =1 then
first_order_ode:-parse_IC(ode,y(x),IC);
ELIF ode_order=2 then
second_order_ode:-parse_IC(ode,y(x),IC);
ELSE
higher_order_ode:-parse_IC(ode,y(x),IC);
END IF

-- the following factors ode if possible. For example for y''*y'=0 gives
-- y''=0 and y'=0 factors. If not possible to factor, ode itself is only
-- factor. in 99% of the times, ode do not factor and ode_factors list
-- will just contain the original ode. But this makes it much easier
-- to solve an ode if it can be factored.

ode_factors := factor_ode(ode);

-- This finds general and any singular solutions if any
solutions_found :=  process_factors(ode,y(x),IC,hint,ode_factors)

-- Update solutions for IC
solutions_found :=  update_solutions_for_IC(solutions_found,y(x),IC)

-- Finally, check solutions. Throw away ones that do not verify
-- the ODE or IC

solutions_found :=  verify_solutions_against_ode_and_IC(solutions_found,ode,y(x),IC)

RETURN solutions_found



The following procedure is the main dispatcher.

It takes in the ode factors after being parsed with the initial conditions also parsed and veriﬁed and dispatches each to the correct solver depending on the ode order.

Its input is the original ode and all the factors found. Most of the time there are no factors and only the ode itself is its own factor. It returns back set of the solutions found.

process_factors:=proc(ode,y(x),IC,hint::string,ode_factors::list)

solutions_found := {};

FOR current_factor in ode_factors DO -- must have at least one

-- possible to have factor not ode. Example x*y'=0, only factor is y'=0
-- and x factor is ignored.
IF current_factor has y THEN
-- find ode order to know which module to call.
ode_order := ode_MGR:-:-get_ode_order(current_factor);

IF ode_order = 0 then -- algebraic factor
-- handle case of factor has only y and no y'. For example y*y'=0
-- or cos(y)*y'=0, then factors are  cos(y)=0 and y'=0 and so on.
-- solutions to algebric factors have no consant of integration
-- but must still satisfy original ode and initial conditions.
solution := SOLVE(current_factor=0,y(x))
-- only keep if it satisfies original ode and IC if any
IF solution does not satisfy ode or does not satisfy IC THEN
solution:={};
END IF;

ELIF ode_order = 1 then
solution := first_order_ode:-dsolve(current_factor,y(x),IC,hint);
ELIF ode_order = 2 then
solution := second_order_ode:-dsolve(current_factor,y(x),IC,hint);
ELSE
solution := higher_order_ode:-dsolve(current_factor,y(x),IC,hint);
FI;

-- collect solutions and remove duplicates
solutions_found := solutions_found UNION solution;
END IF;
END DO;

RETURN solutions_found
END proc;