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