File indexing completed on 2024-04-28 03:40:46

0001 /*************************************************************************************
0002  *  Copyright (C) 2007 by Aleix Pol <aleixpol@kde.org>                               *
0003  *                                                                                   *
0004  *  This program is free software; you can redistribute it and/or                    *
0005  *  modify it under the terms of the GNU General Public License                      *
0006  *  as published by the Free Software Foundation; either version 2                   *
0007  *  of the License, or (at your option) any later version.                           *
0008  *                                                                                   *
0009  *  This program 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                    *
0012  *  GNU General Public License for more details.                                     *
0013  *                                                                                   *
0014  *  You should have received a copy of the GNU General Public License                *
0015  *  along with this program; if not, write to the Free Software                      *
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
0017  *************************************************************************************/
0018 
0019 #include "value.h"
0020 #include "operator.h"
0021 #include "abstractexpressionvisitor.h"
0022 
0023 #include <QDomElement>
0024 
0025 
0026 
0027 using namespace Analitza;
0028 
0029 Object* Cn::copy() const
0030 {
0031     Cn *v = new Cn;
0032     v->m_value = m_value;
0033     v->m_imaginaryPart = m_imaginaryPart;
0034     v->m_format = m_format;
0035     return v;
0036 }
0037 
0038 
0039 QVariant Cn::accept(AbstractExpressionVisitor* e) const
0040 {
0041     return e->visit(this);
0042 }
0043 
0044 bool Cn::setValue(const QDomElement& val)
0045 {
0046 //     this->m_vformat=whatValueFormat(val);
0047     bool wrong=false;
0048     QString tag = val.tagName();
0049     m_format=Real;
0050     m_imaginaryPart=0;
0051     
0052     if(tag == QLatin1String("cn")){ // a is a number
0053         if(val.attribute(QStringLiteral("type"), QStringLiteral("integer")) == QLatin1String("real")) {
0054             m_value= val.text().trimmed().toDouble(&wrong); //TODO: Base on double not implemented
0055         } else if(val.attribute(QStringLiteral("type"), QStringLiteral("integer")) == QLatin1String("integer")){
0056             int base = val.attribute(QStringLiteral("base"), QStringLiteral("10")).toInt(nullptr, 10);
0057             m_value= val.text().trimmed().toInt(&wrong, base);
0058             m_format=Integer;
0059         }
0060 #if 0
0061         else if(val.attribute("type") == "e-notation")    { /*TODO: Not implemented */ }
0062         else if(val.attribute("type") == "rational")        { /*TODO: Not implemented */ }
0063         else if(val.attribute("type") == "complex-cartesian")    { /*TODO: Not implemented */ }
0064         else if(val.attribute("type") == "complex-polar")    { /*TODO: Not implemented */ }
0065 #endif
0066         else if(val.attribute(QStringLiteral("type")) == QLatin1String("constant")){
0067             if(val.text() == QLatin1String("&pi;"))            { m_value = pi().m_value; }
0068             else if (val.text() == QLatin1String("&ee;") || val.text() == QLatin1String("&ExponentialE;")){ m_value = e().m_value; }
0069             else if (val.text() == QLatin1String("&true;"))    { m_value=1.; m_format=Boolean; }
0070             else if (val.text() == QLatin1String("&false;"))    { m_value=0.; m_format=Boolean; }
0071             else if (val.text() == QLatin1String("&gamma;"))    { m_value = 0.5772156649; }
0072             else if (val.text() == QLatin1String("&ImagniaryI;"))    { m_value=0; m_imaginaryPart=1; m_format=Complex; }
0073 #if 0
0074             else if (val.text() == "&infin;")    ; //TODO: Not implemented  }
0075             else if (val.text() == "&NaN;")        ; //TODO: Not implemented  }*/
0076 #endif
0077         }
0078     }
0079     return wrong;
0080 }
0081 
0082 Cn Cn::pi() { return Cn(3.1415926535897932384626433); }
0083 Cn Cn::e() { return Cn(2.718281828); }
0084 Cn Cn::euler() { return Cn(0.5772156649); }
0085 
0086 bool Cn::matches(const Object* exp, QMap< QString, const Object* >*) const
0087 {
0088     return exp->type()==type() && *static_cast<const Cn*>(exp)==*this;
0089 }
0090 
0091 void Cn::setValue(const double& v)
0092 {
0093     m_format = Real;
0094     m_value = v;
0095     m_imaginaryPart = 0;
0096 }
0097 
0098 void Cn::setValue(int v)
0099 {
0100     m_format = Integer;
0101     m_value = v;
0102     m_imaginaryPart = 0;
0103 }
0104 
0105 void Cn::setValue(uint v)
0106 {
0107     m_format = Integer;
0108     m_value = v;
0109     m_imaginaryPart = 0;
0110 }
0111 
0112 void Cn::setValue(bool v)
0113 {
0114     m_format = Boolean;
0115     m_value = v;
0116     m_imaginaryPart = 0;
0117 }
0118 
0119 std::complex<double> Cn::complexValue() const
0120 {
0121     return std::complex<double>(m_value, m_imaginaryPart);
0122 }
0123 
0124 void Cn::setValue(std::complex<double> v)
0125 {
0126     if(v.imag() == 0)
0127         setValue(v.real());
0128     else {
0129         m_format = Complex;
0130         m_imaginaryPart = v.imag();
0131         m_value = v.real();
0132     }
0133 }
0134 
0135 constexpr bool ourFuzzyCompare(qreal a, qreal b)
0136 {
0137     return qAbs(a - b) < std::numeric_limits<double>::epsilon()*2;
0138 }
0139 
0140 bool Cn::operator==(const Analitza::Cn& d) const{
0141     return ourFuzzyCompare(m_value, d.m_value) && ourFuzzyCompare(m_imaginaryPart, d.m_imaginaryPart);
0142 }
0143