File indexing completed on 2024-04-28 16:21:38
0001 /* This file is part of the KDE project 0002 Copyright (C) 2005-2007 Tomas Mecir <mecirt@gmail.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #ifndef CALLIGRA_SHEETS_VALUECALC 0021 #define CALLIGRA_SHEETS_VALUECALC 0022 0023 #include <map> 0024 0025 #include <QVector> 0026 0027 #include "Number.h" 0028 #include "Value.h" 0029 0030 #include "sheets_odf_export.h" 0031 0032 #ifdef max 0033 # undef max 0034 #endif 0035 #ifdef min 0036 # undef min 0037 #endif 0038 0039 namespace Calligra 0040 { 0041 namespace Sheets 0042 { 0043 class Cell; 0044 class ValueCalc; 0045 class ValueConverter; 0046 0047 // Condition structures 0048 enum Comp { isEqual, isLess, isGreater, lessEqual, greaterEqual, notEqual, stringMatch, regexMatch, wildcardMatch }; 0049 enum Type { numeric, string }; 0050 0051 struct Condition { 0052 Comp comp; 0053 int index; 0054 Number value; 0055 QString stringValue; 0056 Type type; 0057 }; 0058 0059 typedef void (*arrayWalkFunc)(ValueCalc *, Value &result, 0060 Value val, Value param); 0061 // A function that can map an array element-wise 0062 typedef Value (ValueCalc::*arrayMapFunc)(const Value &val, const Value ¶m); 0063 0064 /** 0065 * \ingroup Value 0066 The ValueCalc class is used to perform all sorts of calculations. 0067 0068 Usage of this class for simpler calculations is deprecated, as we now use 0069 the Number object directly for that. This class is to be used for computations 0070 of more complicated and ranged functions. 0071 */ 0072 0073 class CALLIGRA_SHEETS_ODF_EXPORT ValueCalc 0074 { 0075 public: 0076 explicit ValueCalc(ValueConverter* c); 0077 0078 ValueConverter *conv() { 0079 return converter; 0080 } 0081 0082 const CalculationSettings* settings() const; 0083 0084 /** basic arithmetic operations */ 0085 Value add(const Value &a, const Value &b); 0086 Value sub(const Value &a, const Value &b); 0087 Value mul(const Value &a, const Value &b); 0088 Value div(const Value &a, const Value &b); 0089 Value mod(const Value &a, const Value &b); 0090 Value pow(const Value &a, const Value &b); 0091 Value sqr(const Value &a); 0092 Value sqrt(const Value &a); 0093 Value add(const Value &a, Number b); 0094 Value sub(const Value &a, Number b); 0095 Value mul(const Value &a, Number b); 0096 Value div(const Value &a, Number b); 0097 Value pow(const Value &a, Number b); 0098 Value abs(const Value &a); 0099 0100 /** comparison and related */ 0101 bool isZero(const Value &a); 0102 bool isEven(const Value &a); 0103 /** numerical comparison */ 0104 bool equal(const Value &a, const Value &b); 0105 /** numerical comparison with a little epsilon tolerance */ 0106 bool approxEqual(const Value &a, const Value &b); 0107 /** numerical comparison */ 0108 bool greater(const Value &a, const Value &b); 0109 /** numerical comparison - greater or equal */ 0110 bool gequal(const Value &a, const Value &b); 0111 /** numerical comparison */ 0112 bool lower(const Value &a, const Value &b); 0113 /** string comparison */ 0114 bool strEqual(const Value &a, const Value &b, bool CalcS = true); 0115 /** string comparison */ 0116 bool strGreater(const Value &a, const Value &b, bool CalcS = true); 0117 /** string comparison - greater or equal */ 0118 bool strGequal(const Value &a, const Value &b, bool CalcS = true); 0119 /** string comparison */ 0120 bool strLower(const Value &a, const Value &b, bool CalcS = true); 0121 /** string or numerical comparison */ 0122 bool naturalEqual(const Value &a, const Value &b, bool CalcS = true); 0123 /** string or numerical comparison */ 0124 bool naturalGreater(const Value &a, const Value &b, bool CalcS = true); 0125 /** string or numerical comparison - greater or equal */ 0126 bool naturalGequal(const Value &a, const Value &b, bool CalcS = true); 0127 /** string or numerical comparison */ 0128 bool naturalLower(const Value &a, const Value &b, bool CalcS = true); 0129 /** string or numerical comparison - lower or equal */ 0130 bool naturalLequal(const Value &a, const Value &b, bool CalcS = true); 0131 0132 int sign(const Value &a); 0133 0134 // just a quick workaround 0135 Value add(Number a, const Value& b) { 0136 return add(Value(a), b); 0137 } 0138 Value sub(Number a, const Value& b) { 0139 return sub(Value(a), b); 0140 } 0141 Value mul(Number a, const Value& b) { 0142 return mul(Value(a), b); 0143 } 0144 Value div(Number a, const Value& b) { 0145 return div(Value(a), b); 0146 } 0147 Value pow(Number a, const Value& b) { 0148 return pow(Value(a), b); 0149 } 0150 0151 bool equal(const Value &a, Number b) { 0152 return equal(a, Value(b)); 0153 } 0154 bool greater(const Value &a, Number b) { 0155 return greater(a, Value(b)); 0156 } 0157 bool lower(const Value &a, Number b) { 0158 return lower(a, Value(b)); 0159 } 0160 bool equal(Number a, const Value &b) { 0161 return equal(Value(a), b); 0162 } 0163 bool greater(Number a, const Value &b) { 0164 return greater(Value(a), b); 0165 } 0166 bool lower(Number a, const Value &b) { 0167 return lower(Value(a), b); 0168 } 0169 0170 0171 /** rounding */ 0172 Value roundDown(const Value &a, const Value &digits); 0173 Value roundUp(const Value &a, const Value &digits); 0174 Value round(const Value &a, const Value &digits); 0175 Value roundDown(const Value &a, int digits = 0); 0176 Value roundUp(const Value &a, int digits = 0); 0177 Value round(const Value &a, int digits = 0); 0178 0179 /** logarithms and exponentials */ 0180 Value log(const Value &number, const Value &base); 0181 Value log(const Value &number, Number base = 10); 0182 Value ln(const Value &number); 0183 Value exp(const Value &number); 0184 0185 /** constants */ 0186 Value pi(); 0187 Value eps(); 0188 0189 /** random number from <0.0, range) */ 0190 Value random(Number range = 1.0); 0191 Value random(Value range); 0192 0193 /** some computational functions */ 0194 Value fact(const Value &which); 0195 Value fact(const Value &which, const Value &end); 0196 Value fact(int which, int end = 0); 0197 /** Number factorial (every other number multiplied) */ 0198 Value factDouble(int which); 0199 Value factDouble(Value which); 0200 0201 /** combinations */ 0202 Value combin(int n, int k); 0203 Value combin(Value n, Value k); 0204 0205 /** greatest common divisor */ 0206 Value gcd(const Value &a, const Value &b); 0207 /** lowest common multiplicator */ 0208 Value lcm(const Value &a, const Value &b); 0209 0210 /** base conversion 10 -> base */ 0211 Value base(const Value &val, int base = 16, int prec = 0, int minLength = 0); 0212 /** base conversion base -> 10 */ 0213 Value fromBase(const Value &val, int base = 16); 0214 0215 /** goniometric functions */ 0216 Value sin(const Value &number); 0217 Value cos(const Value &number); 0218 Value tg(const Value &number); 0219 Value cotg(const Value &number); 0220 Value asin(const Value &number); 0221 Value acos(const Value &number); 0222 Value atg(const Value &number); 0223 Value atan2(const Value &y, const Value &x); 0224 0225 /** hyperbolic functions */ 0226 Value sinh(const Value &number); 0227 Value cosh(const Value &number); 0228 Value tgh(const Value &number); 0229 Value asinh(const Value &number); 0230 Value acosh(const Value &number); 0231 Value atgh(const Value &number); 0232 0233 /** some statistical stuff 0234 TODO: we may want to move these over to a separate class or something, 0235 as the functions are mostly big */ 0236 Value phi(Value x); 0237 Value gauss(Value xx); 0238 Value gaussinv(Value xx); 0239 Value GetGamma(Value _x); 0240 Value GetLogGamma(Value _x); 0241 Value GetGammaDist(Value _x, Value _alpha, 0242 Value _beta); 0243 Value GetBeta(Value _x, Value _alpha, 0244 Value _beta); 0245 0246 /** bessel functions - may also end up being separated from here */ 0247 Value besseli(Value v, Value x); 0248 Value besselj(Value v, Value x); 0249 Value besselk(Value v, Value x); 0250 Value besseln(Value v, Value x); 0251 0252 /** error functions (see: man erf) */ 0253 Value erf(Value x); 0254 Value erfc(Value x); 0255 0256 /** array/range walking */ 0257 void arrayWalk(const Value &range, Value &res, 0258 arrayWalkFunc func, Value param); 0259 /** Walk the array in function-like style. 0260 This method is here to avoid duplication in function handlers. */ 0261 void arrayWalk(QVector<Value> &range, Value &res, 0262 arrayWalkFunc func, Value param); 0263 Value arrayMap(const Value &array, arrayMapFunc func, const Value ¶m); 0264 Value twoArrayMap(const Value &array1, arrayMapFunc func, const Value &array2); 0265 void twoArrayWalk(const Value &a1, const Value &a2, 0266 Value &res, arrayWalkFunc func); 0267 void twoArrayWalk(QVector<Value> &a1, 0268 QVector<Value> &a2, Value &res, arrayWalkFunc func); 0269 arrayWalkFunc awFunc(const QString &name); 0270 void registerAwFunc(const QString &name, arrayWalkFunc func); 0271 0272 /** basic range functions */ 0273 // if full is true, A-version is used (means string/bool values included) 0274 Value sum(const Value &range, bool full = true); 0275 Value sumsq(const Value &range, bool full = true); 0276 Value sumIf(const Value &range, const Condition &cond); 0277 Value sumIf(const Cell &sumRangeStart, 0278 const Value &checkRange, const Condition &cond); 0279 Value sumIfs(const Cell &sumRangeStart, 0280 QList<Value> c_Range, QList<Condition> cond, const float limit); 0281 Value averageIf(const Value &range, const Condition &cond); 0282 Value averageIf(const Cell &avgRangeStart, 0283 const Value &checkRange, const Condition &cond); 0284 Value averageIfs(const Cell &avgRangeStart, 0285 QList<Value> c_Range, QList<Condition> cond, const float limit); 0286 int count(const Value &range, bool full = true); 0287 int countIf(const Value &range, const Condition &cond); 0288 Value countIfs(const Cell &cntRangeStart, QList<Value> c_range, QList<Condition> cond, const float limit); 0289 Value avg(const Value &range, bool full = true); 0290 Value max(const Value &range, bool full = true); 0291 Value min(const Value &range, bool full = true); 0292 Value product(const Value &range, Value init, 0293 bool full = true); 0294 Value stddev(const Value &range, bool full = true); 0295 Value stddev(const Value &range, Value avg, 0296 bool full = true); 0297 Value stddevP(const Value &range, bool full = true); 0298 Value stddevP(const Value &range, Value avg, 0299 bool full = true); 0300 0301 /** range functions using value lists */ 0302 Value sum(QVector<Value> range, bool full = true); 0303 int count(QVector<Value> range, bool full = true); 0304 Value avg(QVector<Value> range, bool full = true); 0305 Value max(QVector<Value> range, bool full = true); 0306 Value min(QVector<Value> range, bool full = true); 0307 Value product(QVector<Value> range, Value init, 0308 bool full = true); 0309 Value stddev(QVector<Value> range, bool full = true); 0310 Value stddev(QVector<Value> range, Value avg, 0311 bool full = true); 0312 Value stddevP(QVector<Value> range, bool full = true); 0313 Value stddevP(QVector<Value> range, Value avg, 0314 bool full = true); 0315 0316 /** 0317 This method parses the condition in string text to the condition cond. 0318 It sets the condition's type and value. 0319 */ 0320 void getCond(Condition &cond, Value val); 0321 0322 /** 0323 Returns true if value d matches the condition cond, built with getCond(). 0324 Otherwise, it returns false. 0325 */ 0326 bool matches(const Condition &cond, Value d); 0327 0328 /** return formatting for the result, based on formattings of input values */ 0329 Value::Format format(Value a, Value b); 0330 0331 protected: 0332 ValueConverter* converter; 0333 0334 /** registered array-walk functions */ 0335 std::map<QString, arrayWalkFunc> awFuncs; 0336 }; 0337 0338 inline bool approxEqual(double a, double b) 0339 { 0340 if (a == b) 0341 return true; 0342 double x = a - b; 0343 return (x < 0.0 ? -x : x) 0344 < ((a < 0.0 ? -a : a) *(1.0 / (16777216.0 * 16777216.0))); 0345 } 0346 0347 inline double approxFloor(double a) 0348 { 0349 double b = floor(a); 0350 // The second approxEqual() is necessary for values that are near the limit 0351 // of numbers representable with 4 bits stripped off. (#i12446#) 0352 if (approxEqual(a - 1.0, b) && !approxEqual(a, b)) 0353 return b + 1.0; 0354 return b; 0355 } 0356 0357 } // namespace Sheets 0358 } // namespace Calligra 0359 0360 0361 #endif // CALLIGRA_SHEETS_VALUECALC 0362