Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

  • ea39c83
  • /
  • multistate.cpp
Raw File Download

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
content badge Iframe embedding
swh:1:cnt:1675364d748a3e0071e9f7f1f9931c95fdcb15ca
directory badge Iframe embedding
swh:1:dir:ea39c833982ff2502bae9f08b31eb051063bc57d

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
multistate.cpp
#include <RcppArmadillo.h>
#include <errno.h>
#include <math.h>
// #include <boost/numeric/odeint.hpp>
#include <vector>
#include <algorithm>

/*
 *	Natural Splines
 *	---------------
 *	Here the end-conditions are determined by setting the second
 *	derivative of the spline at the end-points to equal to zero.
 *
 *	There are n-2 unknowns (y[i]'' at x[2], ..., x[n-1]) and n-2
 *	equations to determine them.  Either Choleski or Gaussian
 *	elimination could be used.
 */
static void
natural_spline(int n, double *x, double *y, double *b, double *c, double *d)
{
    int nm1, i;
    double t;
    x--; y--; b--; c--; d--;
    if(n < 2) {
	errno = EDOM;
	return;
    }
    if(n < 3) {
	t = (y[2] - y[1]);
	b[1] = t / (x[2]-x[1]);
	b[2] = b[1];
	c[1] = c[2] = d[1] = d[2] = 0.0;
	return;
    }
    nm1 = n - 1;
    /* Set up the tridiagonal system */
    /* b = diagonal, d = offdiagonal, c = right hand side */
    d[1] = x[2] - x[1];
    c[2] = (y[2] - y[1])/d[1];
    for( i=2 ; i<n ; i++) {
	d[i] = x[i+1] - x[i];
	b[i] = 2.0 * (d[i-1] + d[i]);
	c[i+1] = (y[i+1] - y[i])/d[i];
	c[i] = c[i+1] - c[i];
    }
    /* Gaussian elimination */
    for(i=3 ; i<n ; i++) {
	t = d[i-1]/b[i-1];
	b[i] = b[i] - t*d[i-1];
	c[i] = c[i] - t*c[i-1];
    }
    /* Backward substitution */
    c[nm1] = c[nm1]/b[nm1];
    for(i=n-2 ; i>1 ; i--)
	c[i] = (c[i]-d[i]*c[i+1])/b[i];
    /* End conditions */
    c[1] = c[n] = 0.0;
    /* Get cubic coefficients */
    b[1] = (y[2] - y[1])/d[1] - d[i] * c[2];
    c[1] = 0.0;
    d[1] = c[2]/d[1];
    b[n] = (y[n] - y[nm1])/d[nm1] + d[nm1] * c[nm1];
    for(i=2 ; i<n ; i++) {
	b[i] = (y[i+1]-y[i])/d[i] - d[i]*(c[i+1]+2.0*c[i]);
	d[i] = (c[i+1]-c[i])/d[i];
	c[i] = 3.0*c[i];
    }
    c[n] = 0.0;
    d[n] = 0.0;
    return;
}
/*
 *	Splines a la Forsythe Malcolm and Moler
 *	---------------------------------------
 *	In this case the end-conditions are determined by fitting
 *	cubic polynomials to the first and last 4 points and matching
 *	the third derivitives of the spline at the end-points to the
 *	third derivatives of these cubics at the end-points.
 */
static void
fmm_spline(int n, double *x, double *y, double *b, double *c, double *d)
{
    int nm1, i;
    double t;
    /* Adjustment for 1-based arrays */
    x--; y--; b--; c--; d--;
    if(n < 2) {
	errno = EDOM;
	return;
    }
    if(n < 3) {
	t = (y[2] - y[1]);
	b[1] = t / (x[2]-x[1]);
	b[2] = b[1];
	c[1] = c[2] = d[1] = d[2] = 0.0;
	return;
    }
    nm1 = n - 1;
    /* Set up tridiagonal system */
    /* b = diagonal, d = offdiagonal, c = right hand side */
    d[1] = x[2] - x[1];
    c[2] = (y[2] - y[1])/d[1];/* = +/- Inf	for x[1]=x[2] -- problem? */
    for(i=2 ; i<n ; i++) {
	d[i] = x[i+1] - x[i];
	b[i] = 2.0 * (d[i-1] + d[i]);
	c[i+1] = (y[i+1] - y[i])/d[i];
	c[i] = c[i+1] - c[i];
    }
    /* End conditions. */
    /* Third derivatives at x[0] and x[n-1] obtained */
    /* from divided differences */
    b[1] = -d[1];
    b[n] = -d[nm1];
    c[1] = c[n] = 0.0;
    if(n > 3) {
	c[1] = c[3]/(x[4]-x[2]) - c[2]/(x[3]-x[1]);
	c[n] = c[nm1]/(x[n] - x[n-2]) - c[n-2]/(x[nm1]-x[n-3]);
	c[1] = c[1]*d[1]*d[1]/(x[4]-x[1]);
	c[n] = -c[n]*d[nm1]*d[nm1]/(x[n]-x[n-3]);
    }
    /* Gaussian elimination */
    for(i=2 ; i<=n ; i++) {
	t = d[i-1]/b[i-1];
	b[i] = b[i] - t*d[i-1];
	c[i] = c[i] - t*c[i-1];
    }
    /* Backward substitution */
    c[n] = c[n]/b[n];
    for(i=nm1 ; i>=1 ; i--)
	c[i] = (c[i]-d[i]*c[i+1])/b[i];
    /* c[i] is now the sigma[i-1] of the text */
    /* Compute polynomial coefficients */
    b[n] = (y[n] - y[n-1])/d[n-1] + d[n-1]*(c[n-1]+ 2.0*c[n]);
    for(i=1 ; i<=nm1 ; i++) {
	b[i] = (y[i+1]-y[i])/d[i] - d[i]*(c[i+1]+2.0*c[i]);
	d[i] = (c[i+1]-c[i])/d[i];
	c[i] = 3.0*c[i];
    }
    c[n] = 3.0*c[n];
    d[n] = d[nm1];
    return;
}
/*
 *	Periodic Spline
 *	---------------
 *	The end conditions here match spline (and its derivatives)
 *	at x[1] and x[n].
 *
 *	Note: There is an explicit check that the user has supplied
 *	data with y[1] equal to y[n].
 */
static void
periodic_spline(int n, double *x, double *y, double *b, double *c, double *d)
{
    double s;
    int i, nm1;
    // double *e = (double *) R_alloc(n, sizeof(double));
    arma::vec ev(n);
    double* e = ev.memptr();
    /* Adjustment for 1-based arrays */
    x--; y--; b--; c--; d--; e--;
    if(n < 2 || y[1] != y[n]) {
	errno = EDOM;
	return;
    }
    if(n == 2) {
	b[1] = b[2] = c[1] = c[2] = d[1] = d[2] = 0.0;
	return;
    } else if (n == 3) {
	b[1] = b[2] = b[3] = -(y[1] - y[2])*(x[1] - 2*x[2] + x[3])/(x[3]-x[2])/(x[2]-x[1]);
	c[1] = -3*(y[1]-y[2])/(x[3]-x[2])/(x[2]-x[1]);
	c[2] = -c[1];
	c[3] = c[1];
	d[1] = -2*c[1]/3/(x[2]-x[1]);
	d[2] = -d[1]*(x[2]-x[1])/(x[3]-x[2]);
	d[3] = d[1];
	return;
    }
    /* else --------- n >= 4 --------- */
    nm1 = n-1;
    /* Set up the matrix system */
    /* A = diagonal	 B = off-diagonal  C = rhs */
#define A	b
#define B	d
#define C	c
    B[1]  = x[2] - x[1];
    B[nm1]= x[n] - x[nm1];
    A[1] = 2.0 * (B[1] + B[nm1]);
    C[1] = (y[2] - y[1])/B[1] - (y[n] - y[nm1])/B[nm1];
    for(i = 2; i < n; i++) {
	B[i] = x[i+1] - x[i];
	A[i] = 2.0 * (B[i] + B[i-1]);
	C[i] = (y[i+1] - y[i])/B[i] - (y[i] - y[i-1])/B[i-1];
    }
    /* Choleski decomposition */
#define L	b
#define M	d
#define E	e
    L[1] = sqrt(A[1]);
    E[1] = (x[n] - x[nm1])/L[1];
    s = 0.0;
    for(i = 1; i <= nm1 - 2; i++) {
	M[i] = B[i]/L[i];
	if(i != 1) E[i] = -E[i-1] * M[i-1] / L[i];
	L[i+1] = sqrt(A[i+1]-M[i]*M[i]);
	s = s + E[i] * E[i];
    }
    M[nm1-1] = (B[nm1-1] - E[nm1-2] * M[nm1-2])/L[nm1-1];
    L[nm1] = sqrt(A[nm1] - M[nm1-1]*M[nm1-1] - s);
    /* Forward Elimination */
#define Y	c
#define D	c
    Y[1] = D[1]/L[1];
    s = 0.0;
    for(i=2 ; i<=nm1-1 ; i++) {
	Y[i] = (D[i] - M[i-1]*Y[i-1])/L[i];
	s = s + E[i-1] * Y[i-1];
    }
    Y[nm1] = (D[nm1] - M[nm1-1] * Y[nm1-1] - s) / L[nm1];
#define X	c
    X[nm1] = Y[nm1]/L[nm1];
    X[nm1-1] = (Y[nm1-1] - M[nm1-1] * X[nm1])/L[nm1-1];
    for(i=nm1-2 ; i>=1 ; i--)
	X[i] = (Y[i] - M[i] * X[i+1] - E[i] * X[nm1])/L[i];
    /* Wrap around */
    X[n] = X[1];
    /* Compute polynomial coefficients */
    for(i=1 ; i<=nm1 ; i++) {
	s = x[i+1] - x[i];
	b[i] = (y[i+1]-y[i])/s - s*(c[i+1]+2.0*c[i]);
	d[i] = (c[i+1]-c[i])/s;
	c[i] = 3.0*c[i];
    }
    b[n] = b[1];
    c[n] = c[1];
    d[n] = d[1];
    return;
}
#undef A
#undef B
#undef C
#undef L
#undef M
#undef E
#undef Y
#undef D
#undef X
/* These were the public interfaces */
static void
spline_coef(int method, int n, double *x, double *y,
	    double *b, double *c, double *d)
{
    switch(method) {
    case 1:
    	periodic_spline(n, x, y, b, c, d);	break;
    case 2:
	natural_spline(n, x, y, b, c, d);	break;
    case 3:
	fmm_spline(n, x, y, b, c, d);	break;
    }
}
static void
spline_eval(int method, int nu, double *u, double *v,
	    int n, double *x, double *y, double *b, double *c, double *d)
{
/* Evaluate  v[l] := spline(u[l], ...),	    l = 1,..,nu, i.e. 0:(nu-1)
 * Nodes x[i], coef (y[i]; b[i],c[i],d[i]); i = 1,..,n , i.e. 0:(*n-1)
 */
    const int n_1 = n - 1;
    int i, j, k, l;
    double ul, dx, tmp;
    if(method == 1 && n > 1) { /* periodic */
    	dx = x[n_1] - x[0];
    	for(l = 0; l < nu; l++) {
    	    v[l] = fmod(u[l]-x[0], dx);
    	    if(v[l] < 0.0) v[l] += dx;
    	    v[l] += x[0];
    	}
    } else
      for(l = 0; l < nu; l++) v[l] = u[l];
    for(l = 0, i = 0; l < nu; l++) {
	ul = v[l];
	if(ul < x[i] || (i < n_1 && x[i+1] < ul)) {
	    /* reset i  such that  x[i] <= ul <= x[i+1] : */
	    i = 0;
	    j = n;
	    do {
		k = (i+j)/2;
		if(ul < x[k]) j = k;
		else i = k;
	    } while(j > i+1);
	}
	dx = ul - x[i];
	/* for natural splines extrapolate linearly left */
	tmp = (method == 2 && ul < x[0]) ? 0.0 : d[i];
	v[l] = y[i] + dx*(b[i] + dx*(c[i] + dx*tmp));
    }
}
class SplineCoef {
public:
  SplineCoef(arma::vec x, arma::vec y, int method = 2) : x(x), y(y), method(method) {
    int n = x.n_elem;
    // if(y.n_elem != x.n_elem) REprintf("inputs of different lengths");
    b.resize(n); c.resize(n); d.resize(n);
    b.zeros(); c.zeros(); d.zeros();
    if (method==1 && y(0) != y(n-1))
      y(n-1)=y(0);
    spline_coef(method, x.n_elem, x.memptr(), y.memptr(), b.memptr(), c.memptr(), d.memptr());
  }
  arma::vec eval(arma::vec xout) {
    int nu = xout.n_elem;
    arma::vec yout(nu);
    spline_eval(method, nu, xout.memptr(), yout.memptr(),
		x.n_elem, x.memptr(), y.memptr(), b.memptr(), c.memptr(), d.memptr());
    return yout;
  }
  double eval(double xout) {
    double yout;
    spline_eval(method, 1, &xout, &yout,
		x.n_elem, x.memptr(), y.memptr(), b.memptr(), c.memptr(), d.memptr());
    return yout;
  }
  static arma::vec eval(double xout, std::vector<SplineCoef>& z);
  arma::vec x, y, b, c, d;
  int method;
};
arma::vec SplineCoef::eval(double xout, std::vector<SplineCoef>& z)
  {
    arma::vec yout(z.size());
    for (size_t i=0; i<z.size(); i++)
      yout(i) = z[i].eval(xout);
    return yout;
  }

// namespace boost { namespace numeric { namespace odeint {
//       template <>
//       struct is_resizeable<arma::vec>
//       {
// 	typedef boost::true_type type;
// 	const static bool value = type::value;
//       };
//       template <>
//       struct same_size_impl<arma::vec, arma::vec>
//       {
// 	static bool same_size(const arma::vec& x, const arma::vec& y)
// 	{
// 	  return x.size() == y.size();
// 	}
//       };
//       template<>
//       struct resize_impl<arma::vec, arma::vec>
//       {
// 	static void resize(arma::vec& v1, const arma::vec& v2)
// 	{
// 	  v1.resize(v2.size());
// 	}
//       };
//     } } } // namespace boost::numeric::odeint
// typedef arma::vec state_type;
// typedef std::vector<state_type> vector_state_type;
// typedef std::vector<double> vector_times;
// struct push_back_state_and_time
// {
//     std::vector< state_type >& m_states;
//     std::vector< double >& m_times;
//     push_back_state_and_time( std::vector< state_type > &states , std::vector< double > &times )
//     : m_states( states ) , m_times( times ) { }
//     void operator()( const state_type &x , double t )
//     {
//         m_states.push_back( x );
//         m_times.push_back( t );
//     }
// };
// struct push_back_state
// {
//     std::vector< state_type >& m_states;
//     push_back_state( std::vector< state_type > &states)
//     : m_states( states ) { }
//     void operator()( const state_type &x , double t )
//     {
//         m_states.push_back( x );
//     }
// };
// struct Flow {
//   size_t from, to;
//   SplineCoef s;
//   std::vector<SplineCoef> gradients;
//   bool use_log;
// };
// // old version of libarmadillo-dev: mat.as_col() not available
// arma::vec flatten(arma::mat m) {
//   arma::vec v(m.n_cols*m.n_rows);
//   for (size_t j=0; j<m.n_cols; j++)
//     for (size_t i=0; i<m.n_rows; i++)
//       v(j*m.n_rows+i) = m(i,j);
//   return v;
// }
// struct StateComponents {
//   arma::vec P, L;
//   arma::mat gradP, gradL;
// };
// struct StateComponentsCombined {
//   arma::vec times;
//   arma::mat P, L;
//   arma::cube gradP, gradL;
// };
// // forward declaration
// class Markov {
// public:
//   typedef std::vector<Flow> Flows;
//   Flows& flows;
//   double minTm;
//   size_t nStates, nGradients;
//   StateComponents stateComponents(const state_type& x) {
//     arma::vec P = x(arma::span(0,nStates-1));
//     arma::vec L = x(arma::span(nStates,2*nStates-1));
//     arma::mat gradP(arma::vec(x(arma::span(2*nStates,2*nStates+nStates*nGradients-1))).memptr(),
// 		    nStates, nGradients);
//     arma::mat gradL(arma::vec(x(arma::span(2*nStates+nStates*nGradients,
// 					   2*nStates+2*nStates*nGradients-1))).memptr(),
// 		    nStates, nGradients);
//     return {P, L, gradP, gradL};
//   }
//   Markov(Flows& flows, double minTm = 1.0e-8) : flows(flows), minTm(minTm) {
//     nGradients = nStates = 0;
//     for(size_t i=0; i<flows.size(); i++) {
//       nGradients += flows[i].gradients.size();
//       nStates = std::max(std::max(nStates,flows[i].from),flows[i].to);
//     }
//     nStates++;
//   }
//   void operator() ( const state_type &x , state_type &dxdt , const double t )
//   {
//     arma::vec rates(flows.size());
//     arma::vec dPdt(nStates,arma::fill::zeros);
//     arma::vec dLdt;
//     arma::mat dGradPdt(nStates,nGradients,arma::fill::zeros);
//     arma::mat dGradLdt;
//     // destructure the state vector
//     StateComponents c = stateComponents(x);
//     // P (transition probabilities)
//     for (size_t i=0; i<flows.size(); i++) {
//       rates(i) = flows[i].s.eval(flows[i].use_log ? log(t<minTm ? minTm : t) : t);
//       // if (flows[i].use_log) rates(i) = exp(rates(i));
//       double delta = c.P(flows[i].from)*rates(i);
//       dPdt(flows[i].to) += delta;
//       dPdt(flows[i].from) -= delta;
//     }
//     // L (length of stay)
//     dLdt = c.P;
//     // gradients for P
//     for (size_t i=0, start=0; i<flows.size(); start+=flows[i].gradients.size(), i++) {
//       for (size_t j=0; j<flows[i].gradients.size(); j++) {
// 	double delta = c.gradP(flows[i].from,start+j)*rates(i)+
// 	  c.P(flows[i].from)*flows[i].gradients[j].eval(t);
// 	dGradPdt(flows[i].to,start+j) += delta;
// 	dGradPdt(flows[i].from,start+j) -= delta;
//       }
//     }
//     // gradients for L
//     dGradLdt = c.gradP;
//     dxdt = arma::join_cols(dPdt,
// 			   arma::join_cols(dLdt,
// 					   arma::join_cols(flatten(dGradPdt),
// 							   flatten(dGradLdt))));
//   }
// };
// StateComponentsCombined run(Markov &model, arma::vec p0, arma::vec times) {
//   using namespace boost::numeric::odeint;
//   vector_state_type states;
//   // times, outtimes and vtimes all have the same data
//   vector_times outtimes; // not strictly needed - we could use push_back_state()
//   vector_times vtimes = arma::conv_to< vector_times >::from(times);
//   state_type x = join_cols(p0, arma::zeros(model.nStates+2*model.nStates*model.nGradients));
//   // BOOST_STATIC_ASSERT( is_resizeable<state_type>::value == true );
//   integrate_times(make_dense_output( 1.0e-10 , 1.0e-10 , runge_kutta_dopri5< state_type >() ),
// 		  model, x,
// 		  vtimes.begin(),
// 		  vtimes.end(),
// 		  1.0,
// 		  push_back_state_and_time(states, outtimes));
//   size_t nx = states[0].size(), nTimes = times.size();
//   // combine the results
//   arma::mat combined(nTimes,nx);
//   for (size_t i=0; i<nTimes; i++)
//     combined(arma::span(i,i),arma::span(0,nx-1)) = states[i].t();
//   // destructure the combined matrix
//   arma::mat P = combined(arma::span::all,arma::span(0,model.nStates-1));
//   arma::mat L = combined(arma::span::all,arma::span(model.nStates,2*model.nStates-1));
//   arma::cube gradP(arma::mat(combined(arma::span::all,
// 				      arma::span(2*model.nStates,2*model.nStates+model.nStates*model.nGradients-1))).memptr(),
// 		   nTimes, model.nStates, model.nGradients);
//   arma::cube gradL(arma::mat(combined(arma::span::all,
// 			    arma::span(2*model.nStates+model.nStates*model.nGradients,
// 				       2*model.nStates+2*model.nStates*model.nGradients-1))).memptr(),
// 		   nTimes, model.nStates, model.nGradients);
//   return {times, P, L, gradP, gradL};
// }
// // Rcpp::List runMarkovODE(arma::vec y0, arma::vec times, arma::vec tlam, arma::mat lam, Rcpp::List gradients, arma::ivec from, arma::ivec to, Rcpp::LogicalVector use_logs, double minTm = 1.0e-8) {
// RcppExport SEXP runMarkovODE(SEXP _y0, SEXP _times, SEXP _tlam, SEXP _lam, SEXP _gradients, SEXP _from, SEXP _to, SEXP _use_logs, SEXP _minTm) {
//   using namespace Rcpp;
//   arma::vec y0 = as<arma::vec>(_y0);
//   arma::vec times = as<arma::vec>(_times);
//   arma::vec tlam = as<arma::vec>(_tlam);
//   arma::mat lam = as<arma::mat>(_lam);
//   List gradients = as<List>(_gradients);
//   arma::ivec from = as<arma::ivec>(_from);
//   arma::ivec to = as<arma::ivec>(_to);
//   LogicalVector use_logs = as<LogicalVector>(_use_logs);
//   double minTm = as<double>(_minTm);
//   Markov::Flows flows;
//   for (size_t i=0; i<from.size(); i++) {
//     SplineCoef coef = SplineCoef(use_logs[i] ? log(tlam) : tlam, lam.col(i));
//     std::vector<SplineCoef> vgradients;
//     arma::mat g = Rcpp::as<arma::mat>(gradients[i]);
//     for (int j=0; j<gradients.size(); j++)
//       vgradients.push_back(SplineCoef(tlam, g.col(j)));
//     flows.push_back({size_t(from(i)), size_t(to(i)), coef, vgradients,
//                      bool(use_logs[i])});
//   }
//   Markov markov(flows, minTm);
//   auto report = run(markov, y0, times);
//   return wrap(List::create(Named("times")=report.times,
// 			   Named("P")=report.P,
// 			   Named("L")=report.L,
// 			   Named("gradP")=report.gradP,
// 			   Named("gradL")=report.gradL));
// }

RcppExport SEXP multistate_ddt(SEXP P_, SEXP Pu_, SEXP Q_, SEXP Qu_) {
  using namespace arma;
  // P(nstates,nobs), Pu(nstates,ncoef,nobs), Q(nstates,nstates,nobs), Qu(nstates*nstates,ncoef,nobs)
  mat P = Rcpp::as<mat>(P_);
  cube Pu = Rcpp::as<cube>(Pu_);
  cube Q = Rcpp::as<cube>(Q_);
  cube Qu = Rcpp::as<cube>(Qu_);
  int nstates = P.n_rows;
  int nobs=P.n_cols;
  int ncoef=Pu.n_cols;
  mat dPdt = P*0.0;   // nstates,nobs
  cube dPudt = Pu*0.0; // nstates,ncoef,nobs
  for(int i=0; i<nobs; i++) {
    mat Qi = Q.slice(i);
    rowvec Pi = conv_to<rowvec>::from(P.col(i));
    vec rs = sum(Qi,1);
    for (int j=0; j<nstates; j++)
      Qi(j,j) = -rs(j);
    dPdt.col(i) = conv_to<vec>::from(Pi*Qi); // is this valid?
    cube Qui = Qu(span::all, span::all, span(i,i));
    Qui.reshape(nstates,nstates,ncoef);
    mat Pui = Pu.slice(i);
    for (int j=0; j<ncoef; j++) {
      vec rs = sum(Qui.slice(j),1);
      for (int m=0; m<nstates; m++)
	Qui(m,m,j) = -rs(m);
    }
    dPudt.slice(i) = (Pui.t() * Qi).t();
    for(int j=0; j<ncoef; j++) {
      rowvec PiQuij = Pi * Qui.slice(j);
      for(int k=0; k<nstates; k++)
	dPudt(k,j,i) += PiQuij(k);
    }
  }
  return Rcpp::wrap(Rcpp::List::create(dPdt,dPudt));
}


// class ExpM {
// public:
//   arma::mat Qmat;
//   ExpM(arma::mat _Qmat) : Qmat(_Qmat) { }
//   void operator() ( const state_type &x , state_type &dxdt , const double t )
//   {
//     dxdt = (x.t() * Qmat).t();
//   }
// };
// RcppExport SEXP runExpM(SEXP _y0, SEXP _times, SEXP _Qmat) {
//   using namespace Rcpp;
//   arma::vec y0 = as<arma::vec>(_y0);
//   arma::vec times = as<arma::vec>(_times);
//   arma::mat Qmat = as<arma::mat>(_Qmat);
//   ExpM model(Qmat);
//   using namespace boost::numeric::odeint;
//   vector_state_type states;
//   // times, outtimes and vtimes all have the same data
//   vector_times outtimes; // not strictly needed - we could use push_back_state()
//   vector_times vtimes = arma::conv_to< vector_times >::from(times);
//   // BOOST_STATIC_ASSERT( is_resizeable<state_type>::value == true );
//   integrate_times(make_dense_output( 1.0e-10 , 1.0e-10 , runge_kutta_dopri5< state_type >() ),
// 		  model, y0,
// 		  vtimes.begin(),
// 		  vtimes.end(),
// 		  1.0,
// 		  push_back_state_and_time(states, outtimes));
//   size_t nx = states[0].size(), nTimes = times.size();
//   // combine the results
//   arma::mat combined(nTimes,nx);
//   for (size_t i=0; i<nTimes; i++)
//     combined(arma::span(i,i),arma::span(0,nx-1)) = states[i].t();
//   return wrap(combined);
// }

back to top

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Content policy— Contact— JavaScript license information— Web API