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]; } }
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; }
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; }
FgMatrixV<T> fgConcatVert( const FgMatrixV<T> & upper, const FgMatrixV<T> & lower) { if (upper.empty()) return lower; if (lower.empty()) return upper; FGASSERT(upper.numCols() == lower.numCols()); FgMatrixV<T> ret(upper.numRows()+lower.numRows(),upper.numCols()); for (uint ii=0; ii<upper.numElems(); ++ii) ret[ii] = upper[ii]; uint off = upper.numElems(); for (uint ii=0; ii<lower.numElems(); ++ii) ret[off+ii] = lower[ii]; return ret; }
FgMatrixV<T> fgConcatHoriz( const FgMatrixV<T> & left, const FgMatrixV<T> & right) { if (left.empty()) return right; if (right.empty()) return left; FGASSERT(left.numRows() == right.numRows()); uint numRows = left.numRows(), numCols = left.numCols() + right.numCols(); FgMatrixV<T> retval(numRows,numCols); for (uint rr=0; rr<numRows; rr++) { uint col=0; for (uint cc=0; cc<left.numCols(); ++cc) retval.elem(rr,col++) = left.elem(rr,cc); for (uint cc=0; cc<right.numCols(); ++cc) retval.elem(rr,col++) = right.elem(rr,cc); } return retval; }
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; }
explicit FgMatrixC(const FgMatrixV<T>& mm) { FGASSERT((nrows == mm.numRows()) && (ncols == mm.numCols())); for (uint ii=0; ii<nrows*ncols; ++ii) m[ii] = mm[ii]; }