HypergeomRepresentation.ml

(* Copyright INRIA and Microsoft Corporation, 2008-2013. *)
(* DDMF is distributed under CeCILL-B license. *)

INCLUDE "preamble.ml"

let title _ = <:text<Hypergeometric Representation>>


(* Compute the hypergeometric representation of a transseries record. *)
(* Returns FAIL if no such representation exists. *)
let hyperrep_of_transseries ser =
  let u = << $(ser):-sequence_name >>
  and n = << $(ser):-index_name >>
  and lps = << $(ser):-log_powers >>
  and x = << $(ser):-variable ^ (1 / $(ser):-ramification) >> in
  let x = << combine($(x), 'power', 'symbolic') >> in
  let cfs =
    ClosedForm.call_generalTerms
      << $(ser):-recurrences >> << $(ser):-initial_conditions >> u n x lps in
  if <:bool< member(false, map(a -> a:-isHyper, $(cfs))) >> then
    << FAIL >>
  else
    <<
      $(ser):-exp_factor * $(ser):-variable ^ $(ser):-alpha *
      ($(ser):-finite_part +
        add(ln($(x))^$(lps)[i] * $(cfs)[i]:-hyperSeries, i = 1 .. nops($(lps))))
    >>


(* Compute the hypergeometric representation of a special function *)
(* at a given point. *)
(* Returns a list, which is empty if no such representation exists, *)
(* or which contains a single element, namely the hg representation. *)
let hyperrep_at_point marshaled_sf y point =
  (* The last two arguments (notation, parametrized) are only relevant *)
  (* for the descr, but here we need the obj. *)
  let linear_comb =
    LocalExpansion.obj ((marshaled_sf, point, y, "", true), ()) in
  let linear_comb =
    if <:bool< $(linear_comb) = FAIL >>
    then << [] >>
    else << DDMF:-decode_linear_combination($(linear_comb)) >> in
  let coeffs = << map(a -> a[1], $(linear_comb)) >>
  and sers = << map(a -> a[2], $(linear_comb)) >> in
  let hypers =
    CommonTools.symb_of_symb_list
      (List.map hyperrep_of_transseries (CommonTools.symb_list_of_symb sers)) in
  if <:bool< member(FAIL, $(hypers)) or not(has($(hypers), hypergeom)) >> then
    << [] >>
  else
    let hrep =
      <<
        `+`(op(zip((a, b) -> `if`(op(0, b) = `+`, map(c -> a * c, b), a * b),
          $(coeffs), $(hypers))))
      >> in
    let hrep = << `if`(op(0, $(hrep)) = `+`, [op($(hrep))], [$(hrep)]) >> in
    let hrep =
      <<
        sort($(hrep),
          proc(a, b) local t1, t2;
            t1 := has(a, hypergeom);
            t2 := has(b, hypergeom);
            `if`(t1 = t2, [a, b] = sort([a, b]), t2)
          end proc)
      >> in
    let hrep =
      <<
        map(a -> `if`(op(0, a) = `*`, DDMF:-dynamow_times_to_frac(
          __DynaMoW_times([op(a)]), [hypergeom]), a), $(hrep))
      >> in
    let hrep =
      << `if`(nops($(hrep)) > 1, __DynaMoW_plus($(hrep)), `+`(op($(hrep)))) >>
    in
    << [DDMF:-maple_to_dynamow($(hrep))] >>


(* Display various hypergeometric representations of a special function, *)
(* according to the singular points of its differential equation, and to *)
(* 0 and infinity. The obj function indicates whether at least one such  *)
(* representation exists. *)
let_service HypergeomRepresentation
  (marshaled_sf : string)
  (y : name maple)
  (notation : string) :
  DC.sec_entities * bool with { title = title } =

  let sf = DB.unmarshal_sf marshaled_sf in
  let x = SF.var_of_t sf in
  let sings = << DDMF:-singular_points($(sf.SF.lode), $(y), $(x)) >> in
  let points = << [0, op({op($(sings))} minus {0, infinity}), infinity] >> in
  let hypers =
    List.map
      (hyperrep_at_point marshaled_sf y)
      (CommonTools.symb_list_of_symb points) in
  let hypers = List.flatten (List.map CommonTools.symb_list_of_symb hypers) in
  let texts =
    List.map
      (fun a -> <:par<<:dmath< $(str: notation) = $(symb: a) >>>>) hypers in
  if texts = [] then
    DC.section (title _req_params) DC.ent_null, false
  else
    DC.section (title _req_params) (List.fold_left (@:@) <:par<>> texts), true

Generated by GNU Enscript 1.6.5.90.