Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : * -------------------------------------------------------------------------- *
3 : * Lepton *
4 : * -------------------------------------------------------------------------- *
5 : * This is part of the Lepton expression parser originating from *
6 : * Simbios, the NIH National Center for Physics-Based Simulation of *
7 : * Biological Structures at Stanford, funded under the NIH Roadmap for *
8 : * Medical Research, grant U54 GM072970. See https://simtk.org. *
9 : * *
10 : * Portions copyright (c) 2013-2016 Stanford University and the Authors. *
11 : * Authors: Peter Eastman *
12 : * Contributors: *
13 : * *
14 : * Permission is hereby granted, free of charge, to any person obtaining a *
15 : * copy of this software and associated documentation files (the "Software"), *
16 : * to deal in the Software without restriction, including without limitation *
17 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
18 : * and/or sell copies of the Software, and to permit persons to whom the *
19 : * Software is furnished to do so, subject to the following conditions: *
20 : * *
21 : * The above copyright notice and this permission notice shall be included in *
22 : * all copies or substantial portions of the Software. *
23 : * *
24 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
25 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
26 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
27 : * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
28 : * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
29 : * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
30 : * USE OR OTHER DEALINGS IN THE SOFTWARE. *
31 : * -------------------------------------------------------------------------- *
32 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
33 : #ifndef __PLUMED_lepton_Operation_h
34 : #define __PLUMED_lepton_Operation_h
35 :
36 : /* -------------------------------------------------------------------------- *
37 : * lepton *
38 : * -------------------------------------------------------------------------- *
39 : * This is part of the lepton expression parser originating from *
40 : * Simbios, the NIH National Center for Physics-Based Simulation of *
41 : * Biological Structures at Stanford, funded under the NIH Roadmap for *
42 : * Medical Research, grant U54 GM072970. See https://simtk.org. *
43 : * *
44 : * Portions copyright (c) 2009-2019 Stanford University and the Authors. *
45 : * Authors: Peter Eastman *
46 : * Contributors: *
47 : * *
48 : * Permission is hereby granted, free of charge, to any person obtaining a *
49 : * copy of this software and associated documentation files (the "Software"), *
50 : * to deal in the Software without restriction, including without limitation *
51 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
52 : * and/or sell copies of the Software, and to permit persons to whom the *
53 : * Software is furnished to do so, subject to the following conditions: *
54 : * *
55 : * The above copyright notice and this permission notice shall be included in *
56 : * all copies or substantial portions of the Software. *
57 : * *
58 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
59 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
60 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
61 : * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
62 : * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
63 : * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
64 : * USE OR OTHER DEALINGS IN THE SOFTWARE. *
65 : * -------------------------------------------------------------------------- */
66 :
67 : #include "windowsIncludes.h"
68 : #include "CustomFunction.h"
69 : #include "Exception.h"
70 : #include <cmath>
71 : #include <map>
72 : #include <string>
73 : #include <vector>
74 : #include <sstream>
75 : #include <algorithm>
76 : #include <limits>
77 :
78 : namespace PLMD {
79 : namespace lepton {
80 :
81 : class ExpressionTreeNode;
82 :
83 : /**
84 : * An Operation represents a single step in the evaluation of an expression, such as a function,
85 : * an operator, or a constant value. Each Operation takes some number of values as arguments
86 : * and produces a single value.
87 : *
88 : * This is an abstract class with subclasses for specific operations.
89 : */
90 :
91 : class LEPTON_EXPORT Operation {
92 : public:
93 : virtual ~Operation() {
94 : }
95 : /**
96 : * This enumeration lists all Operation subclasses. This is provided so that switch statements
97 : * can be used when processing or analyzing parsed expressions.
98 : */
99 : enum Id {CONSTANT, VARIABLE, CUSTOM, ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, NEGATE, SQRT, EXP, LOG,
100 : SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, ATAN2, SINH, COSH, TANH, ERF, ERFC, STEP, DELTA, NANDELTA, SQUARE, CUBE, RECIPROCAL,
101 : ADD_CONSTANT, MULTIPLY_CONSTANT, POWER_CONSTANT, MIN, MAX, ABS, FLOOR, CEIL, SELECT,
102 : ACOT, ASEC, ACSC, COTH, SECH, CSCH, ASINH, ACOSH, ATANH, ACOTH, ASECH, ACSCH};
103 : /**
104 : * Get the name of this Operation.
105 : */
106 : virtual std::string getName() const = 0;
107 : /**
108 : * Get this Operation's ID.
109 : */
110 : virtual Id getId() const = 0;
111 : /**
112 : * Get the number of arguments this operation expects.
113 : */
114 : virtual int getNumArguments() const = 0;
115 : /**
116 : * Create a clone of this Operation.
117 : */
118 : virtual Operation* clone() const = 0;
119 : /**
120 : * Perform the computation represented by this operation.
121 : *
122 : * @param args the array of arguments
123 : * @param variables a map containing the values of all variables
124 : * @return the result of performing the computation.
125 : */
126 : virtual double evaluate(double* args, const std::map<std::string, double>& variables) const = 0;
127 : /**
128 : * Return an ExpressionTreeNode which represents the analytic derivative of this Operation with respect to a variable.
129 : *
130 : * @param children the child nodes
131 : * @param childDerivs the derivatives of the child nodes with respect to the variable
132 : * @param variable the variable with respect to which the derivate should be taken
133 : */
134 : virtual ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const = 0;
135 : /**
136 : * Get whether this operation should be displayed with infix notation.
137 : */
138 98954 : virtual bool isInfixOperator() const {
139 98954 : return false;
140 : }
141 : /**
142 : * Get whether this is a symmetric binary operation, such that exchanging its arguments
143 : * does not affect the result.
144 : */
145 1030714 : virtual bool isSymmetric() const {
146 1030714 : return false;
147 : }
148 8522745 : virtual bool operator!=(const Operation& op) const {
149 8522745 : return op.getId() != getId();
150 : }
151 8273372 : virtual bool operator==(const Operation& op) const {
152 8273372 : return !(*this != op);
153 : }
154 : class Constant;
155 : class Variable;
156 : class Custom;
157 : class Add;
158 : class Subtract;
159 : class Multiply;
160 : class Divide;
161 : class Power;
162 : class Negate;
163 : class Sqrt;
164 : class Exp;
165 : class Log;
166 : class Sin;
167 : class Cos;
168 : class Sec;
169 : class Csc;
170 : class Tan;
171 : class Cot;
172 : class Asin;
173 : class Acos;
174 : class Atan;
175 : class Atan2;
176 : class Sinh;
177 : class Cosh;
178 : class Tanh;
179 : class Erf;
180 : class Erfc;
181 : class Step;
182 : class Delta;
183 : class Nandelta;
184 : class Square;
185 : class Cube;
186 : class Reciprocal;
187 : class AddConstant;
188 : class MultiplyConstant;
189 : class PowerConstant;
190 : class Min;
191 : class Max;
192 : class Abs;
193 : class Floor;
194 : class Ceil;
195 : class Select;
196 : class Acot;
197 : class Asec;
198 : class Acsc;
199 : class Coth;
200 : class Sech;
201 : class Csch;
202 : class Asinh;
203 : class Acosh;
204 : class Atanh;
205 : class Acoth;
206 : class Asech;
207 : class Acsch;
208 : };
209 :
210 : class LEPTON_EXPORT Operation::Constant : public Operation {
211 : public:
212 2070326 : Constant(double value) : value(value) {
213 : }
214 1307 : std::string getName() const {
215 1307 : std::stringstream name;
216 1307 : name << value;
217 1307 : return name.str();
218 1307 : }
219 235493 : Id getId() const {
220 235493 : return CONSTANT;
221 : }
222 2159039 : int getNumArguments() const {
223 2159039 : return 0;
224 : }
225 4819946 : Operation* clone() const {
226 4819946 : return new Constant(value);
227 : }
228 2039421 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
229 2039421 : return value;
230 : }
231 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
232 : double getValue() const {
233 57509 : return value;
234 : }
235 1378293 : bool operator!=(const Operation& op) const {
236 1378293 : const Constant* o = dynamic_cast<const Constant*>(&op);
237 1378293 : return (o == NULL || o->value != value);
238 : }
239 : private:
240 : double value;
241 : };
242 :
243 : class LEPTON_EXPORT Operation::Variable : public Operation {
244 : public:
245 3225653 : Variable(const std::string& name) : name(name) {
246 3225653 : }
247 97912 : std::string getName() const {
248 97912 : return name;
249 : }
250 509539 : Id getId() const {
251 509539 : return VARIABLE;
252 : }
253 99657 : int getNumArguments() const {
254 99657 : return 0;
255 : }
256 3204494 : Operation* clone() const {
257 6408988 : return new Variable(name);
258 : }
259 30 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
260 30 : std::map<std::string, double>::const_iterator iter = variables.find(name);
261 30 : if (iter == variables.end())
262 44 : throw Exception("No value specified for variable "+name);
263 8 : return iter->second;
264 : }
265 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
266 898008 : bool operator!=(const Operation& op) const {
267 898008 : const Variable* o = dynamic_cast<const Variable*>(&op);
268 898008 : return (o == NULL || o->name != name);
269 : }
270 : private:
271 : std::string name;
272 : };
273 :
274 : class LEPTON_EXPORT Operation::Custom : public Operation {
275 : public:
276 0 : Custom(const std::string& name, CustomFunction* function) : name(name), function(function), isDerivative(false), derivOrder(function->getNumArguments(), 0) {
277 0 : }
278 : Custom(const std::string& name, CustomFunction* function, const std::vector<int>& derivOrder) : name(name), function(function), isDerivative(false), derivOrder(derivOrder) {
279 : for (int order : derivOrder)
280 : if (order != 0)
281 : isDerivative = true;
282 : }
283 0 : Custom(const Custom& base, int derivIndex) : name(base.name), function(base.function->clone()), isDerivative(true), derivOrder(base.derivOrder) {
284 0 : derivOrder[derivIndex]++;
285 0 : }
286 0 : ~Custom() {
287 0 : delete function;
288 0 : }
289 0 : std::string getName() const {
290 0 : return name;
291 : }
292 0 : Id getId() const {
293 0 : return CUSTOM;
294 : }
295 0 : int getNumArguments() const {
296 0 : return function->getNumArguments();
297 : }
298 0 : Operation* clone() const {
299 0 : Custom* clone = new Custom(name, function->clone());
300 0 : clone->isDerivative = isDerivative;
301 0 : clone->derivOrder = derivOrder;
302 0 : return clone;
303 : }
304 0 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
305 0 : if (isDerivative)
306 0 : return function->evaluateDerivative(args, &derivOrder[0]);
307 0 : return function->evaluate(args);
308 : }
309 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
310 : const std::vector<int>& getDerivOrder() const {
311 : return derivOrder;
312 : }
313 0 : bool operator!=(const Operation& op) const {
314 0 : const Custom* o = dynamic_cast<const Custom*>(&op);
315 0 : return (o == NULL || o->name != name || o->isDerivative != isDerivative || o->derivOrder != derivOrder);
316 : }
317 : private:
318 : std::string name;
319 : CustomFunction* function;
320 : bool isDerivative;
321 : std::vector<int> derivOrder;
322 : };
323 :
324 : class LEPTON_EXPORT Operation::Add : public Operation {
325 : public:
326 9202 : Add() {
327 : }
328 6137 : std::string getName() const {
329 6137 : return "+";
330 : }
331 4693891 : Id getId() const {
332 4693891 : return ADD;
333 : }
334 79378 : int getNumArguments() const {
335 79378 : return 2;
336 : }
337 1371244 : Operation* clone() const {
338 1371244 : return new Add();
339 : }
340 424 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
341 424 : return args[0]+args[1];
342 : }
343 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
344 6137 : bool isInfixOperator() const {
345 6137 : return true;
346 : }
347 505512 : bool isSymmetric() const {
348 505512 : return true;
349 : }
350 : };
351 :
352 : class LEPTON_EXPORT Operation::Subtract : public Operation {
353 : public:
354 4818 : Subtract() {
355 : }
356 1387 : std::string getName() const {
357 1387 : return "-";
358 : }
359 1762394 : Id getId() const {
360 1762394 : return SUBTRACT;
361 : }
362 37633 : int getNumArguments() const {
363 37633 : return 2;
364 : }
365 825569 : Operation* clone() const {
366 825569 : return new Subtract();
367 : }
368 1328 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
369 1328 : return args[0]-args[1];
370 : }
371 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
372 1387 : bool isInfixOperator() const {
373 1387 : return true;
374 : }
375 : };
376 :
377 : class LEPTON_EXPORT Operation::Multiply : public Operation {
378 : public:
379 27507 : Multiply() {
380 : }
381 3346 : std::string getName() const {
382 3346 : return "*";
383 : }
384 4234767 : Id getId() const {
385 4234767 : return MULTIPLY;
386 : }
387 126490 : int getNumArguments() const {
388 126490 : return 2;
389 : }
390 1564448 : Operation* clone() const {
391 1564448 : return new Multiply();
392 : }
393 3447 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
394 3447 : return args[0]*args[1];
395 : }
396 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
397 3346 : bool isInfixOperator() const {
398 3346 : return true;
399 : }
400 65568 : bool isSymmetric() const {
401 65568 : return true;
402 : }
403 : };
404 :
405 : class LEPTON_EXPORT Operation::Divide : public Operation {
406 : public:
407 8812 : Divide() {
408 : }
409 2990 : std::string getName() const {
410 2990 : return "/";
411 : }
412 707207 : Id getId() const {
413 707207 : return DIVIDE;
414 : }
415 61685 : int getNumArguments() const {
416 61685 : return 2;
417 : }
418 241491 : Operation* clone() const {
419 241491 : return new Divide();
420 : }
421 813 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
422 813 : return args[0]/args[1];
423 : }
424 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
425 2990 : bool isInfixOperator() const {
426 2990 : return true;
427 : }
428 : };
429 :
430 : class LEPTON_EXPORT Operation::Power : public Operation {
431 : public:
432 5564 : Power() {
433 : }
434 4 : std::string getName() const {
435 4 : return "^";
436 : }
437 1589975 : Id getId() const {
438 1589975 : return POWER;
439 : }
440 17617 : int getNumArguments() const {
441 17617 : return 2;
442 : }
443 560283 : Operation* clone() const {
444 560283 : return new Power();
445 : }
446 205 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
447 205 : return std::pow(args[0], args[1]);
448 : }
449 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
450 4 : bool isInfixOperator() const {
451 4 : return true;
452 : }
453 : };
454 :
455 : class LEPTON_EXPORT Operation::Negate : public Operation {
456 : public:
457 6072 : Negate() {
458 : }
459 772 : std::string getName() const {
460 772 : return "-";
461 : }
462 342739 : Id getId() const {
463 342739 : return NEGATE;
464 : }
465 32474 : int getNumArguments() const {
466 32474 : return 1;
467 : }
468 448490 : Operation* clone() const {
469 448490 : return new Negate();
470 : }
471 2811 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
472 2811 : return -args[0];
473 : }
474 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
475 : };
476 :
477 : class LEPTON_EXPORT Operation::Sqrt : public Operation {
478 : public:
479 1063 : Sqrt() {
480 : }
481 732 : std::string getName() const {
482 732 : return "sqrt";
483 : }
484 54306 : Id getId() const {
485 54306 : return SQRT;
486 : }
487 10688 : int getNumArguments() const {
488 10688 : return 1;
489 : }
490 50179 : Operation* clone() const {
491 50179 : return new Sqrt();
492 : }
493 1116 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
494 1116 : return std::sqrt(args[0]);
495 : }
496 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
497 : };
498 :
499 : class LEPTON_EXPORT Operation::Exp : public Operation {
500 : public:
501 2986 : Exp() {
502 : }
503 2230 : std::string getName() const {
504 2230 : return "exp";
505 : }
506 1165561 : Id getId() const {
507 1165561 : return EXP;
508 : }
509 29973 : int getNumArguments() const {
510 29973 : return 1;
511 : }
512 354615 : Operation* clone() const {
513 354615 : return new Exp();
514 : }
515 406 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
516 406 : return std::exp(args[0]);
517 : }
518 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
519 : };
520 :
521 : class LEPTON_EXPORT Operation::Log : public Operation {
522 : public:
523 1957 : Log() {
524 : }
525 370 : std::string getName() const {
526 370 : return "log";
527 : }
528 196293 : Id getId() const {
529 196293 : return LOG;
530 : }
531 11847 : int getNumArguments() const {
532 11847 : return 1;
533 : }
534 180809 : Operation* clone() const {
535 180809 : return new Log();
536 : }
537 109 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
538 109 : return std::log(args[0]);
539 : }
540 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
541 : };
542 :
543 : class LEPTON_EXPORT Operation::Sin : public Operation {
544 : public:
545 488 : Sin() {
546 : }
547 900 : std::string getName() const {
548 900 : return "sin";
549 : }
550 93264 : Id getId() const {
551 93264 : return SIN;
552 : }
553 6610 : int getNumArguments() const {
554 6610 : return 1;
555 : }
556 80709 : Operation* clone() const {
557 80709 : return new Sin();
558 : }
559 207 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
560 207 : return std::sin(args[0]);
561 : }
562 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
563 : };
564 :
565 : class LEPTON_EXPORT Operation::Cos : public Operation {
566 : public:
567 1599 : Cos() {
568 : }
569 1342 : std::string getName() const {
570 1342 : return "cos";
571 : }
572 121365 : Id getId() const {
573 121365 : return COS;
574 : }
575 10578 : int getNumArguments() const {
576 10578 : return 1;
577 : }
578 122503 : Operation* clone() const {
579 122503 : return new Cos();
580 : }
581 205 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
582 205 : return std::cos(args[0]);
583 : }
584 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
585 : };
586 :
587 : class LEPTON_EXPORT Operation::Sec : public Operation {
588 : public:
589 8 : Sec() {
590 : }
591 6 : std::string getName() const {
592 6 : return "sec";
593 : }
594 340 : Id getId() const {
595 340 : return SEC;
596 : }
597 78 : int getNumArguments() const {
598 78 : return 1;
599 : }
600 256 : Operation* clone() const {
601 256 : return new Sec();
602 : }
603 608 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
604 608 : return 1.0/std::cos(args[0]);
605 : }
606 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
607 : };
608 :
609 : class LEPTON_EXPORT Operation::Csc : public Operation {
610 : public:
611 8 : Csc() {
612 : }
613 6 : std::string getName() const {
614 6 : return "csc";
615 : }
616 362 : Id getId() const {
617 362 : return CSC;
618 : }
619 78 : int getNumArguments() const {
620 78 : return 1;
621 : }
622 336 : Operation* clone() const {
623 336 : return new Csc();
624 : }
625 608 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
626 608 : return 1.0/std::sin(args[0]);
627 : }
628 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
629 : };
630 :
631 : class LEPTON_EXPORT Operation::Tan : public Operation {
632 : public:
633 6 : Tan() {
634 : }
635 4 : std::string getName() const {
636 4 : return "tan";
637 : }
638 224 : Id getId() const {
639 224 : return TAN;
640 : }
641 52 : int getNumArguments() const {
642 52 : return 1;
643 : }
644 146 : Operation* clone() const {
645 146 : return new Tan();
646 : }
647 203 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
648 203 : return std::tan(args[0]);
649 : }
650 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
651 : };
652 :
653 : class LEPTON_EXPORT Operation::Cot : public Operation {
654 : public:
655 6 : Cot() {
656 : }
657 4 : std::string getName() const {
658 4 : return "cot";
659 : }
660 236 : Id getId() const {
661 236 : return COT;
662 : }
663 52 : int getNumArguments() const {
664 52 : return 1;
665 : }
666 190 : Operation* clone() const {
667 190 : return new Cot();
668 : }
669 406 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
670 406 : return 1.0/std::tan(args[0]);
671 : }
672 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
673 : };
674 :
675 : class LEPTON_EXPORT Operation::Asin : public Operation {
676 : public:
677 54 : Asin() {
678 : }
679 2 : std::string getName() const {
680 2 : return "asin";
681 : }
682 74 : Id getId() const {
683 74 : return ASIN;
684 : }
685 28 : int getNumArguments() const {
686 28 : return 1;
687 : }
688 50 : Operation* clone() const {
689 50 : return new Asin();
690 : }
691 102 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
692 102 : return std::asin(args[0]);
693 : }
694 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
695 : };
696 :
697 : class LEPTON_EXPORT Operation::Acos : public Operation {
698 : public:
699 183 : Acos() {
700 : }
701 7 : std::string getName() const {
702 7 : return "acos";
703 : }
704 324 : Id getId() const {
705 324 : return ACOS;
706 : }
707 105 : int getNumArguments() const {
708 105 : return 1;
709 : }
710 167 : Operation* clone() const {
711 167 : return new Acos();
712 : }
713 102 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
714 102 : return std::acos(args[0]);
715 : }
716 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
717 : };
718 :
719 : class LEPTON_EXPORT Operation::Atan : public Operation {
720 : public:
721 54 : Atan() {
722 : }
723 2 : std::string getName() const {
724 2 : return "atan";
725 : }
726 74 : Id getId() const {
727 74 : return ATAN;
728 : }
729 28 : int getNumArguments() const {
730 28 : return 1;
731 : }
732 50 : Operation* clone() const {
733 50 : return new Atan();
734 : }
735 102 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
736 102 : return std::atan(args[0]);
737 : }
738 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
739 : };
740 :
741 : class LEPTON_EXPORT Operation::Atan2 : public Operation {
742 : public:
743 1353 : Atan2() {
744 : }
745 30 : std::string getName() const {
746 30 : return "atan2";
747 : }
748 1878 : Id getId() const {
749 1878 : return ATAN2;
750 : }
751 633 : int getNumArguments() const {
752 633 : return 2;
753 : }
754 1270 : Operation* clone() const {
755 1270 : return new Atan2();
756 : }
757 408 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
758 408 : return std::atan2(args[0], args[1]);
759 : }
760 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
761 : };
762 :
763 : class LEPTON_EXPORT Operation::Sinh : public Operation {
764 : public:
765 6 : Sinh() {
766 : }
767 4 : std::string getName() const {
768 4 : return "sinh";
769 : }
770 144 : Id getId() const {
771 144 : return SINH;
772 : }
773 52 : int getNumArguments() const {
774 52 : return 1;
775 : }
776 110 : Operation* clone() const {
777 110 : return new Sinh();
778 : }
779 203 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
780 203 : return std::sinh(args[0]);
781 : }
782 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
783 : };
784 :
785 : class LEPTON_EXPORT Operation::Cosh : public Operation {
786 : public:
787 6 : Cosh() {
788 : }
789 4 : std::string getName() const {
790 4 : return "cosh";
791 : }
792 144 : Id getId() const {
793 144 : return COSH;
794 : }
795 52 : int getNumArguments() const {
796 52 : return 1;
797 : }
798 110 : Operation* clone() const {
799 110 : return new Cosh();
800 : }
801 203 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
802 203 : return std::cosh(args[0]);
803 : }
804 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
805 : };
806 :
807 : class LEPTON_EXPORT Operation::Tanh : public Operation {
808 : public:
809 23 : Tanh() {
810 : }
811 13 : std::string getName() const {
812 13 : return "tanh";
813 : }
814 1793 : Id getId() const {
815 1793 : return TANH;
816 : }
817 251 : int getNumArguments() const {
818 251 : return 1;
819 : }
820 2237 : Operation* clone() const {
821 2237 : return new Tanh();
822 : }
823 304 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
824 304 : return std::tanh(args[0]);
825 : }
826 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
827 : };
828 :
829 : class LEPTON_EXPORT Operation::Erf : public Operation {
830 : public:
831 50 : Erf() {
832 : }
833 2 : std::string getName() const {
834 2 : return "erf";
835 : }
836 68 : Id getId() const {
837 68 : return ERF;
838 : }
839 26 : int getNumArguments() const {
840 26 : return 1;
841 : }
842 46 : Operation* clone() const {
843 46 : return new Erf();
844 : }
845 : double evaluate(double* args, const std::map<std::string, double>& variables) const;
846 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
847 : };
848 :
849 : class LEPTON_EXPORT Operation::Erfc : public Operation {
850 : public:
851 50 : Erfc() {
852 : }
853 2 : std::string getName() const {
854 2 : return "erfc";
855 : }
856 68 : Id getId() const {
857 68 : return ERFC;
858 : }
859 26 : int getNumArguments() const {
860 26 : return 1;
861 : }
862 46 : Operation* clone() const {
863 46 : return new Erfc();
864 : }
865 : double evaluate(double* args, const std::map<std::string, double>& variables) const;
866 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
867 : };
868 :
869 : class LEPTON_EXPORT Operation::Step : public Operation {
870 : public:
871 393 : Step() {
872 : }
873 431 : std::string getName() const {
874 431 : return "step";
875 : }
876 163299 : Id getId() const {
877 163299 : return STEP;
878 : }
879 5084 : int getNumArguments() const {
880 5084 : return 1;
881 : }
882 48060 : Operation* clone() const {
883 48060 : return new Step();
884 : }
885 607 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
886 607 : return (args[0] >= 0.0 ? 1.0 : 0.0);
887 : }
888 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
889 : };
890 :
891 : class LEPTON_EXPORT Operation::Delta : public Operation {
892 : public:
893 257 : Delta() {
894 : }
895 248 : std::string getName() const {
896 248 : return "delta";
897 : }
898 126045 : Id getId() const {
899 126045 : return DELTA;
900 : }
901 3899 : int getNumArguments() const {
902 3899 : return 1;
903 : }
904 25363 : Operation* clone() const {
905 25363 : return new Delta();
906 : }
907 203 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
908 203 : return (args[0] == 0.0 ? 1.0/0.0 : 0.0);
909 : }
910 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
911 : };
912 :
913 : class LEPTON_EXPORT Operation::Nandelta : public Operation {
914 : public:
915 8 : Nandelta() {
916 : }
917 6 : std::string getName() const {
918 6 : return "nandelta";
919 : }
920 204 : Id getId() const {
921 204 : return NANDELTA;
922 : }
923 74 : int getNumArguments() const {
924 74 : return 1;
925 : }
926 138 : Operation* clone() const {
927 138 : return new Nandelta();
928 : }
929 304 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
930 304 : return (args[0] == 0.0 ? std::numeric_limits<double>::quiet_NaN() : 0.0);
931 : }
932 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
933 : };
934 :
935 : class LEPTON_EXPORT Operation::Square : public Operation {
936 : public:
937 5378 : Square() {
938 : }
939 6521 : std::string getName() const {
940 6521 : return "square";
941 : }
942 2042212 : Id getId() const {
943 2042212 : return SQUARE;
944 : }
945 60400 : int getNumArguments() const {
946 60400 : return 1;
947 : }
948 841065 : Operation* clone() const {
949 841065 : return new Square();
950 : }
951 3707 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
952 3707 : return args[0]*args[0];
953 : }
954 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
955 : };
956 :
957 : class LEPTON_EXPORT Operation::Cube : public Operation {
958 : public:
959 3024 : Cube() {
960 : }
961 51 : std::string getName() const {
962 51 : return "cube";
963 : }
964 5171 : Id getId() const {
965 5171 : return CUBE;
966 : }
967 689 : int getNumArguments() const {
968 689 : return 1;
969 : }
970 2879 : Operation* clone() const {
971 2879 : return new Cube();
972 : }
973 204 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
974 204 : return args[0]*args[0]*args[0];
975 : }
976 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
977 : };
978 :
979 : class LEPTON_EXPORT Operation::Reciprocal : public Operation {
980 : public:
981 870 : Reciprocal() {
982 : }
983 738 : std::string getName() const {
984 738 : return "recip";
985 : }
986 43704 : Id getId() const {
987 43704 : return RECIPROCAL;
988 : }
989 10874 : int getNumArguments() const {
990 10874 : return 1;
991 : }
992 36189 : Operation* clone() const {
993 36189 : return new Reciprocal();
994 : }
995 2122 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
996 2122 : return 1.0/args[0];
997 : }
998 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
999 : };
1000 :
1001 : class LEPTON_EXPORT Operation::AddConstant : public Operation {
1002 : public:
1003 3221 : AddConstant(double value) : value(value) {
1004 : }
1005 4440 : std::string getName() const {
1006 4440 : std::stringstream name;
1007 4440 : name << value << "+";
1008 4440 : return name.str();
1009 4440 : }
1010 420588 : Id getId() const {
1011 420588 : return ADD_CONSTANT;
1012 : }
1013 26804 : int getNumArguments() const {
1014 26804 : return 1;
1015 : }
1016 792892 : Operation* clone() const {
1017 792892 : return new AddConstant(value);
1018 : }
1019 2887 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1020 2887 : return args[0]+value;
1021 : }
1022 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1023 : double getValue() const {
1024 7176 : return value;
1025 : }
1026 983418 : bool operator!=(const Operation& op) const {
1027 983418 : const AddConstant* o = dynamic_cast<const AddConstant*>(&op);
1028 983418 : return (o == NULL || o->value != value);
1029 : }
1030 : private:
1031 : double value;
1032 : };
1033 :
1034 : class LEPTON_EXPORT Operation::MultiplyConstant : public Operation {
1035 : public:
1036 12414 : MultiplyConstant(double value) : value(value) {
1037 : }
1038 8359 : std::string getName() const {
1039 8359 : std::stringstream name;
1040 8359 : name << value << "*";
1041 8359 : return name.str();
1042 8359 : }
1043 946722 : Id getId() const {
1044 946722 : return MULTIPLY_CONSTANT;
1045 : }
1046 92138 : int getNumArguments() const {
1047 92138 : return 1;
1048 : }
1049 935939 : Operation* clone() const {
1050 935939 : return new MultiplyConstant(value);
1051 : }
1052 2634 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1053 2634 : return args[0]*value;
1054 : }
1055 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1056 : double getValue() const {
1057 32210 : return value;
1058 : }
1059 2024697 : bool operator!=(const Operation& op) const {
1060 2024697 : const MultiplyConstant* o = dynamic_cast<const MultiplyConstant*>(&op);
1061 2024697 : return (o == NULL || o->value != value);
1062 : }
1063 : private:
1064 : double value;
1065 : };
1066 :
1067 : class LEPTON_EXPORT Operation::PowerConstant : public Operation {
1068 : public:
1069 4093 : PowerConstant(double value) : value(value) {
1070 4093 : intValue = (int) value;
1071 115 : isIntPower = (intValue == value);
1072 : }
1073 69 : std::string getName() const {
1074 69 : std::stringstream name;
1075 69 : name << "^" << value;
1076 69 : return name.str();
1077 69 : }
1078 4021 : Id getId() const {
1079 4021 : return POWER_CONSTANT;
1080 : }
1081 761 : int getNumArguments() const {
1082 761 : return 1;
1083 : }
1084 3978 : Operation* clone() const {
1085 3978 : return new PowerConstant(value);
1086 : }
1087 11045323 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1088 11045323 : if (isIntPower) {
1089 : // Integer powers can be computed much more quickly by repeated multiplication.
1090 :
1091 11041104 : int exponent = intValue;
1092 11041104 : double base = args[0];
1093 11041104 : if (exponent < 0) {
1094 804 : exponent = -exponent;
1095 804 : base = 1.0/base;
1096 : }
1097 : double result = 1.0;
1098 44166323 : while (exponent != 0) {
1099 33125219 : if ((exponent&1) == 1)
1100 23777800 : result *= base;
1101 33125219 : base *= base;
1102 33125219 : exponent = exponent>>1;
1103 : }
1104 : return result;
1105 : }
1106 : else
1107 4219 : return std::pow(args[0], value);
1108 : }
1109 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1110 : double getValue() const {
1111 : return value;
1112 : }
1113 1277 : bool operator!=(const Operation& op) const {
1114 1277 : const PowerConstant* o = dynamic_cast<const PowerConstant*>(&op);
1115 1277 : return (o == NULL || o->value != value);
1116 : }
1117 138 : bool isInfixOperator() const {
1118 138 : return true;
1119 : }
1120 : private:
1121 : double value;
1122 : int intValue;
1123 : bool isIntPower;
1124 : };
1125 :
1126 : class LEPTON_EXPORT Operation::Min : public Operation {
1127 : public:
1128 100 : Min() {
1129 : }
1130 4 : std::string getName() const {
1131 4 : return "min";
1132 : }
1133 136 : Id getId() const {
1134 136 : return MIN;
1135 : }
1136 68 : int getNumArguments() const {
1137 68 : return 2;
1138 : }
1139 92 : Operation* clone() const {
1140 92 : return new Min();
1141 : }
1142 408 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1143 : // parens around (std::min) are workaround for horrible microsoft max/min macro trouble
1144 408 : return (std::min)(args[0], args[1]);
1145 : }
1146 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1147 : };
1148 :
1149 : class LEPTON_EXPORT Operation::Max : public Operation {
1150 : public:
1151 100 : Max() {
1152 : }
1153 4 : std::string getName() const {
1154 4 : return "max";
1155 : }
1156 136 : Id getId() const {
1157 136 : return MAX;
1158 : }
1159 68 : int getNumArguments() const {
1160 68 : return 2;
1161 : }
1162 92 : Operation* clone() const {
1163 92 : return new Max();
1164 : }
1165 408 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1166 : // parens around (std::min) are workaround for horrible microsoft max/min macro trouble
1167 408 : return (std::max)(args[0], args[1]);
1168 : }
1169 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1170 : };
1171 :
1172 : class LEPTON_EXPORT Operation::Abs : public Operation {
1173 : public:
1174 21 : Abs() {
1175 : }
1176 18 : std::string getName() const {
1177 18 : return "abs";
1178 : }
1179 1092 : Id getId() const {
1180 1092 : return ABS;
1181 : }
1182 200 : int getNumArguments() const {
1183 200 : return 1;
1184 : }
1185 1152 : Operation* clone() const {
1186 1152 : return new Abs();
1187 : }
1188 507 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1189 507 : return std::abs(args[0]);
1190 : }
1191 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1192 : };
1193 :
1194 : class LEPTON_EXPORT Operation::Floor : public Operation {
1195 : public:
1196 :
1197 50 : Floor() {
1198 : }
1199 2 : std::string getName() const {
1200 2 : return "floor";
1201 : }
1202 68 : Id getId() const {
1203 68 : return FLOOR;
1204 : }
1205 26 : int getNumArguments() const {
1206 26 : return 1;
1207 : }
1208 46 : Operation* clone() const {
1209 46 : return new Floor();
1210 : }
1211 102 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1212 102 : return std::floor(args[0]);
1213 : }
1214 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1215 : };
1216 :
1217 : class LEPTON_EXPORT Operation::Ceil : public Operation {
1218 : public:
1219 50 : Ceil() {
1220 : }
1221 2 : std::string getName() const {
1222 2 : return "ceil";
1223 : }
1224 68 : Id getId() const {
1225 68 : return CEIL;
1226 : }
1227 26 : int getNumArguments() const {
1228 26 : return 1;
1229 : }
1230 46 : Operation* clone() const {
1231 46 : return new Ceil();
1232 : }
1233 102 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1234 102 : return std::ceil(args[0]);
1235 : }
1236 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1237 : };
1238 :
1239 : class LEPTON_EXPORT Operation::Select : public Operation {
1240 : public:
1241 44 : Select() {
1242 : }
1243 24 : std::string getName() const {
1244 24 : return "select";
1245 : }
1246 852 : Id getId() const {
1247 852 : return SELECT;
1248 : }
1249 424 : int getNumArguments() const {
1250 424 : return 3;
1251 : }
1252 592 : Operation* clone() const {
1253 592 : return new Select();
1254 : }
1255 2444 : double evaluate(double* args, const std::map<std::string, double>& variables) const {
1256 2444 : return (args[0] != 0.0 ? args[1] : args[2]);
1257 : }
1258 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
1259 : };
1260 :
1261 : #define LEPTON_CLASS_OPERATION(Name,name,NAME,nargs,impl) \
1262 : class LEPTON_EXPORT Operation::Name : public Operation { \
1263 : public: \
1264 : Name() { \
1265 : } \
1266 : std::string getName() const { \
1267 : return #name; \
1268 : } \
1269 : Id getId() const { \
1270 : return NAME; \
1271 : } \
1272 : int getNumArguments() const { \
1273 : return nargs; \
1274 : } \
1275 : Operation* clone() const { \
1276 : return new Name(); \
1277 : } \
1278 : double evaluate(double* args, const std::map<std::string, double>& variables) const { \
1279 : return impl; \
1280 : } \
1281 : ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const; \
1282 : }
1283 :
1284 350 : LEPTON_CLASS_OPERATION(Acot,acot,ACOT,1,std::atan(1.0/args[0]));
1285 350 : LEPTON_CLASS_OPERATION(Asec,asec,ASEC,1,std::acos(1.0/args[0]));
1286 350 : LEPTON_CLASS_OPERATION(Acsc,acsc,ACSC,1,std::asin(1.0/args[0]));
1287 1410 : LEPTON_CLASS_OPERATION(Coth,coth,ACOT,1,1.0/std::tanh(args[0]));
1288 894 : LEPTON_CLASS_OPERATION(Sech,sech,SECH,1,1.0/std::cosh(args[0]));
1289 894 : LEPTON_CLASS_OPERATION(Csch,csch,CSCH,1,1.0/std::sinh(args[0]));
1290 :
1291 248 : LEPTON_CLASS_OPERATION(Asinh,asinh,ASINH,1,std::asinh(args[0]));
1292 248 : LEPTON_CLASS_OPERATION(Acosh,acosh,ACOSH,1,std::acosh(args[0]));
1293 248 : LEPTON_CLASS_OPERATION(Atanh,atanh,ATANH,1,std::atanh(args[0]));
1294 :
1295 350 : LEPTON_CLASS_OPERATION(Acoth,acoth,ACOTH,1,0.5*std::log((args[0]+1.0)/(args[0]-1.0)));
1296 350 : LEPTON_CLASS_OPERATION(Asech,asech,ASECH,1,std::log(std::sqrt(1.0/args[0]-1.0)*std::sqrt(1.0/args[0]+1.0)+1.0/args[0]));
1297 350 : LEPTON_CLASS_OPERATION(Acsch,acsch,ACSCH,1,std::log(1.0/args[0]+std::sqrt(1.0/(args[0]*args[0])+1.0)));
1298 :
1299 : } // namespace lepton
1300 : } // namespace PLMD
1301 :
1302 : #endif /*LEPTON_OPERATION_H_*/
|