void mxW_CVodeMonitor(int call, double t, N_Vector y, N_Vector yQ, N_Vector *yS,
                       cvmPbData fwdPb)
{
  mxArray *mx_in[8], *mx_out[1];
  double *tmp;
  int is;

  mx_in[0] = mxCreateDoubleScalar(call);            /* call type (0:first, 1:interm. 2:last) */
  mx_in[1] = mxCreateDoubleScalar(t);               /* current time */
  mx_in[2] = mxCreateDoubleMatrix(N,1,mxREAL);      /* current solution */
  if (quadr)
    mx_in[3] = mxCreateDoubleMatrix(Nq,1,mxREAL);   /* current quadratures */
  else
    mx_in[3] = mxCreateDoubleMatrix(0,0,mxREAL);
  mx_in[4] = mxCreateDoubleScalar(Ns);              /* number of sensitivities */
  if (fsa)
    mx_in[5] = mxCreateDoubleMatrix(N*Ns,1,mxREAL); /* current sensitivities */
  else
    mx_in[5] = mxCreateDoubleMatrix(0,0,mxREAL);
  mx_in[6] = fwdPb->MONfct;                         /* Matlab monitor function */
  mx_in[7] = fwdPb->MONdata;                        /* data for monitor function */

  if (call == 1) {

    GetData(y, mxGetPr(mx_in[2]), N);

    if (quadr)
      GetData(yQ, mxGetPr(mx_in[3]), Nq);

    if (fsa) {
      tmp = mxGetPr(mx_in[5]);
      for (is=0; is<Ns; is++)
        GetData(yS[is], &tmp[is*N], N);
    }

  }

  mexCallMATLAB(1,mx_out,8,mx_in,"cvm_monitor");

  if (!mxIsEmpty(mx_out[0])) {
    UpdateMonitorData(mx_out[0], fwdPb);
  }

  mxDestroyArray(mx_in[0]);
  mxDestroyArray(mx_in[1]);
  mxDestroyArray(mx_in[2]);
  mxDestroyArray(mx_in[3]);
  mxDestroyArray(mx_in[4]);
  mxDestroyArray(mx_in[5]);
  mxDestroyArray(mx_out[0]);
}
void mxW_CVodeMonitorB(int call, int idxB, double tB, N_Vector yB, N_Vector yQB,
                       cvmPbData bckPb)
{
  mxArray *mx_in[7], *mx_out[1];

  mx_in[0] = mxCreateDoubleScalar(call);            /* 0: first, 1: interm. 2: last */
  mx_in[1] = mxCreateDoubleScalar(idxB);            /* index of current problem */
  mx_in[2] = mxCreateDoubleScalar(tB);              /* current time */
  mx_in[3] = mxCreateDoubleMatrix(NB,1,mxREAL);     /* current solution */
  if (quadrB)
    mx_in[4] = mxCreateDoubleMatrix(NqB,1,mxREAL);  /* current quadratures */
  else
    mx_in[4] = mxCreateDoubleMatrix(0,0,mxREAL);
  mx_in[5] = bckPb->MONfct;
  mx_in[6] = bckPb->MONdata;

  if (call == 1) {
    
    GetData(yB, mxGetPr(mx_in[3]), NB);

    if (quadrB)
      GetData(yQB, mxGetPr(mx_in[4]), NqB);
  }

  mexCallMATLAB(1,mx_out,7,mx_in,"cvm_monitorB");

  if (!mxIsEmpty(mx_out[0])) {
    UpdateMonitorData(mx_out[0], bckPb);
  }

  mxDestroyArray(mx_in[0]);
  mxDestroyArray(mx_in[1]);
  mxDestroyArray(mx_in[2]);
  mxDestroyArray(mx_in[3]);
  mxDestroyArray(mx_in[4]);
  mxDestroyArray(mx_out[0]);
}
void mtlb_IdaMonitor(int call, double t,
                     N_Vector yy, N_Vector yp,
                     N_Vector yQ,
                     N_Vector *yyS, N_Vector *ypS)
{
    mxArray *mx_in[10], *mx_out[1];
    double *tmp_yyS, *tmp_ypS;
    int is;

    mx_in[0] = mxCreateScalarDouble(call);            /* call type (0:first, 1:interm. 2:last) */
    mx_in[1] = mxCreateScalarDouble(t);               /* current time */
    mx_in[2] = mxCreateDoubleMatrix(N,1,mxREAL);      /* current yy */
    mx_in[3] = mxCreateDoubleMatrix(N,1,mxREAL);      /* current yp */
    if (idm_quad) {
        mx_in[4] = mxCreateDoubleMatrix(Nq,1,mxREAL);   /* current quadratures */
    } else {
        mx_in[4] = mxCreateDoubleMatrix(0,0,mxREAL);
    }
    mx_in[5] = mxCreateScalarDouble(Ns);              /* number of sensitivities */
    if (idm_fsa) {
        mx_in[6] = mxCreateDoubleMatrix(N*Ns,1,mxREAL); /* current yyS */
        mx_in[7] = mxCreateDoubleMatrix(N*Ns,1,mxREAL); /* current ypS */
    } else {
        mx_in[6] = mxCreateDoubleMatrix(0,0,mxREAL);
        mx_in[7] = mxCreateDoubleMatrix(0,0,mxREAL);
    }
    mx_in[8] = mx_MONfct;                             /* Matlab monitor function */
    mx_in[9] = mx_MONdata;                            /* data for monitor function */

    if (call == 1) {

        GetData(yy, mxGetPr(mx_in[2]), N);
        GetData(yp, mxGetPr(mx_in[3]), N);

        if (idm_quad) {
            GetData(yQ, mxGetPr(mx_in[4]), Nq);
        }

        if (idm_fsa) {
            tmp_yyS = mxGetPr(mx_in[6]);
            tmp_ypS = mxGetPr(mx_in[7]);
            for (is=0; is<Ns; is++) {
                GetData(yyS[is], &tmp_yyS[is*N], N);
                GetData(ypS[is], &tmp_ypS[is*N], N);
            }
        }

    }

    mexCallMATLAB(1,mx_out,10,mx_in,"idm_monitor");

    if (!mxIsEmpty(mx_out[0])) {
        UpdateMonitorData(mx_out[0]);
    }

    mxDestroyArray(mx_in[0]);
    mxDestroyArray(mx_in[1]);
    mxDestroyArray(mx_in[2]);
    mxDestroyArray(mx_in[3]);
    mxDestroyArray(mx_in[4]);
    mxDestroyArray(mx_in[5]);
    mxDestroyArray(mx_in[6]);
    mxDestroyArray(mx_in[7]);
    mxDestroyArray(mx_out[0]);
}