
    Vpf)                        d Z ddlmZ ddl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mZ dd	lmZ dd
lmZmZ ddl	mZ eZeZd Zej        d             Zd Zd Zd Z d Z!d Z"d Z#	 	 d#dZ$ddej%        ej%        ddZ& eej'        d          d             Z( eej)        d          d              Z*d! Z+d" Z,e*-                    e+e,           dS )$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)core)custom_derivatives)lax)promote_dtypes_inexact)safe_mapsafe_zipravel_pytree)tree_leavestree_map)linear_utilc                 P    t          t          j        |           |          j        S N)ravel_first_arg_lu	wrap_initcall_wrapped)funravels     T/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/experimental/ode.pyravel_first_argr   /   s    	",q//7	3	3	@@    c              '   `   K    | |          }|f|z   i fV }t          |          \  }}|V  d S r   r
   )r   y_flatargsyansans_flat_s          r   r   r   2   sF      gfoo!dTk2o#S!!+(A.....r   c           
         t          j        g d| 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_doprir1   9   s    i ? ? ? GIhP P P) ryy""SWY%:%::
:%	-b"eQqT1R5"MM	N	NNr   c                    |                     | 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,   r0   dy0dy1r.   abcdes              r   r*   r*   B   s    	yy"	"fSj2b592%B.U:!	"uSy2b59s2v%B.U:!	"fSjbfs2v%B.U:!3h!!	
Aq!Qr   c           	      2   t          ||          \  }}|j        }|t          j        |          |z  z   }t          j                            ||                    |          z            }	t          j                            ||                    |          z            }
t          j        |	dk     |
dk     z  dd|	z  |
z            }||                    |          |z  z   } | |||z             }t          j                            ||z
  |                    |          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_sizerP   K   sq    ""b))&"b
(%
t#
#%
zrELL///00"
zrELL///00"
y"t)T	*D$)b.AA"	BIIer!!"
s2rBw"
zR5<<#6#6677"<"
y"+"+.D"t),,B+++urz1BCE 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                                       }t          j        dd||          }	                    j                  t          j
        ||          z  z   }		                    j                  t          j
        ||          z  }
|d         }|	||
|fS )N)皙?g333333?g?gqq?r<   r<   r   r"   )rR   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                  t          j        | dz
  d d f         |          z  z   } 	||          }|j        | d d f                             |          S )N   )r'   r#   r%   r(   atset)ir-   tiyiftalphabetar.   rH   funcrD   r+   s        r   body_funz"runge_kutta_step.<locals>.body_funs   s    	b51:o	B	bii!!CGD1aaaL!$<$<<	<B	b"B4111:>>"r      r   rT   r$   )r%   r&   r#   zerosshaperU   rV   r   	fori_loopr'   r(   )r]   r+   rH   rD   r.   c_solc_errorr^   r-   r,   y1_errorrM   r[   r\   s   `````       @@r   runge_kutta_steprf   a   s   
)<<<BH
M
M
M%	   "A"A"A...GGGLLLEEE	G
 H
 
 
$ )DDDH  % I    8  '
           
iBHQK "(++.q!!!t488<<!	mAq(A&&!	yySWUA...3"YYrx  377A#6#66(u"	R1	r   c                 ^    t          j        |           r| j        dz  | j        dz  z   S | dz  S )N   )r%   iscomplexobjrealimag)xs    r   abs2rm      s5    a 6Q;1$$6Mr   c                     ||t          j        t          j        |          t          j        |                    z  z   }| |                    | j                  z  }t          j        t          j        t          |                              S r   )r%   rA   r=   r'   r#   sqrtmeanrm   )error_estimaterF   rG   r+   r,   err_tol	err_ratios          r   mean_error_ratiort      sf    4#+cgbkk372;;????'w~~n.BCCC)	#(4	??++	,	,,r   ?      $@rR   r3   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.rT   r<   g      r   )r%   r@   rB   rA   )	last_steprt   safetyifactordfactorrE   factors          r   optimal_step_sizer}      st     I&*C99';wk"2TE\"BV"KWUUW W&	#q()g*=y6?Q	R	RRr   gC֔N>rF   rG   mxstephmaxc          	      z   t          |          D ]C}t          |t          j                  s't          j        |          st          d| d          Dt          j        |j        t          j	                  st          d| d          t          j        | ||d         g|R  \  }	}
t          |	||||||g||
R  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+   trF   rG   r   r   r   arg	convertedconstss              r   odeintr      s    ,  S Scc4;'' S0B30G0G SQ3QQQS S S		.	. C
AQAAA
B
BB(8r1Q4O$OOO)V	D$b!	Td	TV	T	T	TTr   )r   rT   rh         )static_argnumsc           	          t          |          \  }}t          | |          } t          | ||||||g|R  }	 t          j        |          |	          S r   )r   r   _odeintjaxvmap)
r]   rF   rG   r   r   r+   tsr   r   outs
             r   r   r      s]    R  +"g	w	'	'$dD&$B>>>>#	'		3		r   )nondiff_argnumsc                      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R  S r    )r   r   r   r]   s     r   <lambda>z_odeint.<locals>.<lambda>   s    ttAq(4((( r   c                     fd}
fd}t          j        ||dg| z             ^}} | \  }}}}}}|z
  ||z
  z  }t          j        ||                    |j                            }	| |	fS )Nc                 @    | \  }}}}}}}|k     |k     z  |dk    z  S )Nr   r   )staterW   r    r   r.   r   target_ts        r   cond_funz+_odeint.<locals>.scan_fun.<locals>.cond_fun   s3    "aAq"a(lq6z*b1f55r   c                 p   | \  }}}}}}}t          ||||          \  }}	}
}||z   }t          |
||          }t          ||||          }t          j        t          ||          d          }|dz   ||	||||g}|dz   ||||||g}t          t          t          j        |dk              ||          S )N        minmaxrT   r<   )	rf   rt   r1   r%   clipr}   mapr   r@   )r   rW   r   r   r   r.   last_tinterp_coeffnext_ynext_fnext_y_errorr-   next_terror_rationew_interp_coeffnewoldrG   func_r   rF   s                    r   r^   z+_odeint.<locals>.scan_fun.<locals>.body_fun   s    -2*aAq"fl(81a(L(L%fflA2vf$\4q&IIk)!VQ;;8%b+66BDIIIbUFFFBQ8HIcUBLIcK2$566SAAAr   r   )r   
while_loopr%   polyvalr'   r#   )carryr   r   r^   r    r   r   r   relative_output_timey_targetrG   r   r   r   rF   s    `        r   scan_funz_odeint.<locals>.scan_fun   s    6 6 6 6 6 6
B 
B 
B 
B 
B 
B 
B 
B xA3;??IA',$Aq!Q$v-!f*={<)=)D)D\EW)X)XYYH(?r   r   r   r   r      rT   )r%   r   rP   r&   r   scanconcatenate)r]   rF   rG   r   r   r+   r   r   r   rH   r.   r   
init_carryr    ysr   s   `````  `       @r   r   r      s    
(
(
(
(
(%        0 uRA"
x!%AAtT2FFBTXYYY"B4!8$$,B1r2a5,7*
(8ZABB
0
0%!R	"T(B	(	((r   c           	      6    t          | ||||||g|R  }||||ffS r   )r   )	r]   rF   rG   r   r   r+   r   r   r   s	            r   _odeint_fwdr      s4    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|R S )Nc                 ^    | ^}}}t          j        || g|R  \  }}| g ||          R 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   sL    "LAuq GD!aR/$///ME6F#VVE]]###r   r$   r   c           
        
 | \  }}}t          j         
|         |         gR  |                   j        }||z
  }t          	|         |||ft          j        |          |dz
            g          gR d\  }}}}t          t          j        d          |||f          \  }}}||dz
           z   }|||f|fS )NrT   r~   )r%   r(   rj   r   r&   r   op
itemgetter)r   rW   r   t0_barargs_bart_barr    r   rG   r   r]   gr   r   rF   r   r   s          r   r   z_odeint_rev.<locals>.scan_fun   s   #E68 GDDA1----qt449Ee^F!'r!ueVX6	BqE6Bq1uI:&''"? 
"? "? tF"? "? "?Aufh 'r}Q'7'7%9RSSE68Aa!eHE68$e++r   rT   r   )	r   r%   
zeros_liker   r   arangelenr   r&   )r]   rF   rG   r   r   resr   r   ts_barr   r   r   r   
rev_ts_barr   r   r   r   s   ````` `       @@@@r   _odeint_revr      s#   ,"b$$ $ $ $ $ B%%&&, , , , , , , , , , , , , ,  "r8CND99:**-(
CJs2ww{Ar::+< +<'5&(Z?CIvh//DDbD1ABCC&
	#(	#	##r   )ru   rv   rR   r3   ).__doc__	functoolsr   operatorr   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   zipr   transformationr   r1   r*   rP   rf   rm   rt   r}   infr   jitr   
custom_vjpr   r   r   defvjpr   r   r   <module>r      se              



             " " " " " "       6 6 6 6 6 6 , , , , , , , , ) ) ) ) ) ) / / / / / / / / & & & & & &A A A   O O O  $ $ $,  @  - - -
 HL),S S S S %+cg U U U U U@ 	111    21  	999 )  ) :9 )D  #$ #$ #$J {K ( ( ( ( (r   