File indexing completed on 2024-05-12 17:22:41

0001 // quantity.h
0002 // Support for units and dimensions
0003 //
0004 // This file is part of the SpeedCrunch project
0005 // Copyright (C) 2016 Pol Welter.
0006 // Copyright (C) 2016 @heldercorreia
0007 //
0008 // This program is free software; you can redistribute it and/or
0009 // modify it under the terms of the GNU General Public License
0010 // as published by the Free Software Foundation; either version 2
0011 // of the License, or (at your option) any later version.
0012 //
0013 // This program is distributed in the hope that it will be useful,
0014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016 // GNU General Public License for more details.
0017 //
0018 // You should have received a copy of the GNU General Public License
0019 // along with this program; see the file COPYING.  If not, write to
0020 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021 // Boston, MA 02110-1301, USA.
0022 
0023 #ifndef QUANTITY_H
0024 #define QUANTITY_H
0025 
0026 #include "cmath.h"
0027 #include "hmath.h"
0028 #include "errors.h"
0029 
0030 #include <QMap>
0031 
0032 class CNumber;
0033 class HNumber;
0034 class QJsonObject;
0035 class QString;
0036 class Rational;
0037 
0038 class DMath;
0039 class Quantity;
0040 
0041 Quantity operator*(const HNumber&, const Quantity&);
0042 Quantity operator*(const CNumber&, const Quantity&);
0043 Quantity operator/(const HNumber&, const Quantity&);
0044 Quantity operator/(const CNumber&, const Quantity&);
0045 
0046 class Quantity {
0047     friend class DMath;
0048     friend Quantity operator-(const Quantity&);
0049     friend Quantity operator-(const Quantity&, const Quantity&);
0050     friend bool operator>(const Quantity&, const Quantity&);
0051     friend bool operator<(const Quantity&, const Quantity&);
0052     friend bool operator>=(const Quantity&, const Quantity&);
0053     friend bool operator<=(const Quantity&, const Quantity&);
0054     friend bool operator==(const Quantity&, const Quantity&);
0055     friend bool operator!=(const Quantity&, const Quantity&);
0056 
0057 public:
0058     Quantity();
0059     Quantity(const Quantity&);
0060     Quantity(int);
0061     Quantity(const QJsonObject&);
0062     Quantity(const HNumber&);
0063     Quantity(const CNumber&);
0064     ~Quantity();
0065 
0066     bool isNan() const;
0067     bool isZero() const;
0068     bool isReal() const;
0069     bool isPositive() const;
0070     bool isNegative() const;
0071     bool isInteger() const;
0072 
0073     bool hasUnit() const;
0074     CNumber unit() const;
0075     QString unitName() const;
0076     CNumber numericValue() const;
0077     Quantity& setDisplayUnit(const CNumber unit, const QString& name);
0078     void stripUnits();
0079     bool hasDimension() const;
0080     bool isDimensionless() const;
0081     QMap<QString, Rational> getDimension() const;
0082     void modifyDimension(const QString& key, const Rational& exponent);
0083     void copyDimension(const Quantity&);
0084     void clearDimension();
0085     bool sameDimension(const Quantity& other) const;
0086     void cleanDimension();
0087 
0088     void serialize(QJsonObject&) const;
0089     static Quantity deSerialize(const QJsonObject&);
0090 
0091     Error error() const;
0092 
0093     Quantity& operator=(const Quantity&);
0094     Quantity operator+(const Quantity&) const;
0095     Quantity& operator+=(const Quantity&);
0096     Quantity& operator-=(const Quantity&);
0097     Quantity operator*(const Quantity&) const;
0098     Quantity operator*(const CNumber&) const;
0099     Quantity operator*(const HNumber&) const;
0100     Quantity& operator*=(const Quantity&);
0101     Quantity operator/(const Quantity&) const;
0102     Quantity operator/(const HNumber&) const;
0103     Quantity operator/(const CNumber&) const;
0104     Quantity& operator/=(const Quantity&);
0105     Quantity operator%(const Quantity&) const;
0106     Quantity operator&(const Quantity&) const;
0107     Quantity& operator&=(const Quantity&);
0108     Quantity operator|(const Quantity&) const;
0109     Quantity& operator|=(const Quantity&);
0110     Quantity operator^(const Quantity&) const;
0111     Quantity& operator^=(const Quantity&);
0112     Quantity operator~() const;
0113     Quantity operator>>(const Quantity&) const;
0114     Quantity operator<<(const Quantity&) const;
0115 
0116     class Format : public CNumber::Format {
0117     public:
0118         Format();
0119         Format(const CNumber::Format&);
0120         Format(const HNumber::Format&);
0121         Format operator+(const Format&) const;
0122 
0123         void serialize(QJsonObject&) const;
0124         static Format deSerialize(const QJsonObject&);
0125         bool isNull() const;
0126     };
0127 
0128     Format format() const { return m_format; }
0129     Quantity& setFormat(Format);
0130 
0131 private:
0132     CNumber m_numericValue;
0133     QMap<QString, Rational> m_dimension;
0134     CNumber* m_unit;
0135     QString m_unitName;
0136     Format m_format;
0137 };
0138 
0139 /*
0140  * Math functions for quantities with dimensions
0141  */
0142 class DMath {
0143 public:
0144     static bool complexMode;
0145 
0146     static QString format(const Quantity, Quantity::Format = Quantity::Format());
0147 
0148     // CONSTANTS
0149     static Quantity e();
0150     static Quantity phi();
0151     static Quantity pi();
0152     static Quantity nan(Error = Success);
0153     static Quantity i();
0154     // GENERAL MATH
0155     static Quantity rad2deg(const Quantity&);
0156     static Quantity deg2rad(const Quantity&);
0157     static Quantity rad2gon(const Quantity&);
0158     static Quantity gon2rad(const Quantity&);
0159     static Quantity abs(const Quantity&);
0160     static Quantity integer(const Quantity&);
0161     static Quantity frac(const Quantity&);
0162     static Quantity floor(const Quantity&);
0163     static Quantity ceil(const Quantity&);
0164     static Quantity gcd(const Quantity&, const Quantity&);
0165     static Quantity idiv(const Quantity&, const Quantity&);
0166     static Quantity round(const Quantity&, int prec = 0);
0167     static Quantity trunc(const Quantity&, int prec = 0);
0168     static Quantity sqrt(const Quantity&);
0169     static Quantity cbrt(const Quantity&);
0170     static Quantity raise(const Quantity&, int);
0171     static Quantity raise(const Quantity&, const Quantity&);
0172     static Quantity sgn(const Quantity&);
0173     // EXPONENTIAL FUNCTION AND RELATED
0174     static Quantity exp(const Quantity&);
0175     static Quantity ln(const Quantity&);
0176     static Quantity lg(const Quantity&);
0177     static Quantity lb(const Quantity&);
0178     static Quantity log(const Quantity& base, const Quantity&);
0179     static Quantity sinh(const Quantity&);
0180     static Quantity cosh(const Quantity&);
0181     static Quantity tanh(const Quantity&);
0182     static Quantity arsinh(const Quantity&);
0183     static Quantity arcosh(const Quantity&);
0184     static Quantity artanh(const Quantity&);
0185     // COMPLEX
0186     static Quantity real(const Quantity&);
0187     static Quantity imag(const Quantity&);
0188     static Quantity conj(const Quantity&);
0189     static Quantity phase(const Quantity&);
0190     // TRIGONOMETRY
0191     static Quantity sin(const Quantity&);
0192     static Quantity cos(const Quantity&);
0193     static Quantity tan(const Quantity&);
0194     static Quantity cot(const Quantity&);
0195     static Quantity sec(const Quantity&);
0196     static Quantity csc(const Quantity&);
0197     static Quantity arcsin(const Quantity&);
0198     static Quantity arccos(const Quantity&);
0199     static Quantity arctan(const Quantity&);
0200     static Quantity arctan2(const Quantity&, const Quantity & y);
0201     // HIGHER MATH FUNCTIONS
0202     static Quantity factorial(const Quantity& x, const Quantity& base = CNumber(1));
0203     static Quantity gamma(const Quantity&);
0204     static Quantity lnGamma(const Quantity&);
0205     static Quantity erf(const Quantity&);
0206     static Quantity erfc(const Quantity&);
0207     // PROBABILITY
0208     static Quantity nCr(const Quantity& n, const Quantity& k);
0209     static Quantity nPr(const Quantity& n, const Quantity& r);
0210     static Quantity binomialPmf(const Quantity& k, const Quantity& n, const Quantity& p);
0211     static Quantity binomialCdf(const Quantity& k, const Quantity& n, const Quantity& p);
0212     static Quantity binomialMean(const Quantity& n, const Quantity& p);
0213     static Quantity binomialVariance(const Quantity& n, const Quantity& p);
0214     static Quantity hypergeometricPmf(const Quantity& k, const Quantity& N, const Quantity& M, const Quantity& n);
0215     static Quantity hypergeometricCdf(const Quantity& k, const Quantity& N, const Quantity& M, const Quantity& n);
0216     static Quantity hypergeometricMean(const Quantity& N, const Quantity& M, const Quantity& n);
0217     static Quantity hypergeometricVariance(const Quantity& N, const Quantity& M, const Quantity& n);
0218     static Quantity poissonPmf(const Quantity& k, const Quantity& l);
0219     static Quantity poissonCdf(const Quantity& k, const Quantity& l);
0220     static Quantity poissonMean(const Quantity& l);
0221     static Quantity poissonVariance(const Quantity& l);
0222     // LOGIC
0223     static Quantity mask (const Quantity&, const Quantity& bits);
0224     static Quantity sgnext (const Quantity&, const Quantity& bits);
0225     static Quantity ashr(const Quantity&, const Quantity& bits);
0226     // IEEE-754 CONVERSION
0227     static Quantity decodeIeee754(const Quantity&, const Quantity& exp_bits, const Quantity& significand_bits);
0228     static Quantity decodeIeee754(const Quantity&, const Quantity& exp_bits, const Quantity& significand_bits,
0229                                   const Quantity& exp_bias);
0230     static Quantity encodeIeee754(const Quantity&, const Quantity& exp_bits, const Quantity& significand_bits);
0231     static Quantity encodeIeee754(const Quantity&, const Quantity& exp_bits, const Quantity& significand_bits,
0232                                   const Quantity& exp_bias);
0233 };
0234 
0235 #endif // QUANTITY_H