Esempio n. 1
0
void MarkovExpectation::compute(FitContext *fc, const char *what, const char *how)
{
	if (fc) {
		for (auto c1 : components) {
			c1->compute(fc, what, how);
		}
	}

	omxRecompute(initial, fc);
	if (initialV != omxGetMatrixVersion(initial)) {
		omxCopyMatrix(scaledInitial, initial);
		EigenVectorAdaptor Ei(scaledInitial);
		if (scale == SCALE_SOFTMAX) Ei.derived() = Ei.array().exp();
		if (scale != SCALE_NONE) {
			Ei /= Ei.sum();
		}
		if (verbose >= 2) mxPrintMat("initial", Ei);
		initialV = omxGetMatrixVersion(initial);
	}

	if (transition) {
		omxRecompute(transition, fc);
		if (transitionV != omxGetMatrixVersion(transition)) {
			omxCopyMatrix(scaledTransition, transition);
			EigenArrayAdaptor Et(scaledTransition);
			if (scale == SCALE_SOFTMAX) Et.derived() = Et.array().exp();
			if (scale != SCALE_NONE) {
				Eigen::ArrayXd v = Et.colwise().sum();
				Et.rowwise() /= v.transpose();
			}
			if (verbose >= 2) mxPrintMat("transition", Et);
			transitionV = omxGetMatrixVersion(transition);
		}
	}
}
Esempio n. 2
0
void arrayops() {
  double nx = 10;
  double ny = 10;
  double nt = 100;
  double c = 1;
  double dx = 2/(nx-1);
  double dy = 2/(ny-1);
  double sigma = .2;
  double dt = sigma*dx;
  
  Eigen::ArrayXd x; // Array containing our x values
  x.setLinSpaced(nx,0,2);
  
  Eigen::ArrayXd y; // Array containing our x values
  y.setLinSpaced(ny,0,2);

  Eigen::ArrayXXd u;
  u.setOnes(ny,nx);
  
  Eigen::ArrayXXd un;
  un.setOnes(ny,nx);
  
  u.block(.5/dy,.5/dx,(1/dy+1)-.5/dy,(1/dx+1)-.5/dx) = Eigen::ArrayXXd::Constant((1/dy+1)-.5/dy,(1/dx+1)-.5/dx,2);
  
  int count;
  for(int i=0;i<nt;i++) {
    un << u;
    u.block(1,1,ny-1,nx-1) = un.block(1,1,ny-1,nx-1)-(c*dt/dx*(un.block(1,1,ny-1,nx-1)-un.block(0,1,ny-1,nx-1)))-(c*dt/dy*(un.block(1,1,ny-1,nx-1)-un.block(1,0,ny-1,nx-1)));
    
  }
  
  std::cout << u << std::endl;
 
}  
Esempio n. 3
0
Eigen::ArrayXXd mpFlow::math::circularPoints(double const radius, double const distance,
    double const offset, bool const invertDirection, Eigen::Ref<Eigen::ArrayXd const> const midpoint) {
    Eigen::ArrayXd const phi = arange(offset / radius, offset / radius + 2.0 * M_PI, distance / radius);

    Eigen::ArrayXXd result = Eigen::ArrayXXd::Zero(phi.rows(), 2);
    result.col(0) = midpoint(0) + radius * phi.cos();
    result.col(1) = midpoint(1) + (invertDirection ? -1.0 : 1.0) * radius * phi.sin();

    return result;
}
Esempio n. 4
0
// create initial points distribution
Eigen::ArrayXXd distmesh::utils::createInitialPoints(
    Functional const& distanceFunction, double const initialPointDistance,
    Functional const& elementSizeFunction, Eigen::Ref<Eigen::ArrayXXd const> const boundingBox,
    Eigen::Ref<Eigen::ArrayXXd const> const fixedPoints) {
    // extract dimension of mesh
    unsigned const dimension = boundingBox.cols();

    // initially distribute points evenly in complete bounding box
    Eigen::ArrayXi pointsPerDimension(dimension);
    for (int dim = 0; dim < dimension; ++dim) {
        pointsPerDimension(dim) = ceil((boundingBox(1, dim) - boundingBox(0, dim)) /
            (initialPointDistance * (dim == 0 ? 1.0 : sqrt(3.0) / 2.0)));
    }

    Eigen::ArrayXXd points(pointsPerDimension.prod(), dimension);
    for (int point = 0; point < points.rows(); ++point)
    for (int dim = 0; dim < dimension; ++dim) {
        int const pointIndex = (point / std::max(pointsPerDimension.topRows(dim).prod(), 1)) %
            pointsPerDimension(dim);

        points(point, dim) = boundingBox(0, dim) + (double)pointIndex * initialPointDistance *
            (dim == 0 ? 1.0 : sqrt(3.0) / 2.0);

        if (dim > 0) {
            points(point, dim - 1) += pointIndex % 2 != 0 ? initialPointDistance / 2.0 : 0.0;
        }
    }

    // reject points outside of region defined by distance function
    points = selectMaskedArrayElements<double>(points,
        distanceFunction(points) < constants::geometryEvaluationThreshold * initialPointDistance);

    // clear duplicate points
    Eigen::Array<bool, Eigen::Dynamic, 1> isUniquePoint =
        Eigen::Array<bool, Eigen::Dynamic, 1>::Constant(points.rows(), true);
    for (int i = 0; i < fixedPoints.rows(); ++i)
    for (int j = 0; j < points.rows(); ++j) {
        isUniquePoint(j) &= !(fixedPoints.row(i) == points.row(j)).all();
    }
    points = selectMaskedArrayElements<double>(points, isUniquePoint);

    // calculate probability to keep points
    Eigen::ArrayXd probability = 1.0 / elementSizeFunction(points).pow(dimension);
    probability /= probability.maxCoeff();

    // reject points with wrong probability
    points = selectMaskedArrayElements<double>(points,
        0.5 * (1.0 + Eigen::ArrayXd::Random(points.rows())) < probability);

    // combine fixed and variable points to one array
    Eigen::ArrayXXd finalPoints(points.rows() + fixedPoints.rows(), dimension);
    finalPoints << fixedPoints, points;

    return finalPoints;
}
Esempio n. 5
0
void nonlin2d() {
  double nx = 101;
  double ny = 101;
  double nt = 80;
  double c = 1;
  double dx = 2/(nx-1);
  double dy = 2/(ny-1);
  double sigma = .2;
  double dt = sigma*dx;
  
  // Make an output folder
  std::string dir = "step6/";
  
  Eigen::ArrayXd x; // Array containing our x values
  x.setLinSpaced(nx,0,2);
  
  Eigen::ArrayXd y; // Array containing our x values
  y.setLinSpaced(ny,0,2);

  Eigen::ArrayXXd u;
  u.setOnes(ny,nx);
  Eigen::ArrayXXd v;
  v.setOnes(ny,nx);
  Eigen::ArrayXXd un;
  un.setOnes(ny,nx);
  Eigen::ArrayXXd vn;
  vn.setOnes(ny,nx);
    
  u.block(.5/dy, .5/dx, 1/dy+1-.5/dy, 1/dx+1-.5/dx) = Eigen::ArrayXXd::Constant(1/dy+1-.5/dy,1/dx+1-.5/dx,2);
  v.block(.5/dy, .5/dx, 1/dy+1-.5/dy, 1/dx+1-.5/dx) = Eigen::ArrayXXd::Constant(1/dy+1-.5/dy,1/dx+1-.5/dx,2);
  
  for(int i=0;i<nt+1;i++) {
    un << u;
    vn << v;
    
    u.block(1,1,ny-1,nx-1) = un.block(1,1,ny-1,nx-1)-(un.block(1,1,ny-1,nx-1)*dt/dx*(un.block(1,1,ny-1,nx-1)-un.block(0,1,ny-1,nx-1)))-(vn.block(1,1,ny-1,nx-1)*dt/dy*(un.block(1,1,ny-1,nx-1)-un.block(1,0,ny-1,nx-1)));
    v.block(1,1,ny-1,nx-1) = vn.block(1,1,ny-1,nx-1)-(un.block(1,1,ny-1,nx-1)*dt/dx*(vn.block(1,1,ny-1,nx-1)-vn.block(0,1,ny-1,nx-1)))-(vn.block(1,1,ny-1,nx-1)*dt/dy*(vn.block(1,1,ny-1,nx-1)-vn.block(1,0,ny-1,nx-1)));
    
    u.block(0,0,1,nx-1) = Eigen::ArrayXXd::Constant(1,nx-1,1);
    u.block(ny-1,0,1,nx-1) = Eigen::ArrayXXd::Constant(1,nx-1,1);
    u.block(0,0,ny-1,1) = Eigen::ArrayXXd::Constant(ny-1,1,1);
    u.block(0,nx-1,ny-1,1) = Eigen::ArrayXXd::Constant(ny-1,1,1);
    
    v.block(0,0,1,nx-1) = Eigen::ArrayXXd::Constant(1,nx-1,1);
    v.block(ny-1,0,1,nx-1) = Eigen::ArrayXXd::Constant(1,nx-1,1);
    v.block(0,0,ny-1,1) = Eigen::ArrayXXd::Constant(ny-1,1,1);
    v.block(0,nx-1,ny-1,1) = Eigen::ArrayXXd::Constant(ny-1,1,1);
  }
  
  ofstream writexdata((dir + "output.dat").c_str(), ios::out | ios::trunc);
  writexdata << u << endl;
  writexdata.close();
}
Esempio n. 6
0
PFloat Verify::mult_weights(Eigen::ArrayXd w)
{
	PFloat ret = PFloat(w[0]);

	for(int i = 1; i < w.size(); i++)
	{
		PFloat tmp = PFloat(w(i));
		ret = ret*tmp;
	}
	return ret;
}
Esempio n. 7
0
double L2R_Huber_SVC::predict(const std::string fileNameLibSVMFormat,
                              Eigen::VectorXd &w) {
  Eigen::SparseMatrix<double, 1> vX;
  Eigen::ArrayXd vy;
  const char *fn = fileNameLibSVMFormat.c_str();
  read_LibSVMdata1(fn, vX, vy);
  // loadLib(fileNameLibSVMFormat, vX, vy);
  int vl = vX.rows();
  int vn = vX.cols();
  int success = 0;

  if (vn != w.size()) {
    w.conservativeResize(vn);
  }
  Eigen::ArrayXd prob = vy * (vX * w).array();

  for (int i = 0; i < vl; ++i) {
    if (prob.coeffRef(i) >= 0.0)
      ++success;
  }
  return (double)success / vl;
}
Esempio n. 8
0
            /**
             * Compute average temperature in all regions.
             *
             * \param[in] state Dynamic reservoir state.
             */
            void
            averageTemperature(const BlackoilState& state)
            {
                T_avg_.setZero();

                const std::vector<double>& T = state.temperature();
                for (std::vector<double>::size_type
                         i = 0, n = T.size(); i < n; ++i)
                {
                    T_avg_(rmap_.region(i)) += T[i];
                }

                T_avg_ /= ncells_;
            }
Esempio n. 9
0
            /**
             * Compute average hydrocarbon pressure in all regions.
             *
             * \param[in] state Dynamic reservoir state.
             */
            void
            averagePressure(const BlackoilState& state)
            {
                p_avg_.setZero();

                const std::vector<double>& p = state.pressure();
                for (std::vector<double>::size_type
                         i = 0, n = p.size(); i < n; ++i)
                {
                    p_avg_(rmap_.region(i)) += p[i];
                }

                p_avg_ /= ncells_;
            }
Esempio n. 10
0
GLMMBelief::GLMMBelief(const std::vector<int>& items,
		       const Eigen::MatrixXd& X,
		       const Eigen::MatrixXd& Zt,
		       const Eigen::SparseMatrix<double>& Lambdat,
		       const Eigen::VectorXi& Lind,
		       const Eigen::ArrayXd& response,
		       const Eigen::ArrayXd& weights):
  ContinuousBeliefBase(items),
  numObservations_(response.size()), numFixed_(X.cols()),
  X_(X), Zt_(Zt), Lambdat_(Lambdat), Lind_(Lind),
  response_(response), weights_(weights)
{
  initializeParameterDependents();
}
Esempio n. 11
0
void laplace2d() {
  double nx = 31;
  double ny = 31;
  double c = 1;
  double dx = 2/(nx-1);
  double dy = 2/(ny-1);
  double linorm_target = .01;
  double linorm = 1;
  
  // Make an output folder
  std::string dir = "step9/";
  
  Eigen::ArrayXd x; // Array containing our x values
  x.setLinSpaced(nx,0,2); // Array is linearly spaced values from 0 to 2
  
  Eigen::ArrayXd y; // Array containing our x values
  y.setLinSpaced(ny,0,1);
  
  // Arrays containing our calculated values
  Eigen::ArrayXXd p;
  Eigen::ArrayXXd pn;
  
  // Initial Conditions
  p.setZero(ny,nx);
  pn.setZero(ny,nx);
  
  //Set Boundary Conditions
  p.block(0,0,ny,1) = Eigen::ArrayXXd::Constant(ny,1,0);
  p.block(0,nx-1,ny,1) = y.block(0,0,ny,1);
  p.block(0,0,1,nx) = p.block(1,0,1,nx);
  p.block(ny-1,0,1,nx) = p.block(ny-2,0,1,nx);

  while(linorm>linorm_target)
  {
    pn << p;
    p.block(1,1,ny-2,nx-2) = (pow(dy,2)*(pn.block(2,1,ny-2,nx-2)+pn.block(0,1,ny-2,nx-2))+pow(dx,2)*(pn.block(1,2,ny-2,nx-2)+pn.block(1,0,ny-2,nx-2)))/(2*(pow(dx,2)+pow(dy,2)));
    p(0,0) = (pow(dy,2)*(pn(1,0)+pn(ny-1,0))+pow(dx,2)*(pn(0,1)+pn(0,nx-1)))/(2*(pow(dx,2)+pow(dy,2)));
    p(ny-1,nx-1) = (pow(dy,2)*(pn(0,nx-1)+pn(ny-2,nx-1))+pow(dx,2)*(pn(ny-1,0)+pn(ny-1,nx-2)))/(2*(pow(dx,2)+pow(dy,2)));
    
    //Set Boundary Conditions
    p.block(0,0,ny,1) = Eigen::ArrayXXd::Constant(ny,1,0);
    p.block(0,nx-1,ny,1) = y.block(0,0,ny,1);
    p.block(0,0,1,nx) = p.block(1,0,1,nx);
    p.block(ny-1,0,1,nx) = p.block(ny-2,0,1,nx);
   
    linorm = (p.cwiseAbs()-pn.cwiseAbs()).sum()/(pn.cwiseAbs()).sum();
    
  }
  
  ofstream writexdata((dir + "output.dat").c_str(), ios::out | ios::trunc);
  writexdata << p << endl;
  writexdata.close();
}
Esempio n. 12
0
void channelns() {
  double nx = 41;
  double ny = 41;
  double nt = 10;
  double nit = 50;
  double c  = 1;
  double dx = 2/(nx-1);
  double dy = 2/(ny-1);
  
  double rho = 1;
  double nu =.1;
  double F = 1;
  double dt = .01;
  
  std::string dir = "step11/";
  
  Eigen::ArrayXd x; // Array containing our x values
  x.setLinSpaced(nx,0,2); // Array is linearly spaced values from 0 to 2
  
  Eigen::ArrayXd y; // Array containing our x values
  y.setLinSpaced(ny,0,2);
  
  Eigen::ArrayXXd X;
  Eigen::ArrayXXd Y;
  
  X = x.transpose().replicate(nx,1); // Need to transpose this because the type we declared, ArrayXd, is row-major (and we need column-major for a proper meshgrid)
  Y = y.replicate(1,ny);
  
  Eigen::ArrayXXd u;
  u.setZero(ny,nx);
  Eigen::ArrayXXd un;
  un.setZero(ny,nx);
  Eigen::ArrayXXd v;
  v.setZero(ny,nx);
  Eigen::ArrayXXd vn;
  vn.setZero(ny,nx);
  Eigen::ArrayXXd b; 
  b.setZero(ny,nx);
  Eigen::ArrayXXd p;
  p.setZero(ny,nx);
  Eigen::ArrayXXd pn;
  pn.setZero(ny,nx);
  
  
}
Esempio n. 13
0
void RGRRTNode::FindReachableSet(){
    //Need to discretize control space, and fill in reachableStates and reachableControls arrays
    Eigen::ArrayXd contactPointLocations = Eigen::ArrayXd::LinSpaced(DISC_S,0,2*LO);
    Eigen::ArrayXd normalForceMagnitude = Eigen::ArrayXd::LinSpaced(DISC_FN,MIN_FN,MAX_FN);
    Eigen::ArrayXd tangentForceMagnitude = Eigen::ArrayXd::LinSpaced(DISC_FT,-1.0*MU,MU);
    Eigen::Matrix<double, CONTROL_SPACE_DIM,1> controlArray;
    int counter = 0;
    for(int i = 0; i < contactPointLocations.rows(); i++) {
	for(int j = 0; j < normalForceMagnitude.rows(); j++) {
	    for(int k = 0; k < tangentForceMagnitude.rows(); k++) {
		controlArray << contactPointLocations(i,0), \
		    normalForceMagnitude(j,0),		    \
		    tangentForceMagnitude(k,0)*normalForceMagnitude(j,0);
		reachableStates[counter] = spawn(nodeState,controlArray);
		reachableControls[counter] = controlArray;
		counter++;
	    }
	}
    }
}
Esempio n. 14
0
void omxComputeNumericDeriv::computeImpl(FitContext *fc)
{
	if (fc->fitUnits == FIT_UNITS_SQUARED_RESIDUAL ||
	    fc->fitUnits == FIT_UNITS_SQUARED_RESIDUAL_CHISQ) {  // refactor TODO
		numParams = 0;
		if (verbose >= 1) mxLog("%s: derivatives %s units are meaningless",
					name, fitUnitsToName(fc->fitUnits));
		return; //Possible TODO: calculate Hessian anyway?
	}

	int newWanted = fc->wanted | FF_COMPUTE_GRADIENT;
	if (wantHessian) newWanted |= FF_COMPUTE_HESSIAN;

	int nf = fc->calcNumFree();
	if (numParams != 0 && numParams != nf) {
		mxThrow("%s: number of parameters changed from %d to %d",
			 name, numParams, nf);
	}

	numParams = nf;
	if (numParams <= 0) { complainNoFreeParam(); return; }

	optima.resize(numParams);
	fc->copyEstToOptimizer(optima);
	paramMap.resize(numParams);
	for (int px=0,ex=0; px < numParams; ++ex) {
		if (fc->profiledOut[ex]) continue;
		paramMap[px++] = ex;
	}

	omxAlgebraPreeval(fitMat, fc);
	fc->createChildren(fitMat); // allow FIML rowwiseParallel even when parallel=false

	fc->state->countNonlinearConstraints(fc->state->numEqC, fc->state->numIneqC, false);
	int c_n = fc->state->numEqC + fc->state->numIneqC;
	fc->constraintFunVals.resize(c_n);
	fc->constraintJacobian.resize(c_n, numParams);
	if(c_n){
		omxCalcFinalConstraintJacobian(fc, numParams);
	}
	// TODO: Allow more than one hessian value for calculation

	int numChildren = 1;
	if (parallel && !fc->openmpUser && fc->childList.size()) numChildren = fc->childList.size();

	if (!fc->haveReferenceFit(fitMat)) return;

	minimum = fc->fit;

	hessWorkVector = new hess_struct[numChildren];
	if (numChildren == 1) {
		omxPopulateHessianWork(hessWorkVector, fc);
	} else {
		for(int i = 0; i < numChildren; i++) {
			omxPopulateHessianWork(hessWorkVector + i, fc->childList[i]);
		}
	}
	if(verbose >= 1) mxLog("Numerical Hessian approximation (%d children, ref fit %.2f)",
			       numChildren, minimum);

	hessian = NULL;
	if (wantHessian) {
		hessian = fc->getDenseHessUninitialized();
		Eigen::Map< Eigen::MatrixXd > eH(hessian, numParams, numParams);
		eH.setConstant(NA_REAL);

		if (knownHessian) {
			int khSize = int(khMap.size());
			Eigen::Map< Eigen::MatrixXd > kh(knownHessian, khSize, khMap.size());
			for (int rx=0; rx < khSize; ++rx) {
				for (int cx=0; cx < khSize; ++cx) {
					if (khMap[rx] < 0 || khMap[cx] < 0) continue;
					eH(khMap[rx], khMap[cx]) = kh(rx, cx);
				}
			}
		}
	}

	if (detail) {
		recordDetail = false; // already done it once
	} else {
		Rf_protect(detail = Rf_allocVector(VECSXP, 4));
		SET_VECTOR_ELT(detail, 0, Rf_allocVector(LGLSXP, numParams));
		for (int gx=0; gx < 3; ++gx) {
			SET_VECTOR_ELT(detail, 1+gx, Rf_allocVector(REALSXP, numParams));
		}
		SEXP detailCols;
		Rf_protect(detailCols = Rf_allocVector(STRSXP, 4));
		Rf_setAttrib(detail, R_NamesSymbol, detailCols);
		SET_STRING_ELT(detailCols, 0, Rf_mkChar("symmetric"));
		SET_STRING_ELT(detailCols, 1, Rf_mkChar("forward"));
		SET_STRING_ELT(detailCols, 2, Rf_mkChar("central"));
		SET_STRING_ELT(detailCols, 3, Rf_mkChar("backward"));

		SEXP detailRowNames;
		Rf_protect(detailRowNames = Rf_allocVector(STRSXP, numParams));
		Rf_setAttrib(detail, R_RowNamesSymbol, detailRowNames);
		for (int nx=0; nx < int(numParams); ++nx) {
			SET_STRING_ELT(detailRowNames, nx, Rf_mkChar(fc->varGroup->vars[nx]->name));
		}
		markAsDataFrame(detail);
	}

	gforward = REAL(VECTOR_ELT(detail, 1));
	gcentral = REAL(VECTOR_ELT(detail, 2));
	gbackward = REAL(VECTOR_ELT(detail, 3));
	Eigen::Map< Eigen::ArrayXd > Gf(gforward, numParams);
	Eigen::Map< Eigen::ArrayXd > Gc(gcentral, numParams);
	Eigen::Map< Eigen::ArrayXd > Gb(gbackward, numParams);
	Gf.setConstant(NA_REAL);
	Gc.setConstant(NA_REAL);
	Gb.setConstant(NA_REAL);

	calcHessianEntry che(this);
	CovEntrywiseParallel(numChildren, che);

	for(int i = 0; i < numChildren; i++) {
		struct hess_struct *hw = hessWorkVector + i;
		totalProbeCount += hw->probeCount;
	}
	delete [] hessWorkVector;
	if (isErrorRaised()) return;

	Eigen::Map< Eigen::ArrayXi > Gsymmetric(LOGICAL(VECTOR_ELT(detail, 0)), numParams);
	double gradNorm = 0.0;
	
	double feasibilityTolerance = Global->feasibilityTolerance;
	for (int px=0; px < numParams; ++px) {
		// factor out simliar code in ComputeNR
		omxFreeVar &fv = *fc->varGroup->vars[ paramMap[px] ];
		if ((fabs(optima[px] - fv.lbound) < feasibilityTolerance && Gc[px] > 0) ||
		    (fabs(optima[px] - fv.ubound) < feasibilityTolerance && Gc[px] < 0)) {
			Gsymmetric[px] = false;
			continue;
		}
		gradNorm += Gc[px] * Gc[px];
		double relsym = 2 * fabs(Gf[px] + Gb[px]) / (Gb[px] - Gf[px]);
		Gsymmetric[px] = (Gf[px] < 0 && 0 < Gb[px] && relsym < 1.5);
		if (checkGradient && verbose >= 2 && !Gsymmetric[px]) {
			mxLog("%s: param[%d] %d %f", name, px, Gsymmetric[px], relsym);
		}
	}
	
	fc->grad.resize(fc->numParam);
	fc->grad.setZero();
	fc->copyGradFromOptimizer(Gc);
	
	if(c_n){
		fc->inequality.resize(fc->state->numIneqC);
		fc->analyticIneqJacTmp.resize(fc->state->numIneqC, numParams);
		fc->myineqFun(true, verbose, omxConstraint::LESS_THAN, false);
	}

	gradNorm = sqrt(gradNorm);
	double gradThresh = Global->getGradientThreshold(minimum);
	//The gradient will generally not be near zero at a local minimum if there are equality constraints 
	//or active inequality constraints:
	if ( checkGradient && gradNorm > gradThresh && !(fc->state->numEqC || fc->inequality.array().sum()) ) {
		if (verbose >= 1) {
			mxLog("Some gradient entries are too large, norm %f", gradNorm);
		}
		if (fc->getInform() < INFORM_NOT_AT_OPTIMUM) fc->setInform(INFORM_NOT_AT_OPTIMUM);
	}

	fc->setEstFromOptimizer(optima);
	// auxillary information like per-row likelihoods need a refresh
	ComputeFit(name, fitMat, FF_COMPUTE_FIT, fc);
	fc->wanted = newWanted;
}
Esempio n. 15
0
//[[Rcpp::export]]
List SPMBgraphsqrt(Eigen::Map<Eigen::MatrixXd> data, NumericVector &lambda, int nlambda, int d, NumericVector &x, IntegerVector &col_cnz, IntegerVector &row_idx)
{

    Eigen::ArrayXd Xb, r, grad, w1, Y, XX, gr;
    Eigen::ArrayXXd X;
    Eigen::MatrixXd tmp_icov;
    tmp_icov.resize(d, d);
    tmp_icov.setZero();
    std::vector<Eigen::MatrixXd > tmp_icov_p;
    tmp_icov_p.clear();
    for(int i = 0; i < nlambda; i++)
      tmp_icov_p.push_back(tmp_icov);
    int n = data.rows();
    X = data;
    XX.resize(d);
    for (int j = 0; j < d; j++)
      XX[j] = (X.col(j)*X.col(j)).sum()/n;
    double prec = 1e-4;
    int max_iter = 1000;
    int num_relaxation_round = 3;
	  int cnz = 0;
    for(int m=0;m<d;m++)
    {
      Xb.resize(n);
      Xb.setZero();
      grad.resize(d);
      grad.setZero();
      gr.resize(d);
      gr.setZero();
      w1.resize(d);
      w1.setZero();
      r.resize(n);
      r.setZero();
      Y = X.col(m);

      Eigen::ArrayXd Xb_master(n);
      Eigen::ArrayXd w1_master(n);
      std::vector<int> actset_indcat(d, 0);
      std::vector<int> actset_indcat_master(d, 0);
      std::vector<int> actset_idx;
      std::vector<double> old_coef(d, 0);
      std::vector<double> grad(d, 0);
      std::vector<double> grad_master(d, 0);

      double a = 0, g = 0, L = 0, sum_r = 0, sum_r2 = 0;
      double tmp_change = 0, local_change = 0;

      r = Y - Xb;
      sum_r = r.sum();
      sum_r2 = r.matrix().dot(r.matrix());
      L = sqrt(sum_r2 / n);

      double dev_thr = fabs(L) * prec;

      //cout<<dev_thr<<endl;


      for(int i = 0; i < d; i++)
      {
        grad[i] = (r * X.col(i)).sum() / (n*L);
      }
      for(int i = 0; i < d; i++) gr[i] = abs(grad[i]);
      w1_master = w1;
      Xb_master = Xb;
      for (int i = 0; i < d; i++) grad_master[i] = gr[i];

      std::vector<double> stage_lambdas(d, 0);

      for(int i=0;i<nlambda;i++)
      {
        double ilambda = lambda[i];
        w1 = w1_master;
        Xb = Xb_master;

        for (int j = 0; j < d; j++)
        {
          gr[j] = grad_master[j];
          actset_indcat[j] = actset_indcat_master[j];
        }

        // init the active set
        double threshold;
        if (i > 0)
          threshold = 2 * lambda[i] - lambda[i - 1];
        else
          threshold = 2 * lambda[i];

        for (int j = 0; j < m; ++j)
        {
          stage_lambdas[j] = lambda[i];

          if (gr[j] > threshold) actset_indcat[j] = 1;
        }
        for (int j = m+1; j < d; ++j)
        {
          stage_lambdas[j] = lambda[i];

          if (gr[j] > threshold) actset_indcat[j] = 1;
        }
        stage_lambdas[m] = lambda[i];
        r = Y - Xb;
        sum_r = r.sum();
        sum_r2 = r.matrix().dot(r.matrix());
        L = sqrt(sum_r2 / n);
        // loop level 0: multistage convex relaxation
        int loopcnt_level_0 = 0;
        int idx;
        double old_w1, updated_coord;
        while (loopcnt_level_0 < num_relaxation_round)
        {
          loopcnt_level_0++;

          // loop level 1: active set update
          int loopcnt_level_1 = 0;
          bool terminate_loop_level_1 = true;
          while (loopcnt_level_1 < max_iter)
          {
            loopcnt_level_1++;
            terminate_loop_level_1 = true;

            for (int j = 0; j < d; j++) old_coef[j] = w1[j];

            // initialize actset_idx
            actset_idx.clear();
            for (int j = 0; j < m; j++)
              if (actset_indcat[j])
              {
                g = 0.0;
                a = 0.0;

                double tmp;

                sum_r2 = r.matrix().dot(r.matrix());
                L = sqrt(sum_r2 / n);

                Eigen::ArrayXd wXX  = (1 - r*r/sum_r2) * X.col(j) * X.col(j);
                g = (wXX * w1[j] + r * X.col(j)).sum()/(n*L);
                a = wXX.sum()/(n*L);

                tmp = w1[j];
                w1[j] = thresholdl1(g, stage_lambdas[j]) / a;

                tmp = w1[j] - tmp;
                // Xb += delta*X[idx*n]
                Xb = Xb + tmp * X.col(j);

                sum_r = 0.0;
                sum_r2 = 0.0;
                // r -= delta*X
                r = r - tmp * X.col(j);
                sum_r = r.sum();

                sum_r2 = r.matrix().dot(r.matrix());
                L = sqrt(sum_r2 / n);

                updated_coord = w1[j];

                if (fabs(updated_coord) > 0) actset_idx.push_back(j);
              }

            for (int j = m+1; j < d; j++)
              if (actset_indcat[j])
              {
                  g = 0.0;
                  a = 0.0;

                  double tmp;

                  sum_r2 = r.matrix().dot(r.matrix());
                  L = sqrt(sum_r2 / n);

                  Eigen::ArrayXd wXX  = (1 - r*r/sum_r2) * X.col(j) * X.col(j);
                  g = (wXX * w1[j] + r * X.col(j)).sum()/(n*L);
                  a = wXX.sum()/(n*L);

                  tmp = w1[j];
                  w1[j] = thresholdl1(g, stage_lambdas[j]) / a;

                  tmp = w1[j] - tmp;
                  // Xb += delta*X[idx*n]
                  Xb = Xb + tmp * X.col(j);

                  sum_r = 0.0;
                  sum_r2 = 0.0;
                  // r -= delta*X
                  r = r - tmp * X.col(j);
                  sum_r = r.sum();

                  sum_r2 = r.matrix().dot(r.matrix());
                  L = sqrt(sum_r2 / n);

                  updated_coord = w1[j];

                  if (fabs(updated_coord) > 0) actset_idx.push_back(j);
                }

              // loop level 2: proximal newton on active set
            int loopcnt_level_2 = 0;
            bool terminate_loop_level_2 = true;
            while (loopcnt_level_2 < max_iter)
            {
              loopcnt_level_2++;
              terminate_loop_level_2 = true;

              for (int k = 0; k < actset_idx.size(); k++)
              {
                  idx = actset_idx[k];

                  old_w1 = w1[idx];
                  g = 0.0;
                  a = 0.0;

                  double tmp;

                  sum_r2 = r.matrix().dot(r.matrix());
                  L = sqrt(sum_r2 / n);

                  Eigen::ArrayXd wXX  = (1 - r*r/sum_r2) * X.col(idx) * X.col(idx);
                  g = (wXX * w1[idx] + r * X.col(idx)).sum()/(n*L);
                  a = wXX.sum()/(n*L);

                  tmp = w1[idx];
                  w1[idx] = thresholdl1(g, stage_lambdas[idx]) / a;

                  tmp = w1[idx] - tmp;
                  // Xb += delta*X[idx*n]
                  Xb = Xb + tmp * X.col(idx);

                  sum_r = 0.0;
                  sum_r2 = 0.0;
                  // r -= delta*X
                  r = r - tmp * X.col(idx);
                  sum_r = r.sum();

                  sum_r2 = r.matrix().dot(r.matrix());
                  L = sqrt(sum_r2 / n);

                  updated_coord = w1[idx];
                  tmp_change = old_w1 - w1[idx];
                  double a =  (X.col(idx) * X.col(idx) * (1 - r * r/(L*L*n))).sum()/(n*L);
                  local_change = a * tmp_change * tmp_change / (2 * L * n);
                  if (local_change > dev_thr)
                    terminate_loop_level_2 = false;
                }
              if (terminate_loop_level_2)
                break;
            }

            terminate_loop_level_1 = true;
              // check stopping criterion 1: fvalue change
            for (int k = 0; k < actset_idx.size(); ++k)
            {
              idx = actset_idx[k];
              tmp_change = old_w1 - w1[idx];
              double a =  (X.col(idx) * X.col(idx) * (1 - r * r/(L*L*n))).sum()/(n*L);
              local_change = a * tmp_change * tmp_change / (2 * L * n);
              if (local_change > dev_thr)
                terminate_loop_level_1 = false;
            }

            r = Y - Xb;
            sum_r = r.sum();
            sum_r2 = r.matrix().dot(r.matrix());
            L = sqrt(sum_r2 / n);

            if (terminate_loop_level_1)
              break;


              // check stopping criterion 2: active set change
            bool new_active_idx = false;
            for (int k = 0; k < m; k++)
              if (actset_indcat[k] == 0)
              {
                grad[idx] = (r * X.col(idx)).sum() / (n*L);
                //cout<<grad[idx];
                gr[k] = fabs(grad[k]);
                if (gr[k] > stage_lambdas[k])
                {
                  actset_indcat[k] = 1;
                  new_active_idx = true;
                }
              }
            for (int k = m+1; k < d; k++)
              if (actset_indcat[k] == 0)
              {
                grad[idx] = (r * X.col(idx)).sum() / (n*L);
                //cout<<grad[idx]
                gr[k] = fabs(grad[k]);
                if (gr[k] > stage_lambdas[k])
                {
                  actset_indcat[k] = 1;
                  new_active_idx = true;
                }
              }
            if(!new_active_idx)
              break;
          }
          if (loopcnt_level_0 == 1)
          {
            for (int j = 0; j < d; j++)
            {
              w1_master[j] = w1[j];

              grad_master[j] = gr[j];
              actset_indcat_master[j] = actset_indcat[j];
            }

            for (int j = 0; j < n; j++) Xb_master[j] = Xb[j];
          }
        }
        for(int j=0;j<actset_idx.size();j++)
        {
          int w_idx = actset_idx[j];
          x[cnz] = w1[w_idx];
          row_idx[cnz] = i*d+w_idx;
          cnz++;
          //cout<<cnz<<"    ";
        }
        double tal = 0;
        Eigen::MatrixXd temp;
        temp.resize(n, 1);
        for(int j = 0; j < n; j++)
        {
          temp(j, 0) = 0;
          for(int k = 0; k < d; k++)
            temp(j, 0) += X.matrix()(j, k)*w1[k];
          temp(j, 0) = Y[j] - temp(j, 0);
        }
        //temp = Y.matrix() - X.matrix().transpose()*w1.matrix();
        for(int j = 0; j < n; j++)
          tal += temp(j, 0)*temp(j, 0);
        tal = sqrt(tal)/sqrt(n);

        tmp_icov = tmp_icov_p[i];
        tmp_icov(m, m) = pow(tal, -2);
        for(int j = 0; j < m; j++)
          tmp_icov(j, m) = -tmp_icov(m, m)*w1[j];
        for(int j = m+1; j < d; j++)
          tmp_icov(j, m) = -tmp_icov(m, m)*w1[j];
        tmp_icov_p[i] = tmp_icov;
      }
      col_cnz[m+1]=cnz;
    }
    for(int i = 0; i < nlambda; i++)
      tmp_icov_p[i] = (tmp_icov_p[i].transpose()+tmp_icov_p[i])/2;
	  return List::create(
	    _["col_cnz"] = col_cnz,
	    _["row_idx"] = row_idx,
	    _["x"] = x,
	    _["icov"] = tmp_icov_p
	  );
}