001import org.apache.commons.math3.ode.*; 002 003/** Wrapper used to pass a <i>system of first order ordinary differential equations</i> (odes) to <a target="_blank" href="http://commons.apache.org/math">Commons Math</a> algorithms. 004 * Computes the derivatives {@code dy}<sub>i</sub>{@code /dt} defined in the {@code String[] odes}.<br/> 005 * <br/> 006 * See <a target="_top" href="../0_CommonsMath_README.html#examples">CommonsMath_ODE_Lotka_Volterra~Test.jxn</a> 007 * for an example. 008 */ 009public class JxnODE implements FirstOrderDifferentialEquations 010{ 011 KmgFormelInterpreter fi; 012 static final boolean skipInputLogEnabled = true; 013 014 String itsInit = ""; 015 String [] itsOdes; 016 017 /** Constructs a {@link org.apache.commons.math3.ode.FirstOrderDifferentialEquations} 018 * instance to be used by <a target="_blank" href="http://commons.apache.org/math">Commons Math</a> algorithms. <br/> 019 * Example: 020 * <pre> 021 * ode = @JxODE( $this, { "$y[0]*( a - b $y[1] );", "$y[1]*( d $y[0] - c );" } ) 022 * </pre> 023 * @param fi instance of {@code KmgFormelInterpreter} on which the definitions in {@code odes[...]} are executed 024 * @param odes array of <i>statement_sequence</i>s (one or more statements separated by '{@code ;}'). 025 * The definitions in {@code odes[...]} must use {@code double[] $y} and {@code $t} to calculate the derivatives {@code dy/dt}. 026 * If the definition in {@code odes[i]} ends with '{@code ;}', log output of intermediate steps is suppressed for the definition. 027 */ 028 public JxnODE( KmgFormelInterpreter fi, String [] odes ) 029 { 030 this.fi = fi; 031 itsOdes = odes; 032 } 033 034 /** See {@link #JxnODE}. 035 * @param init <i>statement_sequence</i> (one or more statements separated by '{@code ;}'). {@code init} is evaluated before evaluating {@code odes} and 036 * can use {@code double[] $y} and {@code $t}. If {@code init} ends with '{@code ;}', log output is suppressed. 037 * @param parameters the values can be used in the {@code init} and {@code odes} definitions via the array variable {@code $p[...]} 038 */ 039 public JxnODE( KmgFormelInterpreter fi, String init, String [] odes, double [] parameters ) 040 { 041 this.fi = fi; 042 itsInit = init; 043 itsOdes = odes; 044 045 fi.put( "$p", parameters ); 046 } 047 048// --- interface FirstOrderDifferentialEquations --- 049 050 /** Returns the number of states. */ 051 public int getDimension() 052 { 053 return itsOdes.length; 054 } 055 056 /** Computes derivatives {@code ydot} from {@code y} and {@code t} (internally called by Commons Math algorithms). */ 057 public void computeDerivatives( double t, double [] y, double [] ydot ) 058 { 059 // store values 060 fi.put( "$t", new JxnPrimitiveWrapper(t) ); 061 fi.put( "$y", y ); 062 if( itsInit.length() > 0 ) fi.execute( itsInit, skipInputLogEnabled ); 063 064 // calculate derivatives 065 for( int i = 0; i < itsOdes.length; i++ ) 066 { 067 ydot[i] = KmgFormelInterpreter.doubleValue( fi.execute( itsOdes[i], skipInputLogEnabled ) ); 068 } 069 } 070 071 public String toString() 072 { 073 return itsOdes.length + " ODEs"; 074 } 075}