uint FgLinkGraph<NodeData,LinkData>::addLink( const LinkData & data, const vector<uint> & sources, const vector<uint> & sinks) { FGASSERT(sinks.size() > 0); // A Link must have at least 1 sink uint linkIdx = uint(m_links.size()); m_links.push_back(Link(sources,sinks,data)); // Update the node cross-referencing: for (size_t ii=0; ii<sinks.size(); ii++) { FGASSERT(sinks[ii] < uint(m_nodes.size())); FGASSERT(!fgContains(sources,sinks[ii])); // Causes nasty bugs later Node & node = m_nodes[sinks[ii]]; if (node.incomingLink.valid()) fgThrow("A FgLinkGraph node cannot be a sink for more than 1 link",fgToString(ii)); node.incomingLink = linkIdx; } for (size_t ii=0; ii<sources.size(); ii++) { FGASSERT(sources[ii] < uint(m_nodes.size())); Node & node = m_nodes[sources[ii]]; node.outgoingLinks.push_back(linkIdx); } return linkIdx; }
static void Compare() { FgString a("a"); FgString b("b"); FGASSERT(a < b); FGASSERT(!(b < a)); }
void fgRealSymmEigs( const FgMatrixV<T> &rsm, FgMatrixV<T> &val, // RETURNED: Col vector of eigenvalues, smallest to largest FgMatrixV<T> &vec) // RETURNED: Col vectors are respective eigenvectors { // JAMA enters an infinite loop with NaNs: for (size_t ii=0; ii<rsm.m_data.size(); ++ii) FGASSERT(boost::math::isfinite(rsm.m_data[ii])); uint dim = rsm.numRows(); FGASSERT(rsm.numCols() == dim); // We use a const cast since we know 'solver' will not modify the elements, even though // the Array2D object holds a non-const pointer to our data. JAMA::Eigenvalue<T> solver(TNT::Array2D<T>(rsm.numRows(),rsm.numCols(),const_cast<T*>(rsm.dataPtr()))); TNT::Array2D<T> vecs; TNT::Array1D<T> vals; solver.getV(vecs); solver.getRealEigenvalues(vals); val.resize(dim,1); vec.resize(dim,dim); int idim = static_cast<int>(dim); for (int row=0; row<idim; row++) { val[row] = vals[row]; for (uint col=0; col<dim; col++) vec.elem(row,col) = vecs[row][col]; } }
static void Replace() { { FgString original("ab"); FGASSERT(FgString("aa") == original.replace('b','a')); FGASSERT(FgString("bb") == original.replace('a','b')); } { FgString original("abcd"); FGASSERT(FgString("aacd") == original.replace('b','a')); FGASSERT(FgString("abbd") == original.replace('c','b')); } }
void FgLinkGraph<NodeData,LinkData>::appendSource( uint sourceInd, uint linkIdx) { FGASSERT(sourceInd < m_nodes.size()); FGASSERT(linkIdx < m_links.size()); m_links[linkIdx].sources.push_back(sourceInd); m_nodes[sourceInd].outgoingLinks.push_back(linkIdx); }
static void Copy() { { // Ensure that we are copying on copy FgString original("abcd"); FgString copy(original); FGASSERT(copy == original); copy += "efghi"; FGASSERT(copy != original); } }
static void Construct() { { FgString s; FGASSERT(s.length() == 0); } { FgString s("12345"); FGASSERT(s.length() == 5);} { FgString s(L"12345"); FGASSERT(s.length() == 5); } { FgString s1("12345"); FgString s2(s1); FGASSERT(s1.length() == s2.length() && s1.length() == 5); } }
static void Assign() { { FgString s; s = "12345"; FGASSERT(s.length() == 5); } { FgString s; s = L"12345"; FGASSERT(s.length() == 5); } { FgString s; s = L"12345"; FgString s1; s1 = s; FGASSERT(s1.length() == 5); } }
static void Comparisons() { { FgString s("12345"); FGASSERT(s == "12345"); FGASSERT(s == L"12345"); FGASSERT(s == FgString("12345")); FGASSERT(FgString("12345") == s); } { FgString s("12345"); FGASSERT(s != "abcdefg"); FGASSERT(s != L"Hi"); FGASSERT(s != FgString("Bye")); FGASSERT(s == "12345"); } { FgString s("abcdefg"); FGASSERT(s == "abcdefg"); FGASSERT(s != "abc"); } }
std::ostream & fgMatOstream(std::ostream& ss,const Matrix & mm) { FGASSERT(mm.numRows()*mm.numCols()>0); bool vector((mm.numRows() == 1) || mm.numCols() == 1); std::ios::fmtflags oldFlag = ss.setf( std::ios::fixed | std::ios::showpos | std::ios::right); std::streamsize oldPrec = ss.precision(6); if (vector) { ss << "[" << mm[0]; for (uint ii=1; ii<mm.numElems(); ii++) ss << "," << mm[ii]; ss << "]"; if (mm.numRows() > 1) ss << "^T"; // Indicate transpose of column vector } else { ss << fgpush; for (uint row=0; row<mm.numRows(); row++) { ss << fgnl; ss << "[ "; for (uint col=0; col<mm.numCols(); col++) ss << mm.elem(row,col) << " "; ss << "]"; } ss << fgpop; } ss.flags(oldFlag); ss.precision(oldPrec); return ss; }
void accSubMat(size_t row,size_t col,FgMatrixC<T,mrows,mcols> m) { FGASSERT((mrows+row <= nrows) && (mcols+col <= ncols)); for (uint rr=0; rr<mrows; ++rr) for (uint cc=0; cc<mcols; ++cc) elem(row+rr,col+cc) += m.elem(rr,cc); }
const FgMatrixV & operator-=(const FgMatrixV & rhs) { FGASSERT((nrows == rhs.nrows) && (ncols == rhs.ncols)); for (uint ii=0; ii<m_data.size(); ii++) m_data[ii] -= rhs.m_data[ii]; return *this; }
// Set submatrix and it's tranpose mirror submatrix from the given: void setSubMatMirror(size_t row,size_t col,const FgMatrixV & m) { // Ensure the submatrix doesn't intersect its mirror: FGASSERT((col >= (row + m.nrows)) || (row >= (col + m.ncols))); setSubMat(row,col,m); setSubMatTr(col,row,m); }
uint FgLinkGraph<NodeData,LinkData>::incomingLink( uint sinkInd) const { FGASSERT(sinkInd < m_nodes.size()); return m_nodes[sinkInd].incomingLink.val(); }
// Accumulate in sub-matrix: void accSubMat(size_t row,size_t col,const FgMatrixV & m) { FGASSERT((m.nrows+row <= nrows) && (m.ncols+col <= ncols)); for (uint rr=0; rr<m.nrows; ++rr) for (uint cc=0; cc<m.ncols; ++cc) elem(row+rr,col+cc) += m.elem(rr,cc); }
void setSubMat(const FgMatrixC<T,srows,scols> & sub,uint row,uint col) { FGASSERT((srows+row <= nrows) && (scols+col <= ncols)); for (uint rr=0; rr<srows; rr++) for (uint cc=0; cc<scols; cc++) elem(rr+row,cc+col) = sub.elem(rr,cc); }
typename FgTraits<T>::Scalar fgRmsd(const vector<T> & a,const vector<T> & b) { FGASSERT(a.size() == b.size()); typename FgTraits<T>::Scalar acc(0); for (size_t ii=0; ii<a.size(); ++ii) acc += fgLengthSqr(a[ii]-b[ii]); return std::sqrt(acc / a.size()); }
FgMatrixV operator-(const FgMatrixV & rhs) const { FgMatrixV<T> ret(nrows,ncols); FGASSERT((nrows == rhs.nrows) && (ncols == rhs.ncols)); for (uint ii=0; ii<m_data.size(); ii++) ret.m_data[ii] = m_data[ii] - rhs.m_data[ii]; return ret; }
static void StartsWith() { { FgString a("abcd"); FGASSERT(a.beginsWith(FgString("a"))); FGASSERT(a.beginsWith(FgString("ab"))); FGASSERT(a.beginsWith(FgString("abc"))); FGASSERT(a.beginsWith(FgString("abcd"))); FGASSERT(!a.beginsWith(FgString("d"))); FGASSERT(!a.beginsWith(FgString("db"))); FGASSERT(!a.beginsWith(FgString("dbc"))); FGASSERT(!a.beginsWith(FgString("dbcd"))); FGASSERT(!a.beginsWith(FgString("abcde"))); } { FgString a("a kind of longish string to test with since small strings may hide some bugs"); FGASSERT(a.beginsWith(FgString("a kind of longish string to test with"))); } }
FgMatrixV<T> fgDiagonal(const FgMatrixV<T> & vec) { FGASSERT((vec.numRows() == 1) || (vec.numCols() == 1)); uint dim = vec.numRows() * vec.numCols(); FgMatrixV<T> ret(dim,dim,T(0)); for (uint ii=0; ii<dim; ++ii) ret.elem(ii,ii) = vec[ii]; return ret; }
typename FgTraits<T>::Accumulator fgDot( const vector<FgMatrixC<T,nrows,ncols> > & v0, const vector<FgMatrixC<T,nrows,ncols> > & v1) { FGASSERT(v0.size() == v1.size()); typename FgTraits<T>::Accumulator acc(0); for (size_t ii=0; ii<v0.size(); ++ii) acc += fgDot(v0[ii],v1[ii]); return acc; }
T fgExp(T val,bool clamp=false) { static T maxIn = std::log(std::numeric_limits<T>::max()); if (std::abs(val) < maxIn) return std::exp(val); FGASSERT(clamp); if (val < maxIn) return -std::numeric_limits<T>::max(); return std::numeric_limits<T>::max(); }
T fgSsd( const vector<FgMatrixC<T,nrows,ncols> > & v0, const vector<FgMatrixC<T,nrows,ncols> > & v1) { FGASSERT(v0.size() == v1.size()); double acc(0); for (size_t ii=0; ii<v0.size(); ++ii) acc += (v1[ii]-v0[ii]).lengthSqr(); return T(acc); }
FgMatrixV<T> fgConcatVert( const FgMatrixV<T> & upper, const FgMatrixV<T> & middle, const FgMatrixV<T> & lower) { FGASSERT(upper.numCols() == middle.numCols()); FGASSERT(middle.numCols() == lower.numCols()); FgMatrixV<T> retval(upper.numRows()+middle.numRows()+lower.numRows(),upper.numCols()); uint row=0; for (uint rr=0; rr<upper.numRows(); rr++) for (uint col=0; col<upper.numCols(); col++) retval.elem(row++,col) = upper.elem(rr,col); for (uint rr=0; rr<middle.numRows(); rr++) for (uint col=0; col<middle.numCols(); col++) retval.elem(row++,col) = middle.elem(rr,col); for (uint rr=0; rr<lower.numRows(); rr++) for (uint col=0; col<lower.numCols(); col++) retval.elem(row++,col) = lower.elem(rr,col); return retval; }
FgMatrixV<T> fgModulateCols( const FgMatrixV<T> & matrix, const FgMatrixV<T> & modVector) { FGASSERT(matrix.numCols() == modVector.numElems()); FgMatrixD ret = matrix; for (uint rr=0; rr<matrix.numRows(); ++rr) for (uint cc=0; cc<matrix.numCols(); ++cc) ret.elem(rr,cc) *= modVector[cc]; return ret; }
FgMatrixC<T,1,2> fgBounds(const FgMatrixC<T,nrows,ncols> & mat) { FGASSERT(mat.numElems() > 0); FgMatrixC<T,1,2> ret(mat[0]); for (uint ii=0; ii<mat.numElems(); ++ii) { fgSetIfLess (ret[0],mat[ii]); fgSetIfGreater (ret[1],mat[ii]); } return ret; }
FgMatrixC<T,1,2> fgBounds(const std::vector<T> & data) { FGASSERT(data.size() > 0); FgMatrixC<T,1,2> ret(data[0]); for (size_t ii=1; ii<data.size(); ++ii) { fgSetIfLess (ret[0],data[ii]); fgSetIfGreater (ret[1],data[ii]); } return ret; }
static void Encoding() { { // Character as Unicode code point uint32 character = 0x0161; // Same character as UTF-8 encoded string FgString fg_character("\xC5\xA1"); FGASSERT(character == fg_character[0]); } { FgString source("UTF-8:\xC5\xA1\xC4\x8E"); FgTempFile tf("testString_utf8.txt"); { std::ofstream ofs(tf.filename().c_str()); FGASSERT(ofs); ofs << source << std::endl; } { std::ifstream ifs(tf.filename().c_str()); FGASSERT(ifs); FgString target; ifs >> target; FGASSERT(source == target); } } }
FgMatrixV operator*(const FgMatrixV & m) const { FgMatrixV<T> newMat(nrows,m.ncols); FGASSERT(ncols == m.nrows); for (uint ii=0; ii<nrows; ii++) { for (uint jj=0; jj<m.ncols; jj++) { newMat.elem(ii,jj) = 0.0; for (uint kk=0; kk<ncols; kk++) newMat.elem(ii,jj) += this->elem(ii,kk) * m.elem(kk,jj); } } return newMat; }
// Construct from bounding box mapping: FgAffineCwC( const FgMatrixC<T,dim,2> & domainBounds, // Column vectors are lo and hi bounds resp. const FgMatrixC<T,dim,2> & rangeBounds) // " { FgMatrixC<T,dim,1> domainDelta = domainBounds.colVec(1) - domainBounds.colVec(0), rangeDelta = rangeBounds.colVec(1) - rangeBounds.colVec(0); // Note that the deltas can be negative if the transform inverts an axis: FGASSERT(fgNoZeros(domainDelta) && fgNoZeros(rangeDelta)); for (uint dd=0; dd<dim; ++dd) { m_scales[dd] = rangeDelta[dd] / domainDelta[dd]; m_trans[dd] = rangeBounds.elm(0,dd) - domainBounds.elm(0,dd) * m_scales[dd]; } }