/**---------------------------------------------------------------- * Create the output from a single ChebfunWorkspace. */ void ChebfunToTable::fromChebWorkspace() { ChebfunWorkspace_sptr cws = getClass("InputWorkspace"); Numeric::FunctionDomain1D_sptr domain; size_t n = (int)get("N"); if (n < 2) {// if n has default value (0) use the x-points of the chebfuns domain = cws->fun().createDomainFromXPoints(); n = domain->size(); } else {// otherwise create a regular comb domain = cws->fun().createDomain( n ); } Numeric::FunctionValues values( *domain ); cws->fun().function(*domain, values); auto tws = API::TableWorkspace_ptr(dynamic_cast<API::TableWorkspace*>( API::WorkspaceFactory::instance().create("TableWorkspace")) ); tws->addColumn("double","X"); tws->addColumn("double","Y"); tws->setRowCount(n); auto xColumn = static_cast<API::TableColumn<double>*>(tws->getColumn("X").get()); xColumn->asNumeric()->setPlotRole(API::NumericColumn::X); auto& x = xColumn->data(); auto yColumn = static_cast<API::TableColumn<double>*>(tws->getColumn("Y").get()); yColumn->asNumeric()->setPlotRole(API::NumericColumn::Y); auto& y = yColumn->data(); for(size_t i = 0; i < domain->size(); ++i) { x[i] = (*domain)[i]; y[i] = values.getCalculated(i); } bool dropXInf = get("DropXInf"); if ( dropXInf ) { if ( fabs( x.front() ) == inf ) { tws->removeRow( 0 ); } if ( fabs( x.back() ) == inf ) { tws->removeRow( tws->rowCount() - 1 ); } } setProperty("OutputWorkspace",tws); }
bool Item::exactlyEqual( const Item& other ) const { if ( type() != other.type() ) { return false; } switch( type() ) { case FLC_ITEM_NIL: case FLC_ITEM_UNB: return true; case FLC_ITEM_INT: return asInteger() == other.asInteger(); case FLC_ITEM_NUM: return asNumeric() == other.asNumeric(); case FLC_ITEM_RANGE: if( asRangeIsOpen() != other.asRangeIsOpen() ) return false; if ( asRangeStart() != other.asRangeStart() ) return false; if ( asRangeStep() != other.asRangeStep() ) return false; if ( ! asRangeIsOpen() && (asRangeEnd() != other.asRangeEnd() ) ) return false; return true; case FLC_ITEM_STRING: return *asString() == *other.asString(); case FLC_ITEM_METHOD: if ( asMethodFunc() == other.asMethodFunc() ) { return asMethodItem().exactlyEqual(other.asMethodItem() ); } return false; case FLC_ITEM_CLSMETHOD: if ( asObjectSafe() != other.asObjectSafe() ) return false; // fallthrough case FLC_ITEM_FUNC: case FLC_ITEM_CLASS: return asClass() == other.asClass(); } // the default is to check for the voidp element in data return asObjectSafe() == other.asObjectSafe(); }
int64 Item::forceIntegerEx() const { switch( type() ) { case FLC_ITEM_INT: return asInteger(); case FLC_ITEM_NUM: return (int64) asNumeric(); } throw new TypeError( ErrorParam( e_param_type, __LINE__ ) ); // to make some dumb compiler happy return 0; }
/**---------------------------------------------------------------- * Create the output from a ChebfunVector. */ void ChebfunToTable::fromChebVector() { ChebfunVector_sptr cws = getClass("InputWorkspace"); Numeric::FunctionDomain1D_sptr domain; size_t n = (int)get("N"); if (n < 2) {// if n has default value (0) use the x-points of the chebfuns domain = cws->fun(0).createDomainFromXPoints(); n = domain->size(); } else {// otherwise create a regular comb domain = cws->fun(0).createDomain( n ); } auto tws = API::TableWorkspace_ptr(dynamic_cast<API::TableWorkspace*>( API::WorkspaceFactory::instance().create("TableWorkspace")) ); tws->addColumn("double","x"); tws->setRowCount(n); auto xColumn = tws->getColumn("x"); xColumn->asNumeric()->setPlotRole(API::NumericColumn::X); auto& x = tws->getDoubleData("x"); for(size_t i = 0; i < domain->size(); ++i) { x[i] = (*domain)[i]; } for(size_t i = 0; i < cws->size(); ++i) { const std::string yColumn = "y" + boost::lexical_cast<std::string>( i ); AddFunctionValuesToTable::addColumn( tws, "x", yColumn, cws->fun(i), API::NumericColumn::Y ); } setProperty("OutputWorkspace",tws); }
numeric Item::forceNumeric() const { switch( type() ) { case FLC_ITEM_INT: return (numeric) asInteger(); case FLC_ITEM_NUM: return asNumeric(); case FLC_ITEM_RANGE: return (numeric) asRangeStart(); case FLC_ITEM_STRING: { double tgt; if ( asString()->parseDouble( tgt ) ) return tgt; return 0.0; } } return 0.0; }
int64 Item::forceInteger() const { switch( type() ) { case FLC_ITEM_INT: return asInteger(); case FLC_ITEM_NUM: return (int64) asNumeric(); case FLC_ITEM_RANGE: return (int64)asRangeStart(); case FLC_ITEM_STRING: { int64 tgt; if ( asString()->parseInt( tgt ) ) return tgt; return 0; } } return 0; }
bool Item::isTrue() const { switch( dereference()->type() ) { case FLC_ITEM_BOOL: return asBoolean() != 0; case FLC_ITEM_INT: return asInteger() != 0; case FLC_ITEM_NUM: return asNumeric() != 0.0; case FLC_ITEM_RANGE: return asRangeStart() != asRangeEnd() || asRangeIsOpen(); case FLC_ITEM_STRING: return asString()->size() != 0; case FLC_ITEM_ARRAY: return asArray()->length() != 0; case FLC_ITEM_DICT: return asDict()->length() != 0; case FLC_ITEM_FUNC: case FLC_ITEM_OBJECT: case FLC_ITEM_CLASS: case FLC_ITEM_METHOD: case FLC_ITEM_MEMBUF: case FLC_ITEM_LBIND: // methods are always filled, so they are always true. return true; } return false; }
/// 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); }