summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2013-10-18 00:22:11 -0400
committerKohei Yoshida <kohei.yoshida@collabora.com>2013-10-18 23:22:43 -0400
commit1a590708f5ed69d2387e13334f347160e23c63f6 (patch)
tree16f01a3585fa93ea9eab2fb1aa1f3549bf1da198 /sc
parent7195a5b87ca6ac22246b80cf8e907eb22f8e0f12 (diff)
Faster way to add two result matrices.
Change-Id: I347aec7de10a943d7f91c468cd6e393f980e53b6
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/scmatrix.hxx4
-rw-r--r--sc/source/core/tool/interpr1.cxx16
-rw-r--r--sc/source/core/tool/scmatrix.cxx62
3 files changed, 68 insertions, 14 deletions
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 8317b85a1184..5e9800ea275d 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -167,7 +167,7 @@ public:
};
typedef boost::interprocess::unique_ptr<Pos, PosDeleter> PosRef;
- typedef boost::interprocess::unique_ptr<ConstPos, PosDeleter> ConstPosRef;
+ typedef boost::interprocess::unique_ptr<ConstPos, ConstPosDeleter> ConstPosRef;
/// The maximum number of elements a matrix may have at runtime.
inline static size_t GetElementsMax()
@@ -407,6 +407,8 @@ public:
void GetDoubleArray( std::vector<double>& rArray ) const;
void MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const;
+ ScMatrix& operator+= ( const ScMatrix& r );
+
#if DEBUG_MATRIX
void Dump() const;
#endif
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 5961bc545c8d..9032a5e3dd6e 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5477,19 +5477,9 @@ double ScInterpreter::IterateParametersIfs( ScIterFuncIfs eFunc )
SetError( errIllegalParameter);
}
- for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
- {
- for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
- {
- if (pResultMatrix->IsValue( nCol, nRow) &&
- pResultMatrix->GetDouble( nCol, nRow))
- {
- SCSIZE nC = nCol + nColDiff;
- SCSIZE nR = nRow + nRowDiff;
- pResMat->PutDouble(pResMat->GetDouble(nC, nR)+1.0, nC, nR);
- }
- }
- }
+ // query and result matrices have same geometry, and the
+ // result matrix is filled with boolean values.
+ *pResMat += *pResultMatrix;
}
else
{
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 5d8cc9a2446e..29dcda7f994e 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -304,6 +304,7 @@ public:
void GetDoubleArray( std::vector<double>& rArray ) const;
void MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op eOp ) const;
+ void AddValues( const ScMatrixImpl& rMat );
#if DEBUG_MATRIX
void Dump() const;
@@ -1696,6 +1697,61 @@ void ScMatrixImpl::MergeDoubleArray( std::vector<double>& rArray, ScMatrix::Op e
}
}
+void ScMatrixImpl::AddValues( const ScMatrixImpl& rMat )
+{
+ const MatrixImplType& rOther = rMat.maMat;
+ MatrixImplType::size_pair_type aSize = maMat.size();
+ if (aSize != rOther.size())
+ // Geometry must match.
+ return;
+
+ // For now, we only add two matricies if and only if 1) the receiving
+ // matrix consists only of one numeric block, and 2) the other matrix
+ // consists of either one numeric block or one boolean block. In the
+ // future, we may want to be more flexible support matricies that consist
+ // of multiple blocks.
+
+ MatrixImplType::position_type aPos1 = maMat.position(0, 0);
+ MatrixImplType::const_position_type aPos2 = rOther.position(0, 0);
+ if (MatrixImplType::to_mtm_type(aPos1.first->type) != mdds::mtm::element_numeric)
+ return;
+
+ if (aPos1.first->size != aPos2.first->size)
+ return;
+
+ if (aPos1.first->size != aSize.row * aSize.column)
+ return;
+
+ MatrixImplType::numeric_block_type::iterator it =
+ MatrixImplType::numeric_block_type::begin(*aPos1.first->data);
+ MatrixImplType::numeric_block_type::iterator itEnd =
+ MatrixImplType::numeric_block_type::end(*aPos1.first->data);
+
+ switch (MatrixImplType::to_mtm_type(aPos2.first->type))
+ {
+ case mdds::mtm::element_boolean:
+ {
+ MatrixImplType::boolean_block_type::iterator it2 =
+ MatrixImplType::boolean_block_type::begin(*aPos2.first->data);
+
+ for (; it != itEnd; ++it, ++it2)
+ *it += *it2;
+ }
+ break;
+ case mdds::mtm::element_numeric:
+ {
+ MatrixImplType::numeric_block_type::iterator it2 =
+ MatrixImplType::numeric_block_type::begin(*aPos2.first->data);
+
+ for (; it != itEnd; ++it, ++it2)
+ *it += *it2;
+ }
+ break;
+ default:
+ ;
+ }
+}
+
#if DEBUG_MATRIX
void ScMatrixImpl::Dump() const
{
@@ -2193,6 +2249,12 @@ void ScMatrix::MergeDoubleArray( std::vector<double>& rArray, Op eOp ) const
pImpl->MergeDoubleArray(rArray, eOp);
}
+ScMatrix& ScMatrix::operator+= ( const ScMatrix& r )
+{
+ pImpl->AddValues(*r.pImpl);
+ return *this;
+}
+
#if DEBUG_MATRIX
void ScMatrix::Dump() const
{