[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Fri Jun 28 14:55:02 PDT 2013
sc/inc/scmatrix.hxx | 3 +
sc/source/core/tool/interpr1.cxx | 65 ----------------------
sc/source/core/tool/scmatrix.cxx | 111 +++++++++++++++++++++++++++++++++++++++
3 files changed, 116 insertions(+), 63 deletions(-)
New commits:
commit c91c3d161561e6d8e43527b0211ab67de54d47cf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri Jun 28 17:54:34 2013 -0400
Better to calculate max and min value of matrix *in* the matrix itself.
Change-Id: I410b345ac32550a188aa356e133ef8e0e9b13d9f
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 66b271b..d6ac279 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -349,6 +349,9 @@ public:
IterateResult Product(bool bTextAsZero) const;
size_t Count(bool bCountStrings) const;
+ double GetMaxValue( bool bTextAsZero ) const;
+ double GetMinValue( bool bTextAsZero ) const;
+
// All other matrix functions MatMult, MInv, ... are in ScInterpreter
// to be numerically safe.
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index aa55dcb..9cb89ae 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3729,39 +3729,7 @@ void ScInterpreter::ScMin( bool bTextAsZero )
{
ScMatrixRef pMat = GetMatrix();
if (pMat)
- {
- SCSIZE nC, nR;
- nFuncFmtType = NUMBERFORMAT_NUMBER;
- pMat->GetDimensions(nC, nR);
- if (pMat->IsNumeric())
- {
- for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
- for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
- {
- nVal = pMat->GetDouble(nMatCol,nMatRow);
- if (nMin > nVal) nMin = nVal;
- }
- }
- else
- {
- for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
- {
- for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
- {
- if (!pMat->IsString(nMatCol,nMatRow))
- {
- nVal = pMat->GetDouble(nMatCol,nMatRow);
- if (nMin > nVal) nMin = nVal;
- }
- else if ( bTextAsZero )
- {
- if ( nMin > 0.0 )
- nMin = 0.0;
- }
- }
- }
- }
- }
+ nMin = pMat->GetMinValue(bTextAsZero);
}
break;
case svString :
@@ -3855,36 +3823,7 @@ void ScInterpreter::ScMax( bool bTextAsZero )
if (pMat)
{
nFuncFmtType = NUMBERFORMAT_NUMBER;
- SCSIZE nC, nR;
- pMat->GetDimensions(nC, nR);
- if (pMat->IsNumeric())
- {
- for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
- for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
- {
- nVal = pMat->GetDouble(nMatCol,nMatRow);
- if (nMax < nVal) nMax = nVal;
- }
- }
- else
- {
- for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
- {
- for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
- {
- if (!pMat->IsString(nMatCol,nMatRow))
- {
- nVal = pMat->GetDouble(nMatCol,nMatRow);
- if (nMax < nVal) nMax = nVal;
- }
- else if ( bTextAsZero )
- {
- if ( nMax < 0.0 )
- nMax = 0.0;
- }
- }
- }
- }
+ nMax = pMat->GetMaxValue(bTextAsZero);
}
}
break;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 26fe7d3..bf3ea63 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -223,6 +223,9 @@ public:
ScMatrix::IterateResult Product(bool bTextAsZero) const;
size_t Count(bool bCountStrings) const;
+ double GetMaxValue( bool bTextAsZero ) const;
+ double GetMinValue( bool bTextAsZero ) const;
+
#if DEBUG_MATRIX
void Dump() const;
#endif
@@ -935,6 +938,90 @@ public:
}
};
+struct MaxOp
+{
+ static double init() { return std::numeric_limits<double>::min(); }
+ static double compare(double left, double right)
+ {
+ return std::max(left, right);
+ }
+
+ static double boolValue(
+ mdds::mtv::boolean_element_block::const_iterator it,
+ mdds::mtv::boolean_element_block::const_iterator itEnd)
+ {
+ // If the array has at least one true value, the maximum value is 1.
+ it = std::find(it, itEnd, true);
+ return it == itEnd ? 0.0 : 1.0;
+ }
+};
+
+struct MinOp
+{
+ static double init() { return std::numeric_limits<double>::max(); }
+ static double compare(double left, double right)
+ {
+ return std::min(left, right);
+ }
+
+ static double boolValue(
+ mdds::mtv::boolean_element_block::const_iterator it,
+ mdds::mtv::boolean_element_block::const_iterator itEnd)
+ {
+ // If the array has at least one false value, the minimum value is 0.
+ it = std::find(it, itEnd, false);
+ return it == itEnd ? 1.0 : 0.0;
+ }
+};
+
+template<typename _Op>
+class CalcMaxMinValue : std::unary_function<MatrixImplType::element_block_type, void>
+{
+ double mfVal;
+ bool mbTextAsZero;
+public:
+ CalcMaxMinValue( bool bTextAsZero ) :
+ mfVal(_Op::init()),
+ mbTextAsZero(bTextAsZero) {}
+
+ double getValue() const { return mfVal; }
+
+ void operator() (const MatrixImplType::element_block_node_type& node)
+ {
+ using namespace mdds::mtv;
+
+ switch (node.type)
+ {
+ case mdds::mtm::element_numeric:
+ {
+ numeric_element_block::const_iterator it = numeric_element_block::begin(*node.data);
+ numeric_element_block::const_iterator itEnd = numeric_element_block::end(*node.data);
+ for (; it != itEnd; ++it)
+ mfVal = _Op::compare(mfVal, *it);
+ }
+ break;
+ case mdds::mtm::element_boolean:
+ {
+ boolean_element_block::const_iterator it = boolean_element_block::begin(*node.data);
+ boolean_element_block::const_iterator itEnd = boolean_element_block::end(*node.data);
+ double fVal = _Op::boolValue(it, itEnd);
+ mfVal = _Op::compare(mfVal, fVal);
+ }
+ break;
+ case mdds::mtm::element_string:
+ case mdds::mtm::element_empty:
+ {
+ // empty elements are treated as empty strings.
+ if (mbTextAsZero)
+ mfVal = _Op::compare(mfVal, 0.0);
+ }
+ break;
+ default:
+ ;
+ }
+ }
+};
+
}
ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const
@@ -966,6 +1053,20 @@ size_t ScMatrixImpl::Count(bool bCountStrings) const
return aFunc.getCount();
}
+double ScMatrixImpl::GetMaxValue( bool bTextAsZero ) const
+{
+ CalcMaxMinValue<MaxOp> aFunc(bTextAsZero);
+ maMat.walk(aFunc);
+ return aFunc.getValue();
+}
+
+double ScMatrixImpl::GetMinValue( bool bTextAsZero ) const
+{
+ CalcMaxMinValue<MinOp> aFunc(bTextAsZero);
+ maMat.walk(aFunc);
+ return aFunc.getValue();
+}
+
#if DEBUG_MATRIX
void ScMatrixImpl::Dump() const
{
@@ -1308,6 +1409,16 @@ size_t ScMatrix::Count(bool bCountStrings) const
return pImpl->Count(bCountStrings);
}
+double ScMatrix::GetMaxValue( bool bTextAsZero ) const
+{
+ return pImpl->GetMaxValue(bTextAsZero);
+}
+
+double ScMatrix::GetMinValue( bool bTextAsZero ) const
+{
+ return pImpl->GetMinValue(bTextAsZero);
+}
+
#if DEBUG_MATRIX
void ScMatrix::Dump() const
{
More information about the Libreoffice-commits
mailing list