示例#1
0
// [[Rcpp::export]]
mat randWalkTrain(const mat& X, const mat& A, const colvec& Z,  
                  const colvec& theta, int trainit, 
                  const colvec& sigma, const colvec& etaRange,
                  const mat& V, bool verbose)
{
    double logAccept;
    int p = theta.size() - 1;
    int n = X.n_rows;
    colvec eigval;
    mat eigvec;
    eig_sym(eigval, eigvec, V);
    mat R = eigvec * diagmat(sqrt(eigval));
    colvec Y = rautologistic_(X, A, theta);
    colvec Ynew(n);
    colvec thetaold = theta;
    colvec thetanew = theta;
    colvec normvec(p + 1);
    mat estimates(trainit + 1, p + 1);
    estimates.row(0) = theta.t();
    colvec beta = theta.subvec(0, p - 1);
    double eta = theta[p];
    colvec Xbeta = X * beta;
    colvec mu = exp(Xbeta);
    mu = mu / (1 + mu);
    double Zsum = as_scalar(Z.t() * A * Z);
    int onepct = 0.01 * trainit;
	int pct = 1;
	RNGScope scope;
	Function rnorm("rnorm"),
	         runif("runif");
    for (int i = 1; i < trainit + 1; i++)
    {
        do
        {
            normvec = as<colvec>(rnorm(p + 1));
            thetanew = thetaold + R * normvec;
        }
        while(thetanew[p] < etaRange[0] || thetanew[p] > etaRange[1]);
        Ynew = rautologistic_(X, A, thetanew);
        colvec betaold = thetaold.subvec(0, p - 1);
        colvec betanew = thetanew.subvec(0, p - 1);
        double etaold = thetaold[p];
        double etanew = thetanew[p];
        colvec Xbetaold = X * betaold;
        colvec Xbetanew = X * betanew;
        colvec muold = exp(Xbetaold);
        muold = muold / (1 + muold);
        colvec munew = exp(Xbetanew );
        munew = munew / (1 + munew);
        double Ynewsum = as_scalar(Ynew.t() * A * Ynew);
        double Ysum = as_scalar(Y.t() * A * Y);
        logAccept = as_scalar(0.5 * (eta * (Ynewsum - Ysum) + etanew * (Zsum - Ynewsum) + etaold * (Ysum - Zsum))
                            + trans(Ynew - Y) * Xbeta + trans(Z - Ynew) * Xbetanew + trans(Y - Z) * Xbetaold
                            + etaold * trans(Z - Y) * A * muold + etanew * trans(Ynew - Z) * A * munew + eta * trans(Y - Ynew) * A * mu)
                            + accu((square(betaold) - square(betanew)) / (2 * sigma));
        if (as_scalar(log(as<double>(runif(1)))) < logAccept)
        {
            estimates.row(i) = thetanew.t();
            thetaold = thetanew;
            Y = Ynew;
        }
        else
            estimates.row(i) = thetaold.t();
        if (verbose && i % onepct == 0)
        {
            Rcout << "\rTraining progress: |";
			for (int j = 1; j <= pct; j++)
				Rcout << "+";
			for (int j = 1; j < (100 - pct); j++)
				Rcout << " ";
			Rcout << "| " << pct << "%";
			pct++;
            R_FlushConsole();
        }
    }
	if (verbose)
		Rcout << std::endl << std::endl;
    return estimates.rows(1, trainit);
} 
#include <armadillo>
#include "catch.hpp"

using namespace arma;


TEST_CASE("fn_cumsum_1")
  {
  colvec a = linspace<colvec>(1,5,6);
  rowvec b = linspace<rowvec>(1,5,6);
  
  colvec c = { 1.0000, 2.8000, 5.4000, 8.8000, 13.0000, 18.0000 };
  
  REQUIRE( accu(abs(cumsum(a) - c    )) == Approx(0.0) );
  REQUIRE( accu(abs(cumsum(b) - c.t())) == Approx(0.0) );
  
  REQUIRE_THROWS( b = cumsum(a) );
  }



TEST_CASE("fn_cumsum_2")
  {
  mat A =
    {
    { -0.78838,  0.69298,  0.41084,  0.90142 },
    {  0.49345, -0.12020,  0.78987,  0.53124 },
    {  0.73573,  0.52104, -0.22263,  0.40163 }
    };
  
示例#3
0
// How is that for a descriptive function name???
colvec symmetricTridiagonalFrancisAlgorithmWithWilkinsonShift(colvec a, colvec b) {
    float epsilon = 0.001f; // turned off currently
    int passes = 3;
    int pass = 0;
    unsigned long long int count = 0;

    int m = a.n_elem - 1;
    while (0<m) {
        ++pass;
        float s, c;
        float d = (a(m-1) - a(m)) * 0.5f;
        if (d == 0) {
            s = a(m) - abs(b(m));
        } else {
            s = a(m) - pow(b(m),2) / (d + sgn(d)*sqrt(d*d + b(m)*b(m)));
        }
        float x = a(0) - s;
        float y = b(1);
        for (int k=0; k<=m-1; ++k) {
            if (1 < m) {
                // givens rotation
                float r = hypot(y,x);
                c = x/r;
                s = y/r;
            } else {
                // Orthogonal diagonalization of a symmetric 2x2 matrix
                // http://scipp.ucsc.edu/~haber/ph116A/diag2x2_11.pdf
                float theta;
                theta = 0.5f * atan2(2*b(1),a(0)-a(1));
                s = sin(theta);
                c = cos(theta);
            }
            float w = c*x - s*y;
            d = a(k) - a(k+1);
            float z = (2*c*b(k+1) + d*s)*s;
            a(k)   -= z;
            a(k+1) += z;
            b(k+1) = d*c*s + (c*c - s*s)*b(k);
            x = b(k+1);
            if (0 < k) {
                b(k) = w;
            }
            if (k < m-1) {
                y = -s*b(k+2);
                b(k+2) *= c;
                if (abs(c) > 1) {
                    cout << c << endl;
                }
            }
            // Do not need to calculate Q. Do not need eigenvectors.
        }
        count += m;
//        cout << abs(b(m)) << "       " << epsilon*(abs(a(m-1)) + abs(a(m))) << endl;
        float smallThing = epsilon*(abs(a(m-1)) + abs(a(m)));
        if (isnan(smallThing)) {
            cout << "Not a number!" << endl;
        }
        if (abs(b(m)) < smallThing) { // check for convergence
//            --m;
//            temporarily turned off, to make iterations until m is decreased constant
        }
        if (pass == passes) {
            --m;
            pass = 0;
        }
    }
//    cout << "diagonal" << endl << a.t() << endl;
    cout << "off diagonal" << endl << b.t() << endl;
    cout << "inner loop iterations : " << count << endl; // total number of inner loop iterations performed
    return a;
}