
    uki*                        d Z ddlmZ ddlZddlmZ ddlZddlmZ ddl	m
Z ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZmZ ddlmZ eZeZdedej<                  fdZej@                  d        Z!d Z"d Z#d Z$d Z%d Z&d Z'	 	 d$dZ(ddejR                  ejR                  ddZ* eejV                  d      defd       Z, eejZ                  d       d!        Z.d" Z/d# Z0e.jc                  e/e0       y)%a  JAX-based Dormand-Prince ODE integration with adaptive stepsize.

Integrate systems of ordinary differential equations (ODEs) using the JAX
autograd/diff library and the Dormand-Prince method for adaptive integration
stepsize calculation. Provides improved integration accuracy over fixed
stepsize integration methods.

For details of the mixed 4th/5th order Runge-Kutta integration method, see
https://doi.org/10.1090/S0025-5718-1986-0815836-3

Adjoint algorithm based on Appendix C of https://arxiv.org/pdf/1806.07366.pdf
    )partialN)Callable)api_util)core)custom_derivatives)lax)promote_dtypes_inexact)safe_mapsafe_zipravel_pytree)tree_leavestree_map)linear_utilf
debug_infoc                 X    t        t        j                  | |      |      j                  S )N)r   )ravel_first_arg_lu	wrap_initcall_wrapped)r   unravelr   s      O/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/ode.pyravel_first_argr   1   s$    	",,qZ@!
##/<0    c                 D     ||      } | |g| }t        |      \  }}|S Nr   )r   r   y_flatargsyansans_flat_s           r   r   r   5   s+    fo!	!d#S!+(A	/r   c           
         t        j                  g d| j                        }| |j                  | j                        t        j                  ||      z  z   }t        j
                  t        | |||d   |d   |            S )N)ge
g?r   gG?gg$Wgl,?gh
ygHn^z?dtyper   )jnparrayr&   astypedotasarrayfit_4th_order_polynomial)y0y1kdt	dps_c_midy_mids         r   interp_fit_doprir4   <   sq    ii ? GIhhP) ryy"SWWY%::
:%	-b"eQqT1R5"M	NNr   c                     |j                  | j                        }d|z  |z  d|z  |z  z   d| z  z
  d|z  z
  d|z  z   }d|z  |z  d|z  |z  z
  d| z  z   d|z  z   d	|z  z
  }d
|z  |z  ||z  z   d| z  z
  d|z  z
  d|z  z   }||z  }	| }
||||	|
fS )Ng       g       @g       @g      0@      @g      @g      2@g      ,@g      @@g      g      &@)r*   r&   )r.   r/   r3   dy0dy1r1   abcdes              r   r-   r-   E   s    	yy"	"fSj2b592%B.U:!	"uSy2b59s2v%B.U:!	"fSjbfs2v%B.U:!3h!!	
Aq!Qr   c           	         t        ||      \  }}|j                  }|t        j                  |      |z  z   }t        j                  j                  ||j                  |      z        }	t        j                  j                  ||j                  |      z        }
t        j                  |	dk  |
dk  z  dd|	z  |
z        }||j                  |      |z  z   } | |||z         }t        j                  j                  ||z
  |j                  |      z        |z  }t        j                  |
dk  |dk  z  t        j                  d|dz        dt        j                  |
|      z  d|dz   z  z        }t        j                  d|z  |      S )Ngh㈵>gư>g{Gz?gV瞯<gMbP?      ?g      Y@)
r	   r&   r(   abslinalgnormr*   wheremaximumminimum)funt0r.   orderrtolatolf0r&   scaled0d1h0r/   f1d2h1s                   r   initial_step_sizerS   N   sT    ""b)&"b
((%
t#
#%
zzrELL//0"
zzrELL//0"
yy"t)T	*D$)b.A"	BIIer!!"
2rBw"
zzR5<<#667"<"
yy"+"+.D"t),B++urz1BCE" 
TBY	##r   c           	          t        j                  g dj                        t        j                  g dg dg dg dg dg dgj                        t        j                  g dj                        }t        j                  g d	j                        } fd
}t        j                  dj                  d   fj                        j
                  dd d f   j                        }t        j                  dd||      }j                  j                        t        j                  ||      z  z   }	j                  j                        t        j                  ||      z  }
|d   }|	||
|fS )N)皙?g333333?g?gqq?r?   r?   r   r%   )rU   r   r   r   r   r   r   )g333333?g?r   r   r   r   r   )gII?ggqq@r   r   r   r   )gq@g 1'gR<6R#@gE3ҿr   r   r   )g+@g>%gr!@gE]t?g/pѿr   r   )gUUUUUU?r   gVI?gUUUUU?gϡԿg10?r   )g djJ?r   g9gg>>?g8\gOc?gc                     
| dz
     z  z   }j                  j                        t        j                  | dz
  d d f   |      z  z   } 	||      }|j                  | d d f   j                  |      S )N   )r*   r&   r(   r+   atset)ir0   tiyiftalphabetar1   rK   funcrG   r.   s        r   body_funz"runge_kutta_step.<locals>.body_funv   sr    	b51:o	B	bii!CGGD1aL!$<<	<B	b"B441:>>"r      r   rW   r'   )r(   r)   r&   zerosshaperX   rY   r   	fori_loopr*   r+   )r`   r.   rK   rG   r1   c_solc_errorra   r0   r/   y1_errorrP   r^   r_   s   `````       @@r   runge_kutta_stepri   d   s;   
))<BHH
M%	 "A.GLE	G
 HH
$ ))DHH% II  88'
  
iiBHHQK "((+..q!t488<!	mmAq(A&!	yySWWUA..3"YYrxx 3777A#66(u"	R1	r   c                 t    t        j                  |       r| j                  dz  | j                  dz  z   S | dz  S )N   )r(   iscomplexobjrealimag)xs    r   abs2rp      s4    a66Q;1$$6Mr   c                 $   ||t        j                  t        j                  |      t        j                  |            z  z   }| |j                  | j                        z  }t        j
                  t        j                  t        |                  S r   )r(   rD   r@   r*   r&   sqrtmeanrp   )error_estimaterI   rJ   r.   r/   err_tol	err_ratios          r   mean_error_ratiorw      sa    4#++cggbk3772;???'w~~n.B.BCC)	#((4	?+	,,r   c                     t        j                  |dk  d|      }t        j                  |t        j                  |d|z  z  |z  |            }t        j                  |dk(  | |z  | |z        S )z%Compute optimal Runge-Kutta stepsize.rW   r?   g      r   )r(   rC   rE   rD   )	last_steprw   safetyifactordfactorrH   factors          r   optimal_step_sizer~      sm     II&*C9';;wkk"2TE\"BV"KWUW&	#q()g*=y6?Q	RRr   gC֔N>rI   rJ   mxstephmaxc          	      ~   t        |      D ]A  }t        |t        j                        rt        j                  |      r4t        d| d       t        j                  |j                  t        j                        st        d| d      t        j                  | ||d   g| \  }	}
t        |	||||||g||
 S )a  Adaptive stepsize (Dormand-Prince) Runge-Kutta odeint implementation.

  Args:
    func: function to evaluate the time derivative of the solution `y` at time
      `t` as `func(y, t, *args)`, producing the same shape/structure as `y0`.
    y0: array or pytree of arrays representing the initial value for the state.
    t: array of float times for evaluation, like `jnp.linspace(0., 10., 101)`,
      in which the values must be strictly increasing.
    *args: tuple of additional arguments for `func`, which must be arrays
      scalars, or (nested) standard Python containers (tuples, lists, dicts,
      namedtuples, i.e. pytrees) of those types.
    rtol: float, relative local error tolerance for solver (optional).
    atol: float, absolute local error tolerance for solver (optional).
    mxstep: int, maximum number of steps to take for each timepoint (optional).
    hmax: float, maximum step size allowed (optional).

  Returns:
    Values of the solution `y` (i.e. integrated system values) at each time
    point in `t`, represented as an array (or pytree of arrays) with the same
    shape/structure as `y0` except with a new leading axis of length `len(t)`.
  z@The contents of odeint *args must be arrays or scalars, but got .z&t must be an array of floats, but got r   )r   
isinstancer   Tracervalid_jaxtype	TypeErrorr(   
issubdtyper&   floatingr   closure_convert_odeint_wrapper)r`   r.   trI   rJ   r   r   r   arg	convertedconstss              r   odeintr      s    ,  Scc4;;'0B0B30G
J3%qQS SS 
	.
<QCqA
BB(88r1Q4O$O)V	D$b!	Td	TV	TTr   )r   rW   rk         )static_argnumsr`   c           	          t        |      \  }}t        j                  d| |i       }	t        | ||	      } t	        | ||||||g| }
 t        j                  |      |
      S )Nr   )r   r   r   r   _odeintjaxvmap)r`   rI   rJ   r   r   r.   tsr   r   debugouts              r   r   r      se    R +"g


hdB
7%	w	.$dD&$B>>#	'	3	r   )nondiff_argnumsc                 V     fdfd} ||d         }	t        j                  t        |d   |d|	      d      }
t        j                  |gdz        }||	|d   |
|d   |g}t	        j
                  |||dd        \  }}t        j                  |d    |f      S )	Nc                      | |g S r    )r    r   r   r`   s     r   <lambda>z_odeint.<locals>.<lambda>   s    tAq(4( r   c                     fd}
fd}t        j                  ||dg| z         ^}} | \  }}}}}}|z
  ||z
  z  }t        j                  ||j	                  |j
                              }	| |	fS )Nc                 :    | \  }}}}}}}|k  |k  z  |dkD  z  S )Nr   r   )staterZ   r#   r   r1   r   target_ts        r   cond_funz+_odeint.<locals>.scan_fun.<locals>.cond_fun   s3    "aAq"a(lq6z*b1f55r   c                 H   | \  }}}}}}}t        ||||      \  }}	}
}||z   }t        |
||      }t        ||||      }t        j                  t        ||      d      }|dz   ||	||||g}|dz   ||||||g}t        t        t        j                  |dk        ||      S )N        minmaxrW   r?   )	ri   rw   r4   r(   clipr~   mapr   rC   )r   rZ   r    r   r   r1   last_tinterp_coeffnext_ynext_fnext_y_errorr0   next_terror_rationew_interp_coeffnewoldrJ   func_r   rI   s                    r   ra   z+_odeint.<locals>.scan_fun.<locals>.body_fun   s    -2*aAq"fl(81a(L%fflA2vf$\4q&Ik)!VQ;88%b+6BDIbUFFFBQ8HIcUBLIcK2$56SAAr   r   )r   
while_loopr(   polyvalr*   r&   )carryr   r   ra   r#   r   r   r   relative_output_timey_targetrJ   r   r   r   rI   s    `        r   scan_funz_odeint.<locals>.scan_fun   s~    6
B xA3;?IA',$Aq!Q$v-!f*={{<)=)D)D\EWEW)XYH(?r   r   r   r   r      rW   )r(   r   rS   r)   r   scanconcatenate)r`   rI   rJ   r   r   r.   r   r   r   rK   r1   r   
init_carryr#   ysr   s   `````  `       @r   r   r      s    
(% 0 RA"
xx!%AAtT2FBTXY"B4!8$,B1r2a5,7*
((8ZAB
0%!R	"T(B	((r   c           	      4    t        | ||||||g| }||||ffS r   )r   )	r`   rI   rJ   r   r   r.   r   r   r   s	            r   _odeint_fwdr      s.    tT4r2=="	b"d^	r   c           
          |\   fdd   }g }d}	 f
d}
d   dt        t        j                        f}t        j                  |
|t        j
                  t              dz
  dd            \  \  }}	}}t        j                  t        j                  |	g      |d d d   g      }||g|S )Nc                 `    | ^}}}t        j                  || g| \  }}| g ||      S )z9Original system augmented with vjp_y, vjp_t and vjp_args.)r   vjp)	augmented_stater   r   r    y_barr#   y_dotvjpfunr`   s	           r   aug_dynamicsz!_odeint_rev.<locals>.aug_dynamics   sA    "LAuq GGD!aR/$/ME6F#VE]##r   r'   r   c           
      l  
 | \  }}}t        j                   
|   |   g |         j                  }||z
  }t        	|   |||ft        j                  |    |dz
      g      gd\  }}}}t        t        j                  d      |||f      \  }}}||dz
     z   }|||f|fS )NrW   r   )r(   r+   rm   r   r)   r   op
itemgetter)r   rZ   r   t0_barargs_bart_barr#   r   rJ   r   r`   gr   r   rI   r   r   s          r   r   z_odeint_rev.<locals>.scan_fun   s    #E68 GGDA1--qt499Ee^F!'r!ueVX6		BqE6Bq1uI:&'"? 
"? tF"?Aufh 'r}}Q'7%9RSE68Aa!eHE68$e++r   rW   r   )	r   r(   
zeros_liker   r   arangelenr   r)   )r`   rI   rJ   r   r   resr   r   ts_barr   r   r   r   
rev_ts_barr   r   r   r   s   ````` `       @@@@r   _odeint_revr      s    ,"b$$ B%%&&, ,  "r8CNND9:**-((
CJJs2w{Ar:+<'5&(Z??CIIvh/DbD1ABC&
	#(	##r   )g?g      $@rU   r6   )2__doc__	functoolsr   operatorr   collections.abcr   r   r   	jax.numpynumpyr(   jax._srcr   r   r   jax._src.numpy.utilr	   jax._src.utilr
   r   jax.flatten_utilr   jax.tree_utilr   r   r   r   r   zip	DebugInfor   transformation2r   r4   r-   rS   ri   rp   rw   r~   infr   jitr   
custom_vjpr   r   r   defvjpr   r   r   <module>r      s     $ 
    "  6 , ) / &0x 0dnn 0  O$,@-
 HL),S %+cgg U@ 	1 (   2  	9 ) : )D#$J {K (r   