-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmath_module.h
155 lines (124 loc) · 7.78 KB
/
math_module.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifndef _MATH_MODULE_H__
#define _MATH_MODULE_H__
#include "tinypy.h"
const double Exponential = 2.7182818284590452354;
const double PiGreco = 3.14159265358979323846;
static SharedPtr<Object> math_frexp(PyEngine *py, SharedPtr<ListObject> args)
{
double x = args->getNumberAt(0);
int y = 0;
errno = 0;
double result = frexp(x, &y);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << "frexp(x): x=" << x << ", ""out of range");
return NoneObject;
}
auto ret = py->createList();
ret->pushBack(py->createNumber(result));
ret->pushBack(py->createNumber((double)y));
return ret;
}
static SharedPtr<Object> math_log(PyEngine *py, SharedPtr<ListObject> args) {
int nargs = args->size();
double x = args->getNumberAt(0);
double y = nargs >= 2 ? args->getNumberAt(1) : Exponential;
errno = 0;
double num = log10(x);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << "log(x, y): x=" << x << ",y=" << y << " out of range");
return NoneObject;
}
errno = 0;
double den = log10(y);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << "log(x, y): x=" << x << ",y=" << y << " out of range");
return NoneObject;
}
double ret = num / den;
return py->createNumber(ret);
}
static SharedPtr<Object> math_modf(PyEngine *py, SharedPtr<ListObject> args) {
double x = args->getNumberAt(0);
double y = 0.0;
errno = 0;
double result = modf(x, &y);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << __func__ << "(x): x=" << x << "out of range");
return NoneObject;
}
auto ret = py->createList();
ret->pushBack(py->createNumber(result));
ret->pushBack(py->createNumber(y));
return ret;
}
static SharedPtr<Object> math_fun1(PyEngine *py, SharedPtr<ListObject> args, String name, std::function<double(double)> fn) {
double x = args->getNumberAt(0);
errno = 0;
double ret = fn(x);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << name << "(x): x=" << x << "out of range");
return NoneObject;
}
return py->createNumber(ret);
}
static SharedPtr<Object> math_fun2(PyEngine *py, SharedPtr<ListObject> args, String name, std::function<double(double, double)> fn)
{
double x = args->getNumberAt(0);
double y = args->getNumberAt(1);
errno = 0;
double ret = fn(x, y);
if (errno == EDOM || errno == ERANGE) {
raiseException(StringUtils::format() << name << "(x, y): x=" << x << ",y=" << y << " out of range");
return NoneObject;
}
return py->createNumber(ret);
}
static const double degToRad = 3.141592653589793238462643383 / 180.0;
static double degrees(double x) {
return (x / degToRad);
}
static double radians(double x) {
return (x * degToRad);
}
static SharedPtr<Object> math_pi;
static SharedPtr<Object> math_e;
void math_init(PyEngine *py)
{
auto math_mod = py->createDict();
math_pi = py->createNumber(PiGreco);
math_e = py->createNumber(Exponential);
math_mod->setAttr(py->createString("pi"), math_pi);
math_mod->setAttr(py->createString("e"), math_e);
math_mod->setAttr(py->createString("acos"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "acos", [](double x) {return acos(x); }); }));
math_mod->setAttr(py->createString("asin"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "asin", [](double x) {return asin(x); }); }));
math_mod->setAttr(py->createString("atan"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "atan", [](double x) {return atan(x); }); }));
math_mod->setAttr(py->createString("atan2"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun2(py, args, "atan2", [](double x, double y) {return atan2(x, y); }); }));
math_mod->setAttr(py->createString("ceil"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "ceil", [](double x) {return ceil(x); }); }));
math_mod->setAttr(py->createString("cos"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "cos", [](double x) {return cos(x); }); }));
math_mod->setAttr(py->createString("cosh"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "cosh", [](double x) {return cosh(x); }); }));
math_mod->setAttr(py->createString("degrees"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "degrees", [](double x) {return degrees(x); }); }));
math_mod->setAttr(py->createString("exp"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "exp", [](double x) {return exp(x); }); }));
math_mod->setAttr(py->createString("fabs"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "fabs", [](double x) {return fabs(x); }); }));
math_mod->setAttr(py->createString("floor"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "floor", [](double x) {return floor(x); }); }));
math_mod->setAttr(py->createString("fmod"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun2(py, args, "fmod", [](double x, double y) {return fmod(x, y); }); }));
math_mod->setAttr(py->createString("frexp"), py->createFunction(math_frexp));
math_mod->setAttr(py->createString("hypot"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun2(py, args, "hypot", [](double x, double y) {return hypot(x, y); }); }));
math_mod->setAttr(py->createString("ldexp"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun2(py, args, "ldexp", [](double x, double y) {return ldexp(x, y); }); }));
math_mod->setAttr(py->createString("log"), py->createFunction(math_log));
math_mod->setAttr(py->createString("log10"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "log10", [](double x) {return log10(x); }); }));
math_mod->setAttr(py->createString("modf"), py->createFunction(math_modf));
math_mod->setAttr(py->createString("pow"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun2(py, args, "pow", [](double x, double y) {return pow(x, y); }); }));
math_mod->setAttr(py->createString("radians"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "radians", [](double x) {return radians(x); }); }));
math_mod->setAttr(py->createString("sin"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "sin", [](double x) {return sin(x); }); }));
math_mod->setAttr(py->createString("sinh"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "sinh", [](double x) {return sinh(x); }); }));
math_mod->setAttr(py->createString("sqrt"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "sqrt", [](double x) {return sqrt(x); }); }));
math_mod->setAttr(py->createString("tan"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "tan", [](double x) {return tan(x); }); }));
math_mod->setAttr(py->createString("tanh"), py->createFunction([](PyEngine* py, SharedPtr<ListObject> args) {return math_fun1(py, args, "tanh", [](double x) {return tanh(x); }); }));
math_mod->setAttr(py->createString("__doc__"), py->createString(
"This module is always available. It provides access to the\n"
"mathematical functions defined by the regs[C] standard."));
math_mod->setAttr(py->createString("__name__"), py->createString("math"));
math_mod->setAttr(py->createString("__file__"), py->createString(__FILE__));
py->addModule("math", math_mod);
}
#endif //_MATH_MODULE_H__