File indexing completed on 2024-05-12 05:55:09

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