# Definition.ml

```(* Copyright INRIA and Microsoft Corporation, 2008-2013. *)

INCLUDE "preamble.ml"

(* Gives differential equation and initial conditions at a point. *)
(* Initial conditions are computed only for analytic functions. *)
(* Input: *)
(*   sf: special function object as defined in SF.ml *)
(*   point: where the initial conditions should be given *)
(* Output: *)
(*   {de, ic1, ic2, ...} where *)
(*   de: differential equation (without "= 0") *)
(*   ic1, ic2, ...: initial conditions; void if the function is not analytic *)
(* This is mostly used for point equal to << 0 >>. *)
let definition sf y point =
let var = SF.var_of_t sf
and eqn = sf.SF.lode
and ic = SF.get_initial_conditions sf point in
let feqn = << gfun:-formatdiffeq([\$(eqn), \$(y)(\$(var))]) >> in
let ics =
if ic.SF.analytic then begin
(* Analytic function. *)
(* Determine the list of power series coefficients that constitute *)
(* the initial conditions. *)
(* FIXME: If there is a single element in the list in the analytic case *)
(* the data structure has to reflect it better. *)
let m_list = (List.hd ic.SF.expansions).SF.monomials in
let size = min <:int< nops(\$(feqn)) >> (List.length m_list) in
let m_list = CommonTools.prefix_of_list size m_list in
let ic_list =
List.map
(fun m ->
let e = m.SF.x_expon and c = m.SF.coeff in
<< (D @@ \$(e))(\$(y))(\$(point)) = \$(e)! * \$(c) >>)
m_list in
CommonTools.symb_of_symb_list ic_list
end else << {} >> in
<< {\$(eqn), op(\$(ics))} >>

(* Computes the same as above, but returns also a section for displaying *)
(* the definition. *)
let doc_and_def sf notation y point values =
let eqn = sf.SF.lode
and def = definition sf y point in
let ics = << subsop(1 = NULL, \$(def)) >> in

(* Nicer display of the initial values. *)
let ics =
<<
map(a -> `if`(op(0, op(2, a)) = `*`, op(1, a) =
DDMF:-dynamow_times_to_frac(__DynaMoW_times([op(op(2, a))]), []), a),
\$(ics))
>> in

(* Display the differential equation and the initial conditions. *)
let content =
if <:bool< \$(ics) = {} >> then
<:par<<:dmath< \$(symb:eqn) = 0. >>>>
else
let s = Wording.ending_of_seq ics in
<:par<<:dmath< \$(symb:eqn) = 0 >> with initial value\$(str:s) >> @:@
(Wording.enumeration_of_maplelist << [op(\$(ics))] >>) @:@ <:par<.>> in

(* For displaying the mathematical representation of the function, *)
(* we test whether the particular choice of the parameters allows  *)
(* a simplification; in this (rare) case the output is of the form *)
(* J_{1/2}(x) = sqrt(2/Pi/x)*sin(x). *)
let rep_string = <:latex< \$(sf.SF.rep) >> in
let func_text =
if String.compare notation rep_string = 0
then <:par<<:imath< \$(str: notation) >>>>
else <:par<<:imath< \$(str: notation) = \$(str: rep_string) >>>> in

(* Create a link to the corresponding ODE page. *)
let ode_id = sf.SF.ode_id in
(match List.length values with
| 0 -> OrdinaryDiffEqn.Param0.descr ode_id None
| 1 -> OrdinaryDiffEqn.Param1.descr ode_id (Some (List.hd values))
| 2 ->
OrdinaryDiffEqn.Param2.descr ode_id
(Some (List.hd values, List.nth values 1))
| 3 ->
OrdinaryDiffEqn.Param3.descr
ode_id (Some (List.hd values, List.nth values 1, List.nth values 2))
| _ -> OrdinaryDiffEqn.Paramn.descr ode_id None)
<:text<differential equation>> in

let body =
<:par<The function >> @:@ func_text @:@
(* These links have to be hidden for a relase, as most of them break *)
(* for the moment. *)
(*    <:par< satisfies the \$(ode_link)>> @:@ content in *)