46 #include "ac/lapack.h"
56 std::ostream&
Report(std::ostream& os)
const;
63 virtual std::ostream&
vReport(std::ostream& os)
const=0;
101 virtual std::ostream&
vReport(std::ostream& os)
const;
107 template <
typename T>
116 virtual std::ostream&
vReport(std::ostream& os)
const;
122 template <
typename T>
131 virtual std::ostream&
vReport(std::ostream& os)
const;
137 template <
typename T>
146 virtual std::ostream&
vReport(std::ostream& os)
const;
155 template <
typename T>
164 virtual std::ostream&
vReport(std::ostream& os)
const;
175 template <
typename T>
184 virtual std::ostream&
vReport(std::ostream& os)
const;
199 template <
typename T>
208 virtual std::ostream&
vReport(std::ostream& os)
const;
260 template <
typename T>
267 template <
typename T>
273 template <
typename T>
277 dCondBefore = mh.ConditionNumber(GetCondNumNorm());
280 const bool bScaleRows = !rowScale.empty();
281 const bool bScaleCols = !colScale.empty();
283 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
287 dCoef *= rowScale[i->iRow];
291 dCoef *= colScale[i->iCol];
294 mh(i->iRow + 1, i->iCol + 1) = dCoef;
297 if (uFlags & SolutionManager::SCALEF_COND_NUM) {
298 dCondAfter = mh.ConditionNumber(GetCondNumNorm());
304 template <
typename T>
307 bOK = ComputeScaleFactors(mh, rowScale, colScale);
312 template <
typename T>
367 template <
typename T>
374 template <
typename T>
380 template <
typename T>
387 if (normRow.empty()) {
388 normRow.resize(nrows, 0.);
390 std::fill(normRow.begin(), normRow.end(), 0.);
393 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
394 normRow[i->iRow] += std::abs(i->dCoef);
397 for (
int i = 0; i < nrows; ++i) {
398 rowScale[i] = 1. / normRow[i];
404 template <
typename T>
410 template <
typename T>
417 template <
typename T>
423 template <
typename T>
430 if (normRow.empty()) {
431 normRow.resize(nrows, 0.);
433 std::fill(normRow.begin(), normRow.end(), 0.);
436 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
439 if (d > normRow[i->iRow]) {
440 normRow[i->iRow] = d;
444 for (
int i = 0; i < nrows; ++i) {
445 rowScale[i] = 1. / normRow[i];
451 template <
typename T>
457 template <
typename T>
464 template <
typename T>
470 template <
typename T>
477 if (normCol.empty()) {
478 normCol.resize(ncols, 0.);
480 std::fill(normCol.begin(), normCol.end(), 0.);
483 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
484 normCol[i->iCol] += std::abs(i->dCoef);
487 for (
int i = 0; i < ncols; ++i) {
488 colScale[i] = 1. / normCol[i];
494 template <
typename T>
500 template <
typename T>
507 template <
typename T>
513 template <
typename T>
520 if (normCol.empty()) {
521 normCol.resize(ncols, 0.);
523 std::fill(normCol.begin(), normCol.end(), 0.);
526 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
529 if (d > normCol[i->iCol]) {
530 normCol[i->iCol] = d;
534 for (
int i = 0; i < ncols; ++i) {
535 colScale[i] = 1. / normCol[i];
541 template <
typename T>
547 template <
typename T>
551 #if defined(HAVE_DLAMCH) || defined(HAVE_DLAMCH_)
553 SMLNUM = __FC_DECL__(dlamch)(
"S");
556 SMLNUM = std::numeric_limits<doublereal>::min();
563 template <
typename T>
569 template <
typename T>
578 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
580 if (d > rowScale[i->iRow]) {
581 rowScale[i->iRow] = d;
587 for (std::vector<doublereal>::iterator i = rowScale.begin(); i != rowScale.end(); ++i) {
600 "null min row value in dgeequ");
603 for (std::vector<doublereal>::iterator i = rowScale.begin(); i != rowScale.end(); ++i) {
604 *i = 1./(std::min(std::max(*i, SMLNUM), BIGNUM));
607 rowcnd = std::max(rcmin, SMLNUM)/std::min(rcmax, BIGNUM);
609 for (
typename T::const_iterator i = mh.begin(); i != mh.end(); ++i) {
610 doublereal d = std::abs(i->dCoef)*rowScale[i->iRow];
611 if (d > colScale[i->iCol]) {
612 colScale[i->iCol] = d;
618 for (std::vector<doublereal>::iterator i = colScale.begin(); i != colScale.end(); ++i) {
629 "null min column value in dgeequ");
632 for (std::vector<doublereal>::iterator i = colScale.begin(); i != colScale.end(); ++i) {
633 *i = 1./(std::min(std::max(*i, SMLNUM), BIGNUM));
636 colcnd = std::max(rcmin, SMLNUM)/std::min(rcmax, BIGNUM);
641 template <
typename T>
644 if (amax < std::numeric_limits<doublereal>::epsilon()
645 || amax > 1./std::numeric_limits<doublereal>::epsilon())
647 os <<
"Warning: The matrix should be scaled\n";
651 os <<
"Warning: it is not worth scaling the columns\n";
655 && amax >= std::numeric_limits<doublereal>::epsilon()
656 && amax <= 1./std::numeric_limits<doublereal>::epsilon())
658 os <<
"Warning: it is not worth scaling the rows\n";
664 template <
typename T>
667 iMaxIter(scale.iMaxIter),
676 template <
typename T>
682 template <
typename T>
685 const integer nrows = mh.iGetNumRows();
686 const integer ncols = mh.iGetNumCols();
691 "invalid null or negative row number");
697 "invalid null or negative column number");
700 if (rowScale.empty()) {
701 rowScale.resize(nrows);
704 std::fill(rowScale.begin(), rowScale.end(), 1.);
705 }
else if (rowScale.size() !=
static_cast<size_t>(nrows)) {
711 if (colScale.empty()) {
712 colScale.resize(ncols);
715 std::fill(colScale.begin(), colScale.end(), 1.);
716 }
else if (colScale.size() !=
static_cast<size_t>(ncols)) {
723 bool bConverged =
false, bFirstTime =
true;
726 for (i = 1; i <= iMaxIter; ++i) {
727 std::fill(DR.begin(), DR.end(), 0.);
728 std::fill(DC.begin(), DC.end(), 0.);
730 for (
typename T::const_iterator im = mh.begin(); im != mh.end(); ++im) {
737 d = std::abs(d * rowScale[im->iRow] * colScale[im->iCol]);
739 if (d > DR[im->iRow]) {
743 if (d > DC[im->iCol]) {
748 for (
int j = 0; j < nrows; ++j) {
749 rowScale[j] /=
sqrt(DR[j]);
752 for (
int j = 0; j < ncols; ++j) {
753 colScale[j] /=
sqrt(DC[j]);
756 std::fill(normR.begin(), normR.end(), 0.);
757 std::fill(normC.begin(), normC.end(), 0.);
759 for (
typename T::const_iterator im = mh.begin(); im != mh.end(); ++im) {
766 d = std::abs(d * rowScale[im->iRow] * colScale[im->iCol]);
768 if (d > normR[im->iRow]) {
772 if (d > normC[im->iCol]) {
782 for (std::vector<doublereal>::const_iterator ir = normR.begin();
783 ir != normR.end(); ++ir) {
784 maxNormR = std::max(maxNormR, std::abs(1. - *ir));
789 for (std::vector<doublereal>::const_iterator ic = normC.begin();
790 ic != normC.end(); ++ic) {
791 maxNormC = std::max(maxNormC, std::abs(1. - *ic));
794 if (maxNormR < dTol && maxNormC < dTol) {
802 }
else if (bFirstTime) {
804 std::fill(rowScale.begin(), rowScale.end(), 1.);
805 std::fill(colScale.begin(), colScale.end(), 1.);
818 template <
typename T>
822 os <<
"Warning: matrix scale did not converge\n";
825 os <<
"row scale: " << maxNormR << std::endl
826 <<
"col scale: " << maxNormC << std::endl
827 <<
"iter scale: " << iIterTaken << std::endl;
832 template <
typename T>
842 template <
typename T>
848 template <
typename T>
851 const integer nrows = mh.iGetNumRows();
852 const integer ncols = mh.iGetNumCols();
856 "invalid null or negative row number");
861 "invalid null or negative column number");
864 if (rowScale.empty()) {
865 rowScale.resize(nrows, 1.);
866 normRow.resize(nrows);
867 }
else if (rowScale.size() !=
static_cast<size_t>(nrows)) {
871 if (colScale.empty()) {
872 colScale.resize(ncols, 1.);
873 normCol.resize(ncols);
874 }
else if (colScale.size() !=
static_cast<size_t>(ncols)) {
878 std::fill(normRow.begin(), normRow.end(), 0.);
880 for (
typename T::const_iterator im = mh.begin(); im != mh.end(); ++im) {
889 if (d > normRow[im->iRow]) {
890 normRow[im->iRow] = d;
894 for (
integer i = 0; i < nrows; ++i) {
895 rowScale[i] = 1. / normRow[i];
898 std::fill(normCol.begin(), normCol.end(), 0.);
900 for (
typename T::const_iterator im = mh.begin(); im != mh.end(); ++im) {
907 d = std::abs(rowScale[im->iRow] * d);
909 if (d > normCol[im->iCol]) {
910 normCol[im->iCol] = d;
914 for (
integer i = 0; i < ncols; ++i) {
915 colScale[i] = 1. / normCol[i];
918 if (!this->bReport()) {
924 std::fill(normRow.begin(), normRow.end(), 0.);
925 std::fill(normCol.begin(), normCol.end(), 0.);
927 for (
typename T::const_iterator im = mh.begin(); im != mh.end(); ++im) {
934 d = std::abs(colScale[im->iCol] * rowScale[im->iRow] * d);
936 if (d > normRow[im->iRow]) {
937 normRow[im->iRow] = d;
940 if (d > normCol[im->iCol]) {
941 normCol[im->iCol] = d;
947 for (std::vector<doublereal>::const_iterator ir = normRow.begin();
948 ir != normRow.end(); ++ir) {
949 maxNormRow = std::max(maxNormRow, std::abs(1. - *ir));
954 for (std::vector<doublereal>::const_iterator ic = normCol.begin();
955 ic != normCol.end(); ++ic) {
956 maxNormCol = std::max(maxNormCol, std::abs(1. - *ic));
959 return (maxNormRow < dTol && maxNormCol < dTol);
962 template <
typename T>
966 os <<
"Warning: matrix scale did not converge\n";
969 os <<
"row scale: " << maxNormRow << std::endl
970 <<
"col scale: " << maxNormCol << std::endl;
virtual ~ColSumMatrixScale()
#define MBDYN_EXCEPT_ARGS
MatrixHandler::Norm_t GetCondNumNorm() const
std::vector< doublereal > colScale
bool bGetInitialized() const
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
std::vector< doublereal > DC
bool ComputeScaleFactors(const T &mh)
MatrixScale(const SolutionManager::ScaleOpt &scale)
std::vector< doublereal > normCol
const std::vector< doublereal > & GetRowScale() const
MatrixScaleBase(const SolutionManager::ScaleOpt &scale)
std::ostream & Report(std::ostream &os) const
static VectorHandler & ScaleVector(VectorHandler &v, const std::vector< doublereal > &s)
virtual ~RowMaxMatrixScale()
RowMaxColMaxMatrixScale(const SolutionManager::ScaleOpt &scale)
std::vector< doublereal > normRow
void PrepareCols(const MatrixHandler &mh, integer &ncols)
virtual ~MatrixScaleBase()
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
virtual std::ostream & vReport(std::ostream &os) const
RowSumMatrixScale(const SolutionManager::ScaleOpt &scale)
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
const std::vector< doublereal > & GetColScale() const
std::vector< doublereal > normCol
std::vector< doublereal > normRow
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
void Prepare(const MatrixHandler &mh, integer &nrows, integer &ncols)
virtual ~LapackMatrixScale()
ColSumMatrixScale(const SolutionManager::ScaleOpt &scale)
virtual std::ostream & vReport(std::ostream &os) const
std::vector< doublereal > normR
VectorHandler & ScaleRightHandSide(VectorHandler &bVH) const
virtual std::ostream & vReport(std::ostream &os) const
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
std::vector< doublereal > DR
virtual std::ostream & vReport(std::ostream &os) const
virtual ~RowMaxColMaxMatrixScale()
#define ASSERT(expression)
virtual ~IterativeMatrixScale()
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
RowMaxMatrixScale(const SolutionManager::ScaleOpt &scale)
#define SAFENEWWITHCONSTRUCTOR(pnt, item, constructor)
std::vector< doublereal > rowScale
IterativeMatrixScale(const SolutionManager::ScaleOpt &scale)
LapackMatrixScale(const SolutionManager::ScaleOpt &scale)
virtual std::ostream & vReport(std::ostream &os) const
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
virtual ~RowSumMatrixScale()
static MatrixScale< T > * Allocate(const SolutionManager::ScaleOpt &scale)
std::vector< doublereal > normRow
virtual std::ostream & vReport(std::ostream &os) const =0
void PrepareRows(const MatrixHandler &mh, integer &nrows)
std::vector< doublereal > normC
virtual ~ColMaxMatrixScale()
ColMaxMatrixScale(const SolutionManager::ScaleOpt &scale)
virtual std::ostream & vReport(std::ostream &os) const
virtual bool ComputeScaleFactors(const T &mh, std::vector< doublereal > &rowScale, std::vector< doublereal > &colScale)
VectorHandler & ScaleSolution(VectorHandler &xVH) const
std::vector< doublereal > normCol
virtual std::ostream & vReport(std::ostream &os) const
T & ScaleMatrix(T &mh) const