1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_INC_SCMATRIX_HXX
21 #define INCLUDED_SC_INC_SCMATRIX_HXX
24 #include "matrixoperators.hxx"
26 #include <formula/errorcodes.hxx>
28 #include <rtl/ustring.hxx>
29 #include <svl/sharedstring.hxx>
30 #include <svl/sharedstringpool.hxx>
36 #include <boost/intrusive_ptr.hpp>
38 #define DEBUG_MATRIX 0
41 class SvNumberFormatter
;
43 enum class FormulaError
: sal_uInt16
;
45 namespace formula
{ class DoubleVectorRefToken
; }
50 struct CompareOptions
;
55 * Try NOT to use this struct. This struct should go away in a hopefully
56 * not so distant future.
61 svl::SharedString aStr
;
64 /// Only valid if ScMatrix methods indicate so!
65 const svl::SharedString
& GetString() const { return aStr
; }
67 /// Only valid if ScMatrix methods indicate that this is no string!
68 FormulaError
GetError() const { return GetDoubleErrorValue(fVal
); }
70 /// Only valid if ScMatrix methods indicate that this is a boolean
71 bool GetBoolean() const { return fVal
!= 0.0; }
73 ScMatrixValue() : fVal(0.0), nType(ScMatValType::Empty
) {}
75 ScMatrixValue(const ScMatrixValue
& r
) :
76 fVal(r
.fVal
), aStr(r
.aStr
), nType(r
.nType
) {}
78 bool operator== (const ScMatrixValue
& r
) const
85 case ScMatValType::Value
:
86 case ScMatValType::Boolean
:
87 return fVal
== r
.fVal
;
93 return aStr
== r
.aStr
;
96 bool operator!= (const ScMatrixValue
& r
) const
98 return !operator==(r
);
101 ScMatrixValue
& operator= (const ScMatrixValue
& r
)
113 /// Abstract base class for ScFullMatrix and ScVectorRefMatrix implementations.
114 class SC_DLLPUBLIC ScMatrix
116 mutable size_t nRefCnt
; // reference count
117 mutable bool mbCloneIfConst
; // Whether the matrix is cloned with a CloneIfConst() call.
119 ScMatrix( const ScMatrix
& ) = delete;
120 ScMatrix
& operator=( const ScMatrix
&) = delete;
123 virtual ~ScMatrix() {}
126 enum Op
{ Add
, Sub
, Mul
, Div
};
128 typedef std::function
<void(size_t, size_t, double)> DoubleOpFunction
;
129 typedef std::function
<void(size_t, size_t, bool)> BoolOpFunction
;
130 typedef std::function
<void(size_t, size_t, svl::SharedString
)> StringOpFunction
;
131 typedef std::function
<void(size_t, size_t)> EmptyOpFunction
;
134 * When adding all numerical matrix elements for a scalar result such as
135 * summation, the interpreter wants to separate the first non-zero value
136 * with the rest of the summed values. This is necessary for better
137 * numerical stability, unless we sort all by absolute values before
138 * summing (not really an option) or use another algorithm, e.g. Kahan's
139 * summation algorithm,
140 * https://en.wikipedia.org/wiki/Kahan_summation_algorithm
148 IterateResult(double fFirst
, double fRest
, size_t nCount
) :
149 mfFirst(fFirst
), mfRest(fRest
), mnCount(nCount
) {}
151 IterateResult(const IterateResult
& r
) :
152 mfFirst(r
.mfFirst
), mfRest(r
.mfRest
), mnCount(r
.mnCount
) {}
155 /** Checks nC or nR for zero and uses GetElementsMax() whether a matrix of
156 the size of nC*nR could be allocated. A zero size (both nC and nR zero)
157 matrix is allowed for later resize.
159 bool static IsSizeAllocatable( SCSIZE nC
, SCSIZE nR
);
161 /// Value or boolean.
162 static bool IsValueType( ScMatValType nType
)
164 return nType
<= ScMatValType::Boolean
;
168 static bool IsBooleanType( ScMatValType nType
)
170 return nType
== ScMatValType::Boolean
;
173 /// String, empty or empty path, but not value nor boolean.
174 static bool IsNonValueType( ScMatValType nType
)
176 return bool(nType
& ScMatValType::NonvalueMask
);
179 /** String, but not empty or empty path or any other type.
180 Not named IsStringType to prevent confusion because previously
181 IsNonValueType was named IsStringType. */
182 static bool IsRealStringType( ScMatValType nType
)
184 return (nType
& ScMatValType::NonvalueMask
) == ScMatValType::String
;
187 /// Empty, but not empty path or any other type.
188 static bool IsEmptyType( ScMatValType nType
)
190 return (nType
& ScMatValType::NonvalueMask
) == ScMatValType::Empty
;
193 /// Empty path, but not empty or any other type.
194 static bool IsEmptyPathType( ScMatValType nType
)
196 return (nType
& ScMatValType::NonvalueMask
) == ScMatValType::EmptyPath
;
199 ScMatrix() : nRefCnt(0), mbCloneIfConst(true) {}
201 /** Clone the matrix. */
202 virtual ScMatrix
* Clone() const = 0;
204 /** Clone the matrix if mbCloneIfConst (immutable) is set, otherwise
205 return _this_ matrix, to be assigned to a ScMatrixRef. */
206 ScMatrix
* CloneIfConst();
208 /** Set the matrix to mutable for CloneIfConst(), only the interpreter
209 should do this and know the consequences. */
212 /** Set the matrix to immutable for CloneIfConst(), only the interpreter
213 should do this and know the consequences. */
214 void SetImmutable() const;
217 * Resize the matrix to specified new dimension.
219 virtual void Resize(SCSIZE nC
, SCSIZE nR
) = 0;
221 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) = 0;
223 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
224 MUST be at least of the size of the original matrix. */
225 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const = 0;
230 virtual void SetErrorInterpreter( ScInterpreter
* p
) = 0;
231 virtual void GetDimensions( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
232 virtual SCSIZE
GetElementCount() const = 0;
233 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const = 0;
235 /** For a row vector or column vector, if the position does not point into
236 the vector but is a valid column or row offset it is adapted such that
237 it points to an element to be replicated, same column row 0 for a row
238 vector, same row column 0 for a column vector. Else, for a 2D matrix,
241 virtual bool ValidColRowReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
243 /** Checks if the matrix position is within the matrix. If it is not, for a
244 row vector or column vector the position is adapted such that it points
245 to an element to be replicated, same column row 0 for a row vector,
246 same row column 0 for a column vector. Else, for a 2D matrix and
247 position not within matrix, returns false.
249 virtual bool ValidColRowOrReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const = 0;
251 virtual void PutDouble( double fVal
, SCSIZE nC
, SCSIZE nR
) = 0;
252 virtual void PutDouble( double fVal
, SCSIZE nIndex
) = 0;
253 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) = 0;
255 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) = 0;
256 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nIndex
) = 0;
257 virtual void PutString( const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) = 0;
259 virtual void PutEmpty( SCSIZE nC
, SCSIZE nR
) = 0;
261 /// Jump sal_False without path
262 virtual void PutEmptyPath( SCSIZE nC
, SCSIZE nR
) = 0;
263 virtual void PutError( FormulaError nErrorCode
, SCSIZE nC
, SCSIZE nR
) = 0;
264 virtual void PutBoolean( bool bVal
, SCSIZE nC
, SCSIZE nR
) = 0;
266 virtual void FillDouble( double fVal
,
267 SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) = 0;
269 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
270 virtual void PutDoubleVector( const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) = 0;
272 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
273 virtual void PutStringVector( const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) = 0;
275 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
276 virtual void PutEmptyVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
278 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
279 virtual void PutEmptyResultVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
281 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
282 virtual void PutEmptyPathVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) = 0;
284 /** May be used before obtaining the double value of an element to avoid
285 passing its NAN around.
286 @ATTENTION: MUST NOT be used if the element is a string!
287 Use GetErrorIfNotString() instead if not sure.
288 @returns 0 if no error, else one of err... constants */
289 virtual FormulaError
GetError( SCSIZE nC
, SCSIZE nR
) const = 0;
291 /** Use in ScInterpreter to obtain the error code, if any.
292 @returns 0 if no error or string element, else one of err... constants */
293 FormulaError
GetErrorIfNotString( SCSIZE nC
, SCSIZE nR
) const
294 { return IsValue( nC
, nR
) ? GetError( nC
, nR
) : FormulaError::NONE
; }
296 /// @return 0.0 if empty or empty path, else value or DoubleError.
297 virtual double GetDouble( SCSIZE nC
, SCSIZE nR
) const = 0;
298 /// @return 0.0 if empty or empty path, else value or DoubleError.
299 virtual double GetDouble( SCSIZE nIndex
) const = 0;
300 /// @return value or DoubleError or string converted to value.
301 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const = 0;
303 /// @return empty string if empty or empty path, else string content.
304 virtual svl::SharedString
GetString( SCSIZE nC
, SCSIZE nR
) const = 0;
305 /// @return empty string if empty or empty path, else string content.
306 virtual svl::SharedString
GetString( SCSIZE nIndex
) const = 0;
308 /** @returns the matrix element's string if one is present, otherwise the
309 numerical value formatted as string, or in case of an error the error
310 string is returned; an empty string for empty, a "FALSE" string for
312 virtual svl::SharedString
GetString( SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const = 0;
314 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
316 virtual ScMatrixValue
Get( SCSIZE nC
, SCSIZE nR
) const = 0;
318 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
319 path, in fact non-value. */
320 virtual bool IsStringOrEmpty( SCSIZE nIndex
) const = 0;
322 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
323 path, in fact non-value. */
324 virtual bool IsStringOrEmpty( SCSIZE nC
, SCSIZE nR
) const = 0;
326 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
327 virtual bool IsEmpty( SCSIZE nC
, SCSIZE nR
) const = 0;
329 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
330 virtual bool IsEmptyCell( SCSIZE nC
, SCSIZE nR
) const = 0;
332 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
333 virtual bool IsEmptyResult( SCSIZE nC
, SCSIZE nR
) const = 0;
335 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
336 virtual bool IsEmptyPath( SCSIZE nC
, SCSIZE nR
) const = 0;
338 /// @return <TRUE/> if value or boolean.
339 virtual bool IsValue( SCSIZE nIndex
) const = 0;
341 /// @return <TRUE/> if value or boolean.
342 virtual bool IsValue( SCSIZE nC
, SCSIZE nR
) const = 0;
344 /// @return <TRUE/> if value or boolean or empty or empty path.
345 virtual bool IsValueOrEmpty( SCSIZE nC
, SCSIZE nR
) const = 0;
347 /// @return <TRUE/> if boolean.
348 virtual bool IsBoolean( SCSIZE nC
, SCSIZE nR
) const = 0;
350 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
351 virtual bool IsNumeric() const = 0;
353 virtual void MatTrans( ScMatrix
& mRes
) const = 0;
354 virtual void MatCopy ( ScMatrix
& mRes
) const = 0;
356 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
357 virtual void CompareEqual() = 0;
358 virtual void CompareNotEqual() = 0;
359 virtual void CompareLess() = 0;
360 virtual void CompareGreater() = 0;
361 virtual void CompareLessEqual() = 0;
362 virtual void CompareGreaterEqual() = 0;
364 virtual double And() const = 0; // logical AND of all matrix values, or NAN
365 virtual double Or() const = 0; // logical OR of all matrix values, or NAN
366 virtual double Xor() const = 0; // logical XOR of all matrix values, or NAN
368 virtual IterateResult
Sum(bool bTextAsZero
) const = 0;
369 virtual IterateResult
SumSquare(bool bTextAsZero
) const = 0;
370 virtual IterateResult
Product(bool bTextAsZero
) const = 0;
371 virtual size_t Count(bool bCountStrings
, bool bCountErrors
) const = 0;
372 virtual size_t MatchDoubleInColumns(double fValue
, size_t nCol1
, size_t nCol2
) const = 0;
373 virtual size_t MatchStringInColumns(const svl::SharedString
& rStr
, size_t nCol1
, size_t nCol2
) const = 0;
375 virtual double GetMaxValue( bool bTextAsZero
) const = 0;
376 virtual double GetMinValue( bool bTextAsZero
) const = 0;
377 virtual double GetGcd() const = 0;
378 virtual double GetLcm() const = 0;
380 virtual ScMatrixRef
CompareMatrix(
381 sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
) const = 0;
384 * Convert the content of matrix into a linear array of numeric values.
385 * String elements are mapped to NaN's and empty elements are mapped to
386 * either NaN or zero values.
388 * @param bEmptyAsZero if true empty elements are mapped to zero values,
389 * otherwise they become NaN values.
391 virtual void GetDoubleArray( std::vector
<double>& rArray
, bool bEmptyAsZero
= true ) const = 0;
392 virtual void MergeDoubleArray( std::vector
<double>& rArray
, Op eOp
) const = 0;
394 virtual void NotOp(ScMatrix
& rMat
) = 0;
395 virtual void NegOp(ScMatrix
& rMat
) = 0;
396 virtual void AddOp(double fVal
, ScMatrix
& rMat
) = 0;
397 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
398 virtual void MulOp(double fVal
, ScMatrix
& rMat
) = 0;
399 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
400 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) = 0;
402 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) = 0;
404 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
405 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
406 EmptyOpFunction aEmptyFunc
) const = 0;
408 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
409 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) = 0;
412 virtual void Dump() const = 0;
417 * Matrix data type that can store values of mixed types. Each element can
418 * be one of the following types: numeric, string, boolean, empty, and empty
421 class SC_DLLPUBLIC ScFullMatrix
: public ScMatrix
423 friend class ScMatrixImpl
;
425 std::unique_ptr
<ScMatrixImpl
> pImpl
;
427 ScFullMatrix( const ScFullMatrix
& ) = delete;
428 ScFullMatrix
& operator=( const ScFullMatrix
&) = delete;
432 ScFullMatrix(SCSIZE nC
, SCSIZE nR
);
433 ScFullMatrix(SCSIZE nC
, SCSIZE nR
, double fInitVal
);
435 ScFullMatrix( size_t nC
, size_t nR
, const std::vector
<double>& rInitVals
);
437 virtual ~ScFullMatrix() override
;
439 /** Clone the matrix. */
440 virtual ScMatrix
* Clone() const override
;
443 * Resize the matrix to specified new dimension.
445 virtual void Resize( SCSIZE nC
, SCSIZE nR
) override
;
447 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) override
;
449 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
450 MUST be at least of the size of the original matrix. */
451 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const override
;
453 virtual void SetErrorInterpreter( ScInterpreter
* p
) override
;
454 virtual void GetDimensions( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
455 virtual SCSIZE
GetElementCount() const override
;
456 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const override
;
458 /** For a row vector or column vector, if the position does not point into
459 the vector but is a valid column or row offset it is adapted such that
460 it points to an element to be replicated, same column row 0 for a row
461 vector, same row column 0 for a column vector. Else, for a 2D matrix,
464 virtual bool ValidColRowReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
466 /** Checks if the matrix position is within the matrix. If it is not, for a
467 row vector or column vector the position is adapted such that it points
468 to an element to be replicated, same column row 0 for a row vector,
469 same row column 0 for a column vector. Else, for a 2D matrix and
470 position not within matrix, returns false.
472 virtual bool ValidColRowOrReplicated( SCSIZE
& rC
, SCSIZE
& rR
) const override
;
474 virtual void PutDouble( double fVal
, SCSIZE nC
, SCSIZE nR
) override
;
475 virtual void PutDouble( double fVal
, SCSIZE nIndex
) override
;
476 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
478 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) override
;
479 virtual void PutString( const svl::SharedString
& rStr
, SCSIZE nIndex
) override
;
480 virtual void PutString( const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
482 virtual void PutEmpty( SCSIZE nC
, SCSIZE nR
) override
;
484 /// Jump sal_False without path
485 virtual void PutEmptyPath( SCSIZE nC
, SCSIZE nR
) override
;
486 virtual void PutError( FormulaError nErrorCode
, SCSIZE nC
, SCSIZE nR
) override
;
487 virtual void PutBoolean( bool bVal
, SCSIZE nC
, SCSIZE nR
) override
;
489 virtual void FillDouble( double fVal
,
490 SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) override
;
492 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
493 virtual void PutDoubleVector( const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
495 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
496 virtual void PutStringVector( const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
498 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
499 virtual void PutEmptyVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
501 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
502 virtual void PutEmptyResultVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
504 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
505 virtual void PutEmptyPathVector( SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
507 /** May be used before obtaining the double value of an element to avoid
508 passing its NAN around.
509 @ATTENTION: MUST NOT be used if the element is a string!
510 Use GetErrorIfNotString() instead if not sure.
511 @returns 0 if no error, else one of err... constants */
512 virtual FormulaError
GetError( SCSIZE nC
, SCSIZE nR
) const override
;
514 /// @return 0.0 if empty or empty path, else value or DoubleError.
515 virtual double GetDouble( SCSIZE nC
, SCSIZE nR
) const override
;
516 /// @return 0.0 if empty or empty path, else value or DoubleError.
517 virtual double GetDouble( SCSIZE nIndex
) const override
;
518 /// @return value or DoubleError or string converted to value.
519 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const override
;
521 /// @return empty string if empty or empty path, else string content.
522 virtual svl::SharedString
GetString( SCSIZE nC
, SCSIZE nR
) const override
;
523 /// @return empty string if empty or empty path, else string content.
524 virtual svl::SharedString
GetString( SCSIZE nIndex
) const override
;
526 /** @returns the matrix element's string if one is present, otherwise the
527 numerical value formatted as string, or in case of an error the error
528 string is returned; an empty string for empty, a "FALSE" string for
530 virtual svl::SharedString
GetString( SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const override
;
532 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
534 virtual ScMatrixValue
Get( SCSIZE nC
, SCSIZE nR
) const override
;
536 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
537 path, in fact non-value. */
538 virtual bool IsStringOrEmpty( SCSIZE nIndex
) const override
;
540 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
541 path, in fact non-value. */
542 virtual bool IsStringOrEmpty( SCSIZE nC
, SCSIZE nR
) const override
;
544 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
545 virtual bool IsEmpty( SCSIZE nC
, SCSIZE nR
) const override
;
547 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
548 virtual bool IsEmptyCell( SCSIZE nC
, SCSIZE nR
) const override
;
550 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
551 virtual bool IsEmptyResult( SCSIZE nC
, SCSIZE nR
) const override
;
553 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
554 virtual bool IsEmptyPath( SCSIZE nC
, SCSIZE nR
) const override
;
556 /// @return <TRUE/> if value or boolean.
557 virtual bool IsValue( SCSIZE nIndex
) const override
;
559 /// @return <TRUE/> if value or boolean.
560 virtual bool IsValue( SCSIZE nC
, SCSIZE nR
) const override
;
562 /// @return <TRUE/> if value or boolean or empty or empty path.
563 virtual bool IsValueOrEmpty( SCSIZE nC
, SCSIZE nR
) const override
;
565 /// @return <TRUE/> if boolean.
566 virtual bool IsBoolean( SCSIZE nC
, SCSIZE nR
) const override
;
568 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
569 virtual bool IsNumeric() const override
;
571 virtual void MatTrans( ScMatrix
& mRes
) const override
;
572 virtual void MatCopy ( ScMatrix
& mRes
) const override
;
574 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
575 virtual void CompareEqual() override
;
576 virtual void CompareNotEqual() override
;
577 virtual void CompareLess() override
;
578 virtual void CompareGreater() override
;
579 virtual void CompareLessEqual() override
;
580 virtual void CompareGreaterEqual() override
;
582 virtual double And() const override
; // logical AND of all matrix values, or NAN
583 virtual double Or() const override
; // logical OR of all matrix values, or NAN
584 virtual double Xor() const override
; // logical XOR of all matrix values, or NAN
586 virtual IterateResult
Sum(bool bTextAsZero
) const override
;
587 virtual IterateResult
SumSquare(bool bTextAsZero
) const override
;
588 virtual IterateResult
Product(bool bTextAsZero
) const override
;
589 virtual size_t Count(bool bCountStrings
, bool bCountErrors
) const override
;
590 virtual size_t MatchDoubleInColumns(double fValue
, size_t nCol1
, size_t nCol2
) const override
;
591 virtual size_t MatchStringInColumns(const svl::SharedString
& rStr
, size_t nCol1
, size_t nCol2
) const override
;
593 virtual double GetMaxValue( bool bTextAsZero
) const override
;
594 virtual double GetMinValue( bool bTextAsZero
) const override
;
595 virtual double GetGcd() const override
;
596 virtual double GetLcm() const override
;
598 virtual ScMatrixRef
CompareMatrix(
599 sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
) const override
;
602 * Convert the content of matrix into a linear array of numeric values.
603 * String elements are mapped to NaN's and empty elements are mapped to
604 * either NaN or zero values.
606 * @param bEmptyAsZero if true empty elements are mapped to zero values,
607 * otherwise they become NaN values.
609 virtual void GetDoubleArray( std::vector
<double>& rArray
, bool bEmptyAsZero
= true ) const override
;
610 virtual void MergeDoubleArray( std::vector
<double>& rArray
, Op eOp
) const override
;
612 virtual void NotOp(ScMatrix
& rMat
) override
;
613 virtual void NegOp(ScMatrix
& rMat
) override
;
614 virtual void AddOp(double fVal
, ScMatrix
& rMat
) override
;
615 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
616 virtual void MulOp(double fVal
, ScMatrix
& rMat
) override
;
617 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
618 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
620 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) override
;
622 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
623 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
624 EmptyOpFunction aEmptyFunc
) const override
;
625 ScFullMatrix
& operator+= ( const ScFullMatrix
& r
);
627 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
628 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) override
;
631 virtual void Dump() const override
;
635 class SC_DLLPUBLIC ScVectorRefMatrix
: public ScMatrix
637 const formula::DoubleVectorRefToken
* mpToken
;
638 ScInterpreter
* mpErrorInterpreter
;
640 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
641 std::unique_ptr
<ScFullMatrix
> mpFullMatrix
;
646 ScVectorRefMatrix( const ScVectorRefMatrix
& ) = delete;
647 ScVectorRefMatrix
& operator=( const ScVectorRefMatrix
&) = delete;
649 /// For the operations that are not fully implemented, create a ScFullMatrix, and operate on it.
651 /// Note: This is potentially an expensive operation.
652 /// TODO: Implement as much as possible directly using the DoubleVectorRefToken.
653 void ensureFullMatrix();
657 ScVectorRefMatrix(const formula::DoubleVectorRefToken
* pToken
, SCSIZE nRowStart
, SCSIZE nRowSize
);
659 virtual ~ScVectorRefMatrix() override
;
661 /** Clone the matrix. */
662 virtual ScMatrix
* Clone() const override
;
665 * Resize the matrix to specified new dimension.
667 virtual void Resize(SCSIZE nC
, SCSIZE nR
) override
;
669 virtual void Resize(SCSIZE nC
, SCSIZE nR
, double fVal
) override
;
671 /** Clone the matrix and extend it to the new size. nNewCols and nNewRows
672 MUST be at least of the size of the original matrix. */
673 virtual ScMatrix
* CloneAndExtend(SCSIZE nNewCols
, SCSIZE nNewRows
) const override
;
675 virtual void SetErrorInterpreter(ScInterpreter
* p
) override
;
676 virtual void GetDimensions(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
677 virtual SCSIZE
GetElementCount() const override
;
678 virtual bool ValidColRow( SCSIZE nC
, SCSIZE nR
) const override
;
680 /** For a row vector or column vector, if the position does not point into
681 the vector but is a valid column or row offset it is adapted such that
682 it points to an element to be replicated, same column row 0 for a row
683 vector, same row column 0 for a column vector. Else, for a 2D matrix,
686 virtual bool ValidColRowReplicated(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
688 /** Checks if the matrix position is within the matrix. If it is not, for a
689 row vector or column vector the position is adapted such that it points
690 to an element to be replicated, same column row 0 for a row vector,
691 same row column 0 for a column vector. Else, for a 2D matrix and
692 position not within matrix, returns false.
694 virtual bool ValidColRowOrReplicated(SCSIZE
& rC
, SCSIZE
& rR
) const override
;
696 virtual void PutDouble(double fVal
, SCSIZE nC
, SCSIZE nR
) override
;
697 virtual void PutDouble(double fVal
, SCSIZE nIndex
) override
;
698 virtual void PutDouble(const double* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
700 virtual void PutString(const svl::SharedString
& rStr
, SCSIZE nC
, SCSIZE nR
) override
;
701 virtual void PutString(const svl::SharedString
& rStr
, SCSIZE nIndex
) override
;
702 virtual void PutString(const svl::SharedString
* pArray
, size_t nLen
, SCSIZE nC
, SCSIZE nR
) override
;
704 virtual void PutEmpty(SCSIZE nC
, SCSIZE nR
) override
;
706 /// Jump sal_False without path
707 virtual void PutEmptyPath(SCSIZE nC
, SCSIZE nR
) override
;
708 virtual void PutError(FormulaError nErrorCode
, SCSIZE nC
, SCSIZE nR
) override
;
709 virtual void PutBoolean(bool bVal
, SCSIZE nC
, SCSIZE nR
) override
;
711 virtual void FillDouble(double fVal
, SCSIZE nC1
, SCSIZE nR1
, SCSIZE nC2
, SCSIZE nR2
) override
;
713 /** Put a column vector of doubles, starting at row nR, must fit into dimensions. */
714 virtual void PutDoubleVector(const ::std::vector
< double > & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
716 /** Put a column vector of strings, starting at row nR, must fit into dimensions. */
717 virtual void PutStringVector(const ::std::vector
< svl::SharedString
> & rVec
, SCSIZE nC
, SCSIZE nR
) override
;
719 /** Put a column vector of empties, starting at row nR, must fit into dimensions. */
720 virtual void PutEmptyVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
722 /** Put a column vector of empty results, starting at row nR, must fit into dimensions. */
723 virtual void PutEmptyResultVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
725 /** Put a column vector of empty paths, starting at row nR, must fit into dimensions. */
726 virtual void PutEmptyPathVector(SCSIZE nCount
, SCSIZE nC
, SCSIZE nR
) override
;
728 /** May be used before obtaining the double value of an element to avoid
729 passing its NAN around.
730 @ATTENTION: MUST NOT be used if the element is a string!
731 Use GetErrorIfNotString() instead if not sure.
732 @returns 0 if no error, else one of err... constants */
733 virtual FormulaError
GetError(SCSIZE nC
, SCSIZE nR
) const override
;
735 /// @return 0.0 if empty or empty path, else value or DoubleError.
736 virtual double GetDouble(SCSIZE nC
, SCSIZE nR
) const override
;
737 /// @return 0.0 if empty or empty path, else value or DoubleError.
738 virtual double GetDouble(SCSIZE nIndex
) const override
;
739 /// @return value or DoubleError or string converted to value.
740 virtual double GetDoubleWithStringConversion( SCSIZE nC
, SCSIZE nR
) const override
;
742 /// @return empty string if empty or empty path, else string content.
743 virtual svl::SharedString
GetString(SCSIZE nC
, SCSIZE nR
) const override
;
744 /// @return empty string if empty or empty path, else string content.
745 virtual svl::SharedString
GetString(SCSIZE nIndex
) const override
;
747 /** @returns the matrix element's string if one is present, otherwise the
748 numerical value formatted as string, or in case of an error the error
749 string is returned; an empty string for empty, a "FALSE" string for
751 virtual svl::SharedString
GetString(SvNumberFormatter
& rFormatter
, SCSIZE nC
, SCSIZE nR
) const override
;
753 /// @ATTENTION: If bString the ScMatrixValue->pS may still be NULL to indicate
755 virtual ScMatrixValue
Get(SCSIZE nC
, SCSIZE nR
) const override
;
757 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
758 path, in fact non-value. */
759 virtual bool IsStringOrEmpty(SCSIZE nIndex
) const override
;
761 /** @return <TRUE/> if string or any empty, empty cell, empty result, empty
762 path, in fact non-value. */
763 virtual bool IsStringOrEmpty(SCSIZE nC
, SCSIZE nR
) const override
;
765 /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
766 virtual bool IsEmpty(SCSIZE nC
, SCSIZE nR
) const override
;
768 /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
769 virtual bool IsEmptyCell(SCSIZE nC
, SCSIZE nR
) const override
;
771 /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
772 virtual bool IsEmptyResult(SCSIZE nC
, SCSIZE nR
) const override
;
774 /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
775 virtual bool IsEmptyPath(SCSIZE nC
, SCSIZE nR
) const override
;
777 /// @return <TRUE/> if value or boolean.
778 virtual bool IsValue(SCSIZE nIndex
) const override
;
780 /// @return <TRUE/> if value or boolean.
781 virtual bool IsValue(SCSIZE nC
, SCSIZE nR
) const override
;
783 /// @return <TRUE/> if value or boolean or empty or empty path.
784 virtual bool IsValueOrEmpty(SCSIZE nC
, SCSIZE nR
) const override
;
786 /// @return <TRUE/> if boolean.
787 virtual bool IsBoolean(SCSIZE nC
, SCSIZE nR
) const override
;
789 /// @return <TRUE/> if entire matrix is numeric, including booleans, with no strings or empties
790 virtual bool IsNumeric() const override
;
792 virtual void MatTrans(ScMatrix
& mRes
) const override
;
793 virtual void MatCopy (ScMatrix
& mRes
) const override
;
795 // Convert ScInterpreter::CompareMat values (-1,0,1) to boolean values
796 virtual void CompareEqual() override
;
797 virtual void CompareNotEqual() override
;
798 virtual void CompareLess() override
;
799 virtual void CompareGreater() override
;
800 virtual void CompareLessEqual() override
;
801 virtual void CompareGreaterEqual() override
;
803 virtual double And() const override
; // logical AND of all matrix values, or NAN
804 virtual double Or() const override
; // logical OR of all matrix values, or NAN
805 virtual double Xor() const override
; // logical XOR of all matrix values, or NAN
807 virtual IterateResult
Sum(bool bTextAsZero
) const override
;
808 virtual IterateResult
SumSquare(bool bTextAsZero
) const override
;
809 virtual IterateResult
Product(bool bTextAsZero
) const override
;
810 virtual size_t Count(bool bCountStrings
, bool bCountErrors
) const override
;
811 virtual size_t MatchDoubleInColumns(double fValue
, size_t nCol1
, size_t nCol2
) const override
;
812 virtual size_t MatchStringInColumns(const svl::SharedString
& rStr
, size_t nCol1
, size_t nCol2
) const override
;
814 virtual double GetMaxValue(bool bTextAsZero
) const override
;
815 virtual double GetMinValue(bool bTextAsZero
) const override
;
816 virtual double GetGcd() const override
;
817 virtual double GetLcm() const override
;
819 virtual ScMatrixRef
CompareMatrix(sc::Compare
& rComp
, size_t nMatPos
, sc::CompareOptions
* pOptions
) const override
;
822 * Convert the content of matrix into a linear array of numeric values.
823 * String elements are mapped to NaN's and empty elements are mapped to
824 * either NaN or zero values.
826 * @param bEmptyAsZero if true empty elements are mapped to zero values,
827 * otherwise they become NaN values.
829 virtual void GetDoubleArray(std::vector
<double>& rVector
, bool bEmptyAsZero
= true) const override
;
830 virtual void MergeDoubleArray(std::vector
<double>& rVector
, Op eOp
) const override
;
832 virtual void NotOp(ScMatrix
& rMat
) override
;
833 virtual void NegOp(ScMatrix
& rMat
) override
;
834 virtual void AddOp(double fVal
, ScMatrix
& rMat
) override
;
835 virtual void SubOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
836 virtual void MulOp(double fVal
, ScMatrix
& rMat
) override
;
837 virtual void DivOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
838 virtual void PowOp(bool bFlag
, double fVal
, ScMatrix
& rMat
) override
;
840 virtual std::vector
<ScMatrix::IterateResult
> Collect(bool bTextAsZero
, const std::vector
<std::unique_ptr
<sc::op::Op
>>& aOp
) override
;
842 virtual void ExecuteOperation(const std::pair
<size_t, size_t>& rStartPos
, const std::pair
<size_t, size_t>& rEndPos
,
843 DoubleOpFunction aDoubleFunc
, BoolOpFunction aBoolFunc
, StringOpFunction aStringFunc
,
844 EmptyOpFunction aEmptyFunc
) const override
;
846 ScVectorRefMatrix
& operator+=(const ScVectorRefMatrix
& r
);
848 virtual void MatConcat(SCSIZE nMaxCol
, SCSIZE nMaxRow
, const ScMatrixRef
& xMat1
, const ScMatrixRef
& xMat2
,
849 SvNumberFormatter
& rFormatter
, svl::SharedStringPool
& rPool
) override
;
852 virtual void Dump() const override
858 inline void intrusive_ptr_add_ref(const ScMatrix
* p
)
863 inline void intrusive_ptr_release(const ScMatrix
* p
)
868 #endif // INCLUDED_SC_INC_SCMATRIX_HXX
870 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */