/* * slimath.cc * * This file is part of NEST. * * Copyright (C) 2004 The NEST Initiative * * NEST is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * NEST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NEST. If not, see <http://www.gnu.org/licenses/>. * */ /* slimath.cc */ #define NDEBUG #include <cmath> #include "config.h" #include "slimath.h" #include "integerdatum.h" #include "doubledatum.h" #include "booldatum.h" #include "namedatum.h" #include "stringdatum.h" void IntegerFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); DoubleDatum *op = dynamic_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op != NULL) { Token res(new IntegerDatum(op->get())); i->OStack.top().swap(res); } } void DoubleFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); IntegerDatum *op = dynamic_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if(op != NULL) { Token res(new DoubleDatum(op->get())); i->OStack.top().swap(res); } } void Add_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() += (op2->get()); i->OStack.pop(); } void Add_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); op1->get() +=(op2->get()); i->OStack.pop(); } void Add_diFunction::execute(SLIInterpreter *i) const { // double int add -> double assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); op2->get() += (op1->get()); i->OStack.pop(); } void Add_idFunction::execute(SLIInterpreter *i) const { // ind double add -> double assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); op1->get() += (op2->get()); i->OStack.swap(); i->OStack.pop(); } //----------------------------------------------------- void Sub_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() -=(op2->get()); i->OStack.pop(); } void Sub_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); op1->get() -=(op2->get()); i->OStack.pop(); } void Sub_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() -=(op2->get()); i->OStack.pop(); } void Sub_idFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); op2->get()= op1->get() - op2->get(); i->OStack.swap(); i->OStack.pop(); } //----------------------------------------------------- void Mul_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() *= (op2->get()); i->OStack.pop(); } void Mul_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); op1->get() *=(op2->get()); i->OStack.pop(); } void Mul_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() *= (op2->get()); i->OStack.pop(); } void Mul_idFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); op1->get() *=(op2->get()); i->OStack.swap(); i->OStack.pop(); } //----------------------------------------------------- void Div_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if(op2->get() != 0) { op1->get() /=(op2->get()); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->DivisionByZeroError); } //----------------------------------------------------- /* BeginDocumentation Name: mod - compute the modulo of two integer numbers. Synopsis: int int mod -> int Examples: 7 4 mod -> 3 SeeAlso: E, sin, cos, exp, log */ void Mod_iiFunction::execute(SLIInterpreter *i) const { if(i->OStack.load() < 2) { i->raiseerror(i->StackUnderflowError); return; } IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if(op1 ==NULL || op2 == NULL) { i->raiseerror(i->ArgumentTypeError); return; } if(op2->get() != 0) { *op1= op1->get() % op2->get(); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->DivisionByZeroError); } void Div_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op2->get() != 0) { op1->get() /=(op2->get()); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->DivisionByZeroError); } void Div_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if(op2->get() != 0) { op1->get()/=(op2->get()); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->DivisionByZeroError); } void Div_idFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op2->get() != 0) { op2->get()= (op1->get())/(op2->get()); i->OStack.swap(); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->DivisionByZeroError); } /* BeginDocumentation Name: sin - Calculate the sine of double number. Synopsis: double sin -> double Description: Alternatives: Function sin_d (undocumented) -> behaviour and synopsis are the same. Examples: 1.0 sin -> 0.841471 Author: Hehl FirstVersion: 8.6.1999 SeeAlso: cos */ void Sin_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::sin(op->get()); i->EStack.pop(); } /* BeginDocumentation Name: asin - Calculate the arc sine of double number. Synopsis: double asin -> double Description: Alternatives: Function asin_d (undocumented) -> behaviour and synopsis are the same. Examples: 1.0 asin -> 1.570796 Author: Diesmann FirstVersion: 090225 SeeAlso: sin, acos */ void Asin_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::asin(op->get()); i->EStack.pop(); } /* BeginDocumentation Name: cos - Calculate the cosine of double number. Synopsis: double cos -> double Description: Alternatives: Function cos_d (undocumented) -> behaviour and synopsis are the same. Examples: 1.0 cos -> 0.540302 Author: Hehl FirstVersion: 8.6.1999 SeeAlso: sin */ void Cos_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::cos(op->get()); i->EStack.pop(); } /* BeginDocumentation Name: acos - Calculate the arc cosine of double number. Synopsis: double acos -> double Description: Alternatives: Function acos_d (undocumented) -> behaviour and synopsis are the same. Examples: 1.0 acos -> 0.0 Author: Diesmann FirstVersion: 090225 SeeAlso: cos, asin */ void Acos_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::acos(op->get()); i->EStack.pop(); } /* BeginDocumentation Name: exp - Calculate the exponential of double number Synopsis: double exp -> double Examples: 1.0 exp -> 2.71828 Author: Hehl FirstVersion: 10.6.1999 SeeAlso: E, sin, cos */ void Exp_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::exp(op->get()); i->EStack.pop(); } /* BeginDocumentation Name: log - Calculate decadic logarithm of double number. Synopsis: double exp -> double Examples: 10.0 log -> 1.0 Author: Gewaltig FirstVersion: 7.6.2000 SeeAlso: E, sin, cos, exp */ void Log_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op->get()>0.0) { *op=std::log10(op->get()); i->EStack.pop(); } else i->raiseerror(i->RangeCheckError); } /* BeginDocumentation Name: ln - Calculate natural logarithm of double number. Synopsis: double ln -> double Examples: E ln -> 1.0 Author: Gewaltig FirstVersion: 7.6.2000 SeeAlso: E, sin, cos, exp, log */ void Ln_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op->get()>0.0) { *op=std::log(op->get()); i->EStack.pop(); } else i->raiseerror(i->RangeCheckError); } /*BeginDocumentation Name: sqr - Compute the square of a number. Examples: 2.0 sqr -> 4.0 Synopsis: number sqr -> double SeeAlso: sqrt */ void Sqr_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=op->get()*op->get(); i->EStack.pop(); } /*BeginDocumentation Name: sqrt - compute the square root of a non-negative number Synopsis: number sqrt -> double Description: sqrt computes the the square root of a number. If the value is negative, a RangeCheck error is raised. Examples: 4 sqrt -> 2.0 SeeAlso: sqr */ void Sqrt_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if(op->get()>=0.0) { *op=std::sqrt(op->get()); i->EStack.pop(); } else i->raiseerror(i->RangeCheckError); } /*BeginDocumentation Name: pow - raise a number to a power Synopsis: x y pow -> number Description: pow computes x raised to the y-th power (x^y). Remarks: Raises a RangeCheck error if x is negative, unless y is positive integer. Author: Plesser FirstVersion: 17.05.2004 SeeAlso: exp, log */ void Pow_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if ( op1->get() >= 0.0 ) { *op1 = std::pow(op1->get(), op2->get()); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->RangeCheckError); return; } void Pow_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); // can raise anything to an integer power, except zero to neg power if ( ! ( op1->get() == 0.0 && op2->get() < 0 ) ) { // cast explicitly to double to avoid overloading ambiguity *op1 = std::pow(op1->get(),static_cast<double>(op2->get())); i->OStack.pop(); i->EStack.pop(); } else i->raiseerror(i->RangeCheckError); return; } /* BeginDocumentation Name: modf - Decomposes its argument into fractional and integral part Synopsis: double modf -> double double Description: This is an interface to the C++ function double std::modf(double, double*) Examples: 2.5 modf -> 0.5 2 Author: Diesmann FirstVersion: 17.5.2005 References: Stroustrup 3rd ed p 661 SeeAlso: frexp */ void Modf_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); double y; *op1 = std::modf(op1->get(), &y); i->OStack.push_by_pointer(new DoubleDatum(y)); i->EStack.pop(); } /* BeginDocumentation Name: frexp - Decomposes its argument into an exponent of 2 and a factor Synopsis: double frexp -> double integer Description: This is an interface to the C++ function double std::frexp(double,int*) In accordance with the normalized representation of the mantissa in IEEE doubles, the factor is in the interval [0.5,1). Examples: -5 dexp frexp -> 0.5 -4 Author: Diesmann FirstVersion: 17.5.2005 References: Stroustrup 3rd ed p 661 SeeAlso: ldexp, dexp, modf */ void Frexp_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); int y; *op1 = std::frexp(op1->get(), &y); i->OStack.push(y); i->EStack.pop(); } /* BeginDocumentation Name: ldexp - computes the product of integer power of 2 and a factor Synopsis: double integer ldexp -> double Description: This is an interface to the C++ function double std::ldexp(double,int) Examples: 1.5 3 ldexp -> 12 12.0 frexp -> 0.75 4 12.0 frexp ldexp -> 12.0 1.0 -5 ldexp frexp -> 0.5 -4 Author: Diesmann FirstVersion: 17.5.2005 References: Stroustrup 3rd ed p 661 SeeAlso: frexp, dexp, modf */ void Ldexp_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); *op1 = std::ldexp( op1->get(), op2->get() ); i->OStack.pop(); i->EStack.pop(); } /* BeginDocumentation Name: dexp - computes an integer power of 2 and returns the result as double Synopsis: integer dexp -> double Description: This is an interface to the C++ expression double std::ldexp(1.0,int) Examples: -5 dexp frexp -> 0.5 -4 Author: Diesmann FirstVersion: 17.5.2005 References: Stroustrup 3rd ed p 661 SeeAlso: frexp, ldexp, modf */ void Dexp_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); double d = std::ldexp(1.0, op1->get() ); i->OStack.top()=d; i->EStack.pop(); } //---------------------------------- /* BeginDocumentation Name: abs_i - absolute value of integer Synopsis: integer abs -> integer Description: implemented by C/C++ long labs(long) and Examples: -3 abs_i -> 3 Remarks: If you are not sure, if the value is of type double or integer, use abs. If e.g. abs_d gets an integer as argument, NEST will exit throwing an assertion. Author: Diesmann FirstVersion: 27.4.1999 References: Stroustrup 3rd ed p 661 SeeAlso: abs */ void Abs_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); IntegerDatum *op= static_cast<IntegerDatum *>(i->OStack.top().datum()); *op= std::labs(op->get()); } /* BeginDocumentation Name: abs_d - absolute value of double Synopsis: double abs -> double Description: implemented by C/C++ double fabs(double) Examples: -3.456 abs_d -> 3.456 Remarks: If you are not sure, if the value is of type double or integer, use abs. If e.g. abs_d gets an integer as argument, NEST will exit throwing an assertion. Author: Diesmann FirstVersion: 27.4.1999 References: Stroustrup 3rd ed p 660 SeeAlso: abs */ void Abs_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); DoubleDatum *op= static_cast<DoubleDatum *>(i->OStack.top().datum()); *op= std::fabs(op->get()); } /* BeginDocumentation Name: neg_i - reverse sign of integer value Synopsis: integer neg -> integer Author: Diesmann FirstVersion: 29.7.1999 Remarks: implemented by C/C++ - operator This function is called CHS in HP48S and related dialects. SeeAlso:neg */ void Neg_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); IntegerDatum *op= static_cast<IntegerDatum *>(i->OStack.top().datum()); *op= - op->get(); } /* BeginDocumentation Name: neg_d - reverse sign of double value Synopsis: double neg -> double Author: Diesmann FirstVersion: 29.7.1999 Remarks: implemented by C/C++ - operator This function is called CHS in HP48S and related dialects. SeeAlso: neg */ void Neg_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); DoubleDatum *op= static_cast<DoubleDatum *>(i->OStack.top().datum()); *op= - op->get(); } /* BeginDocumentation Name: inv - compute 1/x Synopsis: double inv -> double Examples: 2.0 inv -> 0.5 Author: Gewaltig */ void Inv_dFunction::execute(SLIInterpreter *i) const { if(i->OStack.load() == 0) { i->raiseerror(i->StackUnderflowError); return; } DoubleDatum *op= static_cast<DoubleDatum *>(i->OStack.top().datum()); if(op == NULL) { i->raiseerror(i->ArgumentTypeError); return; } *op= 1.0/op->get(); i->EStack.pop(); } /*BeginDocumentation: Name: eq - Test two objects for equality Synopsis: any1 any2 eq -> bool Description: eq returns true if the two arguments are equal and false otherwise. eq can also be applied to container objecs like arrays, procedures, strings, and dictionaries: * two arrays or strings are equal, if all their components are equal. * two dictionaries are equal, if they represent the same object. SeeAlso: neq, gt, lt, leq, geq */ void EqFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); Datum *op1 = i->OStack.pick(1).datum(); Datum *op2 = i->OStack.pick(0).datum(); bool result = op1->equals(op2); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } /*BeginDocumentation: Name: neq - Test two objects for inequality Synopsis: any1 any2 neq -> bool Description: neq returns true if the two arguments are not equal and false otherwise. neq can also be applied to container objecs like arrays, procedures, strings, and dictionaries: * two arrays or strings are equal, if all their components are equal. * two dictionaries are equal, if they represent the same object. SeeAlso: eq, gt, lt, leq, geq */ void NeqFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); Datum *op1 = i->OStack.pick(1).datum(); Datum *op2 = i->OStack.pick(0).datum(); bool result = not op1->equals(op2); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } /*BeginDocumentation: Name: geq - Test if one object is greater or equal than another object Synopsis: any1 any2 geq -> bool Description: geq returns true if any1 >= any2 and false otherwise. geq can only be applied to numbers and strings. SeeAlso: eq, neq, gt, lt, leq */ void Geq_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() >= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Geq_idFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() >= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Geq_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() >= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Geq_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() >= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } /*BeginDocumentation: Name: leq - Test if one object is less or equal than another object Synopsis: any1 any2 leq -> bool Description: geq returns true if any1 <= any2 and false otherwise. geq can only be applied to numbers and strings. SeeAlso: eq, neq, gt, lt, geq */ void Leq_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() <= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Leq_idFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() <= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Leq_diFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() <= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Leq_ddFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result= (op1->get() <= op2->get()); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } /*BeginDocumentation Name: not - logical not operator. Synopsis: bool not -> bool int not -> int Description: For booleans, not turns true info false and vice versa. For integer arguments, not performs a bit-wise not where 1 is replaced by 0 and vice versa. Examples: 1 2 eq not -> true 0 not -> -1 SeeAlso: and, or, xor */ void Not_bFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); BoolDatum *op = static_cast<BoolDatum *>(i->OStack.top().datum()); op->get() = not op->get(); } void Not_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); i->EStack.pop(); IntegerDatum *op= static_cast<IntegerDatum *>(i->OStack.top().datum()); op->get()= ~ op->get(); } /*BeginDocumentation Name: or - logical or operator. Synopsis: bool1 bool2 or -> bool int1 int2 or -> int Description: For booleans, or returns true, if either, the arguments are true and false otherwise. For integers, or performs a bitwise or between the two arguments. Examples: true false or -> true true true or -> true false false or -> false 2 8 or -> 10 1 0 or -> 1 SeeAlso: and, or, not */ void OrFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() > 1); i->EStack.pop(); BoolDatum *op1 = static_cast<BoolDatum *>(i->OStack.pick(1).datum()); BoolDatum *op2 = static_cast<BoolDatum *>(i->OStack.pick(0).datum()); assert(op1 != NULL && op2 != NULL); op1->get() = (op1->get() == true || op2->get() == true ); i->OStack.pop(); } /*BeginDocumentation Name: xor - logical xor operator. Synopsis: bool1 bool2 xor -> bool Description: For booleans, xor returns true, if either, but not both of the arguments are true and false otherwise. Examples: true false xor -> true true true xor -> false false false xor -> false SeeAlso: and, or, not */ void XorFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() > 1); i->EStack.pop(); BoolDatum *op1 = static_cast<BoolDatum *>(i->OStack.pick(1).datum()); BoolDatum *op2 = static_cast<BoolDatum *>(i->OStack.pick(0).datum()); op1->get()= ((*op1 || *op2) && !(*op1 && *op2)); i->OStack.pop(); } /*BeginDocumentation Name: and - logical and operator. Synopsis: bool1 bool2 and -> bool int1 int2 and -> int Description: For booleans, and returns true if both arguments are true For integer arguments, and performs a bit-wise and between the two integers. Examples: true true and -> true 10 24 and -> 8 SeeAlso: or, xor, not */ void AndFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() > 1); i->EStack.pop(); BoolDatum *op1 = static_cast<BoolDatum *>(i->OStack.pick(1).datum()); BoolDatum *op2 = static_cast<BoolDatum *>(i->OStack.pick(0).datum()); op1->get()= (*op1 && *op2); i->OStack.pop(); } void And_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() > 1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() = op1->get() & op2->get(); i->OStack.pop(); } void Or_iiFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() > 1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); op1->get() = op1->get() | op2->get(); i->OStack.pop(); } //--------------------------------------------------- /*BeginDocumentation: Name: gt - Test if one object is greater than another object Synopsis: any1 any2 gt -> bool Description: gt returns true if any1 > any2 and false otherwise. gt can only be applied to numbers and strings. SeeAlso: eq, neq, gt, lt, leq */ void Gt_idFunction::execute(SLIInterpreter *i) const { // call: integer double gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result = *op1 > *op2; i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Gt_diFunction::execute(SLIInterpreter *i) const { // call: double integer gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); bool result = *op1 > *op2; i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Gt_iiFunction::execute(SLIInterpreter *i) const { // call: integer integer gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() > op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Gt_ddFunction::execute(SLIInterpreter *i) const { // call: double double gt bool assert(i->OStack.load() >1); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() > op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Gt_ssFunction::execute(SLIInterpreter *i) const { // call: string string gt bool assert(i->OStack.load() >1); i->EStack.pop(); StringDatum *op1 = static_cast<StringDatum *>(i->OStack.pick(1).datum()); StringDatum *op2 = static_cast<StringDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = *op1 > *op2; i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } //---- /*BeginDocumentation: Name: lt - Test if one object is less than another object Synopsis: any1 any2 lt -> bool Description: lt returns true if any1 < any2 and false otherwise. lt can only be applied to numbers and strings. SeeAlso: eq, neq, gt, lt, leq */ void Lt_idFunction::execute(SLIInterpreter *i) const { // call: integer double gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() < op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Lt_diFunction::execute(SLIInterpreter *i) const { // call: double integer gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() < op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Lt_iiFunction::execute(SLIInterpreter *i) const { // call: integer integer gt bool assert(i->OStack.load() >1); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() < op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Lt_ddFunction::execute(SLIInterpreter *i) const { // call: double double gt bool assert(i->OStack.load() >1); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = op1->get() < op2->get(); i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } void Lt_ssFunction::execute(SLIInterpreter *i) const { // call: string string gt bool assert(i->OStack.load() >1); i->EStack.pop(); StringDatum *op1 = static_cast<StringDatum *>(i->OStack.pick(1).datum()); StringDatum *op2 = static_cast<StringDatum *>(i->OStack.pick(0).datum()); assert(op1 !=NULL && op2 != NULL); bool result = *op1 < *op2; i->OStack.pop(2); i->OStack.push_by_pointer(new BoolDatum(result)); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void UnitStep_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >=1); DoubleDatum *x = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); bool result = x->get() >= 0.0; i->EStack.pop(); i->OStack.pop(); if(result) i->OStack.push_by_pointer(new DoubleDatum(1.0)); else i->OStack.push_by_pointer(new DoubleDatum(0.0)); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void UnitStep_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >=1); IntegerDatum *x = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); assert(x !=NULL); bool result = x->get() >= 0; i->EStack.pop(); i->OStack.pop(); if(result) i->OStack.push_by_pointer(new IntegerDatum(1.0)); else i->OStack.push_by_pointer(new IntegerDatum(0.0)); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void UnitStep_daFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >=1); TokenArray *a = dynamic_cast<TokenArray *>(i->OStack.pick(0).datum()); assert(a !=NULL); bool result = true; for (size_t j=0; j < a->size(); ++j) { DoubleDatum *x = static_cast<DoubleDatum *>((*a)[j].datum()); assert(x !=NULL); if (x->get() < 0.0) { result=false; break; } } i->EStack.pop(); i->OStack.pop(); if(result) i->OStack.push_by_pointer(new DoubleDatum(1.0)); else i->OStack.push_by_pointer(new DoubleDatum(0.0)); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void UnitStep_iaFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >=1); TokenArray *a = dynamic_cast<TokenArray *>(i->OStack.pick(0).datum()); assert(a !=NULL); bool result = true; for (size_t j=0; j < a->size(); ++j) { IntegerDatum *x = static_cast<IntegerDatum *>((*a)[j].datum()); assert(x !=NULL); if (x->get() < 0) { result=false; break; } } i->EStack.pop(); i->OStack.pop(); if(result) i->OStack.push_by_pointer(new IntegerDatum(1.0)); else i->OStack.push_by_pointer(new IntegerDatum(0.0)); } // round to the nearest integer void Round_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::floor(op->get()+0.5); i->EStack.pop(); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void Floor_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::floor(op->get()); i->EStack.pop(); } // Documentation can be found in file synod2/lib/sli/mathematica.sli void Ceil_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 1); DoubleDatum *op = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); *op=std::ceil(op->get()); i->EStack.pop(); } // Documentation can be found in file synod2/lib/sli/typeinit.sli void Max_i_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if (op1->get() < op2->get()) i->OStack.swap(); i->OStack.pop(); } void Max_i_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if (op1->get() < op2->get()) i->OStack.swap(); i->OStack.pop(); } void Max_d_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if (op1->get() < op2->get()) i->OStack.swap(); i->OStack.pop(); } void Max_d_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if (op1->get() < op2->get()) i->OStack.swap(); i->OStack.pop(); } // Documentation can be found in file synod2/lib/sli/typeinit.sli void Min_i_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if (op1->get() > op2->get()) i->OStack.swap(); i->OStack.pop(); } void Min_i_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); IntegerDatum *op1 = static_cast<IntegerDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if (op1->get() > op2->get()) i->OStack.swap(); i->OStack.pop(); } void Min_d_iFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); IntegerDatum *op2 = static_cast<IntegerDatum *>(i->OStack.pick(0).datum()); if (op1->get() > op2->get()) i->OStack.swap(); i->OStack.pop(); } void Min_d_dFunction::execute(SLIInterpreter *i) const { assert(i->OStack.load() >= 2); i->EStack.pop(); DoubleDatum *op1 = static_cast<DoubleDatum *>(i->OStack.pick(1).datum()); DoubleDatum *op2 = static_cast<DoubleDatum *>(i->OStack.pick(0).datum()); if (op1->get() > op2->get()) i->OStack.swap(); i->OStack.pop(); } const IntegerFunction integerfunction; const DoubleFunction doublefunction; const Add_ddFunction add_ddfunction; const Add_diFunction add_difunction; const Add_idFunction add_idfunction; const Add_iiFunction add_iifunction; const Sub_ddFunction sub_ddfunction; const Sub_diFunction sub_difunction; const Sub_idFunction sub_idfunction; const Sub_iiFunction sub_iifunction; const Mul_ddFunction mul_ddfunction; const Mul_diFunction mul_difunction; const Mul_idFunction mul_idfunction; const Mul_iiFunction mul_iifunction; const Div_ddFunction div_ddfunction; const Div_diFunction div_difunction; const Div_idFunction div_idfunction; const Div_iiFunction div_iifunction; const Sin_dFunction sin_dfunction; const Asin_dFunction asin_dfunction; const Cos_dFunction cos_dfunction; const Acos_dFunction acos_dfunction; const Exp_dFunction exp_dfunction; const Ln_dFunction ln_dfunction; const Log_dFunction log_dfunction; const Sqr_dFunction sqr_dfunction; const Sqrt_dFunction sqrt_dfunction; const Pow_ddFunction pow_ddfunction; const Pow_diFunction pow_difunction; const Modf_dFunction modf_dfunction; const Frexp_dFunction frexp_dfunction; const Ldexp_diFunction ldexp_difunction; const Dexp_iFunction dexp_ifunction; const Mod_iiFunction mod_iifunction; const Abs_iFunction abs_ifunction; const Abs_dFunction abs_dfunction; const Neg_iFunction neg_ifunction; const Neg_dFunction neg_dfunction; const Inv_dFunction inv_dfunction; const EqFunction eqfunction; const OrFunction orfunction; const XorFunction xorfunction; const AndFunction andfunction; const And_iiFunction and_iifunction; const Or_iiFunction or_iifunction; const Geq_iiFunction geq_iifunction; const Geq_idFunction geq_idfunction; const Geq_diFunction geq_difunction; const Geq_ddFunction geq_ddfunction; const Leq_iiFunction leq_iifunction; const Leq_idFunction leq_idfunction; const Leq_diFunction leq_difunction; const Leq_ddFunction leq_ddfunction; const NeqFunction neqfunction; const Not_bFunction not_bfunction; const Not_iFunction not_ifunction; const Gt_iiFunction gt_iifunction; const Gt_ddFunction gt_ddfunction; const Gt_idFunction gt_idfunction; const Gt_diFunction gt_difunction; const Gt_ssFunction gt_ssfunction; const Lt_iiFunction lt_iifunction; const Lt_ddFunction lt_ddfunction; const Lt_idFunction lt_idfunction; const Lt_diFunction lt_difunction; const Lt_ssFunction lt_ssfunction; const UnitStep_iFunction unitstep_ifunction; const UnitStep_dFunction unitstep_dfunction; const UnitStep_iaFunction unitstep_iafunction; const UnitStep_daFunction unitstep_dafunction; const Round_dFunction round_dfunction; const Floor_dFunction floor_dfunction; const Ceil_dFunction ceil_dfunction; const Max_d_dFunction max_d_dfunction; const Max_d_iFunction max_d_ifunction; const Max_i_dFunction max_i_dfunction; const Max_i_iFunction max_i_ifunction; const Min_d_dFunction min_d_dfunction; const Min_d_iFunction min_d_ifunction; const Min_i_dFunction min_i_dfunction; const Min_i_iFunction min_i_ifunction; void init_slimath(SLIInterpreter *i) { i->createcommand("int_d", &integerfunction); i->createcommand("double_i", &doublefunction); i->createcommand("add_dd", &add_ddfunction); i->createcommand("add_di", &add_difunction); i->createcommand("add_id", &add_idfunction); i->createcommand("add_ii", &add_iifunction); // i->createcommand("sub_dd", &sub_ddfunction); i->createcommand("sub_di", &sub_difunction); i->createcommand("sub_id", &sub_idfunction); i->createcommand("sub_ii", &sub_iifunction); // i->createcommand("mul_dd", &mul_ddfunction); i->createcommand("mul_di", &mul_difunction); i->createcommand("mul_id", &mul_idfunction); i->createcommand("mul_ii", &mul_iifunction); // i->createcommand("div_dd", &div_ddfunction); i->createcommand("div_di", &div_difunction); i->createcommand("div_id", &div_idfunction); i->createcommand("div_ii", &div_iifunction); i->createcommand("mod", &mod_iifunction); // i->createcommand("sin_d", &sin_dfunction); i->createcommand("asin_d", &asin_dfunction); i->createcommand("cos_d", &cos_dfunction); i->createcommand("acos_d", &acos_dfunction); i->createcommand("exp_d", &exp_dfunction); i->createcommand("log_d", &log_dfunction); i->createcommand("ln_d", &ln_dfunction); i->createcommand("sqr_d", &sqr_dfunction); i->createcommand("sqrt_d", &sqrt_dfunction); i->createcommand("pow_dd", &pow_ddfunction); i->createcommand("pow_di", &pow_difunction); // i->createcommand("modf_d", &modf_dfunction); i->createcommand("frexp_d", &frexp_dfunction); // i->createcommand("ldexp_di", &ldexp_difunction); i->createcommand("dexp_i", &dexp_ifunction); // i->createcommand("abs_i", &abs_ifunction); i->createcommand("abs_d", &abs_dfunction); // i->createcommand("neg_i", &neg_ifunction); i->createcommand("neg_d", &neg_dfunction); i->createcommand("inv", &inv_dfunction); // i->createcommand("eq", &eqfunction); i->createcommand("and", &andfunction); i->createcommand("and_ii", &and_iifunction); i->createcommand("or_ii", &or_iifunction); i->createcommand("or", &orfunction); i->createcommand("xor", &xorfunction); i->createcommand("leq_ii", &leq_iifunction); i->createcommand("leq_id", &leq_idfunction); i->createcommand("leq_di", &leq_difunction); i->createcommand("leq_dd", &leq_ddfunction); i->createcommand("geq_ii", &geq_iifunction); i->createcommand("geq_id", &geq_idfunction); i->createcommand("geq_di", &geq_difunction); i->createcommand("geq_dd", &geq_ddfunction); i->createcommand("neq", &neqfunction); i->createcommand("not_b", ¬_bfunction); i->createcommand("not_i", ¬_ifunction); // i->createcommand("gt_ii", >_iifunction); i->createcommand("gt_dd", >_ddfunction); i->createcommand("gt_id", >_idfunction); i->createcommand("gt_di", >_difunction); i->createcommand("gt_ss", >_ssfunction); // i->createcommand("lt_ii", <_iifunction); i->createcommand("lt_dd", <_ddfunction); i->createcommand("lt_id", <_idfunction); i->createcommand("lt_di", <_difunction); i->createcommand("lt_ss", <_ssfunction); // i->createcommand("UnitStep_i", &unitstep_ifunction); i->createcommand("UnitStep_d", &unitstep_dfunction); i->createcommand("UnitStep_ia", &unitstep_iafunction); i->createcommand("UnitStep_da", &unitstep_dafunction); // i->createcommand("round_d", &round_dfunction); i->createcommand("floor_d", &floor_dfunction); i->createcommand("ceil_d", &ceil_dfunction); // i->createcommand("max_d_d", &max_d_dfunction); i->createcommand("max_d_i", &max_d_ifunction); i->createcommand("max_i_d", &max_i_dfunction); i->createcommand("max_i_i", &max_i_ifunction); // i->createcommand("min_d_d", &min_d_dfunction); i->createcommand("min_d_i", &min_d_ifunction); i->createcommand("min_i_d", &min_i_dfunction); i->createcommand("min_i_i", &min_i_ifunction); }