void taskwrenchEllipsoid::computeTorqueEllipsoid() { //Computing pca on the pointset and scale such that it encloses! Eigen::Vector3d mean=sampledPointsEllipse_.rowwise().mean(); MatSampledPts aligned = sampledPointsEllipse_.colwise() - mean; Eigen::Matrix3d covMat=aligned*aligned.transpose(); //maybe already enough?? Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(covMat); Eigen::Vector3d eigenValues=eigensolver.eigenvalues(); Eigen::Matrix3d eigenVectors=eigensolver.eigenvectors(); //Now compute scaling of Eigenvectors such to have a circumscribed ellipsoid. transforming //Points into the PCA::Frame and get Max in each direction! pcaMat_=eigenVectors; pcaEv_=eigenValues; #if DEBUGQM std::cout << "[Debug]:" << std::endl; std::cout << "mean: " << mean.transpose() << std::endl; std::cout << "eigenVectors: " << eigenVectors << std::endl; std::cout << "eigenValues: " << eigenValues.transpose() << std::endl; //Transform Pointset to EigenFrame //getting the max in the eigenvectorFrame //check if right handed rotation matrix! std::cout << "Determinant" << std::endl; std::cout << pcaMat_.determinant() << std::endl; #endif MatSampledPts transf=pcaMat_.inverse()*aligned; //why inverse seems to work?? debug that more!! Eigen::Vector3d max3D=transf.rowwise().maxCoeff(); //get Enclosed Ellipse by scaling Eigenvectors with maxCoeff double delta=0.00001; Eigen::Matrix3d scalMat=Eigen::Vector3d(pow(max3D(0)+delta,-2),pow(max3D(1)+delta,-2),pow(max3D(2)+delta,-2)).asDiagonal(); Eigen::Vector3d maxScale=scalMat*eigenValues;//eigenvalues in new frame, why does the ordering change?! double scale=maxScale.maxCoeff(); #if DEBUGQM std::cout << "max3D" << max3D << std::endl; std::cout << "maxScale" << maxScale<<std::endl; std::cout << "scale" << scale<<std::endl; #endif pcaEv_ << pow((eigenValues(0)+0)/scale,0.5), pow(eigenValues(1)/scale,0.5),pow(eigenValues(2)/scale,0.5); //Now scaled to halfaxes! pca_to_ellipse_.rotation=pcaMat_; pca_to_ellipse_.translation<<0,0,0; }
void eigenTest() { e::Matrix<double, 3, 3> Q; e::Matrix<double, 3, 3> corrMatrix; corrMatrix(0, 0) = 17.25905; corrMatrix(0, 1) = -23.88775; corrMatrix(0, 2) = 6.448684; corrMatrix(1, 0) = -23.88775; corrMatrix(1, 1) = 37.74094; corrMatrix(1, 2) = -0.7966833; corrMatrix(2, 0) = 6.448684; corrMatrix(2, 1) = -0.7966833; corrMatrix(2, 2) = 17.4851; std::cout << "UNITTEST" << std::endl; std::cout << "CorrMatrix: " << std::endl; std::cout << corrMatrix << std::endl; std::cout << "******" << std::endl; std::vector<double> eigenValues(3); //jacobi_sweep(corrMatrix, Q, eigenValues); eigenSolver(corrMatrix, Q, eigenValues); std::cout << "EigenValues: " << eigenValues[0] << " " << eigenValues[1] << " " << eigenValues[2] << std::endl; std::cout << "EigenVec1:" << Q(0, 0) << " " << Q(1, 0) << " " << Q(2, 0) << std::endl; std::cout << "EigenVec2:" << Q(0, 1) << " " << Q(1, 1) << " " << Q(2, 1) << std::endl; std::cout << "EigenVec3:" << Q(0, 2) << " " << Q(1, 2) << " " << Q(2, 2) << std::endl; }
void Foam::Lambda2::execute() { if (active_) { const fvMesh& mesh = refCast<const fvMesh>(obr_); const volVectorField& U = mesh.lookupObject<volVectorField>(UName_); const volTensorField gradU(fvc::grad(U)); const volTensorField SSplusWW ( (symm(gradU) & symm(gradU)) + (skew(gradU) & skew(gradU)) ); volScalarField& Lambda2 = const_cast<volScalarField&> ( mesh.lookupObject<volScalarField>(type()) ); Lambda2 = -eigenValues(SSplusWW)().component(vector::Y); } }
dimensionedVector eigenValues(const dimensionedSymmTensor& dt) { return dimensionedVector ( "eigenValues("+dt.name()+')', dt.dimensions(), eigenValues(dt.value()) ); }
tensor2D eigenVectors(const tensor2D& t) { vector2D evals(eigenValues(t)); tensor2D evs ( eigenVector(t, evals.x()), eigenVector(t, evals.y()) ); return evs; }
int main(int argc, char const *argv[]){ if(argc != 3){ cout << "Parameters should be: (i: input file), (o: output file)" << endl; return 0; } ifstream input(argv[1]); string inFileDir, line; int alpha; input >> inFileDir >> alpha; getline(input, line); getline(input, line); stringstream lineStream(line); DigitImages imagesTrain, imagesTest; Matrix eigenVectors(alpha, vector<double>(DEFAULT_IMAGE_SIZE)); vector<double> eigenValues(alpha); int niter = 1000; populateDigitImages(imagesTrain, imagesTest, inFileDir, lineStream); imagesTrain.getMeans(); imagesTrain.calculateCentralized(); // imagesTrain.calculateCovariances(); imagesTest.calculateCentralizedTest(imagesTrain.means, (int)imagesTrain.images.size()); // PCA(imagesTrain.covariances, eigenVectors, eigenValues, alpha, niter); PLSDA(imagesTrain, eigenVectors, eigenValues, alpha, niter); vector<double> aux(DEFAULT_IMAGE_SIZE); for (int k = 0; k < eigenVectors.size(); ++k){ ofstream output(argv[2] + to_string(k)); double max = eigenVectors[k][0], min = eigenVectors[k][0]; for (int i = 1; i < DEFAULT_IMAGE_SIZE; ++i){ if(eigenVectors[k][i] > max) max = eigenVectors[k][i]; else if(eigenVectors[k][i] < min) min = eigenVectors[k][i]; } for (int i = 0; i < DEFAULT_IMAGE_SIZE; ++i){ aux[i] = eigenVectors[k][i] - min; aux[i] *= 255; aux[i] /= (max - min); } printImage(aux, output); output.close(); } input.close(); return 0; }
tensor eigenVectors(const symmTensor& t) { vector evals(eigenValues(t)); tensor evs ( eigenVector(t, evals.x()), eigenVector(t, evals.y()), eigenVector(t, evals.z()) ); return evs; }
void umdFitLine(int lineCount, e::Vector2d **points, Line &l) { e::Vector2d mean(0, 0); for(int i = 0; i < lineCount; ++i) { mean += *(points[i]); } mean = mean*(1.0/lineCount); //move it to mean; for(int i = 0; i < lineCount; ++i) { *(points[i]) -= mean; } //first compute the correlation matrix //should be row major e::Matrix<double, 2, 2> corrMatrix; for(int row = 0; row < 2; row++) { for(int col = 0; col < 2; col++) { //normal matrix multiplication m * m^T, this could be probably optimized since it's symmetrical double sum = 0; for(int i = 0; i < lineCount; i++) { sum += (*(points[i]))[row]* (*(points[i]))[col]; } corrMatrix(row, col) = sum; } } e::Matrix<double, 2, 2> V; std::vector<double> eigenValues(2); eigenSolver(corrMatrix, V, eigenValues); //we want the normal l.a = V(1, 0); l.b = V(1, 1); //the second eigenvector - it is sorted for 2x2 //compute mean l.c = -l.a*mean[0] - l.b*mean[1]; }
void GenericReconCartesianNonLinearSpirit2DTGadget::perform_nonlinear_spirit_unwrapping(hoNDArray< std::complex<float> >& kspace, hoNDArray< std::complex<float> >& kerIm, hoNDArray< std::complex<float> >& ref2DT, hoNDArray< std::complex<float> >& coilMap2DT, hoNDArray< std::complex<float> >& res, size_t e) { try { bool print_iter = this->spirit_print_iter.value(); size_t RO = kspace.get_size(0); size_t E1 = kspace.get_size(1); size_t E2 = kspace.get_size(2); size_t CHA = kspace.get_size(3); size_t N = kspace.get_size(4); size_t S = kspace.get_size(5); size_t SLC = kspace.get_size(6); size_t ref_N = kerIm.get_size(4); size_t ref_S = kerIm.get_size(5); hoNDArray< std::complex<float> > kspaceLinear(kspace); res = kspace; // detect whether random sampling is used bool use_random_sampling = false; std::vector<long long> sampled_step_size; long long n, e1; for (n=0; n<(long long)N; n++) { long long prev_sampled_line = -1; for (e1=0; e1<(long long)E1; e1++) { if(std::abs(kspace(RO/2, e1, 0, 0, 0, 0, 0))>0 && std::abs(kspace(RO/2, e1, 0, CHA-1, 0, 0, 0))>0) { if(prev_sampled_line>0) { sampled_step_size.push_back(e1 - prev_sampled_line); } prev_sampled_line = e1; } } } if(sampled_step_size.size()>4) { size_t s; for (s=2; s<sampled_step_size.size()-1; s++) { if(sampled_step_size[s]!=sampled_step_size[s-1]) { use_random_sampling = true; break; } } } if(use_random_sampling) { GDEBUG_STREAM("SPIRIT Non linear, random sampling is detected ... "); } Gadgetron::GadgetronTimer timer(false); boost::shared_ptr< hoNDArray< std::complex<float> > > coilMap; bool hasCoilMap = false; if (coilMap2DT.get_size(0) == RO && coilMap2DT.get_size(1) == E1 && coilMap2DT.get_size(3)==CHA) { if (ref_N < N) { coilMap = boost::shared_ptr< hoNDArray< std::complex<float> > >(new hoNDArray< std::complex<float> >(RO, E1, CHA, coilMap2DT.begin())); } else { coilMap = boost::shared_ptr< hoNDArray< std::complex<float> > >(new hoNDArray< std::complex<float> >(RO, E1, CHA, ref_N, coilMap2DT.begin())); } hasCoilMap = true; } hoNDArray<float> gFactor; float gfactorMedian = 0; float smallest_eigen_value(0); // ----------------------------------------------------- // estimate gfactor // ----------------------------------------------------- // mean over N hoNDArray< std::complex<float> > meanKSpace; if(calib_mode_[e]==ISMRMRD_interleaved) { Gadgetron::compute_averaged_data_N_S(kspace, true, true, true, meanKSpace); } else { Gadgetron::compute_averaged_data_N_S(ref2DT, true, true, true, meanKSpace); } if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(meanKSpace, debug_folder_full_path_ + "spirit_nl_2DT_meanKSpace"); } hoNDArray< std::complex<float> > acsSrc(meanKSpace.get_size(0), meanKSpace.get_size(1), CHA, meanKSpace.begin()); hoNDArray< std::complex<float> > acsDst(meanKSpace.get_size(0), meanKSpace.get_size(1), CHA, meanKSpace.begin()); double grappa_reg_lamda = 0.0005; size_t kRO = 5; size_t kE1 = 4; hoNDArray< std::complex<float> > convKer; hoNDArray< std::complex<float> > kIm(RO, E1, CHA, CHA); Gadgetron::grappa2d_calib_convolution_kernel(acsSrc, acsDst, (size_t)this->acceFactorE1_[e], grappa_reg_lamda, kRO, kE1, convKer); Gadgetron::grappa2d_image_domain_kernel(convKer, RO, E1, kIm); hoNDArray< std::complex<float> > unmixC; if(hasCoilMap) { Gadgetron::grappa2d_unmixing_coeff(kIm, *coilMap, (size_t)acceFactorE1_[e], unmixC, gFactor); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array(gFactor, debug_folder_full_path_ + "spirit_nl_2DT_gFactor"); hoNDArray<float> gfactorSorted(gFactor); std::sort(gfactorSorted.begin(), gfactorSorted.begin()+RO*E1); gfactorMedian = gFactor((RO*E1 / 2)); GDEBUG_STREAM("SPIRIT Non linear, the median gfactor is found to be : " << gfactorMedian); } if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(kIm, debug_folder_full_path_ + "spirit_nl_2DT_kIm"); hoNDArray< std::complex<float> > complexIm; // compute linear solution as the initialization if(use_random_sampling) { if (this->perform_timing.value()) timer.start("SPIRIT Non linear, perform linear spirit recon ... "); this->perform_spirit_unwrapping(kspace, kerIm, kspaceLinear); if (this->perform_timing.value()) timer.stop(); } else { if (this->perform_timing.value()) timer.start("SPIRIT Non linear, perform linear recon ... "); //size_t ref2DT_RO = ref2DT.get_size(0); //size_t ref2DT_E1 = ref2DT.get_size(1); //// mean over N //hoNDArray< std::complex<float> > meanKSpace; //Gadgetron::sum_over_dimension(ref2DT, meanKSpace, 4); //if (!debug_folder_full_path_.empty()) { gt_exporter_.export_array_complex(meanKSpace, debug_folder_full_path_ + "spirit_nl_2DT_meanKSpace"); } //hoNDArray< std::complex<float> > acsSrc(ref2DT_RO, ref2DT_E1, CHA, meanKSpace.begin()); //hoNDArray< std::complex<float> > acsDst(ref2DT_RO, ref2DT_E1, CHA, meanKSpace.begin()); //double grappa_reg_lamda = 0.0005; //size_t kRO = 5; //size_t kE1 = 4; //hoNDArray< std::complex<float> > convKer; //hoNDArray< std::complex<float> > kIm(RO, E1, CHA, CHA); //Gadgetron::grappa2d_calib_convolution_kernel(acsSrc, acsDst, (size_t)this->acceFactorE1_[e], grappa_reg_lamda, kRO, kE1, convKer); //Gadgetron::grappa2d_image_domain_kernel(convKer, RO, E1, kIm); //if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(kIm, debug_folder_full_path_ + "spirit_nl_2DT_kIm"); Gadgetron::hoNDFFT<float>::instance()->ifft2c(kspace, complex_im_recon_buf_); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(complex_im_recon_buf_, debug_folder_full_path_ + "spirit_nl_2DT_aliasedImage"); hoNDArray< std::complex<float> > resKSpace(RO, E1, CHA, N); hoNDArray< std::complex<float> > aliasedImage(RO, E1, CHA, N, complex_im_recon_buf_.begin()); Gadgetron::grappa2d_image_domain_unwrapping_aliased_image(aliasedImage, kIm, resKSpace); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(resKSpace, debug_folder_full_path_ + "spirit_nl_2DT_linearImage"); Gadgetron::hoNDFFT<float>::instance()->fft2c(resKSpace); memcpy(kspaceLinear.begin(), resKSpace.begin(), resKSpace.get_number_of_bytes()); Gadgetron::apply_unmix_coeff_aliased_image(aliasedImage, unmixC, complexIm); if (this->perform_timing.value()) timer.stop(); } if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(kspaceLinear, debug_folder_full_path_ + "spirit_nl_2DT_kspaceLinear"); if(hasCoilMap) { if(N>=spirit_reg_minimal_num_images_for_noise_floor.value()) { // estimate the noise level if(use_random_sampling) { Gadgetron::hoNDFFT<float>::instance()->ifft2c(kspaceLinear, complex_im_recon_buf_); hoNDArray< std::complex<float> > complexLinearImage(RO, E1, CHA, N, complex_im_recon_buf_.begin()); Gadgetron::coil_combine(complexLinearImage, *coilMap, 2, complexIm); } if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(complexIm, debug_folder_full_path_ + "spirit_nl_2DT_linearImage_complexIm"); // if N is sufficiently large, we can estimate the noise floor by the smallest eigen value hoMatrix< std::complex<float> > data; data.createMatrix(RO*E1, N, complexIm.begin(), false); hoNDArray< std::complex<float> > eigenVectors, eigenValues, eigenVectorsPruned; // compute eigen hoNDKLT< std::complex<float> > klt; klt.prepare(data, (size_t)1, (size_t)0); klt.eigen_value(eigenValues); if (this->verbose.value()) { GDEBUG_STREAM("SPIRIT Non linear, computes eigen values for all 2D kspaces ... "); eigenValues.print(std::cout); for (size_t i = 0; i<eigenValues.get_size(0); i++) { GDEBUG_STREAM(i << " = " << eigenValues(i)); } } smallest_eigen_value = std::sqrt( std::abs(eigenValues(N - 1).real()) / (RO*E1) ); GDEBUG_STREAM("SPIRIT Non linear, the smallest eigen value is : " << smallest_eigen_value); } } // perform nonlinear reconstruction { boost::shared_ptr<hoNDArray< std::complex<float> > > ker(new hoNDArray< std::complex<float> >(RO, E1, CHA, CHA, ref_N, kerIm.begin())); boost::shared_ptr<hoNDArray< std::complex<float> > > acq(new hoNDArray< std::complex<float> >(RO, E1, CHA, N, kspace.begin())); hoNDArray< std::complex<float> > kspaceInitial(RO, E1, CHA, N, kspaceLinear.begin()); hoNDArray< std::complex<float> > res2DT(RO, E1, CHA, N, res.begin()); if (this->spirit_data_fidelity_lamda.value() > 0) { GDEBUG_STREAM("Start the NL SPIRIT data fidelity iteration - regularization strength : " << this->spirit_image_reg_lamda.value() << " - number of iteration : " << this->spirit_nl_iter_max.value() << " - proximity across cha : " << this->spirit_reg_proximity_across_cha.value() << " - redundant dimension weighting ratio : " << this->spirit_reg_N_weighting_ratio.value() << " - using coil sen map : " << this->spirit_reg_use_coil_sen_map.value() << " - iter thres : " << this->spirit_nl_iter_thres.value() << " - wavelet name : " << this->spirit_reg_name.value() ); typedef hoGdSolver< hoNDArray< std::complex<float> >, hoWavelet2DTOperator< std::complex<float> > > SolverType; SolverType solver; solver.iterations_ = this->spirit_nl_iter_max.value(); solver.set_output_mode(this->spirit_print_iter.value() ? SolverType::OUTPUT_VERBOSE : SolverType::OUTPUT_SILENT); solver.grad_thres_ = this->spirit_nl_iter_thres.value(); if(spirit_reg_estimate_noise_floor.value() && std::abs(smallest_eigen_value)>0) { solver.scale_factor_ = smallest_eigen_value; solver.proximal_strength_ratio_ = this->spirit_image_reg_lamda.value() * gfactorMedian; GDEBUG_STREAM("SPIRIT Non linear, eigen value is used to derive the regularization strength : " << solver.proximal_strength_ratio_ << " - smallest eigen value : " << solver.scale_factor_); } else { solver.proximal_strength_ratio_ = this->spirit_image_reg_lamda.value(); } boost::shared_ptr< hoNDArray< std::complex<float> > > x0 = boost::make_shared< hoNDArray< std::complex<float> > >(kspaceInitial); solver.set_x0(x0); // parallel imaging term std::vector<size_t> dims; acq->get_dimensions(dims); hoSPIRIT2DTDataFidelityOperator< std::complex<float> > spirit(&dims); spirit.set_forward_kernel(*ker, false); spirit.set_acquired_points(*acq); // image reg term hoWavelet2DTOperator< std::complex<float> > wav3DOperator(&dims); wav3DOperator.set_acquired_points(*acq); wav3DOperator.scale_factor_first_dimension_ = this->spirit_reg_RO_weighting_ratio.value(); wav3DOperator.scale_factor_second_dimension_ = this->spirit_reg_E1_weighting_ratio.value(); wav3DOperator.scale_factor_third_dimension_ = this->spirit_reg_N_weighting_ratio.value(); wav3DOperator.with_approx_coeff_ = !this->spirit_reg_keep_approx_coeff.value(); wav3DOperator.change_coeffcients_third_dimension_boundary_ = !this->spirit_reg_keep_redundant_dimension_coeff.value(); wav3DOperator.proximity_across_cha_ = this->spirit_reg_proximity_across_cha.value(); wav3DOperator.no_null_space_ = true; wav3DOperator.input_in_kspace_ = true; wav3DOperator.select_wavelet(this->spirit_reg_name.value()); if (this->spirit_reg_use_coil_sen_map.value() && hasCoilMap) { wav3DOperator.coil_map_ = *coilMap; } // set operators solver.oper_system_ = &spirit; solver.oper_reg_ = &wav3DOperator; if (this->perform_timing.value()) timer.start("NonLinear SPIRIT solver for 2DT with data fidelity ... "); solver.solve(*acq, res2DT); if (this->perform_timing.value()) timer.stop(); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(res2DT, debug_folder_full_path_ + "spirit_nl_2DT_data_fidelity_res"); } else { GDEBUG_STREAM("Start the NL SPIRIT iteration with regularization strength : "<< this->spirit_image_reg_lamda.value() << " - number of iteration : " << this->spirit_nl_iter_max.value() << " - proximity across cha : " << this->spirit_reg_proximity_across_cha.value() << " - redundant dimension weighting ratio : " << this->spirit_reg_N_weighting_ratio.value() << " - using coil sen map : " << this->spirit_reg_use_coil_sen_map.value() << " - iter thres : " << this->spirit_nl_iter_thres.value() << " - wavelet name : " << this->spirit_reg_name.value() ); typedef hoGdSolver< hoNDArray< std::complex<float> >, hoWavelet2DTOperator< std::complex<float> > > SolverType; SolverType solver; solver.iterations_ = this->spirit_nl_iter_max.value(); solver.set_output_mode(this->spirit_print_iter.value() ? SolverType::OUTPUT_VERBOSE : SolverType::OUTPUT_SILENT); solver.grad_thres_ = this->spirit_nl_iter_thres.value(); if(spirit_reg_estimate_noise_floor.value() && std::abs(smallest_eigen_value)>0) { solver.scale_factor_ = smallest_eigen_value; solver.proximal_strength_ratio_ = this->spirit_image_reg_lamda.value() * gfactorMedian; GDEBUG_STREAM("SPIRIT Non linear, eigen value is used to derive the regularization strength : " << solver.proximal_strength_ratio_ << " - smallest eigen value : " << solver.scale_factor_); } else { solver.proximal_strength_ratio_ = this->spirit_image_reg_lamda.value(); } boost::shared_ptr< hoNDArray< std::complex<float> > > x0 = boost::make_shared< hoNDArray< std::complex<float> > >(kspaceInitial); solver.set_x0(x0); // parallel imaging term std::vector<size_t> dims; acq->get_dimensions(dims); hoSPIRIT2DTOperator< std::complex<float> > spirit(&dims); spirit.set_forward_kernel(*ker, false); spirit.set_acquired_points(*acq); spirit.no_null_space_ = true; spirit.use_non_centered_fft_ = false; // image reg term std::vector<size_t> dim; acq->get_dimensions(dim); hoWavelet2DTOperator< std::complex<float> > wav3DOperator(&dim); wav3DOperator.set_acquired_points(*acq); wav3DOperator.scale_factor_first_dimension_ = this->spirit_reg_RO_weighting_ratio.value(); wav3DOperator.scale_factor_second_dimension_ = this->spirit_reg_E1_weighting_ratio.value(); wav3DOperator.scale_factor_third_dimension_ = this->spirit_reg_N_weighting_ratio.value(); wav3DOperator.with_approx_coeff_ = !this->spirit_reg_keep_approx_coeff.value(); wav3DOperator.change_coeffcients_third_dimension_boundary_ = !this->spirit_reg_keep_redundant_dimension_coeff.value(); wav3DOperator.proximity_across_cha_ = this->spirit_reg_proximity_across_cha.value(); wav3DOperator.no_null_space_ = true; wav3DOperator.input_in_kspace_ = true; wav3DOperator.select_wavelet(this->spirit_reg_name.value()); if (this->spirit_reg_use_coil_sen_map.value() && hasCoilMap) { wav3DOperator.coil_map_ = *coilMap; } // set operators solver.oper_system_ = &spirit; solver.oper_reg_ = &wav3DOperator; // set call back solverCallBack cb; cb.solver_ = &solver; solver.call_back_ = &cb; hoNDArray< std::complex<float> > b(kspaceInitial); Gadgetron::clear(b); if (this->perform_timing.value()) timer.start("NonLinear SPIRIT solver for 2DT ... "); solver.solve(b, res2DT); if (this->perform_timing.value()) timer.stop(); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(res2DT, debug_folder_full_path_ + "spirit_nl_2DT_res"); spirit.restore_acquired_kspace(kspace, res2DT); if (!debug_folder_full_path_.empty()) gt_exporter_.export_array_complex(res2DT, debug_folder_full_path_ + "spirit_nl_2DT_res_restored"); } } } catch (...) { GADGET_THROW("Errors happened in GenericReconCartesianNonLinearSpirit2DTGadget::perform_nonlinear_spirit_unwrapping(...) ... "); } }
void WTransform::decomposeTranslateRotateScaleRotate(TRSRDecomposition& result) const { // Performs a Singular Value Decomposition double mtm[4]; LOG_DEBUG("M: \n" << m_[M11] << " " << m_[M12] << "\n " << m_[M21] << " " << m_[M22]); matrixMultiply(m_[M11], m_[M21], m_[M12], m_[M22], m_[M11], m_[M12], m_[M21], m_[M22], mtm); double e[2]; double V[4]; eigenValues(mtm, e, V); result.sx = std::sqrt(e[0]); result.sy = std::sqrt(e[1]); LOG_DEBUG("V: \n" << V[M11] << " " << V[M12] << "\n " << V[M21] << " " << V[M22]); /* * if V is no rotation matrix, it contains a reflexion. A rotation * matrix has determinant of 1; a matrix that contains a reflexion * it has determinant -1. We reflect around the Y axis: */ if (V[0]*V[3] - V[1]*V[2] < 0) { result.sx = -result.sx; V[0] = -V[0]; V[2] = -V[2]; } double U[4]; matrixMultiply(m_[0], m_[1], m_[2], m_[3], V[0], V[1], V[2], V[3], U); U[0] /= result.sx; U[2] /= result.sx; U[1] /= result.sy; U[3] /= result.sy; LOG_DEBUG("U: \n" << U[M11] << " " << U[M12] << "\n " << U[M21] << " " << U[M22]); if (U[0]*U[3] - U[1]*U[2] < 0) { result.sx = -result.sx; U[0] = -U[0]; U[2] = -U[2]; } result.alpha1 = std::atan2(U[2], U[0]); result.alpha2 = std::atan2(V[1], V[0]); LOG_DEBUG("alpha1: " << result.alpha1 << ", alpha2: " << result.alpha2 << ", sx: " << result.sx << ", sy: " << result.sy); /* // check our SVD: m_ = U S VT double tmp[4], tmp2[4]; matrixMultiply(U[0], U[1], U[2], U[3], sx, 0, 0, sy, tmp); matrixMultiply(tmp[0], tmp[1], tmp[2], tmp[3], V[0], V[2], V[1], V[3], tmp2); LOG_DEBUG("check: \n" << tmp2[0] << " " << tmp2[1] << "\n" tmp2[2] << " " << tmp2[3]); */ result.dx = m_[DX]; result.dy = m_[DY]; }
void calcIncompressibleR ( const fvMesh& mesh, const Time& runTime, const volVectorField& U ) { #include "createPhi.H" singlePhaseTransportModel laminarTransport(U, phi); autoPtr<incompressible::turbulenceModel> model ( incompressible::turbulenceModel::New(U, phi, laminarTransport) ); Info<< "Getting R and k fields" << nl << endl; volSymmTensorField& R = model->R()(); volScalarField& k = model->k()(); //normalize R field volSymmTensorField B = R/(2.0*k) - 1.0/3.0*I; //get the eigen values of the normalized B field volVectorField B_eigenValues ( IOobject ( "eigenValues", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), eigenValues(B) ); //calculate the second and third invariants (the first = 0) volScalarField IIs ( IOobject ( "IIs", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Y)+ B_eigenValues.component(vector::Y)* B_eigenValues.component(vector::Z)+ B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Z) ); volScalarField IIIs ( IOobject ( "IIIs", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Y)* B_eigenValues.component(vector::Z) ); Info<< " Writing IIs and IIIs" << endl; IIs.write(); IIIs.write(); }
int main(int argc, char *argv[]) { timeSelector::addOptions(); #include "addRegionOption.H" argList::addBoolOption ( "compressible", "calculate compressible R" ); #include "setRootCase.H" #include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); #include "createNamedMesh.H" const bool compressible = args.optionFound("compressible"); forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); Info<< "Time = " << runTime.timeName() << endl; IOobject RHeader ( "R", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ); IOobject kHeader ( "k", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ); if (RHeader.headerOk() && kHeader.headerOk()) { Info<< "Reading R and k fields " << nl << endl; volSymmTensorField R(RHeader, mesh); volScalarField k(kHeader, mesh); //normalize R field volSymmTensorField B = R/(2.0*k) - 1.0/3.0*I; //get the eigen values of the normalized B field volVectorField B_eigenValues ( IOobject ( "eigenValues", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), eigenValues(B) ); //calculate the second and third invariants (the first = 0) volScalarField IIs ( IOobject ( "IIs", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Y)+ B_eigenValues.component(vector::Y)* B_eigenValues.component(vector::Z)+ B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Z) ); volScalarField IIIs ( IOobject ( "IIIs", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), B_eigenValues.component(vector::X)* B_eigenValues.component(vector::Y)* B_eigenValues.component(vector::Z) ); IIs.write(); IIIs.write(); //calculate eta and xi fields volScalarField eta ( IOobject ( "eta", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), sqrt(-IIs/3.0) ); volScalarField xi ( IOobject ( "xi", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), sign(IIIs)*pow(mag(IIIs)/2.0, 1.0/3.0) ); Info<< " Writing eta and xi" << endl; eta.write(); xi.write(); } else { Info<< " no U or k field" << endl; } }
void umdFitHyperplane(int lineCount, e::Vector3d **lines, e::Hyperplane<double, 3> &hyperplane) { //first compute the correlation matrix //should be row major e::Matrix<double, 3, 3> corrMatrix; //std::cout << "CORRELATION*******************" << std::endl; for(int row = 0; row < 3; row++) { for(int col = 0; col < 3; col++) { //normal matrix multiplication m * m^T, this could be probably optimized since it's symmetrical double sum = 0; for(int i = 0; i < lineCount; i++) { sum += (*(lines[i]))[row]* (*(lines[i]))[col]; } corrMatrix(row, col) = sum; //std::cout << sum << " "; } //std::cout << std::endl; } //std::cout << "CORRELATION*******************" << std::endl; e::Matrix<double, 3, 3> D; e::Matrix<double, 3, 3> Q; //std::cout << "correlation matrix: " << corrMatrix << std::endl; //std::cout << "**********" << std::endl; /* diagonalizer(corrMatrix, Q, D); //this does basically the eigen decomposition, the quaternions rot matrix should give the eigenVectors //get the eigenvalues A = Q * D * QT std::vector<double> eigenValues(3); eigenValues[0] = (const double)(D(0,0)); eigenValues[1] = (const double)(D(1,1)); eigenValues[2] = (const double)(D(2,2)); //find the smallest int k = (int)(std::min_element(eigenValues.begin(), eigenValues.end()) - eigenValues.begin()); //get the k's row for our hyperplane normal hyperplane.coeffs().data()[0] = Q(k , 0); hyperplane.coeffs().data()[1] = Q(k, 1); hyperplane.coeffs().data()[2] = Q(k, 2); hyperplane.coeffs().data()[3] = 0; //non linear part - should go through 0s std::cout << "Coeffs: " << Q(k, 0) << " " << Q(k, 1) << " " << Q(k, 2) << std::endl; std::cout << "Q: " << Q << std::endl; std::cout << "******" << std::endl; std::cout << "D: " << D << std::endl; std::cout << "******" << std::endl; */ std::vector<double> eigenValues(3); //jacobi_sweep(corrMatrix, Q, eigenValues); eigenSolver(corrMatrix, Q, eigenValues); //eigenTest(); //e::SelfAdjointEigenSolver< e::Matrix<double, 3, 3> > slvr(corrMatrix); //e::Vector3d ev = slvr.eigenvalues(); //Q = slvr.eigenvectors(); //eigenValues[0] = ev[0]; //eigenValues[1] = ev[1]; //eigenValues[2] = ev[2]; //std::cout << "Q: " << Q << std::endl; //std::cout << "******" << std::endl; //find the smallest int k = (int)(std::min_element(eigenValues.begin(), eigenValues.end()) - eigenValues.begin()); hyperplane.coeffs().data()[0] = Q(0, k); hyperplane.coeffs().data()[1] = Q(1, k); hyperplane.coeffs().data()[2] = Q(2, k); hyperplane.coeffs().data()[3] = 0; //non linear part - should go through 0s e::Vector3d hyperplaneNormal = hyperplane.normal(); //std::cout << "Normal: " << hyperplaneNormal << std::endl; }
void PrincipalComponentsAnalysis::compute(DataFrame& df) { if (df.getNumFactors() > 2) { // see PrincipalComponentsAnalysisTest cout << "You realize this hasn't been tested, right?" << endl; } Matrix dataMat(df.getNumFactors(), df.getNumDataVectors()); Matrix deviates(df.getNumFactors(), df.getNumDataVectors()); SymmetricMatrix covar(df.getNumFactors()); DiagonalMatrix eigenValues(df.getNumFactors()); Matrix eigenVectors; ColumnVector means(df.getNumFactors()); means = 0.0; RowVector h(df.getNumDataVectors()); h = 1.0; for (unsigned int j = 0; j < df.getNumFactors(); j++) { if (df.isNominal(j)) { throw Tgs::Exception("Only numeric values are supported."); } } for(unsigned int i = 0; i < df.getNumDataVectors(); i++) { for (unsigned int j = 0; j < df.getNumFactors(); j++) { double v = df.getDataElement(i, j); if (df.isNull(v)) { throw Tgs::Exception("Only non-null values are supported."); } dataMat.element(j, i) = v; means.element(j) += v / (double)df.getNumDataVectors(); } } try { deviates = dataMat - (means * h); covar << (1.0/(float)df.getNumDataVectors()) * (deviates * deviates.t()); Jacobi::jacobi(covar, eigenValues, eigenVectors); } catch (const std::exception&) { throw; } catch (...) { throw Tgs::Exception("Unknown error while calculating PCA"); } _sortEigens(eigenVectors, eigenValues); _components.resize(df.getNumFactors()); for (unsigned int v = 0; v < df.getNumFactors(); v++) { _components[v].resize(df.getNumFactors()); for (unsigned int d = 0; d < df.getNumFactors(); d++) { _components[v][d] = eigenVectors.element(d, v); } } }