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

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 "operator.h"
0020 #include "abstractexpressionvisitor.h"
0021 
0022 using namespace Analitza;
0023 
0024 const char Operator::words[nOfOps][14] = {
0025     "onone",
0026     "plus", "times", "minus", "divide", "quotient",
0027     "power", "root", "factorial",
0028     "and", "or", "xor", "not",
0029     "gcd", "lcm", "rem", "factorof",
0030     "max", "min",
0031     "lt", "gt", "eq", "neq", "leq", "geq", "implies",
0032     "approx", "abs", "floor", "ceiling",
0033     "sin", "cos", "tan",
0034     "sec", "csc", "cot",
0035     "sinh", "cosh", "tanh",
0036     "sech", "csch", "coth",
0037     "arcsin", "arccos", "arctan",
0038     "arccot", //"arccoth",
0039     "arccosh", "arccsc", "arccsch",
0040     "arcsec", "arcsech", "arcsinh", "arctanh",
0041     "exp", "ln", "log", 
0042     "conjugate", "arg", "real", "imaginary",
0043     "sum", "product", "diff",
0044     //Vector operations
0045     "card", "scalarproduct", "selector", "union",
0046     "forall", "exists",
0047     
0048     "map", "filter",
0049     
0050     "transpose",
0051     
0052     "function"
0053 };
0054 
0055 QVariant Operator::accept(AbstractExpressionVisitor* e) const
0056 {
0057     return e->visit(this);
0058 }
0059 
0060 QString Operator::name() const
0061 {
0062     Q_ASSERT(m_optype<nOfOps);
0063     return QString(words[m_optype]);
0064 }
0065 
0066 Operator::OperatorType Operator::toOperatorType(const QString &e)
0067 {
0068     OperatorType ret=none;
0069     for(int i=none; ret==none && i<nOfOps; i++) {
0070         if(words[i]==e)
0071             ret = OperatorType(i);
0072     }
0073     
0074     return ret;
0075 }
0076 
0077 Operator::OperatorType Operator::multiplicityOperator(const Operator::OperatorType& t)
0078 {
0079     OperatorType r;
0080     switch(t) {
0081         case minus:
0082         case plus:
0083             r=times;
0084             break;
0085         case times:
0086             r = power;
0087             break;
0088         default:
0089             r=none;
0090     }
0091     return r;
0092 }
0093 
0094 
0095 int Operator::nparams(Operator::OperatorType t)
0096 {
0097     switch(t) {
0098         case plus:
0099         case minus:
0100         case times:
0101         case min:
0102         case max:
0103         case _and:
0104         case _or:
0105         case _xor:
0106         case gcd:
0107         case lcm:
0108         case function:
0109         case scalarproduct:
0110         case _union:
0111             return -1;
0112         case quotient:
0113         case power:
0114         case divide:
0115         case rem:
0116         case factorof:
0117         case lt:
0118         case gt:
0119         case eq:
0120         case neq:
0121         case leq:
0122         case geq:
0123         case implies:
0124         case approx:
0125         case root:
0126         case selector: //FIXME: Should move to -1 when matrix appear
0127         case map:
0128         case filter:
0129             return 2;
0130         case abs:
0131         case sin:
0132         case cos:
0133         case tan:
0134         case sec:
0135         case csc:
0136         case cot:
0137         case sinh:
0138         case cosh:
0139         case tanh:
0140         case sech:
0141         case csch:
0142         case coth:
0143         case arcsin:
0144         case arccos:
0145         case arctan:
0146         case arccot:
0147 //         case arccoth:
0148         case arccosh:
0149         case arccsc:
0150         case arccsch:
0151         case arcsec:
0152         case arcsech:
0153         case arcsinh:
0154         case arctanh:
0155         case exp:
0156         case ln:
0157         case log:
0158         case _not:
0159         case factorial:
0160         case real:
0161         case conjugate:
0162         case arg:
0163         case imaginary:
0164         case floor:
0165         case ceiling:
0166         case sum:
0167         case product:
0168         case forall:
0169         case exists:
0170         case diff:
0171         case card:
0172         case transpose:
0173             return 1;
0174         case nOfOps:
0175         case none:
0176             break;
0177     }
0178     return 0;
0179 }
0180 
0181 Operator* Operator::copy() const
0182 {
0183     return new Operator(m_optype);
0184 }
0185 
0186 bool Operator::isBounded() const
0187 {
0188     switch(m_optype) {
0189         case sum:
0190         case product:
0191         case forall:
0192         case exists:
0193 //         case function:
0194         case diff:
0195             return true;
0196         default:
0197             return false;
0198     }
0199 }
0200 
0201 bool Operator::isTrigonometric(OperatorType t)
0202 {
0203     switch(t) {
0204         case sin:
0205         case cos:
0206         case tan:
0207         case sec:
0208         case csc:
0209         case cot:
0210         case sinh:
0211         case cosh:
0212         case tanh:
0213         case sech:
0214         case csch:
0215         case coth:
0216         case arcsin:
0217         case arccos:
0218         case arctan:
0219         case arccot:
0220 //         case arccoth:
0221         case arccosh:
0222         case arccsc:
0223         case arccsch:
0224         case arcsec:
0225         case arcsech:
0226         case arcsinh:
0227         case arctanh:
0228             return true;
0229         default:
0230             return false;
0231     }
0232 }
0233 
0234 Operator Operator::inverse() const
0235 {
0236     OperatorType ret=Operator::none;
0237     switch(m_optype) {
0238         case plus: ret=Operator::minus; break;
0239         case sin: ret=Operator::arcsin; break;
0240         case cos: ret=Operator::arccos; break;
0241         case tan: ret=Operator::arctan; break;
0242         case sec: ret=Operator::arcsec; break;
0243         case csc: ret=Operator::arccsc; break;
0244         case cot: ret=Operator::arccot; break;
0245         case sinh: ret=Operator::arcsinh; break;
0246         case cosh: ret=Operator::arccosh; break;
0247         case tanh: ret=Operator::arctanh; break;
0248         case sech: ret=Operator::arcsech; break;
0249         case csch: ret=Operator::arccsch; break;
0250 //         case coth: ret=Operator::arccot; break;
0251         case arcsin: ret=Operator::sin; break;
0252         case arccos: ret=Operator::cos; break;
0253         case arctan: ret=Operator::tan; break;
0254         case arccot: ret=Operator::cot; break;
0255 //         case arccoth: ret=Operator::coth; break;
0256         case arccosh: ret=Operator::cosh; break;
0257         case arccsc:  ret=Operator::csc; break;
0258         case arccsch: ret=Operator::csch; break;
0259         case arcsec:  ret=Operator::sec; break;
0260         case arcsech: ret=Operator::sech; break;
0261         case arcsinh: ret=Operator::sinh; break;
0262         case arctanh: ret=Operator::tanh; break;
0263         case transpose: ret=Operator::transpose; break;
0264         default: break;
0265     }
0266     return Operator(ret);
0267 }
0268 
0269 bool Operator::matches(const Object* exp, QMap<QString, const Object*>* ) const
0270 {
0271     if(exp->type()!=Object::oper)
0272         return false;
0273     return ((const Operator*) exp)->operatorType()==m_optype;
0274 }
0275