Kaydet (Commit) 3c405ff8 authored tarafından Eike Rathke's avatar Eike Rathke

resolved fdo#87237 propagate error values through matrix comparisons

Apparently introduced with 8e8b43a0 the
comparison results were stored as boolean values, effectively discarding
any infinite double values and error values encoded as NaN values.

Change-Id: I1fb6f46894a0bee02a37e28b7e6cc84f8c051f28
üst 9338bea6
...@@ -202,7 +202,7 @@ public: ...@@ -202,7 +202,7 @@ public:
ScMatrix(SCSIZE nC, SCSIZE nR); ScMatrix(SCSIZE nC, SCSIZE nR);
ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal); ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal);
ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals ); ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals );
/** Clone the matrix. */ /** Clone the matrix. */
ScMatrix* Clone() const; ScMatrix* Clone() const;
......
...@@ -70,51 +70,63 @@ typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType; ...@@ -70,51 +70,63 @@ typedef mdds::multi_type_matrix<custom_string_trait> MatrixImplType;
namespace { namespace {
struct ElemEqualZero : public unary_function<double, bool> struct ElemEqualZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val == 0.0; if (!::rtl::math::isFinite(val))
return val;
return val == 0.0 ? 1.0 : 0.0;
} }
}; };
struct ElemNotEqualZero : public unary_function<double, bool> struct ElemNotEqualZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val != 0.0; if (!::rtl::math::isFinite(val))
return val;
return val != 0.0 ? 1.0 : 0.0;
} }
}; };
struct ElemGreaterZero : public unary_function<double, bool> struct ElemGreaterZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val > 0.0; if (!::rtl::math::isFinite(val))
return val;
return val > 0.0 ? 1.0 : 0.0;
} }
}; };
struct ElemLessZero : public unary_function<double, bool> struct ElemLessZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val < 0.0; if (!::rtl::math::isFinite(val))
return val;
return val < 0.0 ? 1.0 : 0.0;
} }
}; };
struct ElemGreaterEqualZero : public unary_function<double, bool> struct ElemGreaterEqualZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val >= 0.0; if (!::rtl::math::isFinite(val))
return val;
return val >= 0.0 ? 1.0 : 0.0;
} }
}; };
struct ElemLessEqualZero : public unary_function<double, bool> struct ElemLessEqualZero : public unary_function<double, double>
{ {
bool operator() (double val) const double operator() (double val) const
{ {
return val <= 0.0; if (!::rtl::math::isFinite(val))
return val;
return val <= 0.0 ? 1.0 : 0.0;
} }
}; };
...@@ -123,7 +135,7 @@ class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_ ...@@ -123,7 +135,7 @@ class CompareMatrixElemFunc : std::unary_function<MatrixImplType::element_block_
{ {
static _Comp maComp; static _Comp maComp;
std::vector<bool> maNewMatValues; std::vector<double> maNewMatValues; // double instead of bool to transport error values
size_t mnRow; size_t mnRow;
size_t mnCol; size_t mnCol;
public: public:
...@@ -145,13 +157,6 @@ public: ...@@ -145,13 +157,6 @@ public:
for (; it != itEnd; ++it) for (; it != itEnd; ++it)
{ {
double fVal = *it; double fVal = *it;
if (!rtl::math::isFinite(fVal))
{
/* FIXME: this silently skips an error instead of propagating it! */
maNewMatValues.push_back(false);
continue;
}
maNewMatValues.push_back(maComp(fVal)); maNewMatValues.push_back(maComp(fVal));
} }
} }
...@@ -173,7 +178,7 @@ public: ...@@ -173,7 +178,7 @@ public:
case mdds::mtm::element_empty: case mdds::mtm::element_empty:
default: default:
// Fill it with false. // Fill it with false.
maNewMatValues.resize(maNewMatValues.size() + node.size, false); maNewMatValues.resize(maNewMatValues.size() + node.size, 0.0);
} }
} }
...@@ -200,7 +205,7 @@ public: ...@@ -200,7 +205,7 @@ public:
ScMatrixImpl(SCSIZE nC, SCSIZE nR); ScMatrixImpl(SCSIZE nC, SCSIZE nR);
ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal); ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal);
ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals ); ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals );
~ScMatrixImpl(); ~ScMatrixImpl();
...@@ -295,7 +300,7 @@ ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) : ...@@ -295,7 +300,7 @@ ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR) :
ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) : ScMatrixImpl::ScMatrixImpl(SCSIZE nC, SCSIZE nR, double fInitVal) :
maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {} maMat(nR, nC, fInitVal), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) : ScMatrixImpl::ScMatrixImpl( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {} maMat(nR, nC, rInitVals.begin(), rInitVals.end()), maMatFlag(nR, nC), pErrorInterpreter(NULL), mbCloneIfConst(true) {}
ScMatrixImpl::~ScMatrixImpl() ScMatrixImpl::~ScMatrixImpl()
...@@ -1284,32 +1289,35 @@ public: ...@@ -1284,32 +1289,35 @@ public:
} }
}; };
inline bool evaluate( double fVal, ScQueryOp eOp ) inline double evaluate( double fVal, ScQueryOp eOp )
{ {
if (!rtl::math::isFinite(fVal))
return fVal;
switch (eOp) switch (eOp)
{ {
case SC_EQUAL: case SC_EQUAL:
return fVal == 0.0; return fVal == 0.0 ? 1.0 : 0.0;
case SC_LESS: case SC_LESS:
return fVal < 0.0; return fVal < 0.0 ? 1.0 : 0.0;
case SC_GREATER: case SC_GREATER:
return fVal > 0.0; return fVal > 0.0 ? 1.0 : 0.0;
break; break;
case SC_LESS_EQUAL: case SC_LESS_EQUAL:
return fVal <= 0.0; return fVal <= 0.0 ? 1.0 : 0.0;
break; break;
case SC_GREATER_EQUAL: case SC_GREATER_EQUAL:
return fVal >= 0.0; return fVal >= 0.0 ? 1.0 : 0.0;
break; break;
case SC_NOT_EQUAL: case SC_NOT_EQUAL:
return fVal != 0.0; return fVal != 0.0 ? 1.0 : 0.0;
break; break;
default: default:
; ;
} }
OSL_TRACE( "evaluate: unhandled comparison operator: %d", (int)eOp); OSL_TRACE( "evaluate: unhandled comparison operator: %d", (int)eOp);
return false; return CreateDoubleError( errUnknownState);
} }
class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void> class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type, void>
...@@ -1317,7 +1325,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type ...@@ -1317,7 +1325,7 @@ class CompareMatrixFunc : std::unary_function<MatrixImplType::element_block_type
sc::Compare& mrComp; sc::Compare& mrComp;
size_t mnMatPos; size_t mnMatPos;
sc::CompareOptions* mpOptions; sc::CompareOptions* mpOptions;
std::vector<bool> maResValues; std::vector<double> maResValues; // double instead of bool to transport error values
void compare() void compare()
{ {
...@@ -1397,7 +1405,7 @@ public: ...@@ -1397,7 +1405,7 @@ public:
} }
} }
const std::vector<bool>& getValues() const const std::vector<double>& getValues() const
{ {
return maResValues; return maResValues;
} }
...@@ -1411,7 +1419,7 @@ class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_b ...@@ -1411,7 +1419,7 @@ class CompareMatrixToNumericFunc : std::unary_function<MatrixImplType::element_b
sc::Compare& mrComp; sc::Compare& mrComp;
double mfRightValue; double mfRightValue;
sc::CompareOptions* mpOptions; sc::CompareOptions* mpOptions;
std::vector<bool> maResValues; std::vector<double> maResValues; // double instead of bool to transport error values
void compare() void compare()
{ {
...@@ -1489,7 +1497,7 @@ public: ...@@ -1489,7 +1497,7 @@ public:
} }
} }
const std::vector<bool>& getValues() const const std::vector<double>& getValues() const
{ {
return maResValues; return maResValues;
} }
...@@ -1711,7 +1719,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix( ...@@ -1711,7 +1719,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
maMat.walk(aFunc); maMat.walk(aFunc);
// We assume the result matrix has the same dimension as this matrix. // We assume the result matrix has the same dimension as this matrix.
const std::vector<bool>& rResVal = aFunc.getValues(); const std::vector<double>& rResVal = aFunc.getValues();
if (nSize != rResVal.size()) if (nSize != rResVal.size())
ScMatrixRef(); ScMatrixRef();
...@@ -1723,7 +1731,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix( ...@@ -1723,7 +1731,7 @@ ScMatrixRef ScMatrixImpl::CompareMatrix(
maMat.walk(aFunc); maMat.walk(aFunc);
// We assume the result matrix has the same dimension as this matrix. // We assume the result matrix has the same dimension as this matrix.
const std::vector<bool>& rResVal = aFunc.getValues(); const std::vector<double>& rResVal = aFunc.getValues();
if (nSize != rResVal.size()) if (nSize != rResVal.size())
ScMatrixRef(); ScMatrixRef();
...@@ -1882,7 +1890,7 @@ ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) : ...@@ -1882,7 +1890,7 @@ ScMatrix::ScMatrix(SCSIZE nC, SCSIZE nR, double fInitVal) :
SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!"); SAL_WARN_IF( !nR, "sc", "ScMatrix with 0 rows!");
} }
ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<bool>& rInitVals ) : ScMatrix::ScMatrix( size_t nC, size_t nR, const std::vector<double>& rInitVals ) :
pImpl(new ScMatrixImpl(nC, nR, rInitVals)), nRefCnt(0) pImpl(new ScMatrixImpl(nC, nR, rInitVals)), nRefCnt(0)
{ {
SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!"); SAL_WARN_IF( !nC, "sc", "ScMatrix with 0 columns!");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment