loom

Форк
0
382 строки · 13.6 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo
7
*/
8

9
#include "simodo/variable/Module_interface.h"
10
#include "simodo/variable/VariableSetWrapper.h"
11
#include "simodo/variable/matrix_operations.h"
12
#include "simodo/inout/convert/functions.h"
13
#include "simodo/bormental/DrBormental.h"
14

15
#include <cassert>
16
#include <cmath>
17

18
#ifdef CROSS_WIN
19
// MinGW related workaround
20
#define BOOST_DLL_FORCE_ALIAS_INSTANTIATION
21
#endif
22

23
#include <boost/dll/alias.hpp>
24
#include <functional>
25

26
using namespace simodo;
27
using namespace simodo::variable;
28
using namespace simodo::inout;
29

30
namespace
31
{
32
    Value _sin(Module_interface * , const VariableSetWrapper & args)
33
    {
34
        const Variable & ori = args[0].origin();
35
        assert(ori.value().isFloat());
36
        return sin(ori.value().getFloat());
37
    }
38

39
    Value _cos(Module_interface * , const VariableSetWrapper & args)
40
    {
41
        const Variable & ori = args[0].origin();
42
        assert(ori.value().isFloat());
43
        return cos(ori.value().getFloat());
44
    }
45

46
    Value _tan(Module_interface * , const VariableSetWrapper & args)
47
    {
48
        const Variable & ori = args[0].origin();
49
        assert(ori.value().isFloat());
50
        return tan(ori.value().getFloat());
51
    }
52

53
    Value _asin(Module_interface * , const VariableSetWrapper & args)
54
    {
55
        const Variable & ori = args[0].origin();
56
        assert(ori.value().isFloat());
57
        return asin(ori.value().getFloat());
58
    }
59

60
    Value _acos(Module_interface * , const VariableSetWrapper & args)
61
    {
62
        const Variable & ori = args[0].origin();
63
        assert(ori.value().isFloat());
64
        return acos(ori.value().getFloat());
65
    }
66

67
    Value _atan(Module_interface * , const VariableSetWrapper & args)
68
    {
69
        const Variable & ori = args[0].origin();
70
        assert(ori.value().isFloat());
71
        return atan(ori.value().getFloat());
72
    }
73

74
    Value _sqrt(Module_interface * , const VariableSetWrapper & args)
75
    {
76
        const Variable & ori = args[0].origin();
77
        assert(ori.value().isFloat());
78
        return sqrt(ori.value().getFloat());
79
    }
80

81
    Value _exp(Module_interface * , const VariableSetWrapper & args)
82
    {
83
        const Variable & ori = args[0].origin();
84
        assert(ori.value().isFloat());
85
        return exp(ori.value().getFloat());
86
    }
87

88
    Value _ln(Module_interface * , const VariableSetWrapper & args)
89
    {
90
        const Variable & ori = args[0].origin();
91
        assert(ori.value().isFloat());
92
        return log(ori.value().getFloat());
93
    }
94

95
    bool isZero(double d) {
96
        /// \todo PVS Studio err. Нужно проверять на околонулевую дельту (см. проверку на деление на ноль в интерпретаторе)
97
        /// V590 Consider inspecting the 'd <= 0.0 && 0.0 <= d' expression. 
98
        /// The expression is excessive or contains a misprint
99
        return d <= 0.0 && 0.0 <= d;
100
    }
101

102
    Value _atan2ND(Module_interface * , const VariableSetWrapper & args)
103
    {
104
        const Variable & oriN = args[0].origin();
105
        assert(oriN.type() == ValueType::Float);
106
        double num = std::get<double>(oriN.variant());
107

108
        const Variable & oriD = args[1].origin();
109
        assert(oriD.type() == ValueType::Float);
110
        double denom = std::get<double>(oriD.variant());
111

112
        if (isZero(denom)) {
113
            throw bormental::DrBormental("Module math atan2ND", "Denominator is zero");
114
        }
115

116
        return atan2(num, denom);
117
    }
118

119
    Value _signFloat(Module_interface * , const VariableSetWrapper & args)
120
    {
121
        const Variable & ori = args[0].origin();
122
        assert(ori.type() == ValueType::Float);
123
        return double (std::signbit(std::get<double>(ori.variant())) ? -1.0 : 1.0);
124
    }
125

126
    Value _signInt(Module_interface * , const VariableSetWrapper & args)
127
    {
128
        const Variable & ori = args[0].origin();
129
        assert(ori.type() == ValueType::Int);
130
        return int64_t (std::signbit(std::get<int64_t>(ori.variant())) ? -1 : 1);
131
    }
132

133
    Value _asinND(Module_interface * , const VariableSetWrapper & args)
134
    {
135
        const Variable & oriN = args[0].origin();
136
        assert(oriN.type() == ValueType::Float);
137
        double num = std::get<double>(oriN.variant());
138

139
        const Variable & oriD = args[1].origin();
140
        assert(oriD.type() == ValueType::Float);
141
        double denom = std::get<double>(oriD.variant());
142

143
        if (isZero(denom)) {
144
            throw bormental::DrBormental("Module math asinND", "Denominator is zero");
145
        }
146

147
        return asin(num / denom);
148
    }
149

150
    Value _acosND(Module_interface * , const VariableSetWrapper & args)
151
    {
152
        const Variable & oriN = args[0].origin();
153
        assert(oriN.type() == ValueType::Float);
154
        double num = std::get<double>(oriN.variant());
155

156
        const Variable & oriD = args[1].origin();
157
        assert(oriD.type() == ValueType::Float);
158
        double denom = std::get<double>(oriD.variant());
159

160
        if (isZero(denom)) {
161
            throw bormental::DrBormental("Module math acosND", "Denominator is zero");
162
        }
163

164
        return acos(num / denom);
165
    }
166

167
    Value _atanND(Module_interface * , const VariableSetWrapper & args)
168
    {
169
        const Variable & oriN = args[0].origin();
170
        assert(oriN.type() == ValueType::Float);
171
        double num = std::get<double>(oriN.variant());
172

173
        const Variable & oriD = args[1].origin();
174
        assert(oriD.type() == ValueType::Float);
175
        double denom = std::get<double>(oriD.variant());
176

177
        if (isZero(denom)) {
178
            throw bormental::DrBormental("Module math atanND", "Denominator is zero");
179
        }
180

181
        return atan(num / denom);
182
    }
183

184
    Value _clampReal(Module_interface * , const VariableSetWrapper & args)
185
    {
186
        const Variable & oriL = args[0].origin();
187
        assert(oriL.type() == ValueType::Float);
188
        double left = std::get<double>(oriL.variant());
189

190
        const Variable & oriV = args[1].origin();
191
        assert(oriV.type() == ValueType::Float);
192
        double value = std::get<double>(oriV.variant());
193

194
        const Variable & oriR = args[2].origin();
195
        assert(oriR.type() == ValueType::Float);
196
        double right = std::get<double>(oriR.variant());
197

198
        if (left > right) {
199
            throw bormental::DrBormental("Module math clampReal", "Left boundary is greater than right one");
200
        }
201

202
        return std::clamp(value, left, right);
203
    }
204

205
    Value _clampInt(Module_interface * , const VariableSetWrapper & args)
206
    {
207
        const Variable & oriL = args[0].origin();
208
        assert(oriL.type() == ValueType::Int);
209
        int64_t left = std::get<int64_t>(oriL.variant());
210

211
        const Variable & oriV = args[1].origin();
212
        assert(oriV.type() == ValueType::Int);
213
        int64_t value = std::get<int64_t>(oriV.variant());
214

215
        const Variable & oriR = args[2].origin();
216
        assert(oriR.type() == ValueType::Int);
217
        int64_t right = std::get<int64_t>(oriR.variant());
218

219
        if (left > right) {
220
            throw bormental::DrBormental("Module math clampReal", "Left boundary is greater than right one");
221
        }
222

223
        return std::clamp(value, left, right);
224
    }
225

226
    Value _absReal(Module_interface * , const VariableSetWrapper & args)
227
    {
228
        const Variable & ori = args[0].origin();
229
        assert(ori.type() == ValueType::Float);
230
        return abs(std::get<double>(ori.variant()));
231
    }
232

233
    Value _absInt(Module_interface * , const VariableSetWrapper & args)
234
    {
235
        const Variable & ori = args[0].origin();
236
        assert(ori.type() == ValueType::Int);
237
        return abs(std::get<int64_t>(ori.variant()));
238
    }
239

240
    Value _length(Module_interface * , const VariableSetWrapper & args)
241
    {
242
        const Variable & vector = args[0].origin();
243

244
        if (vector.type() == ValueType::Array)
245
            return lengthVector(vector.value());
246

247
        throw bormental::DrBormental("Module math length", "Input argument must be Array type");
248
    }
249
}
250

251
/*!
252
    * \brief Получение ссылки на глобальное пространство имён математических операций и констант
253
    */
254
class ModuleHost_math : public Module_interface
255
{
256
public:
257
    virtual version_t version() const override { return lib_version(); }
258

259
    virtual Value instantiate(std::shared_ptr<Module_interface> module_host) override {
260
        return {{
261
            {u"pi", M_PI},
262
            {u"sin", {ValueType::Function, Object {{
263
                {u"@", ExternalFunction {module_host, _sin}},
264
                {{}, ValueType::Float},
265
                {u"_value_", ValueType::Float},
266
            }}}},
267
            {u"cos", {ValueType::Function, Object {{
268
                {u"@", ExternalFunction {{module_host}, _cos}},
269
                {{}, ValueType::Float},
270
                {u"_value_", ValueType::Float},
271
            }}}},
272
            {u"tan", {ValueType::Function, Object {{
273
                {u"@", ExternalFunction {{module_host}, _tan}},
274
                {{}, ValueType::Float},
275
                {u"_value_", ValueType::Float},
276
            }}}},
277
            {u"asin", {ValueType::Function, Object {{
278
                {u"@", ExternalFunction {{module_host}, _asin}},
279
                {{}, ValueType::Float},
280
                {u"_value_", ValueType::Float},
281
            }}}},
282
            {u"acos", {ValueType::Function, Object {{
283
                {u"@", ExternalFunction {{module_host}, _acos}},
284
                {{}, ValueType::Float},
285
                {u"_value_", ValueType::Float},
286
            }}}},
287
            {u"atan", {ValueType::Function, Object {{
288
                {u"@", ExternalFunction {{module_host}, _atan}},
289
                {{}, ValueType::Float},
290
                {u"_value_", ValueType::Float},
291
            }}}},
292
            {u"sqrt", {ValueType::Function, Object {{
293
                {u"@", ExternalFunction {{module_host}, _sqrt}},
294
                {{}, ValueType::Float},
295
                {u"_value_", ValueType::Float},
296
            }}}},
297
            {u"exp", {ValueType::Function, Object {{
298
                {u"@", ExternalFunction {{module_host}, _exp}},
299
                {{}, ValueType::Float},
300
                {u"_value_", ValueType::Float},
301
            }}}},
302
            {u"ln", {ValueType::Function, Object {{
303
                {u"@", ExternalFunction {{module_host}, _ln}},
304
                {{}, ValueType::Float},
305
                {u"_value_", ValueType::Float},
306
            }}}},
307
            {u"atan2ND", {ValueType::Function, Object {{
308
                    {u"@", ExternalFunction {{module_host}, _atan2ND}},
309
                    {{}, ValueType::Float},
310
                    {u"_y_", ValueType::Float},
311
                    {u"_x_", ValueType::Float},
312
            }}}},
313
            {u"signFloat", {ValueType::Function, Object {{
314
                    {u"@", ExternalFunction {{module_host}, _signFloat}},
315
                    {{}, ValueType::Float},
316
                    {u"_value_", ValueType::Float},
317
            }}}},
318
            {u"signInt", {ValueType::Function, Object {{
319
                    {u"@", ExternalFunction {{module_host}, _signInt}},
320
                    {{}, ValueType::Int},
321
                    {u"_value_", ValueType::Int},
322
            }}}},
323
            {u"asinND", {ValueType::Function, Object {{
324
                    {u"@", ExternalFunction {{module_host}, _asinND}},
325
                    {{}, ValueType::Float},
326
                    {u"_n_", ValueType::Float},
327
                    {u"_d_", ValueType::Float},
328
            }}}},
329
            {u"acosND", {ValueType::Function, Object {{
330
                    {u"@", ExternalFunction {{module_host}, _acosND}},
331
                    {{}, ValueType::Float},
332
                    {u"_n_", ValueType::Float},
333
                    {u"_d_", ValueType::Float},
334
            }}}},
335
            {u"atanND", {ValueType::Function, Object {{
336
                    {u"@", ExternalFunction {{module_host}, _atanND}},
337
                    {{}, ValueType::Float},
338
                    {u"_n_", ValueType::Float},
339
                    {u"_d_", ValueType::Float},
340
            }}}},
341
            {u"clampReal", {ValueType::Function, Object {{
342
                    {u"@", ExternalFunction {{module_host}, _clampReal}},
343
                    {{}, ValueType::Float},
344
                    {u"_left_", ValueType::Float},
345
                    {u"_value_", ValueType::Float},
346
                    {u"_right_", ValueType::Float},
347
            }}}},
348
            {u"clampInt", {ValueType::Function, Object {{
349
                    {u"@", ExternalFunction {{module_host}, _clampInt}},
350
                    {{}, ValueType::Int},
351
                    {u"_left_", ValueType::Int},
352
                    {u"_value_", ValueType::Int},
353
                    {u"_right_", ValueType::Int},
354
            }}}},
355
            {u"absReal", {ValueType::Function, Object {{
356
                    {u"@", ExternalFunction {{module_host}, _absReal}},
357
                    {{}, ValueType::Float},
358
                    {u"_value_", ValueType::Float},
359
            }}}},
360
            {u"absInt", {ValueType::Function, Object {{
361
                    {u"@", ExternalFunction {{module_host}, _absInt}},
362
                    {{}, ValueType::Int},
363
                    {u"_value_", ValueType::Int},
364
            }}}},
365
            {u"length", {ValueType::Function, Object {{
366
                    {u"@", ExternalFunction {{module_host}, _length}},
367
                    {{}, double(0.0)},
368
                    {u"vector", ValueType::Null},
369
            }}}},
370
        }};
371
    }
372

373
    // Factory method
374
    static std::shared_ptr<Module_interface> create() {
375
        return std::make_shared<ModuleHost_math>();
376
    }
377
};
378

379
BOOST_DLL_ALIAS(
380
    ModuleHost_math::create,    // <-- this function is exported with...
381
    create_simodo_module                              // <-- ...this alias name
382
)
383

384

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.