13#if !defined(VITA_REAL_PRIMITIVE_H)
14#define VITA_REAL_PRIMITIVE_H
23#include "utility/utility.h"
38using base_t = D_DOUBLE;
40static_assert(std::numeric_limits<base_t>::is_iec559,
41 "Vita requires IEC 559/IEEE 754 floating-point types");
51 return std::get<base_t>(v);
69 explicit real(
const cvect &c, base_t m = -1000.0, base_t u = 1000.0)
70 :
terminal(
"REAL", c[0]), min(m), upp(u)
72 Expects(c.size() == 1);
78 terminal_param_t
init() const final {
return random::between(min, upp); }
81 {
return std::to_string(v); }
85 return static_cast<base_t
>(p.fetch_param());
89 const base_t min, upp;
100 explicit integer(
const cvect &c,
int m = -128,
int u = 127)
101 :
terminal(
"REAL", c[0]), min(m), upp(u)
103 Expects(c.size() == 1);
109 terminal_param_t
init() const final {
return random::between(min, upp); }
112 {
return std::to_string(
static_cast<int>(v)); }
116 return static_cast<base_t
>(p.fetch_param());
129 explicit abs(
const cvect &c = {0}) :
function(
"FABS", c[0], {c[0]})
130 { Expects(c.size() == 1); }
136 case cpp_format:
return "std::abs(%%1%%)";
137 case mql_format:
return "MathAbs(%%1%%)";
138 case python_format:
return "abs(%%1%%)";
139 default:
return "fabs(%%1%%)";
145 const auto a(args[0]);
156 explicit add(
const cvect &c = {0}) :
function(
"FADD", c[0], {c[0], c[0]}) {}
162 return "(%%1%%+%%2%%)";
167 const auto a0(args[0]);
170 const auto a1(args[1]);
173 const base_t ret(
base(a0) +
base(a1));
174 if (!std::isfinite(ret))
return {};
192 explicit aq(
const cvect &c = {0}) :
function(
"AQ", c[0], {c[0], c[0]})
193 { Expects(c.size() == 1); }
199 case cpp_format:
return "(%%1%%/std::sqrt(1.0+std::pow(%%2%%,2.0)))";
200 case mql_format:
return "(%%1%%/MathSqrt(1+MathPow(%%2%%,2)))";
201 default:
return "(%%1%%/sqrt(1.0+pow(%%2%%,2.0)))";
207 const auto a0(args[0]);
210 const auto a1(args[1]);
213 const auto x(
base(a0)), y(
base(a1));
214 const base_t ret(x / std::sqrt(1.0 + y * y));
215 if (!std::isfinite(ret))
return {};
227 explicit cos(
const cvect &c = {0}) :
function(
"FCOS", c[0], {c[0]})
228 { Expects(c.size() == 1); }
234 case cpp_format:
return "std::cos(%%1%%)";
235 case mql_format:
return "MathCos(%%1%%)";
236 default:
return "cos(%%1%%)";
242 const auto a(args[0]);
245 return std::cos(
base(a));
255 explicit div(
const cvect &c = {0}) :
function(
"FDIV", c[0], {c[0], c[0]})
256 { Expects(c.size() == 1); }
260 return "(%%1%%/%%2%%)";
265 const auto a0(args[0]);
268 const auto a1(args[1]);
271 const base_t ret(
base(a0) /
base(a1));
272 if (!std::isfinite(ret))
return {};
284 explicit gt(
const cvect &c = {0, 0}) :
function(
">", c[1], {c[0], c[0]})
285 { Expects(c.size() == 2); }
291 case cpp_format:
return "std::isgreater(%%1%%,%%2%%)";
292 default:
return "(%%1%%>%%2%%)";
298 const auto a0(args[0]);
301 const auto a1(args[1]);
304 return std::isgreater(
base(a0),
base(a1));
317 explicit idiv(
const cvect &c = {0}) :
function(
"FIDIV", c[0], {c[0], c[0]})
318 { Expects(c.size() == 1); }
324 case cpp_format:
return "std::floor(%%1%%/%%2%%)";
325 case mql_format:
return "MathFloor(%%1%%/%%2%%)";
326 case python_format:
return "(%%1%%//%%2%%)";
327 default:
return "floor(%%1%%/%%2%%)";
333 const auto a0(args[0]);
336 const auto a1(args[1]);
339 const base_t ret(std::floor(
base(a0) /
base(a1)));
340 if (!std::isfinite(ret))
return {};
354 explicit ifb(
const cvect &c = {0, 0})
355 :
function(
"FIFB", c[1], {c[0], c[0], c[0], c[1], c[1]})
356 { Expects(c.size() == 2); }
363 return "(%%4%% if %%2%% <= %%1%% <= %%3%% else %%5%%)";
365 return "(fmin(%%2%%,%%3%%) <= %%1%% && %%1%% <= fmax(%%2%%,%%3%%) ?"
372 const auto a0(args[0]);
375 const auto a1(args[1]);
378 const auto a2(args[2]);
381 const auto v0(
base(a0));
382 const auto v1(
base(a1));
383 const auto v2(
base(a2));
385 const auto min(std::fmin(v1, v2));
386 const auto max(std::fmax(v1, v2));
388 if (std::isless(v0, min) || std::isgreater(v0,
max))
401 explicit ife(
const cvect &c = {0, 0})
402 :
function(
"FIFE", c[1], {c[0], c[0], c[1], c[1]})
403 { Expects(c.size() == 2); }
410 return "(std::fabs(%%1%%-%%2%%)<2*std::numeric_limits<double>::epsilon()"
413 return "(NormalizeDouble(%%1%%-%%2%%,8)==0 ? %%3%% : %%4%%)";
415 return "(%%3%% if isclose(%%1%%,%%2%%) else %%4%%)";
417 return "(fabs(%%1%%-%%2%%)<2*DBL_EPSILON ? %%3%% : %%4%%)";
423 const auto a0(args[0]);
426 const auto a1(args[1]);
447 explicit ifl(
const cvect &c = {0, 0})
448 :
function(
"FIFL", c[1], {c[0], c[0], c[1], c[1]})
449 { Expects(c.size() == 2); }
455 case python_format:
return "(%%3%% if %%1%%<%%2%% else %%4%%)";
456 default:
return "(%%1%%<%%2%% ? %%3%% : %%4%%)";
462 const auto a0(args[0]);
465 const auto a1(args[1]);
468 const auto v0(
base(a0)), v1(
base(a1));
469 if (std::isless(v0, v1))
487 explicit ifz(
const cvect &c = {0})
488 :
function(
"FIFZ", c[0], {c[0], c[0], c[0]})
489 { Expects(c.size() == 1); }
496 return "(std::fabs(%%1%%)<2*std::numeric_limits<double>::epsilon() ? "
499 return "(NormalizeDouble(%%1%%,8)==0 ? %%2%% : %%3%%)";
501 return "(%%2%% if abs(%%1%%) < 1e-10 else %%3%%)";
503 return "(fabs(%%1%%)<2*DBL_EPSILON ? %%2%% : %%3%%)";
509 const auto a0(args[0]);
512 if (issmall(
base(a0)))
525 explicit length(
const cvect &c = {0, 0}) :
function(
"FLENGTH", c[1], {c[0]})
526 { Expects(c.size() == 2); }
532 case cpp_format:
return "std::string(%%1%%).length()";
533 case mql_format:
return "StringLen(%%1%%)";
534 case python_format:
return "len(%%1%%)";
535 default:
return "strlen(%%1%%)";
541 const auto a(args[0]);
544 return static_cast<base_t
>(std::get<D_STRING>(a).length());
554 explicit ln(
const cvect &c = {0}) :
function(
"FLN", c[0], {c[0]})
555 { Expects(c.size() == 1); }
561 case cpp_format:
return "std::log(%%1%%)";
562 case mql_format:
return "MathLog(%%1%%)";
563 default:
return "log(%%1%%)";
574 const auto a0(args[0]);
577 const auto ret(std::log(
base(a0)));
578 if (!std::isfinite(ret))
return {};
590 explicit lt(
const cvect &c = {0, 0}) :
function(
"<", c[1], {c[0], c[0]})
591 { Expects(c.size() == 2); }
597 case cpp_format:
return "std::isless(%%1%%,%%2%%)";
598 default:
return "(%%1%%<%%2%%)";
604 const auto a0(args[0]);
607 const auto a1(args[1]);
610 return std::isless(
base(a0),
base(a1));
623 explicit max(
const cvect &c = {0}) :
function(
"FMAX", c[0], {c[0], c[0]})
624 { Expects(c.size() == 1); }
630 case cpp_format:
return "std::fmax(%%1%%,%%2%%)";
631 case python_format:
return "max(%%1%%,%%2%%)";
632 default:
return "fmax(%%1%%,%%2%%)";
638 const auto a0(args[0]);
641 const auto a1(args[1]);
644 const base_t ret(std::fmax(
base(a0),
base(a1)));
645 if (!std::isfinite(ret))
return {};
657 explicit mod(
const cvect &c = {0}) :
function(
"FMOD", c[0], {c[0], c[0]})
658 { Expects(c.size() == 1); }
664 case cpp_format:
return "std::fmod(%%1%%,%%2%%)";
665 case mql_format:
return "MathMod(%%1%%,%%2%%)";
666 case python_format:
return "(%%1%% % %%2%%)";
667 default:
return "fmod(%%1%%,%%2%%)";
673 const auto a0(args[0]);
676 const auto a1(args[1]);
679 const base_t ret(std::fmod(
base(a0),
base(a1)));
680 if (!std::isfinite(ret))
return {};
692 explicit mul(
const cvect &c = {0}) :
function(
"FMUL", c[0], {c[0], c[0]})
693 { Expects(c.size() == 1); }
697 return "(%%1%%*%%2%%)";
702 const auto a0(args[0]);
705 const auto a1(args[1]);
708 const base_t ret(
base(a0) *
base(a1));
709 if (!std::isfinite(ret))
return {};
721 explicit sin(
const cvect &c = {0}) :
function(
"FSIN", c[0], {c[0]})
722 { Expects(c.size() == 1); }
728 case cpp_format:
return "std::sin(%%1%%)";
729 case mql_format:
return "MathSin(%%1%%)";
730 default:
return "sin(%%1%%)";
736 const auto a(args[0]);
739 return std::sin(
base(a));
749 explicit sqrt(
const cvect &c = {0}) :
function(
"FSQRT", c[0], {c[0]})
750 { Expects(c.size() == 1); }
756 case cpp_format:
return "std::sqrt(%%1%%)";
757 case mql_format:
return "MathSqrt(%%1%%)";
758 default:
return "sqrt(%%1%%)";
764 const auto a(args[0]);
767 const auto v(
base(a));
768 if (std::isless(v, 0.0))
781 explicit sub(
const cvect &c = {0}) :
function(
"FSUB", c[0], {c[0], c[0]})
782 { Expects(c.size() == 1); }
786 return "(%%1%%-%%2%%)";
791 const auto a0(args[0]);
794 const auto a1(args[1]);
797 const base_t ret(
base(a0) -
base(a1));
798 if (!std::isfinite(ret))
return {};
811 explicit sigmoid(
const cvect &c = {0}) :
function(
"FSIGMOID", c[0], {c[0]})
812 { Expects(c.size() == 1); }
818 case cpp_format:
return "1.0 / (1.0 + std::exp(-%%1%%))";
819 case mql_format:
return "1.0 / (1.0 + MathExp(-%%1%%))";
820 case python_format:
return "1. / (1. + math.exp(-%%1%%))";
821 default:
return "1 / (1 + exp(-%%1%%))";
827 const auto a0(args[0]);
834 const auto x(
base(a0));
836 return 1.0 / (1.0 + std::exp(-x));
838 return std::exp(x) / (1.0 + std::exp(x));
Minimum interface of an interpreter.
A symbol with arity() > 0.
function(const std::string &, category_t, cvect)
The absolute value of a real number.
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
bool associative() const final
Is the symbol subject to the associative law of arithmetic?
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format) const final
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
Unprotected division (UPD) between two real numbers.
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
Quotient of the division between two real numbers.
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
double penalty_nvi(core_interpreter *ci) const final
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
double penalty_nvi(core_interpreter *ci) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
Ephemeral random integer constant.
value_t eval(symbol_params &p) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
bool parametric() const final
A parametric terminal needs an additional parameter to be evaluated.
terminal_param_t init() const final
Used to initialize the internal parameter of the terminal.
std::string display(terminal_param_t v, format) const final
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
Natural logarithm of a real number.
value_t eval(symbol_params &args) const final
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
The larger of two floating point values.
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
Remainder of the division between real numbers.
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format) const final
Ephemeral random constant.
terminal_param_t init() const final
Used to initialize the internal parameter of the terminal.
bool parametric() const final
A parametric terminal needs an additional parameter to be evaluated.
std::string display(terminal_param_t v, format) const final
value_t eval(symbol_params &p) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
Square root of a real number.
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
std::string display(format f) const final
Subtraction between real numbers.
std::string display(format) const final
value_t eval(symbol_params &args) const final
Calculates the value of / performs the action associated with the symbol (it's implementation specifi...
An interface for parameter passing to functions / terminals.
format
Symbol rendering format.
A symbol with zero-arity.
We assume that errors during floating-point operations aren't terminal errors.
base_t base(const value_t &v)
A simple shortcut for casting an value_t to base_t.
double comparison_function_penalty(core_interpreter *ci)
A simple, convenient function for the penalty score of the typical four-terms comparison.
bool has_value(const value_t &v)
std::variant< D_VOID, D_INT, D_DOUBLE, D_STRING > value_t
A variant containing the data types used by the interpreter for internal calculations / output value ...