[Libreoffice-commits] core.git: Branch 'libreoffice-6-2' - 2 commits - sc/inc sc/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Tue Dec 11 21:24:27 UTC 2018
sc/inc/dpglobal.hxx | 2 +-
sc/inc/subtotal.hxx | 23 ++++++++++++++++++++++-
sc/source/core/data/column2.cxx | 14 ++++++++++++--
sc/source/core/data/documen4.cxx | 39 ++++++++++++++++++++++++++++++++++++---
sc/source/core/tool/subtotal.cxx | 8 ++++++++
5 files changed, 79 insertions(+), 7 deletions(-)
New commits:
commit 80fdc2491df857c910afbd30c025b4594cb1cf83
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Tue Dec 11 17:35:00 2018 +0100
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Tue Dec 11 22:24:16 2018 +0100
Correct typed_flags<PivotFunc> mask is 0x1fff
This was wrong since
commit 298ee50676b849020a8a5042e8612f71379ecf3b
CommitDate: Sun Nov 20 00:14:28 2016 +0100
PivotMedian: Implement median as a new pivot table function
and in fact in a debug build failed an assertion
soffice.bin: include/o3tl/typed_flags_set.hxx:85:
constexpr o3tl::is_typed_flags<E, M>::Wrap::Wrap(type name std::underlying_type<_Tp>::type)
[with E = PivotFunc; typename std::underlying_type<_Tp>::type M = 4607; typename std::underlying_type<_Tp>::type = int]:
Assertion `static_cast<typename std::underlying_type<E>::type>(~0) == M || (value & ~M) == 0' failed.
when one of the functions (e.g. StdVar) not included in the mask
was chosen as pivot table data function.
Change-Id: I5b9efc7d2cbcf6fece3ef228db8f6e0ffa17b510
Reviewed-on: https://gerrit.libreoffice.org/64974
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Jenkins
(cherry picked from commit 639a401fbd910c1fede35f7106a5acf716ec5fea)
Reviewed-on: https://gerrit.libreoffice.org/64984
diff --git a/sc/inc/dpglobal.hxx b/sc/inc/dpglobal.hxx
index 295af86db148..0a5b6e94dc6b 100644
--- a/sc/inc/dpglobal.hxx
+++ b/sc/inc/dpglobal.hxx
@@ -39,7 +39,7 @@ enum class PivotFunc {
Auto = 0x1000
};
namespace o3tl {
- template<> struct typed_flags<PivotFunc> : is_typed_flags<PivotFunc, 0x11ff> {};
+ template<> struct typed_flags<PivotFunc> : is_typed_flags<PivotFunc, 0x1fff> {};
}
struct ScDPValue
commit 1cb79dd63e0f825cee46fa58a6a9df39e8160f60
Author: Eike Rathke <erack at redhat.com>
AuthorDate: Tue Dec 11 12:43:14 2018 +0100
Commit: Eike Rathke <erack at redhat.com>
CommitDate: Tue Dec 11 22:24:03 2018 +0100
Resolves: tdf#46119 implement GeneralFunction_VAR, VARP, STDEV and STDEVP
These were never implemented. Likely because they aren't used
internally by Calc, which for formula expressions in the
interpreter and for DataPilot / pivot table uses a different
approach, but they are needed for
css::sheet::XSheetOperation::computeFunction()
Change-Id: I1af038bf9db8d0c04d69598b992b827b083e2248
Reviewed-on: https://gerrit.libreoffice.org/64957
Reviewed-by: Eike Rathke <erack at redhat.com>
Tested-by: Jenkins
(cherry picked from commit fc1568d570a96bfa57013ae62adf3f9606639fd3)
Reviewed-on: https://gerrit.libreoffice.org/64975
diff --git a/sc/inc/subtotal.hxx b/sc/inc/subtotal.hxx
index 7858fcae6f2b..46f6fcc7693c 100644
--- a/sc/inc/subtotal.hxx
+++ b/sc/inc/subtotal.hxx
@@ -30,11 +30,32 @@ public:
static bool SafeDiv( double& fVal1, double fVal2);
};
+/** Implements the Welford Online one-pass algorithm.
+ See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_Online_algorithm
+ and Donald E. Knuth, TAoCP vol.2, 3rd edn., p. 232
+ */
+class WelfordRunner
+{
+public:
+ WelfordRunner() : fMean(0.0), fM2(0.0), nCount(0) {}
+ void update( double fVal );
+ sal_uInt64 getCount() const { return nCount; }
+ double getMean() const { return fMean; }
+ double getVarianceSample() const { return nCount > 1 ? fM2 / (nCount-1) : 0.0; }
+ double getVariancePopulation() const { return nCount > 0 ? fM2 / nCount : 0.0; }
+
+private:
+ double fMean;
+ double fM2;
+ sal_Int64 nCount;
+};
+
struct ScFunctionData // to calculate single functions
{
+ WelfordRunner maWelford;
ScSubTotalFunc const eFunc;
double nVal;
- long nCount;
+ sal_uInt64 nCount;
bool bError;
ScFunctionData( ScSubTotalFunc eFn ) :
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index c46f1a70ce8b..5f77628699f6 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -3423,10 +3423,20 @@ class UpdateSubTotalHandler
mrData.nVal = fVal;
}
break;
- default:
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_VARP:
+ case SUBTOTAL_FUNC_STD:
+ case SUBTOTAL_FUNC_STDP:
{
- // added to avoid warnings
+ if (!bVal)
+ return;
+
+ mrData.maWelford.update( fVal);
}
+ break;
+ default:
+ // unhandled unknown
+ mrData.bError = true;
}
}
diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx
index 9e4cc23cb85d..94b361cde765 100644
--- a/sc/source/core/data/documen4.cxx
+++ b/sc/source/core/data/documen4.cxx
@@ -642,10 +642,43 @@ bool ScDocument::GetSelectionFunction( ScSubTotalFunc eFunc,
else
aData.bError = true;
break;
+ case SUBTOTAL_FUNC_VAR:
+ case SUBTOTAL_FUNC_STD:
+ if (aData.maWelford.getCount() < 2)
+ aData.bError = true;
+ else
+ {
+ rResult = aData.maWelford.getVarianceSample();
+ if (eFunc == SUBTOTAL_FUNC_STD)
+ {
+ if (rResult < 0.0)
+ aData.bError = true;
+ else
+ rResult = sqrt( rResult);
+ }
+ }
+ break;
+ case SUBTOTAL_FUNC_VARP:
+ case SUBTOTAL_FUNC_STDP:
+ if (aData.maWelford.getCount() < 1)
+ aData.bError = true;
+ else if (aData.maWelford.getCount() == 1)
+ rResult = 0.0;
+ else
+ {
+ rResult = aData.maWelford.getVariancePopulation();
+ if (eFunc == SUBTOTAL_FUNC_STDP)
+ {
+ if (rResult < 0.0)
+ aData.bError = true;
+ else
+ rResult = sqrt( rResult);
+ }
+ }
+ break;
default:
- {
- // added to avoid warnings
- }
+ // unhandled unknown
+ aData.bError = true;
}
if (aData.bError)
diff --git a/sc/source/core/tool/subtotal.cxx b/sc/source/core/tool/subtotal.cxx
index f57d0ae1d8d4..ec908b16eeec 100644
--- a/sc/source/core/tool/subtotal.cxx
+++ b/sc/source/core/tool/subtotal.cxx
@@ -62,4 +62,12 @@ bool SubTotal::SafeDiv(double& fVal1, double fVal2)
return bOk;
}
+void WelfordRunner::update( double fVal )
+{
+ ++nCount;
+ const double fDelta = fVal - fMean;
+ fMean += fDelta / nCount;
+ fM2 += fDelta * (fVal - fMean);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list