/* **************************************************************
 * dltest2.c: Another dynamic linking example (2). This function
 *            evaluates Van Der Pol's equation, and is intended
 *            to be used in conjunction with one of the existing
 *            ODE integrators.
 * ************************************************************** */

#include "rlab.h"
#include "symbol.h"
#include "mem.h"
#include "bltin.h"
#include "scalar.h"
#include "matrix.h"
#include "matop1.h"
#include "matop2.h"
#include "r_string.h"
#include "util.h"
#include "mathl.h"

#include <math.h>
#include <stdio.h>

#define TARG_DESTROY(arg, targ)   if (targ.u.ent != arg.u.ent) \
                                    remove_tmp_destroy (targ.u.ent);
void
VDPolEq (return_ptr, n_args, d_arg)
     VPTR *return_ptr;
     int n_args;
     Datum *d_arg;
{
  Datum arg1, targ1, arg2, targ2;
  Matrix *T, *X, *XDOT;
  double *x, *xdot;
  double t;

  /* Check n_args */
  if (n_args != 2)
    error_1 ("vdpol: requires 2 arguments", 0);

  /* Get 1st arg, time. */
  arg1 = get_bltin_arg ("vdpol", d_arg, 1, NUM);
  targ1 = convert_to_matrix (arg1);
  T = (Matrix *) e_data (targ1.u.ent);
  t = MAT (T, 1, 1);

  /* Get 2nd arg, the state vector. */
  arg2 = get_bltin_arg ("vdpol", d_arg, 2, NUM);
  targ2 = convert_to_matrix (arg2);
  X = (Matrix *) e_data (targ2.u.ent);
  x = MDPTRr (X);

  XDOT = matrix_Create (2, 1);
  xdot = MDPTRr (XDOT);

  xdot[0] = x[0] * (1 - x[1]*x[1]) - x[1];
  xdot[1] = x[0];

  TARG_DESTROY (arg1, targ1);
  TARG_DESTROY (arg2, targ2);

  *return_ptr = (VPTR) XDOT;
}
