36 #ifndef OPENVDB_MATH_CONJGRADIENT_HAS_BEEN_INCLUDED 37 #define OPENVDB_MATH_CONJGRADIENT_HAS_BEEN_INCLUDED 44 #include <boost/shared_ptr.hpp> 45 #include <boost/scoped_array.hpp> 46 #include <tbb/parallel_for.h> 47 #include <tbb/parallel_reduce.h> 65 template<
typename ValueType>
class Vector;
83 template<
typename ValueType>
91 s.
absoluteError = std::numeric_limits<ValueType>::epsilon() * 100.0;
118 template<
typename PositiveDefMatrix>
121 const PositiveDefMatrix& A,
125 const State& termination = terminationDefaults<typename PositiveDefMatrix::ValueType>());
150 template<
typename PositiveDefMatrix,
typename Interrupter>
153 const PositiveDefMatrix& A,
157 Interrupter& interrupter,
158 const State& termination = terminationDefaults<typename PositiveDefMatrix::ValueType>());
170 typedef boost::shared_ptr<Vector>
Ptr;
175 Vector(SizeType n): mData(new T[n]), mSize(n) {}
177 Vector(SizeType n,
const ValueType& val): mData(new T[n]), mSize(n) { this->fill(val); }
179 ~Vector() { mSize = 0;
delete[] mData; mData = NULL; }
187 SizeType
size()
const {
return mSize; }
189 bool empty()
const {
return (mSize == 0); }
193 void resize(SizeType n);
196 void swap(
Vector& other) { std::swap(mData, other.mData); std::swap(mSize, other.mSize); }
199 void fill(
const ValueType& value);
202 template<
typename Scalar>
void scale(
const Scalar& s);
208 ValueType dot(
const Vector&)
const;
211 ValueType infNorm()
const;
220 template<
typename OtherValueType>
225 std::string str()
const;
228 inline T& at(SizeType i) {
return mData[i]; }
230 inline const T&
at(SizeType i)
const {
return mData[i]; }
232 inline const T&
operator[](SizeType i)
const {
return this->at(i); }
236 inline T* data() {
return mData; }
238 inline const T*
data()
const {
return mData; }
244 template<
typename Scalar>
struct ScaleOp;
245 struct DeterministicDotProductOp;
247 template<
typename OtherValueType>
struct EqOp;
265 template<
typename ValueType_, SizeType STENCIL_SIZE>
271 typedef boost::shared_ptr<SparseStencilMatrix>
Ptr;
273 class ConstValueIter;
286 SizeType numRows()
const {
return mNumRows; }
288 SizeType
size()
const {
return mNumRows; }
294 void setValue(SizeType row, SizeType col,
const ValueType&);
297 const ValueType& getValue(SizeType row, SizeType col)
const;
301 const ValueType& operator()(SizeType row, SizeType col)
const;
305 ConstRow getConstRow(SizeType row)
const;
308 RowEditor getRowEditor(SizeType row);
311 template<
typename Scalar>
void scale(
const Scalar& s);
313 template<
typename Scalar>
320 template<
typename VecValueType>
327 template<
typename VecValueType>
328 void vectorMultiply(
const VecValueType* inVec, VecValueType* resultVec)
const;
332 template<
typename OtherValueType>
340 std::string str()
const;
344 RowData(ValueType* v, SizeType* c, SizeType& s): mVals(v), mCols(c), mSize(s) {}
345 ValueType* mVals; SizeType* mCols; SizeType& mSize;
348 struct ConstRowData {
349 ConstRowData(
const ValueType* v,
const SizeType* c,
const SizeType& s):
350 mVals(v), mCols(c), mSize(s) {}
351 const ValueType* mVals;
const SizeType* mCols;
const SizeType& mSize;
355 template<
typename DataType_ = RowData>
359 typedef DataType_ DataType;
361 static SizeType capacity() {
return STENCIL_SIZE; }
363 RowBase(
const DataType& data): mData(data) {}
365 bool empty()
const {
return (mData.mSize == 0); }
366 const SizeType& size()
const {
return mData.mSize; }
368 const ValueType& getValue(SizeType columnIdx,
bool& active)
const;
369 const ValueType& getValue(SizeType columnIdx)
const;
372 ConstValueIter cbegin()
const;
376 template<
typename OtherDataType>
377 bool eq(
const RowBase<OtherDataType>& other,
383 template<
typename VecValueType>
384 VecValueType dot(
const VecValueType* inVec, SizeType vecSize)
const;
387 template<
typename VecValueType>
391 std::string str()
const;
394 friend class ConstValueIter;
396 const ValueType& value(SizeType i)
const {
return mData.mVals[i]; }
397 SizeType column(SizeType i)
const {
return mData.mCols[i]; }
403 SizeType find(SizeType columnIdx)
const;
408 typedef RowBase<ConstRowData> ConstRowBase;
417 if (mData.mSize == 0)
return SparseStencilMatrix::sZeroValue;
418 return mData.mVals[mCursor];
421 SizeType
column()
const {
return mData.mCols[mCursor]; }
425 operator bool()
const {
return (mCursor < mData.mSize); }
431 ConstValueIter(
const RowData& d): mData(d.mVals, d.mCols, d.mSize), mCursor(0) {}
434 const ConstRowData mData;
443 ConstRow(
const ValueType* valueHead,
const SizeType* columnHead,
const SizeType& rowSize);
451 RowEditor(ValueType* valueHead, SizeType* columnHead, SizeType& rowSize, SizeType colSize);
458 SizeType setValue(SizeType column,
const ValueType& value);
461 template<
typename Scalar>
void scale(
const Scalar&);
463 template<
typename Scalar>
468 const SizeType mNumColumns;
474 template<
typename VecValueType>
struct VecMultOp;
475 template<
typename Scalar>
struct RowScaleOp;
479 template<
typename OtherValueType>
struct EqOp;
481 const SizeType mNumRows;
482 boost::scoped_array<ValueType> mValueArray;
483 boost::scoped_array<SizeType> mColumnIdxArray;
484 boost::scoped_array<SizeType> mRowSizeArray;
497 typedef boost::shared_ptr<Preconditioner>
Ptr;
521 CopyOp(
const T* from_, T* to_): from(from_), to(to_) {}
524 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) to[n] = from[n];
536 FillOp(T* data_,
const T& val_): data(data_), val(val_) {}
539 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) data[n] = val;
551 LinearOp(
const T& a_,
const T* x_,
const T* y_, T* out_): a(a_), x(x_), y(y_), out(out_) {}
555 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) out[n] = x[n] + y[n];
557 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) out[n] = -x[n] + y[n];
559 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) out[n] = a * x[n] + y[n];
576 os << (state.
success ?
"succeeded with " :
"")
601 if (mSize != other.mSize) {
604 mData =
new T[mSize];
620 if (mData)
delete[] mData;
636 template<
typename Scalar>
639 ScaleOp(T* data_,
const Scalar& s_): data(data_), s(s_) {}
641 void operator()(
const SizeRange& range)
const {
642 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) data[n] *= s;
651 template<
typename Scalar>
655 tbb::parallel_for(
SizeRange(0, mSize), ScaleOp<Scalar>(mData, s));
663 const SizeType binCount_,
const SizeType arraySize_, T* reducetmp_):
664 a(a_), b(b_), binCount(binCount_), arraySize(arraySize_), reducetmp(reducetmp_) {}
669 const SizeType binSize = arraySize / binCount;
672 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
673 const SizeType begin = n * binSize;
674 const SizeType end = (n == binCount-1) ? arraySize : begin + binSize;
677 T sum = zeroVal<T>();
678 for (SizeType i = begin; i < end; ++i) {
699 assert(this->size() == other.
size());
701 const T* aData = this->data();
702 const T* bData = other.
data();
704 SizeType arraySize = this->size();
706 T result = zeroVal<T>();
708 if (arraySize < 1024) {
712 for (SizeType n = 0; n < arraySize; ++n) {
713 result += aData[n] * bData[n];
722 const SizeType binCount = 100;
725 tbb::parallel_for(
SizeRange(0, binCount),
726 DeterministicDotProductOp(aData, bData, binCount, arraySize, partialSums));
728 for (SizeType n = 0; n < binCount; ++n) {
729 result += partialSums[n];
744 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
745 maxValue =
Max(maxValue,
Abs(data[n]));
750 static T
join(T max1, T max2) {
return Max(max1, max2); }
761 T result = tbb::parallel_reduce(
SizeRange(0, this->size()), zeroVal<T>(),
762 InfNormOp(this->data()), InfNormOp::join);
775 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
776 if (!std::isfinite(data[n]))
return false;
782 static bool join(
bool finite1,
bool finite2) {
return (finite1 && finite2); }
793 bool finite = tbb::parallel_reduce(
SizeRange(0, this->size()),
true,
794 IsFiniteOp(this->data()), IsFiniteOp::join);
800 template<
typename OtherValueType>
803 EqOp(
const T* a_,
const OtherValueType* b_, T e): a(a_), b(b_), eps(e) {}
805 bool operator()(
const SizeRange& range,
bool equal)
const 808 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
815 static bool join(
bool eq1,
bool eq2) {
return (eq1 && eq2); }
818 const OtherValueType* b;
824 template<
typename OtherValueType>
828 if (this->size() != other.
size())
return false;
829 bool equal = tbb::parallel_reduce(
SizeRange(0, this->size()),
true,
830 EqOp<OtherValueType>(this->data(), other.
data(), eps), EqOp<OtherValueType>::join);
839 std::ostringstream ostr;
842 for (SizeType n = 0, N = this->size(); n < N; ++n) {
843 ostr << sep << (*this)[n];
854 template<
typename ValueType, SizeType STENCIL_SIZE>
858 template<
typename ValueType, SizeType STENCIL_SIZE>
862 , mValueArray(new
ValueType[mNumRows * STENCIL_SIZE])
863 , mColumnIdxArray(new SizeType[mNumRows * STENCIL_SIZE])
864 , mRowSizeArray(new SizeType[mNumRows])
867 tbb::parallel_for(
SizeRange(0, mNumRows),
872 template<
typename ValueType, SizeType STENCIL_SIZE>
876 from(&from_), to(&to_) {}
880 const ValueType* fromVal = from->mValueArray.get();
881 const SizeType* fromCol = from->mColumnIdxArray.get();
882 ValueType* toVal = to->mValueArray.get();
883 SizeType* toCol = to->mColumnIdxArray.get();
884 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
885 toVal[n] = fromVal[n];
886 toCol[n] = fromCol[n];
894 template<
typename ValueType, SizeType STENCIL_SIZE>
897 : mNumRows(other.mNumRows)
898 , mValueArray(new
ValueType[mNumRows * STENCIL_SIZE])
899 , mColumnIdxArray(new SizeType[mNumRows * STENCIL_SIZE])
900 , mRowSizeArray(new SizeType[mNumRows])
902 SizeType size = mNumRows * STENCIL_SIZE;
905 tbb::parallel_for(
SizeRange(0, size), MatrixCopyOp(other, *
this));
908 tbb::parallel_for(
SizeRange(0, mNumRows),
913 template<
typename ValueType, SizeType STENCIL_SIZE>
918 assert(row < mNumRows);
919 this->getRowEditor(row).setValue(col, val);
923 template<
typename ValueType, SizeType STENCIL_SIZE>
927 assert(row < mNumRows);
928 return this->getConstRow(row).getValue(col);
932 template<
typename ValueType, SizeType STENCIL_SIZE>
936 return this->getValue(row,col);
940 template<
typename ValueType, SizeType STENCIL_SIZE>
941 template<
typename Scalar>
946 void operator()(
const SizeRange& range)
const 948 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
949 RowEditor row = mat->getRowEditor(n);
959 template<
typename ValueType, SizeType STENCIL_SIZE>
960 template<
typename Scalar>
965 tbb::parallel_for(
SizeRange(0, mNumRows), RowScaleOp<Scalar>(*
this, s));
969 template<
typename ValueType, SizeType STENCIL_SIZE>
970 template<
typename VecValueType>
974 mat(&m), in(i), out(o) {}
976 void operator()(
const SizeRange& range)
const 978 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
979 ConstRow row = mat->getConstRow(n);
980 out[n] = row.dot(in, mat->numRows());
985 const VecValueType* in;
990 template<
typename ValueType, SizeType STENCIL_SIZE>
991 template<
typename VecValueType>
996 if (inVec.
size() != mNumRows) {
998 << mNumRows <<
"x" << mNumRows <<
" vs. " << inVec.
size() <<
")");
1000 if (resultVec.
size() != mNumRows) {
1002 << mNumRows <<
"x" << mNumRows <<
" vs. " << resultVec.
size() <<
")");
1005 vectorMultiply(inVec.
data(), resultVec.
data());
1009 template<
typename ValueType, SizeType STENCIL_SIZE>
1010 template<
typename VecValueType>
1013 const VecValueType* inVec, VecValueType* resultVec)
const 1016 tbb::parallel_for(
SizeRange(0, mNumRows),
1017 VecMultOp<VecValueType>(*
this, inVec, resultVec));
1021 template<
typename ValueType, SizeType STENCIL_SIZE>
1022 template<
typename OtherValueType>
1027 a(&a_), b(&b_), eps(e) {}
1029 bool operator()(
const SizeRange& range,
bool equal)
const 1032 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
1033 if (!a->getConstRow(n).eq(b->getConstRow(n), eps))
return false;
1039 static bool join(
bool eq1,
bool eq2) {
return (eq1 && eq2); }
1043 const ValueType eps;
1047 template<
typename ValueType, SizeType STENCIL_SIZE>
1048 template<
typename OtherValueType>
1053 if (this->numRows() != other.
numRows())
return false;
1054 bool equal = tbb::parallel_reduce(
SizeRange(0, this->numRows()),
true,
1055 EqOp<OtherValueType>(*
this, other, eps), EqOp<OtherValueType>::join);
1060 template<
typename ValueType, SizeType STENCIL_SIZE>
1068 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
1069 const ConstRow row = mat->getConstRow(n);
1071 if (!std::isfinite(*it))
return false;
1078 static bool join(
bool finite1,
bool finite2) {
return (finite1 && finite2); }
1084 template<
typename ValueType, SizeType STENCIL_SIZE>
1089 bool finite = tbb::parallel_reduce(
SizeRange(0, this->numRows()),
true,
1090 IsFiniteOp(*
this), IsFiniteOp::join);
1095 template<
typename ValueType, SizeType STENCIL_SIZE>
1099 std::ostringstream ostr;
1100 for (SizeType n = 0, N = this->size(); n < N; ++n) {
1101 ostr << n <<
": " << this->getConstRow(n).
str() <<
"\n";
1107 template<
typename ValueType, SizeType STENCIL_SIZE>
1111 assert(i < mNumRows);
1112 const SizeType head = i * STENCIL_SIZE;
1113 return RowEditor(&mValueArray[head], &mColumnIdxArray[head], mRowSizeArray[i], mNumRows);
1117 template<
typename ValueType, SizeType STENCIL_SIZE>
1121 assert(i < mNumRows);
1122 const SizeType head = i * STENCIL_SIZE;
1123 return ConstRow(&mValueArray[head], &mColumnIdxArray[head], mRowSizeArray[i]);
1127 template<
typename ValueType, SizeType STENCIL_SIZE>
1128 template<
typename DataType>
1132 if (this->empty())
return mData.mSize;
1136 const SizeType* colPtr = std::lower_bound(mData.mCols, mData.mCols + mData.mSize, columnIdx);
1138 return static_cast<SizeType
>(colPtr - mData.mCols);
1142 template<
typename ValueType, SizeType STENCIL_SIZE>
1143 template<
typename DataType>
1144 inline const ValueType&
1146 SizeType columnIdx,
bool& active)
const 1149 SizeType idx = this->find(columnIdx);
1150 if (idx < this->size() && this->column(idx) == columnIdx) {
1152 return this->value(idx);
1154 return SparseStencilMatrix::sZeroValue;
1157 template<
typename ValueType, SizeType STENCIL_SIZE>
1158 template<
typename DataType>
1159 inline const ValueType&
1162 SizeType idx = this->find(columnIdx);
1163 if (idx < this->size() && this->column(idx) == columnIdx) {
1164 return this->value(idx);
1166 return SparseStencilMatrix::sZeroValue;
1170 template<
typename ValueType, SizeType STENCIL_SIZE>
1171 template<
typename DataType>
1175 return ConstValueIter(mData);
1179 template<
typename ValueType, SizeType STENCIL_SIZE>
1180 template<
typename DataType>
1181 template<
typename OtherDataType>
1184 const RowBase<OtherDataType>& other, ValueType eps)
const 1186 if (this->size() != other.size())
return false;
1187 for (ConstValueIter it = cbegin(), oit = other.cbegin(); it || oit; ++it, ++oit) {
1188 if (it.column() != oit.column())
return false;
1195 template<
typename ValueType, SizeType STENCIL_SIZE>
1196 template<
typename DataType>
1197 template<
typename VecValueType>
1200 const VecValueType* inVec, SizeType vecSize)
const 1202 VecValueType result = zeroVal<VecValueType>();
1203 for (SizeType idx = 0, N =
std::min(vecSize, this->size()); idx < N; ++idx) {
1204 result +=
static_cast<VecValueType
>(this->value(idx) * inVec[this->column(idx)]);
1209 template<
typename ValueType, SizeType STENCIL_SIZE>
1210 template<
typename DataType>
1211 template<
typename VecValueType>
1216 return dot(inVec.
data(), inVec.
size());
1220 template<
typename ValueType, SizeType STENCIL_SIZE>
1221 template<
typename DataType>
1225 std::ostringstream ostr;
1227 for (SizeType n = 0, N = this->size(); n < N; ++n) {
1228 ostr << sep <<
"(" << this->column(n) <<
", " << this->value(n) <<
")";
1235 template<
typename ValueType, SizeType STENCIL_SIZE>
1238 const ValueType* valueHead,
const SizeType* columnHead,
const SizeType& rowSize):
1239 ConstRowBase(ConstRowData(const_cast<ValueType*>(valueHead),
1240 const_cast<SizeType*>(columnHead), const_cast<SizeType&>(rowSize)))
1245 template<
typename ValueType, SizeType STENCIL_SIZE>
1248 ValueType* valueHead, SizeType* columnHead, SizeType& rowSize, SizeType colSize):
1249 RowBase<>(RowData(valueHead, columnHead, rowSize)), mNumColumns(colSize)
1254 template<
typename ValueType, SizeType STENCIL_SIZE>
1259 RowBase<>::mData.mSize = 0;
1263 template<
typename ValueType, SizeType STENCIL_SIZE>
1266 SizeType column,
const ValueType& value)
1268 assert(column < mNumColumns);
1270 RowData& data = RowBase<>::mData;
1274 SizeType offset = this->find(column);
1276 if (offset < data.mSize && data.mCols[offset] == column) {
1278 data.mVals[offset] = value;
1283 assert(data.mSize < this->capacity());
1285 if (offset >= data.mSize) {
1287 data.mVals[data.mSize] = value;
1288 data.mCols[data.mSize] = column;
1291 for (SizeType i = data.mSize; i > offset; --i) {
1292 data.mVals[i] = data.mVals[i - 1];
1293 data.mCols[i] = data.mCols[i - 1];
1295 data.mVals[offset] = value;
1296 data.mCols[offset] = column;
1304 template<
typename ValueType, SizeType STENCIL_SIZE>
1305 template<
typename Scalar>
1309 for (
int idx = 0, N = this->size(); idx < N; ++idx) {
1310 RowBase<>::mData.mVals[idx] *= s;
1319 template<
typename MatrixType>
1327 typedef typename MatrixType::ValueType
ValueType;
1330 typedef boost::shared_ptr<JacobiPreconditioner>
Ptr;
1335 tbb::parallel_for(
SizeRange(0, A.numRows()), InitOp(A, mDiag.data()));
1342 const SizeType size = mDiag.size();
1345 assert(r.
size() == size);
1347 tbb::parallel_for(
SizeRange(0, size), ApplyOp(mDiag.data(), r.
data(), z.
data()));
1357 InitOp(
const MatrixType& m, ValueType* v): mat(&m), vec(v) {}
1358 void operator()(
const SizeRange& range)
const {
1359 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
1360 const ValueType val = mat->getValue(n, n);
1362 vec[n] =
static_cast<ValueType
>(1.0 / val);
1365 const MatrixType* mat; ValueType* vec;
1371 ApplyOp(
const ValueType* x_,
const ValueType* y_, ValueType* out_):
1372 x(x_), y(y_), out(out_) {}
1373 void operator()(
const SizeRange& range)
const {
1374 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) out[n] = x[n] * y[n];
1376 const ValueType *x, *y; ValueType* out;
1385 template<
typename MatrixType>
1389 struct CopyToLowerOp;
1393 typedef typename MatrixType::ValueType
ValueType;
1396 typedef boost::shared_ptr<IncompleteCholeskyPreconditioner>
Ptr;
1403 , mLowerTriangular(matrix.
numRows())
1404 , mUpperTriangular(matrix.
numRows())
1408 const SizeType
numRows = mLowerTriangular.numRows();
1411 tbb::parallel_for(
SizeRange(0, numRows), CopyToLowerOp(matrix, mLowerTriangular));
1431 mPassedCompatibilityCondition =
true;
1433 for (SizeType k = 0; k <
numRows; ++k) {
1435 TriangleConstRow crow_k = mLowerTriangular.getConstRow(k);
1436 ValueType diagonalValue = crow_k.getValue(k);
1439 if (diagonalValue < 1.e-5) {
1440 mPassedCompatibilityCondition =
false;
1444 diagonalValue =
Sqrt(diagonalValue);
1446 TriangleRowEditor row_k = mLowerTriangular.getRowEditor(k);
1447 row_k.setValue(k, diagonalValue);
1450 typename MatrixType::ConstRow srcRow = matrix.getConstRow(k);
1451 typename MatrixType::ConstValueIter citer = srcRow.cbegin();
1452 for ( ; citer; ++citer) {
1453 SizeType ii = citer.column();
1454 if (ii < k+1)
continue;
1456 TriangleRowEditor row_ii = mLowerTriangular.getRowEditor(ii);
1458 row_ii.setValue(k, *citer / diagonalValue);
1463 for ( ; citer; ++citer) {
1464 SizeType j = citer.column();
1465 if (j < k+1)
continue;
1467 TriangleConstRow row_j = mLowerTriangular.getConstRow(j);
1468 ValueType a_jk = row_j.getValue(k);
1472 typename MatrixType::ConstRow mask = matrix.getConstRow(j);
1473 typename MatrixType::ConstValueIter maskIter = mask.cbegin();
1474 for ( ; maskIter; ++maskIter) {
1475 SizeType i = maskIter.column();
1476 if (i < j)
continue;
1478 TriangleConstRow crow_i = mLowerTriangular.getConstRow(i);
1479 ValueType a_ij = crow_i.getValue(j);
1480 ValueType a_ik = crow_i.getValue(k);
1481 TriangleRowEditor row_i = mLowerTriangular.getRowEditor(i);
1482 a_ij -= a_ik * a_jk;
1484 row_i.setValue(j, a_ij);
1490 tbb::parallel_for(
SizeRange(0, numRows),
1491 TransposeOp(matrix, mLowerTriangular, mUpperTriangular));
1496 virtual bool isValid()
const {
return mPassedCompatibilityCondition; }
1500 if (!mPassedCompatibilityCondition) {
1506 SizeType size = mLowerTriangular.numRows();
1508 zVec.
fill(zeroVal<ValueType>());
1509 ValueType* zData = zVec.
data();
1511 if (size == 0)
return;
1513 assert(rVec.
size() == size);
1514 assert(zVec.
size() == size);
1517 mTempVec.fill(zeroVal<ValueType>());
1518 ValueType* tmpData = mTempVec.data();
1519 const ValueType* rData = rVec.
data();
1522 for (SizeType i = 0; i < size; ++i) {
1523 typename TriangularMatrix::ConstRow row = mLowerTriangular.getConstRow(i);
1524 ValueType diagonal = row.getValue(i);
1525 ValueType dot = row.dot(mTempVec);
1526 tmpData[i] = (rData[i] - dot) / diagonal;
1527 if (!std::isfinite(tmpData[i])) {
1534 for (SizeType ii = 0; ii < size; ++ii) {
1535 SizeType i = size - 1 - ii;
1536 typename TriangularMatrix::ConstRow row = mUpperTriangular.getConstRow(i);
1537 ValueType diagonal = row.getValue(i);
1538 ValueType dot = row.dot(zVec);
1539 zData[i] = (tmpData[i] - dot) / diagonal;
1540 if (!std::isfinite(zData[i])) {
1546 const TriangularMatrix&
lowerMatrix()
const {
return mLowerTriangular; }
1547 const TriangularMatrix&
upperMatrix()
const {
return mUpperTriangular; }
1551 struct CopyToLowerOp
1553 CopyToLowerOp(
const MatrixType& m, TriangularMatrix& l): mat(&m), lower(&l) {}
1554 void operator()(
const SizeRange& range)
const {
1555 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
1556 typename TriangularMatrix::RowEditor outRow = lower->getRowEditor(n);
1558 typename MatrixType::ConstRow inRow = mat->getConstRow(n);
1559 for (
typename MatrixType::ConstValueIter it = inRow.cbegin(); it; ++it) {
1560 if (it.column() > n)
continue;
1561 outRow.setValue(it.column(), *it);
1565 const MatrixType* mat; TriangularMatrix* lower;
1571 TransposeOp(
const MatrixType& m,
const TriangularMatrix& l, TriangularMatrix& u):
1572 mat(&m), lower(&l), upper(&u) {}
1573 void operator()(
const SizeRange& range)
const {
1574 for (SizeType n = range.begin(), N = range.end(); n < N; ++n) {
1575 typename TriangularMatrix::RowEditor outRow = upper->getRowEditor(n);
1578 typename MatrixType::ConstRow inRow = mat->getConstRow(n);
1579 for (
typename MatrixType::ConstValueIter it = inRow.cbegin(); it; ++it) {
1580 const SizeType column = it.column();
1581 if (column < n)
continue;
1582 outRow.setValue(column, lower->getValue(column, n));
1586 const MatrixType* mat;
const TriangularMatrix* lower; TriangularMatrix* upper;
1589 TriangularMatrix mLowerTriangular;
1590 TriangularMatrix mUpperTriangular;
1592 bool mPassedCompatibilityCondition;
1599 namespace internal {
1602 template<
typename T>
1604 axpy(
const T& a,
const T* xVec,
const T* yVec, T* resultVec, SizeType size)
1610 template<
typename T>
1614 assert(xVec.
size() == yVec.
size());
1615 assert(xVec.
size() == result.
size());
1621 template<
typename MatrixOperator,
typename VecValueType>
1624 const VecValueType* b, VecValueType* r)
1627 A.vectorMultiply(x, r);
1633 template<
typename MatrixOperator,
typename T>
1639 assert(x.
size() == A.numRows());
1650 template<
typename PositiveDefMatrix>
1653 const PositiveDefMatrix& Amat,
1657 const State& termination)
1660 return solve(Amat, bVec, xVec, precond, interrupter, termination);
1664 template<
typename PositiveDefMatrix,
typename Interrupter>
1667 const PositiveDefMatrix& Amat,
1671 Interrupter& interrupter,
1672 const State& termination)
1674 typedef typename PositiveDefMatrix::ValueType
ValueType;
1683 const SizeType size = Amat.numRows();
1688 if (size != bVec.
size()) {
1690 << size <<
"x" << size <<
" vs. " << bVec.
size() <<
")");
1692 if (size != xVec.
size()) {
1694 << size <<
"x" << size <<
" vs. " << xVec.
size() <<
")");
1698 VectorType zVec(size);
1699 VectorType pVec(size);
1700 VectorType qVec(size);
1703 const ValueType tmp = bVec.
infNorm();
1704 const ValueType infNormOfB =
isZero(tmp) ? 1.f : tmp;
1707 VectorType rVec(size);
1711 assert(rVec.isFinite());
1723 ValueType rDotZPrev(1);
1730 for ( ; iteration < termination.
iterations; ++iteration) {
1732 if (interrupter.wasInterrupted()) {
1742 precond.
apply(rVec, zVec);
1745 const ValueType rDotZ = rVec.dot(zVec);
1746 assert(std::isfinite(rDotZ));
1748 if (0 == iteration) {
1752 const ValueType beta = rDotZ / rDotZPrev;
1758 Amat.vectorMultiply(pVec, qVec);
1761 const ValueType pAp = pVec.dot(qVec);
1762 assert(std::isfinite(pAp));
1764 const ValueType alpha = rDotZ / pAp;
1774 l2Error = rVec.l2Norm();
1775 minL2Error =
Min(l2Error, minL2Error);
1780 if (l2Error > 2 * minL2Error) {
1811 #endif // OPENVDB_MATH_CONJGRADIENT_HAS_BEEN_INCLUDED virtual void apply(const Vector< ValueType > &r, Vector< ValueType > &z)
Apply this preconditioner to a residue vector: z = M−1r
Definition: ConjGradient.h:1340
const T val
Definition: ConjGradient.h:543
Vector(SizeType n, const ValueType &val)
Construct a vector of n elements and initialize each element to the given value.
Definition: ConjGradient.h:177
boost::shared_ptr< Preconditioner > Ptr
Definition: ConjGradient.h:497
const T * data() const
Return a pointer to this vector's elements.
Definition: ConjGradient.h:238
boost::shared_ptr< SparseStencilMatrix > Ptr
Definition: ConjGradient.h:271
void operator()(const SizeRange &range) const
Definition: ConjGradient.h:553
virtual void apply(const Vector< ValueType > &rVec, Vector< ValueType > &zVec)
Apply this preconditioner to a residue vector: z = M−1r
Definition: ConjGradient.h:1498
MatrixCopyOp(const SparseStencilMatrix &from_, SparseStencilMatrix &to_)
Definition: ConjGradient.h:875
Coord Abs(const Coord &xyz)
Definition: Coord.h:247
RowEditor & operator*=(const Scalar &s)
Scale all of the entries in this row.
Definition: ConjGradient.h:464
static T join(T max1, T max2)
Definition: ConjGradient.h:750
ValueType infNorm() const
Return the infinity norm of this vector.
Definition: ConjGradient.h:758
void computeResidual(const MatrixOperator &A, const VecValueType *x, const VecValueType *b, VecValueType *r)
Compute r = b − Ax.
Definition: ConjGradient.h:1623
Lightweight, variable-length vector.
Definition: ConjGradient.h:65
SparseStencilMatrix & operator*=(const Scalar &s)
Multiply all elements in the matrix by s;.
Definition: ConjGradient.h:314
void axpy(const T &a, const T *xVec, const T *yVec, T *resultVec, SizeType size)
Compute ax + y.
Definition: ConjGradient.h:1604
void operator()(const SizeRange &range) const
Definition: ConjGradient.h:538
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
Iterator over the stored values in a row of this matrix.
Definition: ConjGradient.h:412
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Dummy NOOP interrupter class defining interface.
Definition: NullInterrupter.h:52
SizeType setValue(SizeType column, const ValueType &value)
Set the value of the entry in the specified column.
Definition: ConjGradient.h:1265
#define OPENVDB_LOG_DEBUG_RUNTIME(message)
Log a debugging message in both debug and optimized builds.
Definition: logging.h:48
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:727
const T * y
Definition: ConjGradient.h:563
bool isFinite() const
Return true if all values along the diagonal are finite.
Definition: ConjGradient.h:1351
Definition: ConjGradient.h:873
bool isFinite(const Type &x)
Return true if x is finite.
Definition: Math.h:363
static const ValueType sZeroValue
Definition: ConjGradient.h:275
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:622
LinearOp(const T &a_, const T *x_, const T *y_, T *out_)
Definition: ConjGradient.h:551
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Definition: ConjGradient.h:738
Definition: Exceptions.h:78
void scale(const Scalar &)
Scale all of the entries in this row.
Definition: ConjGradient.h:1307
Definition: ConjGradient.h:549
CopyOp(const T *from_, T *to_)
Definition: ConjGradient.h:521
Vector()
Construct an empty vector.
Definition: ConjGradient.h:173
bool empty() const
Return true if this vector has no elements.
Definition: ConjGradient.h:189
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:324
const T * b
Definition: ConjGradient.h:689
const T * a
Definition: ConjGradient.h:688
bool operator()(const SizeRange &range, bool finite) const
Definition: ConjGradient.h:1065
Definition: ConjGradient.h:534
T operator()(const SizeRange &range, T maxValue) const
Definition: ConjGradient.h:742
const SizeType binCount
Definition: ConjGradient.h:690
boost::shared_ptr< JacobiPreconditioner > Ptr
Definition: ConjGradient.h:1330
FillOp(T *data_, const T &val_)
Definition: ConjGradient.h:536
Vector< ValueType > VectorType
Definition: ConjGradient.h:270
const T & at(SizeType i) const
Return the value of this vector's ith element.
Definition: ConjGradient.h:230
Definition: ConjGradient.h:1061
const SizeType arraySize
Definition: ConjGradient.h:691
ConstValueIter & operator++()
Definition: ConjGradient.h:424
Vector< ValueType > VectorType
Definition: ConjGradient.h:1395
void operator()(const SizeRange &range) const
Definition: ConjGradient.h:666
ValueType_ ValueType
Definition: ConjGradient.h:269
Information about the state of a conjugate gradient solution.
Definition: ConjGradient.h:74
TriangularMatrix::RowEditor TriangleRowEditor
Definition: ConjGradient.h:1399
SizeType size() const
Return the number of elements in this vector.
Definition: ConjGradient.h:187
void increment()
Definition: ConjGradient.h:423
std::string str() const
Return a string representation of this matrix.
Definition: ConjGradient.h:1097
Vector & operator*=(const Scalar &s)
Multiply each element of this vector by s.
Definition: ConjGradient.h:204
T * data
Definition: ConjGradient.h:542
Definition: ConjGradient.h:768
TriangularMatrix::ConstRow TriangleConstRow
Definition: ConjGradient.h:1398
T & operator[](SizeType i)
Return the value of this vector's ith element.
Definition: ConjGradient.h:231
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:370
Vector< double > VectorD
Definition: ConjGradient.h:256
T ValueType
Definition: ConjGradient.h:496
DeterministicDotProductOp(const T *a_, const T *b_, const SizeType binCount_, const SizeType arraySize_, T *reducetmp_)
Definition: ConjGradient.h:662
void operator()(const SizeRange &range) const
Definition: ConjGradient.h:523
#define OPENVDB_VERSION_NAME
Definition: version.h:43
T * out
Definition: ConjGradient.h:564
SizeType numRows() const
Return the number of rows in this matrix.
Definition: ConjGradient.h:287
bool operator()(const SizeRange &range, bool finite) const
Definition: ConjGradient.h:772
Preconditioner< ValueType > BaseType
Definition: ConjGradient.h:1394
virtual void apply(const Vector< T > &r, Vector< T > &z)=0
Apply this preconditioner to a residue vector: z = M−1r
Diagonal preconditioner.
Definition: ConjGradient.h:70
const T * data
Definition: ConjGradient.h:752
const T * from
Definition: ConjGradient.h:527
Vector< ValueType > VectorType
Definition: ConjGradient.h:1329
State solve(const PositiveDefMatrix &A, const Vector< typename PositiveDefMatrix::ValueType > &b, Vector< typename PositiveDefMatrix::ValueType > &x, Preconditioner< typename PositiveDefMatrix::ValueType > &preconditioner, const State &termination=terminationDefaults< typename PositiveDefMatrix::ValueType >())
Solve Ax = b via the preconditioned conjugate gradient method.
Definition: ConjGradient.h:1652
State terminationDefaults()
Return default termination conditions for a conjugate gradient solver.
Definition: ConjGradient.h:85
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:39
T * data()
Return a pointer to this vector's elements.
Definition: ConjGradient.h:237
SparseStencilMatrix< ValueType, 4 > TriangularMatrix
Definition: ConjGradient.h:1397
Definition: Exceptions.h:86
Vector(SizeType n)
Construct a vector of n elements, with uninitialized values.
Definition: ConjGradient.h:175
const TriangularMatrix & upperMatrix() const
Definition: ConjGradient.h:1547
Preconditioner< ValueType > BaseType
Definition: ConjGradient.h:1328
static bool join(bool finite1, bool finite2)
Definition: ConjGradient.h:1078
tbb::blocked_range< SizeType > SizeRange
Definition: ConjGradient.h:63
virtual ~JacobiPreconditioner()
Definition: ConjGradient.h:1338
Definition: ConjGradient.h:519
void axpy(const T &a, const Vector< T > &xVec, const Vector< T > &yVec, Vector< T > &result)
Compute ax + y.
Definition: ConjGradient.h:1612
Definition: Exceptions.h:39
Tolerance for floating-point comparison.
Definition: Math.h:125
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:594
IsFiniteOp(const SparseStencilMatrix &m)
Definition: ConjGradient.h:1063
uint32_t Index32
Definition: Types.h:56
Vector< float > VectorS
Definition: ConjGradient.h:255
bool success
Definition: ConjGradient.h:75
RowEditor(ValueType *valueHead, SizeType *columnHead, SizeType &rowSize, SizeType colSize)
Definition: ConjGradient.h:1247
Index32 SizeType
Definition: ConjGradient.h:61
const T * constData() const
Return a pointer to this vector's elements.
Definition: ConjGradient.h:239
Preconditioner(const SparseStencilMatrix< T, STENCIL_SIZE > &)
Definition: ConjGradient.h:499
static bool join(bool finite1, bool finite2)
Definition: ConjGradient.h:782
SizeType size() const
Return the number of rows in this matrix.
Definition: ConjGradient.h:288
JacobiPreconditioner(const MatrixType &A)
Definition: ConjGradient.h:1332
void computeResidual(const MatrixOperator &A, const Vector< T > &x, const Vector< T > &b, Vector< T > &r)
Compute r = b − Ax.
Definition: ConjGradient.h:1635
T * to
Definition: ConjGradient.h:528
void fill(const ValueType &value)
Set all elements of this vector to value.
Definition: ConjGradient.h:629
double relativeError
Definition: ConjGradient.h:77
const ValueType & operator()(SizeType row, SizeType col) const
Return the value at the given coordinates.
Definition: ConjGradient.h:934
virtual bool isValid() const
Definition: ConjGradient.h:502
void operator()(const SizeRange &range) const
Definition: ConjGradient.h:878
InfNormOp(const T *data_)
Definition: ConjGradient.h:740
virtual bool isValid() const
Definition: ConjGradient.h:1496
IsFiniteOp(const T *data_)
Definition: ConjGradient.h:770
int iterations
Definition: ConjGradient.h:76
virtual ~Preconditioner()
Definition: ConjGradient.h:500
std::ostream & operator<<(std::ostream &os, const State &state)
Definition: ConjGradient.h:574
MatrixType::ValueType ValueType
Definition: ConjGradient.h:1390
State solve(const PositiveDefMatrix &A, const Vector< typename PositiveDefMatrix::ValueType > &b, Vector< typename PositiveDefMatrix::ValueType > &x, Preconditioner< typename PositiveDefMatrix::ValueType > &preconditioner, Interrupter &interrupter, const State &termination=terminationDefaults< typename PositiveDefMatrix::ValueType >())
Solve Ax = b via the preconditioned conjugate gradient method.
Definition: ConjGradient.h:1666
MatrixType::ValueType ValueType
Definition: ConjGradient.h:1324
boost::shared_ptr< Vector > Ptr
Definition: ConjGradient.h:170
virtual ~IncompleteCholeskyPreconditioner()
Definition: ConjGradient.h:1494
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:561
ValueType l2Norm() const
Return the L2 norm of this vector.
Definition: ConjGradient.h:213
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:336
const T * data
Definition: ConjGradient.h:784
boost::shared_ptr< IncompleteCholeskyPreconditioner > Ptr
Definition: ConjGradient.h:1396
Sparse, square matrix representing a 3D stencil operator of size STENCIL_SIZE.
Definition: ConjGradient.h:67
double absoluteError
Definition: ConjGradient.h:78
std::string str() const
Return a string representation of this vector.
Definition: ConjGradient.h:837
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
void reset()
Definition: ConjGradient.h:427
Definition: ConjGradient.h:660
Read-only accessor to a row of this matrix.
Definition: ConjGradient.h:440
Base class for conjugate gradient preconditioners.
Definition: ConjGradient.h:69
void swap(Vector &other)
Swap internal storage with another vector, which need not be the same size.
Definition: ConjGradient.h:196
T ValueType
Definition: ConjGradient.h:169
const TriangularMatrix & lowerMatrix() const
Definition: ConjGradient.h:1546
SizeType column() const
Definition: ConjGradient.h:421
~Vector()
Definition: ConjGradient.h:179
const T & operator[](SizeType i) const
Return the value of this vector's ith element.
Definition: ConjGradient.h:232
SparseStencilMatrix * to
Definition: ConjGradient.h:890
IncompleteCholeskyPreconditioner(const MatrixType &matrix)
Definition: ConjGradient.h:1401
void clear()
Set the number of entries in this row to zero.
Definition: ConjGradient.h:1256
T * reducetmp
Definition: ConjGradient.h:692
const ValueType & operator*() const
Definition: ConjGradient.h:415
const SparseStencilMatrix * mat
Definition: ConjGradient.h:1080
Read/write accessor to a row of this matrix.
Definition: ConjGradient.h:448
Preconditioner using incomplete Cholesky factorization.
Definition: ConjGradient.h:71