/** * Generates an artificial topographyGrid of size numRows x numCols if no * topographic data is available. Results are dumped into topographyGrid. * @param topographyGrid A pointer to a zero-initialized Grid of size * numRows x numCols. * @param numRows The desired number of non-border rows in the resulting matrix. * @param numCols The desired number of non-border cols in the resulting matrix. */ void simulatetopographyGrid(Grid* topographyGrid, int numRows, int numCols) { Eigen::VectorXd refx = refx.LinSpaced(numCols, -2*M_PI, 2*M_PI); Eigen::VectorXd refy = refx.LinSpaced(numRows, -2*M_PI, 2*M_PI); Eigen::MatrixXd X = refx.replicate(1, numRows); X.transposeInPlace(); Eigen::MatrixXd Y = refy.replicate(1, numCols); // Eigen can only deal with two matrices at a time, // so split the computation: // topographyGrid = sin(X) * sin(Y) * abs(X) * abs(Y) -pi Eigen::MatrixXd absXY = X.cwiseAbs().cwiseProduct(Y.cwiseAbs()); Eigen::MatrixXd sins = X.array().sin().cwiseProduct(Y.array().sin()); Eigen::MatrixXd temp; temp.resize(numRows, numCols); temp = absXY.cwiseProduct(sins); // All this work to create a matrix of pi... Eigen::MatrixXd pi; pi.resize(numRows, numCols); pi.setConstant(M_PI); temp = temp - pi; // And the final result. topographyGrid->data.block(border, border, numRows, numCols) = temp.block(0, 0, numRows, numCols); // Ignore positive values. topographyGrid->data = topographyGrid->data.unaryExpr(std::ptr_fun(validateDepth)); topographyGrid->clearNA(); }
TEST(decimate,hemisphere) { // Load a hemisphere centered at the origin. For each original vertex compute // its "perfect normal" (i.e., its position treated as unit vectors). // Decimate the model and using the birth indices of the output vertices grab // their original "perfect normals" and compare them to their current // positions treated as unit vectors. If vertices have not moved much, then // these should be similar (mostly this is checking if the birth indices are // sane). Eigen::MatrixXd V,U; Eigen::MatrixXi F,G; Eigen::VectorXi J,I; // Load example mesh: GetParam() will be name of mesh file test_common::load_mesh("hemisphere.obj", V, F); // Perfect normals from positions Eigen::MatrixXd NV = V.rowwise().normalized(); // Remove half of the faces igl::decimate(V,F,F.rows()/2,U,G,J,I); // Expect that all normals still point in same direction as original Eigen::MatrixXd NU = U.rowwise().normalized(); Eigen::MatrixXd NVI; igl::slice(NV,I,1,NVI); ASSERT_EQ(NVI.rows(),NU.rows()); ASSERT_EQ(NVI.cols(),NU.cols()); // Dot product Eigen::VectorXd D = (NU.array()*NVI.array()).rowwise().sum(); Eigen::VectorXd O = Eigen::VectorXd::Ones(D.rows()); // 0.2 chosen to succeed on 256 face hemisphere.obj reduced to 128 faces test_common::assert_near(D,O,0.02); }
/*Predicts where the tracked bounding box will be in the next frame*/ Eigen::Vector4d bb_predict(Eigen::VectorXd const & bb0, Eigen::MatrixXd const & pt0, Eigen::MatrixXd const & pt1) { Eigen::MatrixXd of(pt1.rows(), pt1.cols()); of = pt1.array() - pt0.array(); double dx = median(of.row(0)); double dy = median(of.row(1)); unsigned int matCols = pt0.cols(), pos = 0, len = (matCols * (matCols - 1)) / 2; Eigen::RowVectorXd d1(len); Eigen::RowVectorXd d2(len); //calculate euclidean distance for (unsigned int h = 0; h < matCols - 1; h++) for (unsigned int j = h + 1; j < matCols; j++, pos++) { d1(pos) = sqrt(((pt0(0, h) - pt0(0, j)) * (pt0(0, h) - pt0(0, j))) + ((pt0(1, h) - pt0(1, j)) * (pt0(1, h) - pt0(1, j)))); d2(pos) = sqrt(((pt1(0, h) - pt1(0, j)) * (pt1(0, h) - pt1(0, j))) + ((pt1(1, h) - pt1(1, j)) * (pt1(1, h) - pt1(1, j)))); } Eigen::RowVectorXd ds(len); //calculate mean value ds = d2.array() / d1.array(); double s = median(ds); double s1 = (0.5 * (s - 1) * bb_width(bb0)); double s2 = (0.5 * (s - 1) * bb_height(bb0)); Eigen::Vector4d bb1; // bb1(0) = bb0(0) - s1 + dx; bb1(1) = bb0(1) - s2 + dy; bb1(2) = bb0(2) + s1 + dx; bb1(3) = bb0(3) + s2 + dy; return bb1; }
// Great circle distance, up to a constant of proportionality equal to 2*R // where R is the earth's radius Eigen::MatrixXd greatcirc_dist(const Eigen::MatrixXd &X, const Eigen::MatrixXd &Y) { int nr = X.rows(); int nc = Y.rows(); Eigen::MatrixXd lon1 = X.col(0).replicate(1,nc) * pi_180; Eigen::MatrixXd lat1 = X.col(1).replicate(1,nc) * pi_180; Eigen::MatrixXd lon2 = Y.col(0).transpose().replicate(nr,1) * pi_180; Eigen::MatrixXd lat2 = Y.col(1).transpose().replicate(nr,1) * pi_180; Eigen::MatrixXd dlon = 0.5*(lon2 - lon1); Eigen::MatrixXd dlat = 0.5*(lat2 - lat1); Eigen::MatrixXd a = dlat.array().sin().square().matrix() + (dlon.array().sin().square() * lat1.array().cos() * lat2.array().cos()).matrix(); Eigen::MatrixXd c = (a.array()<1.0).select(a.array().sqrt(),Eigen::MatrixXd::Ones(nr,nc)).array().asin(); return (c); // Instead of (2*R*c) where R = 6378137 is the Earth's radius. }
// Compute the average contour, by calling compute_contour_vals repeatedly // // [[Rcpp::export]] Eigen::MatrixXd rcppstandardize_rates(const Eigen::VectorXd &tiles, const Eigen::VectorXd &rates, const Eigen::VectorXd &xseed, const Eigen::VectorXd &yseed, const Eigen::MatrixXd &marks, const Eigen::VectorXd &nmrks, const std::string &distm) { bool use_weighted_mean = true; int nxmrks = nmrks(0); int nymrks = nmrks(1); Eigen::MatrixXd Zvals = Eigen::MatrixXd::Zero(nymrks,nxmrks); Eigen::MatrixXd zvals = Eigen::MatrixXd::Zero(nymrks,nxmrks); int niters = tiles.size(); for ( int i = 0, pos = 0 ; i < niters ; i++ ) { int now_tiles = (int)tiles(i); Eigen::VectorXd now_rates = rates.segment(pos,now_tiles); Eigen::VectorXd now_xseed = xseed.segment(pos,now_tiles); Eigen::VectorXd now_yseed = yseed.segment(pos,now_tiles); Eigen::MatrixXd now_seeds(now_tiles, 2); now_seeds << now_xseed,now_yseed; if (use_weighted_mean) { compute_contour_vals(zvals,marks,now_rates,now_seeds,distm); zvals = zvals.array() - zvals.mean(); } else { now_rates = now_rates.array() - now_rates.mean(); compute_contour_vals(zvals,marks,now_rates,now_seeds,distm); } Zvals += zvals; pos += now_tiles; } // Do not divide by niters here but in 'average.eems.contours' instead // Zvals = Zvals.array() / niters; return Zvals.transpose(); }
Eigen::MatrixXd RtHPIS::magnetic_dipole(Eigen::MatrixXd pos, Eigen::MatrixXd pnt, Eigen::MatrixXd ori) { double u0 = 1e-7; int nchan; Eigen::MatrixXd r, r2, r5, x, y, z, mx, my, mz, Tx, Ty, Tz, lf, temp; nchan = pnt.rows(); // Shift the magnetometers so that the dipole is in the origin pnt.array().col(0) -= pos(0);pnt.array().col(1) -= pos(1);pnt.array().col(2) -= pos(2); r = pnt.array().square().rowwise().sum().sqrt(); r2 = r5 = x = y = z = mx = my = mz = Tx = Ty = Tz = lf = Eigen::MatrixXd::Zero(nchan,3); for(int i = 0;i < nchan;i++) { r2.row(i).array().fill(pow(r(i),2)); r5.row(i).array().fill(pow(r(i),5)); } for(int i = 0;i < nchan;i++) { x.row(i).array().fill(pnt(i,0)); y.row(i).array().fill(pnt(i,1)); z.row(i).array().fill(pnt(i,2)); } mx.col(0).array().fill(1);my.col(1).array().fill(1);mz.col(2).array().fill(1); Tx = 3 * x.cwiseProduct(pnt) - mx.cwiseProduct(r2); Ty = 3 * y.cwiseProduct(pnt) - my.cwiseProduct(r2); Tz = 3 * z.cwiseProduct(pnt) - mz.cwiseProduct(r2); for(int i = 0;i < nchan;i++) { lf(i,0) = Tx.row(i).dot(ori.row(i)); lf(i,1) = Ty.row(i).dot(ori.row(i)); lf(i,2) = Tz.row(i).dot(ori.row(i)); } for(int i = 0;i < nchan;i++) { for(int j = 0;j < 3;j++) { lf(i,j) = u0 * lf(i,j)/(4 * M_PI * r5(i,j)); } } return lf; }
int FeatureTransformationEstimator::consensus3D(Eigen::MatrixXd P, Eigen::MatrixXd Q, Eigen::Isometry3d T, double thresh, Eigen::Array<bool, 1, Eigen::Dynamic> &consensusSet) { int consensus = 0; P = T * P.colwise().homogeneous(); Eigen::MatrixXd norms = (P - Q).colwise().norm(); consensusSet = norms.array() < thresh; consensus = consensusSet.count(); return consensus; }
int main(int argc, char * argv[]) { using namespace Eigen; using namespace std; using namespace igl; VectorXd D; if(!read_triangle_mesh("../shared/beetle.off",V,F)) { cout<<"failed to load mesh"<<endl; } twod = V.col(2).minCoeff()==V.col(2).maxCoeff(); bbd = (V.colwise().maxCoeff()-V.colwise().minCoeff()).norm(); SparseMatrix<double> L,M; cotmatrix(V,F,L); L = (-L).eval(); massmatrix(V,F,MASSMATRIX_TYPE_DEFAULT,M); const size_t k = 5; if(!eigs(L,M,k+1,EIGS_TYPE_SM,U,D)) { cout<<"failed."<<endl; } U = ((U.array()-U.minCoeff())/(U.maxCoeff()-U.minCoeff())).eval(); igl::viewer::Viewer viewer; viewer.callback_key_down = [&](igl::viewer::Viewer & viewer,unsigned char key,int)->bool { switch(key) { default: return false; case ' ': { U = U.rightCols(k).eval(); // Rescale eigen vectors for visualization VectorXd Z = bbd*0.5*U.col(c); Eigen::MatrixXd C; igl::parula(U.col(c).eval(),false,C); c = (c+1)%U.cols(); if(twod) { V.col(2) = Z; } viewer.data.set_mesh(V,F); viewer.data.compute_normals(); viewer.data.set_colors(C); return true; } } }; viewer.callback_key_down(viewer,' ',0); viewer.core.show_lines = false; viewer.launch(); }
void scaleData(Eigen::MatrixXd& data, double min, double max) { if(min >= max) throw OpenANNException("Scaling failed: max has to be greater than min!"); const double minData = data.minCoeff(); const double maxData = data.maxCoeff(); const double dataRange = maxData - minData; const double desiredRange = max - min; const double scaling = desiredRange / dataRange; data = data.array() * scaling + (min - minData * scaling); }
normal_fullrank operator/=(const normal_fullrank& rhs) { static const char* function = "stan::variational::normal_fullrank::operator/="; stan::math::check_size_match(function, "Dimension of lhs", dimension_, "Dimension of rhs", rhs.dimension()); mu_.array() /= rhs.mu().array(); L_chol_.array() /= rhs.L_chol().array(); return *this; }
IGL_INLINE void igl::ViewerData::set_colors(const Eigen::MatrixXd &C) { using namespace std; using namespace Eigen; // Ambient color should be darker color const auto ambient = [](const MatrixXd & C)->MatrixXd { return 0.1*C; }; // Specular color should be a less saturated and darker color: dampened // highlights const auto specular = [](const MatrixXd & C)->MatrixXd { const double grey = 0.3; return grey+0.1*(C.array()-grey); }; if (C.rows() == 1) { for (unsigned i=0;i<V_material_diffuse.rows();++i) { V_material_diffuse.row(i) = C.row(0); } V_material_ambient = ambient(V_material_diffuse); V_material_specular = specular(V_material_diffuse); for (unsigned i=0;i<F_material_diffuse.rows();++i) { F_material_diffuse.row(i) = C.row(0); } F_material_ambient = ambient(F_material_diffuse); F_material_specular = specular(F_material_diffuse); } else if (C.rows() == V.rows()) { set_face_based(false); V_material_diffuse = C; V_material_ambient = ambient(V_material_diffuse); V_material_specular = specular(V_material_diffuse); } else if (C.rows() == F.rows()) { set_face_based(true); F_material_diffuse = C; F_material_ambient = ambient(F_material_diffuse); F_material_specular = specular(F_material_diffuse); } else cerr << "ERROR (set_colors): Please provide a single color, or a color per face or per vertex."; dirty |= DIRTY_DIFFUSE; }
void test_linear_ring() { trace.beginBlock("linear ring"); const Domain domain(Point(-5,-5), Point(5,5)); typedef DiscreteExteriorCalculus<1, 2, EigenLinearAlgebraBackend> Calculus; Calculus calculus; calculus.initKSpace<Domain>(domain); for (int kk=-8; kk<10; kk++) calculus.insertSCell( calculus.myKSpace.sCell(Point(-8,kk), kk%2 == 0 ? Calculus::KSpace::POS : Calculus::KSpace::NEG) ); for (int kk=-8; kk<10; kk++) calculus.insertSCell( calculus.myKSpace.sCell(Point(kk,10), kk%2 == 0 ? Calculus::KSpace::POS : Calculus::KSpace::NEG) ); for (int kk=10; kk>-8; kk--) calculus.insertSCell( calculus.myKSpace.sCell(Point(10,kk)) ); for (int kk=10; kk>-8; kk--) calculus.insertSCell( calculus.myKSpace.sCell(Point(kk,-8)) ); calculus.updateIndexes(); { trace.info() << calculus << endl; Board2D board; board << domain; board << calculus; board.saveSVG("ring_structure.svg"); } const Calculus::PrimalDerivative0 d0 = calculus.derivative<0, PRIMAL>(); display_operator_info("d0", d0); const Calculus::PrimalHodge0 h0 = calculus.hodge<0, PRIMAL>(); display_operator_info("h0", h0); const Calculus::DualDerivative0 d0p = calculus.derivative<0, DUAL>(); display_operator_info("d0p", d0p); const Calculus::PrimalHodge1 h1 = calculus.hodge<1, PRIMAL>(); display_operator_info("h1", h1); const Calculus::PrimalIdentity0 laplace = calculus.laplace<PRIMAL>(); display_operator_info("laplace", laplace); const int laplace_size = calculus.kFormLength(0, PRIMAL); const Eigen::MatrixXd laplace_dense(laplace.myContainer); for (int ii=0; ii<laplace_size; ii++) FATAL_ERROR( laplace_dense(ii,ii) == 2 ); FATAL_ERROR( laplace_dense.array().rowwise().sum().abs().sum() == 0 ); FATAL_ERROR( laplace_dense.transpose() == laplace_dense ); trace.endBlock(); }
void object::test<6>() { for (int i = 0;i<10;i++) { int dim = rand()%1000+2; int samplenum1 = rand()%1000+100; int samplenum2 = rand()%1000+100; Eigen::MatrixXd ha = Eigen::MatrixXd::Random(dim,samplenum1); Eigen::MatrixXd hb = Eigen::MatrixXd::Random(dim,samplenum2); Eigen::VectorXd haa = (ha.array()*ha.array()).colwise().sum(); Eigen::VectorXd hbb = (hb.array()*hb.array()).colwise().sum(); Eigen::MatrixXd hdist = -2*ha.transpose()*hb; hdist.colwise() += haa; hdist.rowwise() += hbb.transpose(); Matrix<double> ga(ha),gb(hb); Matrix<double> gdist = -2*ga.transpose()*gb; Vector<double> gaa = (ga.array()*ga.array()).colwise().sum(); Vector<double> gbb = (gb.array()*gb.array()).colwise().sum(); gdist.colwise() += gaa; gdist.rowwise() += gbb; ensure(check_diff(hdist,gdist)); } }
dipError RtHPIS::dipfitError(Eigen::MatrixXd pos, Eigen::MatrixXd data, struct sens sensors) { // Variable Declaration struct dipError e; Eigen::MatrixXd lf, dif; // Compute lead field for a magnetic dipole in infinite vacuum lf = ft_compute_leadfield(pos, sensors); e.moment = pinv(lf) * data; dif = data - lf * e.moment; e.error = dif.array().square().sum()/data.array().square().sum(); return e; }
void KMeansTestCase::clustering() { const int N = 1000; const int D = 10; Eigen::MatrixXd X(N, D); OpenANN::RandomNumberGenerator rng; rng.fillNormalDistribution(X); OpenANN::KMeans kmeans(D, 5); const int batchSize = 200; double averageDistToCenter = std::numeric_limits<double>::max(); for(int i = 0; i < N/batchSize; i++) { // Data points will be closer to centers after each update Eigen::MatrixXd Y = kmeans.fitPartial(X.block(i*batchSize, 0, batchSize, D)).transform(X); const double newDistance = Y.array().rowwise().maxCoeff().sum(); ASSERT(newDistance < averageDistToCenter); averageDistToCenter = newDistance; } }
int FeatureTransformationEstimator::consensusReprojection(Eigen::MatrixXd P, Eigen::MatrixXd Q, Eigen::Isometry3d T, double thresh, Eigen::Array<bool, 1, Eigen::Dynamic> &consensusSet) { Eigen::MatrixXd Pproj(2, P.cols()); Eigen::MatrixXd Qproj(2, P.cols()); for (int i = 0; i < P.cols(); i++) { Eigen::Vector3d PT = T * P.col(i).homogeneous(); Pproj(0,i) = pnp.uc + pnp.fu * PT(0) / PT(2); Pproj(1,i) = pnp.vc + pnp.fv * PT(1) / PT(2); Qproj(0,i) = pnp.uc + pnp.fu * Q(0,i) / Q(2,i); Qproj(1,i) = pnp.vc + pnp.fv * Q(1,i) / Q(2,i); } int consensus = 0; Eigen::MatrixXd norms = (Pproj - Qproj).colwise().norm(); consensusSet = norms.array() < thresh; consensus = consensusSet.count(); return consensus; }
normal_fullrank operator+=(double scalar) { mu_.array() += scalar; L_chol_.array() += scalar; return *this; }
int main(int argc, char *argv[]) { using namespace Eigen; using namespace std; // Load a mesh in OFF format igl::readOFF("../shared/cow.off", V, F); // Compute Laplace-Beltrami operator: #V by #V igl::cotmatrix(V,F,L); // Alternative construction of same Laplacian SparseMatrix<double> G,K; // Gradient/Divergence igl::grad(V,F,G); // Diagonal per-triangle "mass matrix" VectorXd dblA; igl::doublearea(V,F,dblA); // Place areas along diagonal #dim times const auto & T = 1.*(dblA.replicate(3,1)*0.5).asDiagonal(); // Laplacian K built as discrete divergence of gradient or equivalently // discrete Dirichelet energy Hessian K = -G.transpose() * T * G; cout<<"|K-L|: "<<(K-L).norm()<<endl; const auto &key_down = [](igl::Viewer &viewer,unsigned char key,int mod)->bool { switch(key) { case 'r': case 'R': U = V; break; case ' ': { // Recompute just mass matrix on each step SparseMatrix<double> M; igl::massmatrix(U,F,igl::MASSMATRIX_TYPE_BARYCENTRIC,M); // Solve (M-delta*L) U = M*U const auto & S = (M - 0.001*L); Eigen::SimplicialLLT<Eigen::SparseMatrix<double > > solver(S); assert(solver.info() == Eigen::Success); U = solver.solve(M*U).eval(); // Compute centroid and subtract (also important for numerics) VectorXd dblA; igl::doublearea(U,F,dblA); double area = 0.5*dblA.sum(); MatrixXd BC; igl::barycenter(U,F,BC); RowVector3d centroid(0,0,0); for(int i = 0;i<BC.rows();i++) { centroid += 0.5*dblA(i)/area*BC.row(i); } U.rowwise() -= centroid; // Normalize to unit surface area (important for numerics) U.array() /= sqrt(area); break; } default: return false; } // Send new positions, update normals, recenter viewer.data.set_vertices(U); viewer.data.compute_normals(); viewer.core.align_camera_center(U,F); return true; }; // Use original normals as pseudo-colors MatrixXd N; igl::per_vertex_normals(V,F,N); MatrixXd C = N.rowwise().normalized().array()*0.5+0.5; // Initialize smoothing with base mesh U = V; viewer.data.set_mesh(U, F); viewer.data.set_colors(C); viewer.callback_key_down = key_down; cout<<"Press [space] to smooth."<<endl;; cout<<"Press [r] to reset."<<endl;; return viewer.launch(); }
void run () { auto input_header = Header::open (argument[0]); Header output_header (input_header); output_header.datatype() = DataType::from_command_line (DataType::from<float> ()); // Linear transform_type linear_transform; bool linear = false; auto opt = get_options ("linear"); if (opt.size()) { linear = true; linear_transform = load_transform (opt[0][0]); } else { linear_transform.setIdentity(); } // Replace const bool replace = get_options ("replace").size(); if (replace && !linear) { INFO ("no linear is supplied so replace with the default (identity) transform"); linear = true; } // Template opt = get_options ("template"); Header template_header; if (opt.size()) { if (replace) throw Exception ("you cannot use the -replace option with the -template option"); template_header = Header::open (opt[0][0]); for (size_t i = 0; i < 3; ++i) { output_header.size(i) = template_header.size(i); output_header.spacing(i) = template_header.spacing(i); } output_header.transform() = template_header.transform(); add_line (output_header.keyval()["comments"], std::string ("regridded to template image \"" + template_header.name() + "\"")); } // Warp 5D warp // TODO add reference to warp format documentation opt = get_options ("warp_full"); Image<default_type> warp; if (opt.size()) { warp = Image<default_type>::open (opt[0][0]).with_direct_io(); if (warp.ndim() != 5) throw Exception ("the input -warp_full image must be a 5D file."); if (warp.size(3) != 3) throw Exception ("the input -warp_full image must have 3 volumes (x,y,z) in the 4th dimension."); if (warp.size(4) != 4) throw Exception ("the input -warp_full image must have 4 volumes in the 5th dimension."); if (linear) throw Exception ("the -warp_full option cannot be applied in combination with -linear since the " "linear transform is already included in the warp header"); } // Warp from image1 or image2 int from = 1; opt = get_options ("from"); if (opt.size()) { from = opt[0][0]; if (!warp.valid()) WARN ("-from option ignored since no 5D warp was input"); } // Warp deformation field opt = get_options ("warp"); if (opt.size()) { if (warp.valid()) throw Exception ("only one warp field can be input with either -warp or -warp_mid"); warp = Image<default_type>::open (opt[0][0]).with_direct_io (Stride::contiguous_along_axis(3)); if (warp.ndim() != 4) throw Exception ("the input -warp file must be a 4D deformation field"); if (warp.size(3) != 3) throw Exception ("the input -warp file must have 3 volumes in the 4th dimension (x,y,z positions)"); } // Inverse const bool inverse = get_options ("inverse").size(); if (inverse) { if (!(linear || warp.valid())) throw Exception ("no linear or warp transformation provided for option '-inverse'"); if (warp.valid()) if (warp.ndim() == 4) throw Exception ("cannot apply -inverse with the input -warp_df deformation field."); linear_transform = linear_transform.inverse(); } // Half const bool half = get_options ("half").size(); if (half) { if (!(linear)) throw Exception ("no linear transformation provided for option '-half'"); { Eigen::Matrix<default_type, 4, 4> temp; temp.row(3) << 0, 0, 0, 1.0; temp.topLeftCorner(3,4) = linear_transform.matrix().topLeftCorner(3,4); linear_transform.matrix() = temp.sqrt().topLeftCorner(3,4); } } // Flip opt = get_options ("flip"); if (opt.size()) { std::vector<int> axes = opt[0][0]; transform_type flip; flip.setIdentity(); for (size_t i = 0; i < axes.size(); ++i) { if (axes[i] < 0 || axes[i] > 2) throw Exception ("axes supplied to -flip are out of bounds (" + std::string (opt[0][0]) + ")"); flip(axes[i],3) += flip(axes[i],axes[i]) * input_header.spacing(axes[i]) * (input_header.size(axes[i])-1); flip(axes[i], axes[i]) *= -1.0; } if (!replace) flip = input_header.transform() * flip * input_header.transform().inverse(); linear_transform = linear_transform * flip; linear = true; } Stride::List stride = Stride::get (input_header); // Detect FOD image for reorientation opt = get_options ("noreorientation"); bool fod_reorientation = false; Eigen::MatrixXd directions_cartesian; if (!opt.size() && (linear || warp.valid() || template_header.valid()) && input_header.ndim() == 4 && input_header.size(3) >= 6 && input_header.size(3) == (int) Math::SH::NforL (Math::SH::LforN (input_header.size(3)))) { CONSOLE ("SH series detected, performing apodised PSF reorientation"); fod_reorientation = true; Eigen::MatrixXd directions_az_el; opt = get_options ("directions"); if (opt.size()) directions_az_el = load_matrix (opt[0][0]); else directions_az_el = DWI::Directions::electrostatic_repulsion_300(); Math::SH::spherical2cartesian (directions_az_el, directions_cartesian); // load with SH coeffients contiguous in RAM stride = Stride::contiguous_along_axis (3, input_header); } // Modulate FODs bool modulate = false; if (get_options ("modulate").size()) { modulate = true; if (!fod_reorientation) throw Exception ("modulation can only be performed with FOD reorientation"); } // Rotate/Flip gradient directions if present if (linear && input_header.ndim() == 4 && !warp && !fod_reorientation) { try { auto grad = DWI::get_DW_scheme (input_header); if (input_header.size(3) == (ssize_t) grad.rows()) { INFO ("DW gradients detected and will be reoriented"); Eigen::MatrixXd rotation = linear_transform.linear(); Eigen::MatrixXd test = rotation.transpose() * rotation; test = test.array() / test.diagonal().mean(); if (!test.isIdentity (0.001)) WARN ("the input linear transform contains shear or anisotropic scaling and " "therefore should not be used to reorient diffusion gradients"); if (replace) rotation = linear_transform.linear() * input_header.transform().linear().inverse(); for (ssize_t n = 0; n < grad.rows(); ++n) { Eigen::Vector3 grad_vector = grad.block<1,3>(n,0); grad.block<1,3>(n,0) = rotation * grad_vector; } DWI::set_DW_scheme (output_header, grad); } } catch (Exception& e) { e.display (2); } } // Interpolator int interp = 2; // cubic opt = get_options ("interp"); if (opt.size()) { interp = opt[0][0]; if (!warp && !template_header) WARN ("interpolator choice ignored since the input image will not be regridded"); } // Out of bounds value float out_of_bounds_value = 0.0; opt = get_options ("nan"); if (opt.size()) { out_of_bounds_value = NAN; if (!warp && !template_header) WARN ("Out of bounds value ignored since the input image will not be regridded"); } auto input = input_header.get_image<float>().with_direct_io (stride); // Reslice the image onto template if (template_header.valid() && !warp) { INFO ("image will be regridded"); if (get_options ("midway_space").size()) { INFO("regridding to midway space"); std::vector<Header> headers; headers.push_back(input_header); headers.push_back(template_header); std::vector<Eigen::Transform<default_type, 3, Eigen::Projective>> void_trafo; auto padding = Eigen::Matrix<double, 4, 1>(1.0, 1.0, 1.0, 1.0); int subsampling = 1; auto midway_header = compute_minimum_average_header (headers, subsampling, padding, void_trafo); for (size_t i = 0; i < 3; ++i) { output_header.size(i) = midway_header.size(i); output_header.spacing(i) = midway_header.spacing(i); } output_header.transform() = midway_header.transform(); } if (interp == 0) output_header.datatype() = DataType::from_command_line (input_header.datatype()); auto output = Image<float>::create (argument[1], output_header).with_direct_io(); switch (interp) { case 0: Filter::reslice<Interp::Nearest> (input, output, linear_transform, Adapter::AutoOverSample, out_of_bounds_value); break; case 1: Filter::reslice<Interp::Linear> (input, output, linear_transform, Adapter::AutoOverSample, out_of_bounds_value); break; case 2: Filter::reslice<Interp::Cubic> (input, output, linear_transform, Adapter::AutoOverSample, out_of_bounds_value); break; case 3: Filter::reslice<Interp::Sinc> (input, output, linear_transform, Adapter::AutoOverSample, out_of_bounds_value); break; default: assert (0); break; } if (fod_reorientation) Registration::Transform::reorient ("reorienting", output, output, linear_transform, directions_cartesian.transpose(), modulate); } else if (warp.valid()) { if (replace) throw Exception ("you cannot use the -replace option with the -warp or -warp_df option"); if (!template_header) { for (size_t i = 0; i < 3; ++i) { output_header.size(i) = warp.size(i); output_header.spacing(i) = warp.spacing(i); } output_header.transform() = warp.transform(); add_line (output_header.keyval()["comments"], std::string ("resliced using warp image \"" + warp.name() + "\"")); } auto output = Image<float>::create(argument[1], output_header).with_direct_io(); if (warp.ndim() == 5) { Image<default_type> warp_deform; // Warp to the midway space defined by the warp grid if (get_options ("midway_space").size()) { warp_deform = Registration::Warp::compute_midway_deformation (warp, from); // Use the full transform to warp from the image image to the template } else { warp_deform = Registration::Warp::compute_full_deformation (warp, template_header, from); } apply_warp (input, output, warp_deform, interp, out_of_bounds_value); if (fod_reorientation) Registration::Transform::reorient_warp ("reorienting", output, warp_deform, directions_cartesian.transpose(), modulate); // Compose and apply input linear and 4D deformation field } else if (warp.ndim() == 4 && linear) { auto warp_composed = Image<default_type>::scratch (warp); Registration::Warp::compose_linear_deformation (linear_transform, warp, warp_composed); apply_warp (input, output, warp_composed, interp, out_of_bounds_value); if (fod_reorientation) Registration::Transform::reorient_warp ("reorienting", output, warp_composed, directions_cartesian.transpose(), modulate); // Apply 4D deformation field only } else { apply_warp (input, output, warp, interp, out_of_bounds_value); if (fod_reorientation) Registration::Transform::reorient_warp ("reorienting", output, warp, directions_cartesian.transpose(), modulate); } // No reslicing required, so just modify the header and do a straight copy of the data } else { if (get_options ("midway").size()) throw Exception ("midway option given but no template image defined"); INFO ("image will not be regridded"); Eigen::MatrixXd rotation = linear_transform.linear(); Eigen::MatrixXd temp = rotation.transpose() * rotation; if (!temp.isIdentity (0.001)) WARN("the input linear transform is not orthonormal and therefore applying this without the -template" "option will mean the output header transform will also be not orthonormal"); add_line (output_header.keyval()["comments"], std::string ("transform modified")); if (replace) output_header.transform() = linear_transform; else output_header.transform() = linear_transform.inverse() * output_header.transform(); auto output = Image<float>::create (argument[1], output_header).with_direct_io(); copy_with_progress (input, output); if (fod_reorientation) { transform_type transform = linear_transform; if (replace) transform = linear_transform * output_header.transform().inverse(); Registration::Transform::reorient ("reorienting", output, output, transform, directions_cartesian.transpose()); } } }
void Dmp::analyticalSolution(const VectorXd& ts, MatrixXd& xs, MatrixXd& xds, Eigen::MatrixXd& forcing_terms, Eigen::MatrixXd& fa_outputs) const { int n_time_steps = ts.size(); // INTEGRATE SYSTEMS ANALYTICALLY AS MUCH AS POSSIBLE // Integrate phase MatrixXd xs_phase; MatrixXd xds_phase; phase_system_->analyticalSolution(ts,xs_phase,xds_phase); // Compute gating term MatrixXd xs_gating; MatrixXd xds_gating; gating_system_->analyticalSolution(ts,xs_gating,xds_gating); // Compute the output of the function approximator fa_outputs.resize(ts.size(),dim_orig()); fa_outputs.fill(0.0); //if (isTrained()) computeFunctionApproximatorOutput(xs_phase, fa_outputs); MatrixXd xs_gating_rep = xs_gating.replicate(1,fa_outputs.cols()); MatrixXd g_minus_y0_rep = (attractor_state()-initial_state()).transpose().replicate(n_time_steps,1); forcing_terms = fa_outputs.array()*xs_gating_rep.array(); // zzz *g_minus_y0_rep.array(); MatrixXd xs_goal, xds_goal; // Get current delayed goal if (goal_system_==NULL) { // If there is no dynamical system for the delayed goal, the goal is // simply the attractor state xs_goal = attractor_state().transpose().replicate(n_time_steps,1); // with zero change xds_goal = MatrixXd::Zero(n_time_steps,dim_orig()); } else { // Integrate goal system and get current goal state goal_system_->analyticalSolution(ts,xs_goal,xds_goal); } xs.resize(n_time_steps,dim()); xds.resize(n_time_steps,dim()); int T = n_time_steps; xs.GOALM(T) = xs_goal; xds.GOALM(T) = xds_goal; xs.PHASEM(T) = xs_phase; xds.PHASEM(T) = xds_phase; xs.GATINGM(T) = xs_gating; xds.GATINGM(T) = xds_gating; // THE REST CANNOT BE DONE ANALYTICALLY // Reset the dynamical system, and get the first state double damping = spring_system_->damping_coefficient(); SpringDamperSystem localspring_system_(tau(),initial_state(),attractor_state(),damping); // Set first attractor state localspring_system_.set_attractor_state(xs_goal.row(0)); // Start integrating spring damper system int dim_spring = localspring_system_.dim(); VectorXd x_spring(dim_spring), xd_spring(dim_spring); // zzz Why are these needed? int t0 = 0; localspring_system_.integrateStart(x_spring, xd_spring); xs.row(t0).SPRING = x_spring; xds.row(t0).SPRING = xd_spring; // Add forcing term to the acceleration of the spring state xds.SPRINGM_Z(1) = xds.SPRINGM_Z(1) + forcing_terms.row(t0)/tau(); for (int tt=1; tt<n_time_steps; tt++) { double dt = ts[tt]-ts[tt-1]; // Euler integration xs.row(tt).SPRING = xs.row(tt-1).SPRING + dt*xds.row(tt-1).SPRING; // Set the attractor state of the spring system localspring_system_.set_attractor_state(xs.row(tt).GOAL); // Integrate spring damper system localspring_system_.differentialEquation(xs.row(tt).SPRING, xd_spring); xds.row(tt).SPRING = xd_spring; // Add forcing term to the acceleration of the spring state xds.row(tt).SPRING_Z = xds.row(tt).SPRING_Z + forcing_terms.row(tt)/tau(); // Compute y component from z xds.row(tt).SPRING_Y = xs.row(tt).SPRING_Z/tau(); } }
void display() { using namespace Eigen; using namespace igl; using namespace std; if(!trackball_on && tot_num_samples < 10000) { if(S.size() == 0) { S.resize(V.rows()); S.setZero(); } VectorXd Si; const int num_samples = 20; ambient_occlusion(ei,V,N,num_samples,Si); S *= (double)tot_num_samples; S += Si*(double)num_samples; tot_num_samples += num_samples; S /= (double)tot_num_samples; } // Convert to 1-intensity C.conservativeResize(S.rows(),3); if(ao_on) { C<<S,S,S; C.array() = (1.0-ao_factor*C.array()); }else { C.setConstant(1.0); } if(ao_normalize) { C.col(0) *= ((double)C.rows())/C.col(0).sum(); C.col(1) *= ((double)C.rows())/C.col(1).sum(); C.col(2) *= ((double)C.rows())/C.col(2).sum(); } C.col(0) *= color(0); C.col(1) *= color(1); C.col(2) *= color(2); glClearColor(back[0],back[1],back[2],0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // All smooth points glEnable( GL_POINT_SMOOTH ); glDisable(GL_LIGHTING); if(lights_on) { lights(); } push_scene(); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); push_object(); // Draw the model // Set material properties glEnable(GL_COLOR_MATERIAL); draw_mesh(V,F,N,C); pop_object(); // Draw a nice floor glPushMatrix(); const double floor_offset = -2./bbd*(V.col(1).maxCoeff()-mid(1)); glTranslated(0,floor_offset,0); const float GREY[4] = {0.5,0.5,0.6,1.0}; const float DARK_GREY[4] = {0.2,0.2,0.3,1.0}; draw_floor(GREY,DARK_GREY); glPopMatrix(); pop_scene(); report_gl_error(); TwDraw(); glutSwapBuffers(); glutPostRedisplay(); }
inline Real stdDev(const Eigen::MatrixXd& input){ return ::sqrt(((Eigen::MatrixXd)((input.array()-input.sum()/input.rows()).pow(2.0))).sum()/(input.rows()-1)); }
normal_fullrank sqrt() const { return normal_fullrank(Eigen::VectorXd(mu_.array().sqrt()), Eigen::MatrixXd(L_chol_.array().sqrt())); }