1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <MovingAverageRegressionCurveCalculator.hxx>
21 #include <RegressionCalculationHelper.hxx>
22 #include <ResId.hxx>
23 #include <strings.hrc>
24
25 #include <rtl/math.hxx>
26
27 #include <com/sun/star/chart2/MovingAverageType.hpp>
28
29 using namespace ::com::sun::star;
30 using namespace ::com::sun::star::chart2;
31
32 namespace chart
33 {
34
MovingAverageRegressionCurveCalculator()35 MovingAverageRegressionCurveCalculator::MovingAverageRegressionCurveCalculator()
36 {}
37
~MovingAverageRegressionCurveCalculator()38 MovingAverageRegressionCurveCalculator::~MovingAverageRegressionCurveCalculator()
39 {}
40
41 // ____ XRegressionCurveCalculator ____
recalculateRegression(const uno::Sequence<double> & aXValues,const uno::Sequence<double> & aYValues)42 void SAL_CALL MovingAverageRegressionCurveCalculator::recalculateRegression(
43 const uno::Sequence< double >& aXValues,
44 const uno::Sequence< double >& aYValues )
45 {
46 ::rtl::math::setNan( & m_fCorrelationCoefficient );
47
48 RegressionCalculationHelper::tDoubleVectorPair aValues(
49 RegressionCalculationHelper::cleanup(
50 aXValues, aYValues,
51 RegressionCalculationHelper::isValid()));
52
53 aYList.clear();
54 aXList.clear();
55
56 // For formulas, see
57 // https://docs.oasis-open.org/office/OpenDocument/v1.3/cs02/part3-schema/OpenDocument-v1.3-cs02-part3-schema.html#property-chart_regression-moving-type
58
59 switch (mnMovingType)
60 {
61 case MovingAverageType::Central:
62 {
63
64 calculateValuesCentral(aValues);
65 break;
66 }
67
68 case MovingAverageType::AveragedAbscissa:
69 {
70 calculateValues(aValues, true);
71 break;
72 }
73 case MovingAverageType::Prior:
74 default:
75 {
76 calculateValues(aValues, false);
77 break;
78 }
79 }
80 }
81
calculateValuesCentral(RegressionCalculationHelper::tDoubleVectorPair aValues)82 void MovingAverageRegressionCurveCalculator::calculateValuesCentral(
83 RegressionCalculationHelper::tDoubleVectorPair aValues)
84 {
85 const size_t aSize = aValues.first.size();
86 for (size_t i = mPeriod - 1; i < aSize; ++i)
87 {
88 double yAvg = 0.0;
89
90 for (sal_Int32 j = 0; j < mPeriod; j++)
91 {
92 yAvg += aValues.second[i - j];
93 }
94 yAvg /= mPeriod;
95 aYList.push_back(yAvg);
96 }
97 sal_Int32 nPeriodLocal = (mPeriod % 2 == 0) ? (mPeriod / 2) : ((mPeriod - 1) / 2);
98 for (size_t i = nPeriodLocal; i < aSize - 1; ++i)
99 {
100 double x = aValues.first[i];
101 aXList.push_back(x);
102 }
103 }
104
calculateValues(RegressionCalculationHelper::tDoubleVectorPair aValues,bool bUseXAvg)105 void MovingAverageRegressionCurveCalculator::calculateValues(
106 RegressionCalculationHelper::tDoubleVectorPair aValues, bool bUseXAvg)
107 {
108 const size_t aSize = aValues.first.size();
109 for (size_t i = mPeriod - 1; i < aSize; ++i)
110 {
111 double xAvg = 0.0;
112 double yAvg = 0.0;
113
114 for (sal_Int32 j = 0; j < mPeriod; j++)
115 {
116 xAvg += aValues.first[i - j];
117 yAvg += aValues.second[i - j];
118 }
119 yAvg /= mPeriod;
120 xAvg /= mPeriod;
121
122 aYList.push_back(yAvg);
123 if (bUseXAvg)
124 {
125 aXList.push_back(xAvg);
126 }
127 else
128 {
129 double x = aValues.first[i];
130 aXList.push_back(x);
131 }
132 }
133 }
134
getCurveValue(double)135 double SAL_CALL MovingAverageRegressionCurveCalculator::getCurveValue( double /*x*/ )
136 {
137 double fResult;
138 rtl::math::setNan(&fResult);
139 return fResult;
140 }
141
getCurveValues(double,double,sal_Int32,const uno::Reference<chart2::XScaling> &,const uno::Reference<chart2::XScaling> &,sal_Bool)142 uno::Sequence< geometry::RealPoint2D > SAL_CALL MovingAverageRegressionCurveCalculator::getCurveValues(
143 double /*min*/, double /*max*/, sal_Int32 /*nPointCount*/,
144 const uno::Reference< chart2::XScaling >& /*xScalingX*/,
145 const uno::Reference< chart2::XScaling >& /*xScalingY*/,
146 sal_Bool /*bMaySkipPointsInCalculation*/ )
147 {
148 size_t nSize = std::min(aXList.size(), aYList.size());
149 uno::Sequence< geometry::RealPoint2D > aResult( nSize );
150
151 for( size_t i = 0; i < nSize; ++i )
152 {
153 aResult[i].X = aXList[i];
154 aResult[i].Y = aYList[i];
155 }
156 return aResult;
157 }
158
ImplGetRepresentation(const uno::Reference<util::XNumberFormatter> &,sal_Int32,sal_Int32 *) const159 OUString MovingAverageRegressionCurveCalculator::ImplGetRepresentation(
160 const uno::Reference< util::XNumberFormatter >& /*xNumFormatter*/,
161 sal_Int32 /*nNumberFormatKey*/, sal_Int32* /*pFormulaLength = nullptr */ ) const
162 {
163 return SchResId( STR_OBJECT_MOVING_AVERAGE_WITH_PARAMETERS );
164 }
165
166 } // namespace chart
167
168 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
169