13#if !defined(ULTRA_REAL_PRIMITIVE_H)
14#define ULTRA_REAL_PRIMITIVE_H
20#include "utility/misc.h"
37 return std::get<D_DOUBLE>(v);
50static_assert(std::numeric_limits<D_DOUBLE>::is_iec559,
51 "Ultra requires IEC 559/IEEE 754 floating-point types");
59 explicit number(D_DOUBLE m = -1000.0, D_DOUBLE s = 1000.0,
61 :
terminal(
"REAL", c), min_(m), sup_(s)
66 [[nodiscard]] D_DOUBLE min()
const noexcept {
return min_; }
67 [[nodiscard]] D_DOUBLE sup()
const noexcept {
return sup_; }
73 const D_DOUBLE min_, sup_;
82 explicit integer(D_INT m = -128, D_INT s = 128,
84 :
terminal(
"IREAL", c), min_(m), sup_(s)
89 [[nodiscard]] D_DOUBLE min()
const noexcept
90 {
return static_cast<D_DOUBLE
>(min_);}
91 [[nodiscard]] D_DOUBLE sup()
const noexcept
92 {
return static_cast<D_DOUBLE
>(sup_);}
98 const D_INT min_, sup_;
105 :
terminal(std::to_string(v), c), val_(v)
128 case cpp_format:
return "std::abs({0})";
129 case python_format:
return "abs({0})";
130 default:
return "fabs({0})";
136 const auto p(pars[0]);
139 assert(std::isfinite(
base(p)));
140 return std::fabs(
base(p));
160 const auto p0(pars[0]);
163 const auto p1(pars[1]);
166 const auto ret(
base(p0) +
base(p1));
167 if (!std::isfinite(ret))
return {};
194 Expects(pt.size() == 2);
201 case cpp_format:
return "({0}/std::sqrt(1.0+std::pow({1},2.0)))";
202 case python_format:
return "({0}/math.sqrt(1.0+math.pow({1},2.0)))";
203 default:
return "({0}/sqrt(1.0+pow({1},2.0)))";
209 const auto p0(pars[0]);
212 const auto p1(pars[1]);
215 const auto x(
base(p0)), y(
base(p1));
216 const auto ret(x / std::sqrt(1.0 + y * y));
217 if (!std::isfinite(ret))
return {};
236 case cpp_format:
return "std::cos({0})";
237 case python_format:
return "math.cos({0})";
238 default:
return "cos({0})";
244 const auto p(pars[0]);
247 assert(!std::isinf(
base(p)));
248 return std::cos(
base(p));
263 Expects(pt.size() == 2);
273 const auto p0(pars[0]);
276 const auto p1(pars[1]);
279 const auto ret(
base(p0) /
base(p1));
280 if (!std::isfinite(ret))
return {};
297 Expects(pt.size() == 2);
298 Expects(pt[0] == pt[1]);
305 case cpp_format:
return "std::isgreater({0},{1})";
306 default:
return "({0}>{1})";
312 const auto p0(pars[0]);
315 const auto p1(pars[1]);
318 return std::isgreater(
base(p0),
base(p1));
336 Expects(pt.size() == 2);
337 Expects(pt[0] == pt[1]);
344 case cpp_format:
return "std::floor({0}/{1})";
345 case python_format:
return "({0}//{1})";
346 default:
return "floor({0}/{1})";
352 const auto p0(pars[0]);
355 const auto p1(pars[1]);
358 const auto ret(std::floor(
base(p0) /
base(p1)));
359 if (!std::isfinite(ret))
return {};
378 Expects(pt.size() == 4);
380 Expects(pt[0] == pt[1]);
381 Expects(pt[2] == pt[3]);
389 return "(std::fabs({0}-{1})<2*std::numeric_limits<double>::epsilon() ? "
392 return "({2} if math.isclose({0}, {1}) else {3})";
394 return "(fabs({0}-{1}) < 2*DBL_EPSILON ? {2} : {3})";
400 const auto p0(pars[0]);
403 const auto p1(pars[1]);
426 Expects(pt.size() == 4);
428 Expects(pt[0] == pt[1]);
429 Expects(pt[2] == pt[3]);
436 case python_format:
return "({2} if {0}<{1} else {3})";
437 default:
return "({0}<{1} ? {2} : {3})";
443 const auto p0(pars[0]);
446 const auto p1(pars[1]);
449 const auto v0(
base(p0)), v1(
base(p1));
450 if (std::isless(v0, v1))
470 Expects(pt.size() == 3);
472 Expects(pt[1] == pt[2]);
480 return "(std::fabs({0})<2*std::numeric_limits<double>::epsilon() ? "
483 return "({1} if abs({0}) < 1e-10 else {2})";
485 return "(fabs({0})<2*DBL_EPSILON ? {1} : {2})";
491 const auto p0(pars[0]);
494 return issmall(
base(p0)) ? pars[1] : pars[2];
507 Expects(pt.size() == 1);
515 case cpp_format:
return "std::string({0}).length()";
516 case python_format:
return "len({0})";
517 default:
return "strlen({0})";
523 const auto p(pars[0]);
526 return static_cast<D_DOUBLE
>(std::get<D_STRING>(p).length());
548 case cpp_format:
return "std::log({0})";
549 case python_format:
return "math.log({0})";
550 default:
return "log({0})";
561 const auto p0(pars[0]);
564 const auto ret(std::log(
base(p0)));
565 if (!std::isfinite(ret))
return {};
589 case cpp_format:
return "std::exp({0})";
590 case python_format:
return "math.exp({0})";
591 default:
return "exp({0})";
602 const auto p0(pars[0]);
605 const auto ret(std::exp(
base(p0)));
606 if (!std::isfinite(ret))
return {};
623 Expects(pt.size() == 2);
624 Expects(pt[0] == pt[1]);
631 case cpp_format:
return "std::isless({0},{1})";
632 default:
return "({0}<{1})";
638 const auto p0(pars[0]);
641 const auto p1(pars[1]);
644 return std::isless(
base(p0),
base(p1));
664 case cpp_format:
return "std::fmax({0},{1})";
665 case python_format:
return "max({0},{1})";
666 default:
return "fmax({0},{1})";
672 const auto p0(pars[0]);
675 const auto p1(pars[1]);
678 const auto ret(std::fmax(
base(p0),
base(p1)));
679 if (!std::isfinite(ret))
return {};
696 Expects(pt.size() == 2);
697 Expects(pt[0] == pt[1]);
704 case cpp_format:
return "std::fmod({0},{1})";
705 case python_format:
return "({0} % {1})";
706 default:
return "fmod({0},{1})";
712 const auto p0(pars[0]);
715 const auto p1(pars[1]);
718 const auto ret(std::fmod(
base(p0),
base(p1)));
719 if (!std::isfinite(ret))
return {};
736 Expects(pt.size() == 2);
746 const auto p0(pars[0]);
749 const auto p1(pars[1]);
752 const auto ret(
base(p0) *
base(p1));
753 if (!std::isfinite(ret))
return {};
772 case cpp_format:
return "std::sin({0})";
773 case python_format:
return "math.sin({0})";
774 default:
return "sin({0})";
780 const auto p(pars[0]);
783 assert(!std::isinf(
base(p)));
784 return std::sin(
base(p));
801 case cpp_format:
return "std::sqrt({0})";
802 case python_format:
return "math.sqrt({0})";
803 default:
return "sqrt({0})";
809 const auto p(pars[0]);
812 const auto v(
base(p));
813 if (std::isless(v, 0.0))
836 const auto p0(pars[0]);
839 const auto p1(pars[1]);
842 const auto ret(
base(p0) -
base(p1));
843 if (!std::isfinite(ret))
return {};
862 case cpp_format:
return "1.0 / (1.0 + std::exp(-{0}))";
863 case python_format:
return "1. / (1. + math.exp(-{0}))";
864 default:
return "1 / (1 + exp(-{0}))";
870 const auto p0(pars[0]);
877 const auto x(
base(p0));
879 return x >= 0.0 ? 1.0 / (1.0 + std::exp(-x))
880 : std::exp(x) / (1.0 + std::exp(x));
Definition function.h:108
std::vector< category_t > param_data_types
Definition function.h:49
function(const std::string &, return_type, param_data_types)
Definition function.cc:27
category_t return_type
Type used to describe the return category of the function.
Definition function.h:52
value_t eval(const params &pars) const final
Definition real.h:134
std::string to_string(format f) const final
Definition real.h:124
std::string to_string(format) const final
Definition real.h:153
value_t eval(const params &pars) const final
Definition real.h:158
value_t eval(const params &pars) const final
Definition real.h:207
std::string to_string(format f) const final
Definition real.h:197
value_t eval(const params &pars) const final
Definition real.h:242
std::string to_string(format f) const final
Definition real.h:232
std::string to_string(format) const final
Definition real.h:266
value_t eval(const params &pars) const final
Definition real.h:271
std::string to_string(format f) const final
Definition real.h:585
value_t eval(const params &pars) const final
Definition real.h:600
std::string to_string(format f) const final
Definition real.h:301
value_t eval(const params &pars) const final
Definition real.h:310
value_t eval(const params &pars) const final
Definition real.h:350
std::string to_string(format f) const final
Definition real.h:340
value_t eval(const params &pars) const final
Definition real.h:398
std::string to_string(format f) const final
Definition real.h:384
value_t eval(const params &pars) const final
Definition real.h:441
std::string to_string(format f) const final
Definition real.h:432
value_t eval(const params &pars) const final
Definition real.h:489
std::string to_string(format f) const final
Definition real.h:475
value_t instance() const final
Definition real.h:94
std::string to_string(format f) const final
Definition real.h:511
value_t eval(const params &pars) const final
Definition real.h:521
value_t instance() const noexcept final
Definition real.h:109
value_t eval(const params &pars) const final
Definition real.h:559
std::string to_string(format f) const final
Definition real.h:544
std::string to_string(format f) const final
Definition real.h:627
value_t eval(const params &pars) const final
Definition real.h:636
std::string to_string(format f) const final
Definition real.h:660
value_t eval(const params &pars) const final
Definition real.h:670
std::string to_string(format f) const final
Definition real.h:700
value_t eval(const params &pars) const final
Definition real.h:710
std::string to_string(format) const final
Definition real.h:739
value_t eval(const params &pars) const final
Definition real.h:744
value_t instance() const final
Definition real.h:69
value_t eval(const params &pars) const final
Definition real.h:868
std::string to_string(format f) const final
Definition real.h:858
value_t eval(const params &pars) const final
Definition real.h:778
std::string to_string(format f) const final
Definition real.h:768
std::string to_string(format f) const final
Definition real.h:797
value_t eval(const params &pars) const final
Definition real.h:807
value_t eval(const params &pars) const final
Definition real.h:834
std::string to_string(format) const final
Definition real.h:829
format
Supported rendering formats for symbol stringification.
Definition symbol.h:72
unsigned category_t
Definition symbol.h:55
static constexpr category_t default_category
Default category assigned when typing is not used.
Definition symbol.h:58
bool has_value(const value_t &v) noexcept
Definition value.cc:31
std::variant< D_VOID, D_INT, D_DOUBLE, D_STRING, const D_NULLARY *, D_ADDRESS, const D_VARIABLE *, D_IVECTOR > value_t
Definition value.h:54
T between(T min, T sup)
Definition random.h:57
D_DOUBLE base(const value_t &v)
Definition real.h:35