/// Create a submatrix. A submatrix is a view into the parent matrix. /// Lifetime of a submatrix cannot exceed the lifetime of the parent. /// @param M :: The parent matrix. /// @param row :: The first row in the submatrix. /// @param col :: The first column in the submatrix. /// @param nRows :: The number of rows in the submatrix. /// @param nCols :: The number of columns in the submatrix. GSLMatrix::GSLMatrix(const GSLMatrix &M, size_t row, size_t col, size_t nRows, size_t nCols) { if (row + nRows > M.size1() || col + nCols > M.size2()) { throw std::runtime_error("Submatrix exceeds matrix size."); } auto view = gsl_matrix_const_submatrix(M.gsl(), row, col, nRows, nCols); m_matrix = gsl_matrix_alloc(nRows, nCols); gsl_matrix_memcpy(m_matrix, &view.matrix); }
/** * Calculates covariance matrix for fitting function's active parameters. * @param covar :: Output cavariance matrix. * @param epsrel :: Tolerance. */ void CostFuncLeastSquares::calActiveCovarianceMatrix(GSLMatrix &covar, double epsrel) { UNUSED_ARG(epsrel); if (m_hessian.isEmpty()) { valDerivHessian(); } if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) { std::ostringstream osHess; osHess << "== Hessian (H) ==\n"; osHess << std::left << std::fixed; for (size_t i = 0; i < m_hessian.size1(); ++i) { for (size_t j = 0; j < m_hessian.size2(); ++j) { osHess << std::setw(10); osHess << m_hessian.get(i, j) << " "; } osHess << "\n"; } g_log.debug() << osHess.str(); } covar = m_hessian; covar.invert(); if (g_log.is(Kernel::Logger::Priority::PRIO_DEBUG)) { std::ostringstream osCovar; osCovar << "== Covariance matrix (H^-1) ==\n"; osCovar << std::left << std::fixed; for (size_t i = 0; i < covar.size1(); ++i) { for (size_t j = 0; j < covar.size2(); ++j) { osCovar << std::setw(10); osCovar << covar.get(i, j) << " "; } osCovar << "\n"; } g_log.debug() << osCovar.str(); } }
/// Copy constructor /// @param M :: The other matrix. GSLMatrix::GSLMatrix(const GSLMatrix &M) : m_data(M.m_data), m_view(gsl_matrix_view_array(m_data.data(), M.size1(), M.size2())) {}
/// Execute algorithm. void Schrodinger1D::exec() { double startX = get("StartX"); double endX = get("EndX"); if (endX <= startX) { throw std::invalid_argument("StartX must be <= EndX"); } IFunction_sptr VPot = getClass("VPot"); chebfun vpot( 0, startX, endX ); vpot.bestFit( *VPot ); size_t nBasis = vpot.n() + 1; std::cerr << "n=" << nBasis << std::endl; //if (n < 3) { nBasis = 200; vpot.resize( nBasis ); } const double beta = get("Beta"); auto kinet = new ChebCompositeOperator; kinet->addRight( new ChebTimes(-beta) ); kinet->addRight( new ChebDiff2 ); auto hamiltonian = new ChebPlus; hamiltonian->add('+', kinet ); hamiltonian->add('+', new ChebTimes(VPot) ); GSLMatrix L; hamiltonian->createMatrix( vpot.getBase(), L ); GSLVector d; GSLMatrix v; L.diag( d, v ); std::vector<double> norms = vpot.baseNorm(); assert(norms.size() == L.size1()); assert(norms.size() == L.size2()); for(size_t i = 0; i < norms.size(); ++i) { double factor = 1.0 / norms[i]; for(size_t j = i; j < norms.size(); ++j) { v.multiplyBy(i,j,factor); } } // eigenvectors orthogonality check // GSLMatrix v1 = v; // GSLMatrix tst; // tst = Tr(v1) * v; // std::cerr << tst << std::endl; std::vector<size_t> indx(L.size1()); getSortedIndex( d, indx ); auto eigenvalues = API::TableWorkspace_ptr(dynamic_cast<API::TableWorkspace*>( API::WorkspaceFactory::instance().create("TableWorkspace")) ); eigenvalues->setRowCount(nBasis); setProperty("Eigenvalues", eigenvalues); eigenvalues->addColumn("double","N"); auto nColumn = static_cast<API::TableColumn<double>*>(eigenvalues->getColumn("N").get()); nColumn->asNumeric()->setPlotRole(API::NumericColumn::X); auto& nc = nColumn->data(); eigenvalues->addDoubleColumn("Energy"); auto eColumn = static_cast<API::TableColumn<double>*>(eigenvalues->getColumn("Energy").get()); eColumn->asNumeric()->setPlotRole(API::NumericColumn::Y); auto& ec = eigenvalues->getDoubleData("Energy"); boost::scoped_ptr<ChebfunVector> eigenvectors(new ChebfunVector); chebfun fun0(nBasis,startX,endX); ChebFunction_sptr theSum(new ChebFunction(fun0)); // collect indices of spurious eigenvalues to move them to the back std::vector<size_t> spurious; // index for good eigenvalues size_t n = 0; for(size_t j = 0; j < nBasis; ++j) { size_t i = indx[j]; chebfun fun(fun0); fun.setP(v,i); // check eigenvalues for spurious ones chebfun dfun(fun); dfun.square(); double norm = dfun.integr(); // I am not sure that it's a solid condition if ( norm < 0.999999 ) { // bad eigenvalue spurious.push_back(j); } else { nc[n] = double(n); ec[n] = d[i]; eigenvectors->add(ChebFunction_sptr(new ChebFunction(fun))); // test sum of functions squares *theSum += dfun; // chebfun dfun(fun); // hamiltonian->apply(fun,dfun); // dfun *= fun; // std::cerr << "ener["<<n<<"]=" << ec[n] << ' ' << norm << ' ' << dfun.integr() << std::endl; ++n; } } GSLVector eigv; ChebfunVector *eigf = NULL; improve(hamiltonian, eigenvectors.get(), eigv, &eigf); eigenvalues->setRowCount( eigv.size() ); for(size_t i = 0; i < eigv.size(); ++i) { nc[i] = double(i); ec[i] = eigv[i]; } eigf->add(theSum); setProperty("Eigenvectors",ChebfunVector_sptr(eigf)); //makeQuadrature(eigf); }
/// Copy constructor /// @param M :: The other matrix. GSLMatrix::GSLMatrix(const GSLMatrix &M) { m_matrix = gsl_matrix_alloc(M.size1(), M.size2()); gsl_matrix_memcpy(m_matrix, M.gsl()); }