Loading...
Searching...
No Matches
cwrapper.cpp
1#include <cstdlib>
2#include <cstring>
3
4#include <symengine/symbol.h>
5#include <symengine/cwrapper.h>
6#include <symengine/printers.h>
7#include <symengine/matrix.h>
8#include <symengine/eval.h>
9#include <symengine/parser.h>
10#include <symengine/lambda_double.h>
11#include <symengine/solve.h>
12#ifdef HAVE_SYMENGINE_LLVM
13#include <symengine/llvm_double.h>
16#ifdef HAVE_SYMENGINE_LLVM_LONG_DOUBLE
18#endif
19#endif
20
21#define xstr(s) str(s)
22#define str(s) #s
23
30using SymEngine::down_cast;
31using SymEngine::function_symbol;
33using SymEngine::has_symbol;
35using SymEngine::integer_class;
39using SymEngine::rational_class;
40using SymEngine::RCP;
43using SymEngine::zero;
44#ifdef HAVE_SYMENGINE_MPFR
47#endif // HAVE_SYMENGINE_MPFR
48#ifdef HAVE_SYMENGINE_MPC
50#endif // HAVE_SYMENGINE_MPC
52using SymEngine::is_a;
53using SymEngine::rcp_static_cast;
55using SymEngine::Set;
60#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
61using SymEngine::get_mpq_t;
62using SymEngine::get_mpz_t;
63#endif
64using SymEngine::ccode;
65using SymEngine::diag;
66using SymEngine::eye;
67using SymEngine::jscode;
68using SymEngine::julia_str;
69using SymEngine::latex;
70using SymEngine::mathml;
71using SymEngine::mp_get_si;
72using SymEngine::mp_get_ui;
73using SymEngine::numeric_cast;
74using SymEngine::ones;
75using SymEngine::parse;
76using SymEngine::SymEngineException;
77using SymEngine::zeros;
78
79namespace SymEngine
80{
81
82template <typename T>
83inline bool is_aligned(T *p, size_t n = alignof(T))
84{
85 return 0 == reinterpret_cast<uintptr_t>(p) % n;
86}
87
88static std::string _str(const Basic &a)
89{
90 return a.__str__();
91}
92} // namespace SymEngine
93
94extern "C" {
95
96#define CWRAPPER_BEGIN try {
97
98#define CWRAPPER_END \
99 return SYMENGINE_NO_EXCEPTION; \
100 } \
101 catch (SymEngineException & e) \
102 { \
103 return e.error_code(); \
104 } \
105 catch (...) \
106 { \
107 return SYMENGINE_RUNTIME_ERROR; \
108 }
109
110struct CRCPBasic {
111 SymEngine::RCP<const SymEngine::Basic> m;
112};
113
114struct CSetBasic {
116};
117
118static_assert(sizeof(CRCPBasic) == sizeof(CRCPBasic_C),
119 "Size of 'basic' is not correct");
122 "Alignment of 'basic' is not correct");
123
124void basic_new_stack(basic s)
125{
126 new (s) CRCPBasic();
127}
128
129void basic_free_stack(basic s)
130{
131 s->m.~RCP();
132}
133
134basic_struct *basic_new_heap()
135{
136 return new CRCPBasic();
137}
138
139void basic_free_heap(basic_struct *s)
140{
141 delete s;
142}
143
144const char *symengine_version()
145{
146 return SYMENGINE_VERSION;
147}
148
149void basic_const_set(basic s, const char *c)
150{
152}
153
154void basic_const_zero(basic s)
155{
156 s->m = SymEngine::zero;
157}
158
159void basic_const_one(basic s)
160{
161 s->m = SymEngine::one;
162}
163
164void basic_const_minus_one(basic s)
165{
166 s->m = SymEngine::minus_one;
167}
168
169void basic_const_I(basic s)
170{
171 s->m = SymEngine::I;
172}
173
174void basic_const_pi(basic s)
175{
176 s->m = SymEngine::pi;
177}
178
179void basic_const_E(basic s)
180{
181 s->m = SymEngine::E;
182}
183
184void basic_const_EulerGamma(basic s)
185{
186 s->m = SymEngine::EulerGamma;
187}
188
189void basic_const_Catalan(basic s)
190{
191 s->m = SymEngine::Catalan;
192}
193
194void basic_const_GoldenRatio(basic s)
195{
196 s->m = SymEngine::GoldenRatio;
197}
198
199void basic_const_infinity(basic s)
200{
201 s->m = SymEngine::Inf;
202}
203
204void basic_const_neginfinity(basic s)
205{
206 s->m = SymEngine::NegInf;
207}
208
209void basic_const_complex_infinity(basic s)
210{
211 s->m = SymEngine::ComplexInf;
212}
213
214void basic_const_nan(basic s)
215{
216 s->m = SymEngine::Nan;
217}
218
219TypeID basic_get_class_id(const char *c)
220{
221 static std::map<std::string, TypeID> names = {
222#define SYMENGINE_INCLUDE_ALL
223#define SYMENGINE_ENUM(type, Class) {xstr(Class), type},
224#include "symengine/type_codes.inc"
225#undef SYMENGINE_ENUM
226#undef SYMENGINE_INCLUDE_ALL
227 {"", SYMENGINE_TypeID_Count}};
228
229 return names[std::string(c)];
230}
231
232char *basic_get_class_from_id(TypeID id)
233{
234 static std::map<TypeID, std::string> names = {
235#define SYMENGINE_INCLUDE_ALL
236#define SYMENGINE_ENUM(type, Class) {type, xstr(Class)},
237#include "symengine/type_codes.inc"
238#undef SYMENGINE_ENUM
239#undef SYMENGINE_INCLUDE_ALL
240 {SYMENGINE_TypeID_Count, ""}};
241
242 std::string name = names[id];
243 auto cc = new char[name.length() + 1];
244 std::strcpy(cc, name.c_str());
245 return cc;
246}
247
248TypeID basic_get_type(const basic s)
249{
250 return static_cast<TypeID>(s->m->get_type_code());
251}
252
253CWRAPPER_OUTPUT_TYPE symbol_set(basic s, const char *c)
254{
255 CWRAPPER_BEGIN
257 CWRAPPER_END
258}
259
260int number_is_zero(const basic s)
261{
262 SYMENGINE_ASSERT(is_a_Number(*(s->m)));
263 return (int)((down_cast<const Number &>(*(s->m))).is_zero());
264}
265
266int number_is_negative(const basic s)
267{
268 SYMENGINE_ASSERT(is_a_Number(*(s->m)));
269 return (int)((down_cast<const Number &>(*(s->m))).is_negative());
270}
271
272int number_is_positive(const basic s)
273{
274 SYMENGINE_ASSERT(is_a_Number(*(s->m)));
275 return (int)((down_cast<const Number &>(*(s->m))).is_positive());
276}
277
278int number_is_complex(const basic s)
279{
280 SYMENGINE_ASSERT(is_a_Number(*(s->m)));
281 return (int)((down_cast<const Number &>(*(s->m))).is_complex());
282}
283
284int basic_has_symbol(const basic e, const basic s)
285{
286 return (int)(has_symbol(*(e->m), *(s->m)));
287}
288
289CWRAPPER_OUTPUT_TYPE integer_set_si(basic s, long i)
290{
291 CWRAPPER_BEGIN
292 s->m = SymEngine::integer(integer_class(i));
293 CWRAPPER_END
294}
295
296CWRAPPER_OUTPUT_TYPE integer_set_ui(basic s, unsigned long i)
297{
298 CWRAPPER_BEGIN
299 s->m = SymEngine::integer(integer_class(i));
300 CWRAPPER_END
301}
302
303#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
304CWRAPPER_OUTPUT_TYPE integer_set_mpz(basic s, const mpz_t i)
305{
306 CWRAPPER_BEGIN
307 s->m = SymEngine::integer(integer_class(i));
308 CWRAPPER_END
309}
310#endif
311
312CWRAPPER_OUTPUT_TYPE integer_set_str(basic s, const char *c)
313{
314 CWRAPPER_BEGIN
315 s->m = SymEngine::integer(integer_class(c));
316 CWRAPPER_END
317}
318
319CWRAPPER_OUTPUT_TYPE real_double_set_d(basic s, double d)
320{
321 CWRAPPER_BEGIN
322 s->m = SymEngine::real_double(d);
323 CWRAPPER_END
324}
325
326double real_double_get_d(const basic s)
327{
328 SYMENGINE_ASSERT(is_a<RealDouble>(*(s->m)));
329 return (down_cast<const RealDouble &>(*(s->m))).as_double();
330}
331
332#ifdef HAVE_SYMENGINE_MPFR
333
334CWRAPPER_OUTPUT_TYPE real_mpfr_set_d(basic s, double d, int prec)
335{
336 CWRAPPER_BEGIN
337 mpfr_class mc = mpfr_class(prec);
338 mpfr_set_d(mc.get_mpfr_t(), d, MPFR_RNDN);
340 CWRAPPER_END
341}
342
343CWRAPPER_OUTPUT_TYPE real_mpfr_set_str(basic s, const char *c, int prec)
344{
345 CWRAPPER_BEGIN
346 s->m = SymEngine::real_mpfr(mpfr_class(c, prec, 10));
347 CWRAPPER_END
348}
349
350double real_mpfr_get_d(const basic s)
351{
352 SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
353 return mpfr_get_d(
354 ((down_cast<const RealMPFR &>(*(s->m))).as_mpfr()).get_mpfr_t(),
355 MPFR_RNDN);
356}
357
358CWRAPPER_OUTPUT_TYPE real_mpfr_set(basic s, mpfr_srcptr m)
359{
360 CWRAPPER_BEGIN
361 s->m = SymEngine::real_mpfr(mpfr_class(m));
362 CWRAPPER_END
363}
364
365CWRAPPER_OUTPUT_TYPE real_mpfr_get(mpfr_ptr m, const basic s)
366{
367 CWRAPPER_BEGIN
368 SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
369 mpfr_set(m, ((down_cast<const RealMPFR &>(*(s->m))).as_mpfr()).get_mpfr_t(),
370 MPFR_RNDN);
371 CWRAPPER_END
372}
373
374mpfr_prec_t real_mpfr_get_prec(const basic s)
375{
376 SYMENGINE_ASSERT(is_a<RealMPFR>(*(s->m)));
377 return ((down_cast<const RealMPFR &>(*(s->m))).as_mpfr()).get_prec();
378}
379
380#endif // HAVE_SYMENGINE_MPFR
381
382CWRAPPER_OUTPUT_TYPE complex_base_real_part(basic s, const basic com)
383{
384 CWRAPPER_BEGIN
385 SYMENGINE_ASSERT(SymEngine::is_a_Complex(*(com->m)));
386 s->m = (down_cast<const ComplexBase &>(*(com->m))).real_part();
387 CWRAPPER_END
388}
389
390CWRAPPER_OUTPUT_TYPE complex_base_imaginary_part(basic s, const basic com)
391{
392 CWRAPPER_BEGIN
393 SYMENGINE_ASSERT(SymEngine::is_a_Complex(*(com->m)));
394 s->m = (down_cast<const ComplexBase &>(*(com->m))).imaginary_part();
395 CWRAPPER_END
396}
397
398signed long integer_get_si(const basic s)
399{
400 SYMENGINE_ASSERT(is_a<Integer>(*(s->m)));
401 return mp_get_si((down_cast<const Integer &>(*(s->m))).as_integer_class());
402}
403
404unsigned long integer_get_ui(const basic s)
405{
406 SYMENGINE_ASSERT(is_a<Integer>(*(s->m)));
407 return mp_get_ui((down_cast<const Integer &>(*(s->m))).as_integer_class());
408}
409
410#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
411CWRAPPER_OUTPUT_TYPE integer_get_mpz(mpz_t a, const basic s)
412{
413 CWRAPPER_BEGIN
414 SYMENGINE_ASSERT(is_a<Integer>(*(s->m)));
415 mpz_set(
416 a, get_mpz_t((down_cast<const Integer &>(*(s->m))).as_integer_class()));
417 CWRAPPER_END
418}
419#endif
420
421CWRAPPER_OUTPUT_TYPE rational_set_si(basic s, long a, long b)
422{
423 CWRAPPER_BEGIN
424 s->m = SymEngine::Rational::from_mpq(rational_class(a, b));
425 CWRAPPER_END
426}
427
428CWRAPPER_OUTPUT_TYPE rational_set_ui(basic s, unsigned long a, unsigned long b)
429{
430 CWRAPPER_BEGIN
431 s->m = SymEngine::Rational::from_mpq(rational_class(a, b));
432 CWRAPPER_END
433}
434
435CWRAPPER_OUTPUT_TYPE rational_set(basic s, const basic a, const basic b)
436{
437 if (not is_a_Integer(a) or not is_a_Integer(b)) {
438 return SYMENGINE_RUNTIME_ERROR;
439 }
441 *(rcp_static_cast<const Integer>(a->m)),
442 *(rcp_static_cast<const Integer>(b->m)));
443 return SYMENGINE_NO_EXCEPTION;
444}
445
446#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
447CWRAPPER_OUTPUT_TYPE rational_get_mpq(mpq_t a, const basic s)
448{
449 CWRAPPER_BEGIN
450 SYMENGINE_ASSERT(is_a<Rational>(*(s->m)));
451 mpq_set(a, get_mpq_t(
452 (down_cast<const Rational &>(*(s->m))).as_rational_class()));
453 CWRAPPER_END
454}
455
456CWRAPPER_OUTPUT_TYPE rational_set_mpq(basic s, const mpq_t i)
457{
458 CWRAPPER_BEGIN
459 s->m = SymEngine::Rational::from_mpq(rational_class(i));
460 CWRAPPER_END
461}
462#endif
463
464CWRAPPER_OUTPUT_TYPE complex_set(basic s, const basic re, const basic im)
465{
466 CWRAPPER_BEGIN
468 *(rcp_static_cast<const Number>(re->m)),
469 *(rcp_static_cast<const Number>(im->m)));
470 CWRAPPER_END
471}
472
473CWRAPPER_OUTPUT_TYPE complex_set_rat(basic s, const basic re, const basic im)
474{
475 CWRAPPER_BEGIN
477 *(rcp_static_cast<const Rational>(re->m)),
478 *(rcp_static_cast<const Rational>(im->m)));
479 CWRAPPER_END
480}
481
482#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
483CWRAPPER_OUTPUT_TYPE complex_set_mpq(basic s, const mpq_t re, const mpq_t im)
484{
485 CWRAPPER_BEGIN
486 s->m = SymEngine::Complex::from_mpq(rational_class(re), rational_class(im));
487 CWRAPPER_END
488}
489#endif
490
491dcomplex complex_double_get(const basic s)
492{
493 SYMENGINE_ASSERT(is_a<ComplexDouble>(*(s->m)));
494 dcomplex d;
495 d.real = (down_cast<const ComplexDouble &>(*(s->m)).as_complex_double())
496 .real();
497 d.imag = (down_cast<const ComplexDouble &>(*(s->m)).as_complex_double())
498 .imag();
499 return d;
500}
501
502char *basic_dumps(const basic s, unsigned long *size)
503{
504 std::string str = s->m->dumps();
505 *size = str.length();
506 auto cc = new char[*size];
507 str.copy(cc, *size);
508 return cc;
509}
510
511CWRAPPER_OUTPUT_TYPE basic_loads(basic s, const char *c, unsigned long size)
512{
513 CWRAPPER_BEGIN
514 std::string data(c, size);
515 s->m = Basic::loads(data);
516 CWRAPPER_END
517}
518
519CWRAPPER_OUTPUT_TYPE basic_diff(basic s, const basic expr, basic const symbol)
520{
521 if (not is_a_Symbol(symbol))
522 return SYMENGINE_RUNTIME_ERROR;
523 CWRAPPER_BEGIN
524 s->m = expr->m->diff(rcp_static_cast<const Symbol>(symbol->m));
525 CWRAPPER_END
526}
527
528CWRAPPER_OUTPUT_TYPE basic_assign(basic a, const basic b)
529{
530 CWRAPPER_BEGIN
531 a->m = b->m;
532 CWRAPPER_END
533}
534
535CWRAPPER_OUTPUT_TYPE basic_parse(basic b, const char *str)
536{
537 CWRAPPER_BEGIN
538 b->m = SymEngine::parse(str);
539 CWRAPPER_END
540}
541
542CWRAPPER_OUTPUT_TYPE basic_parse2(basic b, const char *str, int convert_xor)
543{
544 CWRAPPER_BEGIN
545 if (convert_xor > 0) {
546 b->m = SymEngine::parse(str);
547 } else {
548 b->m = SymEngine::parse(str, false);
549 }
550 CWRAPPER_END
551}
552
553CWRAPPER_OUTPUT_TYPE basic_add(basic s, const basic a, const basic b)
554{
555 CWRAPPER_BEGIN
556 s->m = SymEngine::add(a->m, b->m);
557 CWRAPPER_END
558}
559
560CWRAPPER_OUTPUT_TYPE basic_sub(basic s, const basic a, const basic b)
561{
562 CWRAPPER_BEGIN
563 s->m = SymEngine::sub(a->m, b->m);
564 CWRAPPER_END
565}
566
567CWRAPPER_OUTPUT_TYPE basic_mul(basic s, const basic a, const basic b)
568{
569 CWRAPPER_BEGIN
570 s->m = SymEngine::mul(a->m, b->m);
571 CWRAPPER_END
572}
573
574CWRAPPER_OUTPUT_TYPE basic_pow(basic s, const basic a, const basic b)
575{
576 CWRAPPER_BEGIN
577 s->m = SymEngine::pow(a->m, b->m);
578 CWRAPPER_END
579}
580
581CWRAPPER_OUTPUT_TYPE basic_div(basic s, const basic a, const basic b)
582{
583 CWRAPPER_BEGIN
584 s->m = SymEngine::div(a->m, b->m);
585 CWRAPPER_END
586}
587
588int basic_eq(const basic a, const basic b)
589{
590 return SymEngine::eq(*(a->m), *(b->m)) ? 1 : 0;
591}
592
593int basic_neq(const basic a, const basic b)
594{
595 return SymEngine::neq(*(a->m), *(b->m)) ? 1 : 0;
596}
597
598#define IMPLEMENT_ONE_ARG_FUNC(func) \
599 CWRAPPER_OUTPUT_TYPE basic_##func(basic s, const basic a) \
600 { \
601 CWRAPPER_BEGIN \
602 s->m = SymEngine::func(a->m); \
603 CWRAPPER_END \
604 }
605
606IMPLEMENT_ONE_ARG_FUNC(expand)
607IMPLEMENT_ONE_ARG_FUNC(neg)
608IMPLEMENT_ONE_ARG_FUNC(abs)
609IMPLEMENT_ONE_ARG_FUNC(erf)
610IMPLEMENT_ONE_ARG_FUNC(erfc)
611IMPLEMENT_ONE_ARG_FUNC(sin)
612IMPLEMENT_ONE_ARG_FUNC(cos)
613IMPLEMENT_ONE_ARG_FUNC(tan)
614IMPLEMENT_ONE_ARG_FUNC(csc)
615IMPLEMENT_ONE_ARG_FUNC(sec)
616IMPLEMENT_ONE_ARG_FUNC(cot)
617IMPLEMENT_ONE_ARG_FUNC(asin)
618IMPLEMENT_ONE_ARG_FUNC(acos)
619IMPLEMENT_ONE_ARG_FUNC(asec)
620IMPLEMENT_ONE_ARG_FUNC(acsc)
621IMPLEMENT_ONE_ARG_FUNC(atan)
622IMPLEMENT_ONE_ARG_FUNC(acot)
623IMPLEMENT_ONE_ARG_FUNC(sinh)
624IMPLEMENT_ONE_ARG_FUNC(cosh)
625IMPLEMENT_ONE_ARG_FUNC(tanh)
626IMPLEMENT_ONE_ARG_FUNC(csch)
627IMPLEMENT_ONE_ARG_FUNC(sech)
628IMPLEMENT_ONE_ARG_FUNC(coth)
629IMPLEMENT_ONE_ARG_FUNC(asinh)
630IMPLEMENT_ONE_ARG_FUNC(acosh)
631IMPLEMENT_ONE_ARG_FUNC(asech)
632IMPLEMENT_ONE_ARG_FUNC(acsch)
633IMPLEMENT_ONE_ARG_FUNC(atanh)
634IMPLEMENT_ONE_ARG_FUNC(acoth)
635IMPLEMENT_ONE_ARG_FUNC(lambertw)
636IMPLEMENT_ONE_ARG_FUNC(zeta)
637IMPLEMENT_ONE_ARG_FUNC(dirichlet_eta)
638IMPLEMENT_ONE_ARG_FUNC(gamma)
639IMPLEMENT_ONE_ARG_FUNC(loggamma)
640IMPLEMENT_ONE_ARG_FUNC(sqrt)
641IMPLEMENT_ONE_ARG_FUNC(cbrt)
642IMPLEMENT_ONE_ARG_FUNC(exp)
643IMPLEMENT_ONE_ARG_FUNC(log)
644IMPLEMENT_ONE_ARG_FUNC(floor)
645IMPLEMENT_ONE_ARG_FUNC(ceiling)
646
647#define IMPLEMENT_TWO_ARG_FUNC(func) \
648 CWRAPPER_OUTPUT_TYPE basic_##func(basic s, const basic a, const basic b) \
649 { \
650 CWRAPPER_BEGIN \
651 s->m = SymEngine::func(a->m, b->m); \
652 CWRAPPER_END \
653 }
654
655IMPLEMENT_TWO_ARG_FUNC(atan2)
656IMPLEMENT_TWO_ARG_FUNC(kronecker_delta)
657IMPLEMENT_TWO_ARG_FUNC(lowergamma)
658IMPLEMENT_TWO_ARG_FUNC(uppergamma)
659IMPLEMENT_TWO_ARG_FUNC(beta)
660IMPLEMENT_TWO_ARG_FUNC(polygamma)
661
662#define IMPLEMENT_STR_CONVERSION(name, func) \
663 char *basic_##name(const basic s) \
664 { \
665 std::string str; \
666 try { \
667 str = func(*s->m); \
668 } catch (SymEngineException & e) { \
669 return nullptr; \
670 } catch (...) { \
671 return nullptr; \
672 } \
673 auto cc = new char[str.length() + 1]; \
674 std::strcpy(cc, str.c_str()); \
675 return cc; \
676 }
677
678IMPLEMENT_STR_CONVERSION(str, _str)
679IMPLEMENT_STR_CONVERSION(str_julia, julia_str)
680IMPLEMENT_STR_CONVERSION(str_mathml, mathml)
681IMPLEMENT_STR_CONVERSION(str_latex, latex)
682IMPLEMENT_STR_CONVERSION(str_ccode, ccode)
683IMPLEMENT_STR_CONVERSION(str_jscode, jscode)
684
685void basic_str_free(char *s)
686{
687 delete[] s;
688}
689
690void bool_set_true(basic s)
691{
692 s->m = SymEngine::boolTrue;
693}
694
695void bool_set_false(basic s)
696{
697 s->m = SymEngine::boolFalse;
698}
699
700CWRAPPER_OUTPUT_TYPE basic_set_interval(basic s, const basic start,
701 const basic end, int left_open,
702 int right_open)
703{
704 SYMENGINE_ASSERT(is_a_Number(*(start->m)));
705 SYMENGINE_ASSERT(is_a_Number(*(end->m)));
706
707 CWRAPPER_BEGIN
708 s->m = SymEngine::interval(rcp_static_cast<const Number>(start->m),
709 rcp_static_cast<const Number>(end->m),
710 (bool)left_open, (bool)right_open);
711 CWRAPPER_END
712}
713
714CWRAPPER_OUTPUT_TYPE basic_set_finiteset(basic s, const CSetBasic *container)
715{
716 CWRAPPER_BEGIN
717 s->m = SymEngine::finiteset(container->m);
718 CWRAPPER_END
719}
720
721void basic_set_emptyset(basic s)
722{
723 s->m = SymEngine::emptyset();
724}
725
726void basic_set_universalset(basic s)
727{
728 s->m = SymEngine::emptyset();
729}
730
731void basic_set_complexes(basic s)
732{
733 s->m = SymEngine::complexes();
734}
735
736void basic_set_reals(basic s)
737{
738 s->m = SymEngine::reals();
739}
740
741void basic_set_rationals(basic s)
742{
743 s->m = SymEngine::rationals();
744}
745
746void basic_set_integers(basic s)
747{
748 s->m = SymEngine::integers();
749}
750
751CWRAPPER_OUTPUT_TYPE basic_set_union(basic s, const basic a, const basic b)
752{
753 CWRAPPER_BEGIN
754 s->m = rcp_static_cast<const Set>(a->m)->set_union(
755 rcp_static_cast<const Set>(b->m));
756 CWRAPPER_END
757}
758
759CWRAPPER_OUTPUT_TYPE basic_set_intersection(basic s, const basic a,
760 const basic b)
761{
762 CWRAPPER_BEGIN
763 s->m = rcp_static_cast<const Set>(a->m)->set_intersection(
764 rcp_static_cast<const Set>(b->m));
765 CWRAPPER_END
766}
767
768CWRAPPER_OUTPUT_TYPE basic_set_complement(basic s, const basic a, const basic b)
769{
770 CWRAPPER_BEGIN
771 s->m = rcp_static_cast<const Set>(a->m)->set_complement(
772 rcp_static_cast<const Set>(b->m));
773 CWRAPPER_END
774}
775
776CWRAPPER_OUTPUT_TYPE basic_set_contains(basic s, const basic a, const basic b)
777{
778 CWRAPPER_BEGIN
779 s->m = rcp_static_cast<const Set>(a->m)->contains(b->m);
780 CWRAPPER_END
781}
782
783int basic_set_is_subset(const basic a, const basic b)
784{
785 SYMENGINE_ASSERT(is_a_Set(*(a->m)));
786 SYMENGINE_ASSERT(is_a_Set(*(b->m)));
787 return rcp_static_cast<const Set>(a->m)->is_subset(
788 rcp_static_cast<const Set>(b->m));
789}
790
791int basic_set_is_proper_subset(const basic a, const basic b)
792{
793 SYMENGINE_ASSERT(is_a_Set(*(a->m)));
794 SYMENGINE_ASSERT(is_a_Set(*(b->m)));
795 return rcp_static_cast<const Set>(a->m)->is_proper_subset(
796 rcp_static_cast<const Set>(b->m));
797}
798
799int basic_set_is_superset(const basic a, const basic b)
800{
801 SYMENGINE_ASSERT(is_a_Set(*(a->m)));
802 SYMENGINE_ASSERT(is_a_Set(*(b->m)));
803 return rcp_static_cast<const Set>(a->m)->is_superset(
804 rcp_static_cast<const Set>(b->m));
805}
806
807int basic_set_is_proper_superset(const basic a, const basic b)
808{
809 SYMENGINE_ASSERT(is_a_Set(*(a->m)));
810 SYMENGINE_ASSERT(is_a_Set(*(b->m)));
811 return rcp_static_cast<const Set>(a->m)->is_proper_superset(
812 rcp_static_cast<const Set>(b->m));
813}
814
815CWRAPPER_OUTPUT_TYPE basic_set_inf(basic s, const basic a)
816{
817 CWRAPPER_BEGIN
818 s->m = SymEngine::inf(*rcp_static_cast<const Set>(a->m));
819 CWRAPPER_END
820}
821
822CWRAPPER_OUTPUT_TYPE basic_set_sup(basic s, const basic a)
823{
824 CWRAPPER_BEGIN
825 s->m = SymEngine::sup(*rcp_static_cast<const Set>(a->m));
826 CWRAPPER_END
827}
828
829CWRAPPER_OUTPUT_TYPE basic_set_boundary(basic s, const basic a)
830{
831 CWRAPPER_BEGIN
832 s->m = SymEngine::boundary(*rcp_static_cast<const Set>(a->m));
833 CWRAPPER_END
834}
835
836CWRAPPER_OUTPUT_TYPE basic_set_interior(basic s, const basic a)
837{
838 CWRAPPER_BEGIN
839 s->m = SymEngine::interior(*rcp_static_cast<const Set>(a->m));
840 CWRAPPER_END
841}
842
843CWRAPPER_OUTPUT_TYPE basic_set_closure(basic s, const basic a)
844{
845 CWRAPPER_BEGIN
846 s->m = SymEngine::closure(*rcp_static_cast<const Set>(a->m));
847 CWRAPPER_END
848}
849
850int symengine_have_component(const char *c)
851{
852#ifdef HAVE_SYMENGINE_MPFR
853 if (std::strcmp("mpfr", c) == 0)
854 return 1;
855#endif
856#ifdef HAVE_SYMENGINE_MPC
857 if (std::strcmp("mpc", c) == 0)
858 return 1;
859#endif
860#ifdef HAVE_SYMENGINE_FLINT
861 if (std::strcmp("flint", c) == 0)
862 return 1;
863#endif
864#ifdef HAVE_SYMENGINE_ARB
865 if (std::strcmp("arb", c) == 0)
866 return 1;
867#endif
868#ifdef HAVE_SYMENGINE_ECM
869 if (std::strcmp("ecm", c) == 0)
870 return 1;
871#endif
872#ifdef HAVE_SYMENGINE_PRIMESIEVE
873 if (std::strcmp("primesieve", c) == 0)
874 return 1;
875#endif
876#ifdef HAVE_SYMENGINE_PIRANHA
877 if (std::strcmp("piranha", c) == 0)
878 return 1;
879#endif
880#ifdef HAVE_SYMENGINE_BOOST
881 if (std::strcmp("boost", c) == 0)
882 return 1;
883#endif
884#ifdef HAVE_SYMENGINE_PTHREAD
885 if (std::strcmp("pthread", c) == 0)
886 return 1;
887#endif
888#ifdef HAVE_SYMENGINE_LLVM
889 if (std::strcmp("llvm", c) == 0)
890 return 1;
891#endif
892#ifdef HAVE_SYMENGINE_LLVM_LONG_DOUBLE
893 if (std::strcmp("llvm_long_double", c) == 0)
894 return 1;
895#endif
896 return 0;
897}
898
899int is_a_Number(const basic s)
900{
901 return (int)is_a_Number(*(s->m));
902}
903int is_a_Integer(const basic c)
904{
905 return is_a<Integer>(*(c->m));
906}
907int is_a_Rational(const basic c)
908{
909 return is_a<Rational>(*(c->m));
910}
911int is_a_Symbol(const basic c)
912{
913 return is_a<Symbol>(*(c->m));
914}
915int is_a_Complex(const basic c)
916{
917 return is_a<Complex>(*(c->m));
918}
919int is_a_RealDouble(const basic c)
920{
921 return is_a<RealDouble>(*(c->m));
922}
923int is_a_ComplexDouble(const basic c)
924{
925 return is_a<ComplexDouble>(*(c->m));
926}
927int is_a_RealMPFR(const basic c)
928{
929#ifdef HAVE_SYMENGINE_MPFR
930 return is_a<RealMPFR>(*(c->m));
931#else
932 return false;
933#endif // HAVE_SYMENGINE_MPFR
934}
935int is_a_ComplexMPC(const basic c)
936{
937#ifdef HAVE_SYMENGINE_MPC
938 return is_a<ComplexMPC>(*(c->m));
939#else
940 return false;
941#endif // HAVE_SYMENGINE_MPC
942}
943int is_a_Set(const basic c)
944{
945 return SymEngine::is_a_Set(*(c->m));
946}
947
948// C wrapper for std::vector<int>
949
952};
953
954CVectorInt *vectorint_new()
955{
956 return new CVectorInt;
957}
958
959int vectorint_placement_new_check(void *data, size_t size)
960{
961 CVectorInt *self = (CVectorInt *)data;
962 if (size < sizeof(CVectorInt))
963 return 1;
964 if (not SymEngine::is_aligned(self))
965 return 2;
966 return 0;
967}
968
969CVectorInt *vectorint_placement_new(void *data)
970{
971#if defined(WITH_SYMENGINE_ASSERT)
972 // if (size < sizeof(CVectorInt)) return 1; // Requires the 'size' argument
973 CVectorInt *self = (CVectorInt *)data;
974 SYMENGINE_ASSERT(SymEngine::is_aligned(self));
975#endif
976 new (data) CVectorInt;
977 return (CVectorInt *)data;
978}
979
980void vectorint_placement_free(CVectorInt *self)
981{
982 self->m.~vector<int>();
983}
984
985void vectorint_free(CVectorInt *self)
986{
987 delete self;
988}
989
990void vectorint_push_back(CVectorInt *self, int value)
991{
992 self->m.push_back(value);
993}
994
995int vectorint_get(CVectorInt *self, int n)
996{
997 return self->m[n];
998}
999
1000// C wrapper for vec_basic
1001
1004};
1005
1006CVecBasic *vecbasic_new()
1007{
1008 return new CVecBasic;
1009}
1010
1011void vecbasic_free(CVecBasic *self)
1012{
1013 delete self;
1014}
1015
1016CWRAPPER_OUTPUT_TYPE vecbasic_push_back(CVecBasic *self, const basic value)
1017{
1018 CWRAPPER_BEGIN
1019
1020 self->m.push_back(value->m);
1021
1022 CWRAPPER_END
1023}
1024
1025CWRAPPER_OUTPUT_TYPE vecbasic_get(CVecBasic *self, size_t n, basic result)
1026{
1027 CWRAPPER_BEGIN
1028
1029 SYMENGINE_ASSERT(n < self->m.size());
1030 result->m = self->m[n];
1031
1032 CWRAPPER_END
1033}
1034
1035CWRAPPER_OUTPUT_TYPE vecbasic_set(CVecBasic *self, size_t n, const basic s)
1036{
1037 CWRAPPER_BEGIN
1038 SYMENGINE_ASSERT(n < self->m.size());
1039 self->m[n] = s->m;
1040 CWRAPPER_END
1041}
1042
1043CWRAPPER_OUTPUT_TYPE vecbasic_erase(CVecBasic *self, size_t n)
1044{
1045 CWRAPPER_BEGIN
1046 SYMENGINE_ASSERT(n < self->m.size());
1047 self->m.erase(self->m.begin() + n);
1048 CWRAPPER_END
1049}
1050
1051size_t vecbasic_size(CVecBasic *self)
1052{
1053 return self->m.size();
1054}
1055
1056CWRAPPER_OUTPUT_TYPE basic_max(basic s, const CVecBasic *d)
1057{
1058 CWRAPPER_BEGIN
1059 s->m = SymEngine::max(d->m);
1060 CWRAPPER_END
1061}
1062
1063CWRAPPER_OUTPUT_TYPE basic_min(basic s, const CVecBasic *d)
1064{
1065 CWRAPPER_BEGIN
1066 s->m = SymEngine::min(d->m);
1067 CWRAPPER_END
1068}
1069
1070CWRAPPER_OUTPUT_TYPE basic_add_vec(basic s, const CVecBasic *d)
1071{
1072 CWRAPPER_BEGIN
1073 s->m = SymEngine::add(d->m);
1074 CWRAPPER_END
1075}
1076
1077CWRAPPER_OUTPUT_TYPE basic_mul_vec(basic s, const CVecBasic *d)
1078{
1079 CWRAPPER_BEGIN
1080 s->m = SymEngine::mul(d->m);
1081 CWRAPPER_END
1082}
1083
1084// C wrapper for Matrix
1085
1088};
1089
1092};
1093
1094CDenseMatrix *dense_matrix_new()
1095{
1096 return new CDenseMatrix();
1097}
1098
1099CDenseMatrix *dense_matrix_new_vec(unsigned rows, unsigned cols, CVecBasic *l)
1100{
1101 return new CDenseMatrix({{rows, cols, l->m}});
1102}
1103
1104CDenseMatrix *dense_matrix_new_rows_cols(unsigned rows, unsigned cols)
1105{
1106 return new CDenseMatrix({{rows, cols}});
1107}
1108
1109CSparseMatrix *sparse_matrix_new()
1110{
1111 return new CSparseMatrix;
1112}
1113
1114void dense_matrix_free(CDenseMatrix *self)
1115{
1116 delete self;
1117}
1118
1119void sparse_matrix_free(CSparseMatrix *self)
1120{
1121 delete self;
1122}
1123
1124void sparse_matrix_init(CSparseMatrix *s)
1125{
1126 s->m = SymEngine::CSRMatrix();
1127}
1128
1129void sparse_matrix_rows_cols(CSparseMatrix *s, unsigned long int rows,
1130 unsigned long int cols)
1131{
1132 s->m = SymEngine::CSRMatrix(numeric_cast<unsigned>(rows),
1133 numeric_cast<unsigned>(cols));
1134}
1135
1136CWRAPPER_OUTPUT_TYPE dense_matrix_set(CDenseMatrix *s, const CDenseMatrix *d)
1137{
1138 CWRAPPER_BEGIN
1139 s->m = d->m;
1140 CWRAPPER_END
1141}
1142
1143char *dense_matrix_str(const CDenseMatrix *s)
1144{
1145 std::string str = s->m.__str__();
1146 auto cc = new char[str.length() + 1];
1147 std::strcpy(cc, str.c_str());
1148 return cc;
1149}
1150
1151char *sparse_matrix_str(const CSparseMatrix *s)
1152{
1153 std::string str = s->m.__str__();
1154 auto cc = new char[str.length() + 1];
1155 std::strcpy(cc, str.c_str());
1156 return cc;
1157}
1158
1159CWRAPPER_OUTPUT_TYPE dense_matrix_rows_cols(CDenseMatrix *mat, unsigned r,
1160 unsigned c)
1161{
1162 CWRAPPER_BEGIN
1163 mat->m.resize(r, c);
1164 CWRAPPER_END
1165}
1166
1167CWRAPPER_OUTPUT_TYPE dense_matrix_get_basic(basic s, const CDenseMatrix *mat,
1168 unsigned long int r,
1169 unsigned long int c)
1170{
1171 CWRAPPER_BEGIN
1172 s->m = mat->m.get(numeric_cast<unsigned>(r), numeric_cast<unsigned>(c));
1173 CWRAPPER_END
1174}
1175
1176CWRAPPER_OUTPUT_TYPE dense_matrix_set_basic(CDenseMatrix *mat,
1177 unsigned long int r,
1178 unsigned long int c, basic s)
1179{
1180 CWRAPPER_BEGIN
1181 mat->m.set(numeric_cast<unsigned>(r), numeric_cast<unsigned>(c), s->m);
1182 CWRAPPER_END
1183}
1184
1185CWRAPPER_OUTPUT_TYPE sparse_matrix_get_basic(basic s, const CSparseMatrix *mat,
1186 unsigned long int r,
1187 unsigned long int c)
1188{
1189 CWRAPPER_BEGIN
1190 s->m = mat->m.get(numeric_cast<unsigned>(r), numeric_cast<unsigned>(c));
1191 CWRAPPER_END
1192}
1193
1194CWRAPPER_OUTPUT_TYPE sparse_matrix_set_basic(CSparseMatrix *mat,
1195 unsigned long int r,
1196 unsigned long int c, basic s)
1197{
1198 CWRAPPER_BEGIN
1199 mat->m.set(numeric_cast<unsigned>(r), numeric_cast<unsigned>(c), s->m);
1200 CWRAPPER_END
1201}
1202
1203CWRAPPER_OUTPUT_TYPE dense_matrix_det(basic s, const CDenseMatrix *mat)
1204{
1205 CWRAPPER_BEGIN
1206 s->m = mat->m.det();
1207 CWRAPPER_END
1208}
1209CWRAPPER_OUTPUT_TYPE dense_matrix_inv(CDenseMatrix *s, const CDenseMatrix *mat)
1210{
1211 CWRAPPER_BEGIN
1212 dense_matrix_rows_cols(s, mat->m.nrows(), mat->m.ncols());
1213 mat->m.inv(s->m);
1214 CWRAPPER_END
1215}
1216CWRAPPER_OUTPUT_TYPE dense_matrix_transpose(CDenseMatrix *s,
1217 const CDenseMatrix *mat)
1218{
1219 CWRAPPER_BEGIN
1220 dense_matrix_rows_cols(s, mat->m.ncols(), mat->m.nrows());
1221 mat->m.transpose(s->m);
1222 CWRAPPER_END
1223}
1224CWRAPPER_OUTPUT_TYPE
1225dense_matrix_submatrix(CDenseMatrix *s, const CDenseMatrix *mat,
1226 unsigned long int r1, unsigned long int c1,
1227 unsigned long int r2, unsigned long int c2,
1228 unsigned long int r, unsigned long int c)
1229{
1230 CWRAPPER_BEGIN
1231 dense_matrix_rows_cols(s, numeric_cast<unsigned>(r2 - r1 + 1),
1232 numeric_cast<unsigned>(c2 - c1 + 1));
1233 mat->m.submatrix(s->m, numeric_cast<unsigned>(r1),
1234 numeric_cast<unsigned>(c1), numeric_cast<unsigned>(r2),
1235 numeric_cast<unsigned>(c2), numeric_cast<unsigned>(r),
1236 numeric_cast<unsigned>(c));
1237 CWRAPPER_END
1238}
1239
1240CWRAPPER_OUTPUT_TYPE dense_matrix_row_join(CDenseMatrix *A,
1241 const CDenseMatrix *B)
1242{
1243 CWRAPPER_BEGIN
1244 A->m.row_join(B->m);
1245 CWRAPPER_END
1246}
1247
1248CWRAPPER_OUTPUT_TYPE dense_matrix_col_join(CDenseMatrix *A,
1249 const CDenseMatrix *B)
1250{
1251 CWRAPPER_BEGIN
1252 A->m.col_join(B->m);
1253 CWRAPPER_END
1254}
1255
1256CWRAPPER_OUTPUT_TYPE dense_matrix_row_del(CDenseMatrix *A, unsigned k)
1257{
1258 CWRAPPER_BEGIN
1259 A->m.row_del(k);
1260 CWRAPPER_END
1261}
1262
1263CWRAPPER_OUTPUT_TYPE dense_matrix_col_del(CDenseMatrix *A, unsigned k)
1264{
1265 CWRAPPER_BEGIN
1266 A->m.col_del(k);
1267 CWRAPPER_END
1268}
1269
1270unsigned long int dense_matrix_rows(const CDenseMatrix *s)
1271{
1272 return s->m.nrows();
1273}
1274
1275unsigned long int dense_matrix_cols(const CDenseMatrix *s)
1276{
1277 return s->m.ncols();
1278}
1279
1280CWRAPPER_OUTPUT_TYPE dense_matrix_add_matrix(CDenseMatrix *s,
1281 const CDenseMatrix *matA,
1282 const CDenseMatrix *matB)
1283{
1284 CWRAPPER_BEGIN
1285 dense_matrix_rows_cols(s, matA->m.nrows(), matA->m.ncols());
1286 matA->m.add_matrix(matB->m, s->m);
1287 CWRAPPER_END
1288}
1289
1290CWRAPPER_OUTPUT_TYPE dense_matrix_mul_matrix(CDenseMatrix *s,
1291 const CDenseMatrix *matA,
1292 const CDenseMatrix *matB)
1293{
1294 CWRAPPER_BEGIN
1295 dense_matrix_rows_cols(s, matA->m.nrows(), matB->m.ncols());
1296 matA->m.mul_matrix(matB->m, s->m);
1297 CWRAPPER_END
1298}
1299
1300CWRAPPER_OUTPUT_TYPE dense_matrix_add_scalar(CDenseMatrix *s,
1301 const CDenseMatrix *matA,
1302 const basic b)
1303{
1304 CWRAPPER_BEGIN
1305 dense_matrix_rows_cols(s, matA->m.nrows(), matA->m.ncols());
1306 matA->m.add_scalar(b->m, s->m);
1307 CWRAPPER_END
1308}
1309
1310CWRAPPER_OUTPUT_TYPE dense_matrix_mul_scalar(CDenseMatrix *s,
1311 const CDenseMatrix *matA,
1312 const basic b)
1313{
1314 CWRAPPER_BEGIN
1315 dense_matrix_rows_cols(s, matA->m.nrows(), matA->m.ncols());
1316 matA->m.mul_scalar(b->m, s->m);
1317 CWRAPPER_END
1318}
1319
1320CWRAPPER_OUTPUT_TYPE dense_matrix_LU(CDenseMatrix *l, CDenseMatrix *u,
1321 const CDenseMatrix *mat)
1322{
1323 CWRAPPER_BEGIN
1324 dense_matrix_rows_cols(l, mat->m.nrows(), mat->m.ncols());
1325 dense_matrix_rows_cols(u, mat->m.nrows(), mat->m.ncols());
1326 mat->m.LU(l->m, u->m);
1327 CWRAPPER_END
1328}
1329
1330CWRAPPER_OUTPUT_TYPE dense_matrix_LDL(CDenseMatrix *l, CDenseMatrix *d,
1331 const CDenseMatrix *mat)
1332{
1333 CWRAPPER_BEGIN
1334 dense_matrix_rows_cols(l, mat->m.nrows(), mat->m.ncols());
1335 dense_matrix_rows_cols(d, mat->m.nrows(), mat->m.ncols());
1336 mat->m.LDL(l->m, d->m);
1337 CWRAPPER_END
1338}
1339
1340CWRAPPER_OUTPUT_TYPE dense_matrix_FFLU(CDenseMatrix *lu,
1341 const CDenseMatrix *mat)
1342{
1343 CWRAPPER_BEGIN
1344 dense_matrix_rows_cols(lu, mat->m.nrows(), mat->m.ncols());
1345 mat->m.FFLU(lu->m);
1346 CWRAPPER_END
1347}
1348
1349CWRAPPER_OUTPUT_TYPE dense_matrix_FFLDU(CDenseMatrix *l, CDenseMatrix *d,
1350 CDenseMatrix *u,
1351 const CDenseMatrix *mat)
1352{
1353 CWRAPPER_BEGIN
1354 dense_matrix_rows_cols(l, mat->m.nrows(), mat->m.ncols());
1355 dense_matrix_rows_cols(d, mat->m.nrows(), mat->m.ncols());
1356 dense_matrix_rows_cols(u, mat->m.nrows(), mat->m.ncols());
1357 mat->m.FFLDU(l->m, d->m, u->m);
1358 CWRAPPER_END
1359}
1360
1361CWRAPPER_OUTPUT_TYPE dense_matrix_LU_solve(CDenseMatrix *x,
1362 const CDenseMatrix *A,
1363 const CDenseMatrix *b)
1364{
1365 CWRAPPER_BEGIN
1366 dense_matrix_rows_cols(x, A->m.ncols(), 1);
1367 A->m.LU_solve(b->m, x->m);
1368 CWRAPPER_END
1369}
1370
1371CWRAPPER_OUTPUT_TYPE dense_matrix_ones(CDenseMatrix *s, unsigned long int r,
1372 unsigned long int c)
1373{
1374 CWRAPPER_BEGIN
1375 dense_matrix_rows_cols(s, numeric_cast<unsigned>(r),
1376 numeric_cast<unsigned>(c));
1377 ones(s->m);
1378 CWRAPPER_END
1379}
1380
1381CWRAPPER_OUTPUT_TYPE dense_matrix_zeros(CDenseMatrix *s, unsigned long int r,
1382 unsigned long int c)
1383{
1384 CWRAPPER_BEGIN
1385 dense_matrix_rows_cols(s, numeric_cast<unsigned>(r),
1386 numeric_cast<unsigned>(c));
1387 zeros(s->m);
1388 CWRAPPER_END
1389}
1390CWRAPPER_OUTPUT_TYPE dense_matrix_diag(CDenseMatrix *s, CVecBasic *d,
1391 long int k)
1392{
1393 CWRAPPER_BEGIN
1394 unsigned int vec_size = numeric_cast<unsigned>(vecbasic_size(d));
1395 dense_matrix_rows_cols(
1396 s, numeric_cast<unsigned>(vec_size + (k >= 0 ? k : -k)),
1397 numeric_cast<unsigned>(vec_size + (k >= 0 ? k : -k)));
1398 diag(s->m, d->m, numeric_cast<int>(k));
1399 CWRAPPER_END
1400}
1401
1402CWRAPPER_OUTPUT_TYPE dense_matrix_eye(CDenseMatrix *s, unsigned long int N,
1403 unsigned long int M, int k)
1404{
1405 CWRAPPER_BEGIN
1406 dense_matrix_rows_cols(s, numeric_cast<unsigned>(N),
1407 numeric_cast<unsigned>(M));
1408 eye(s->m, k);
1409 CWRAPPER_END
1410}
1411
1412CWRAPPER_OUTPUT_TYPE dense_matrix_diff(CDenseMatrix *result,
1413 const CDenseMatrix *A, basic const x)
1414{
1415 if (not is_a_Symbol(x))
1416 return SYMENGINE_RUNTIME_ERROR;
1417 CWRAPPER_BEGIN
1418 diff(A->m, rcp_static_cast<const Symbol>(x->m), result->m);
1419 CWRAPPER_END
1420}
1421
1422CWRAPPER_OUTPUT_TYPE dense_matrix_jacobian(CDenseMatrix *result,
1423 const CDenseMatrix *A,
1424 const CDenseMatrix *x)
1425{
1426 CWRAPPER_BEGIN
1427 jacobian(A->m, x->m, result->m);
1428 CWRAPPER_END
1429}
1430
1431int is_a_DenseMatrix(const CDenseMatrix *c)
1432{
1433 return is_a<DenseMatrix>(c->m);
1434}
1435
1436int is_a_SparseMatrix(const CSparseMatrix *c)
1437{
1438 return is_a<CSRMatrix>(c->m);
1439}
1440
1441int dense_matrix_eq(CDenseMatrix *lhs, CDenseMatrix *rhs)
1442{
1443 return (lhs->m) == (rhs->m);
1444}
1445
1446int sparse_matrix_eq(CSparseMatrix *lhs, CSparseMatrix *rhs)
1447{
1448 return (lhs->m) == (rhs->m);
1449}
1450
1451// C Wrapper for set_basic
1452
1453CSetBasic *setbasic_new()
1454{
1455 return new CSetBasic;
1456}
1457
1458void setbasic_free(CSetBasic *self)
1459{
1460 delete self;
1461}
1462
1463int setbasic_insert(CSetBasic *self, const basic value)
1464{
1465 return (self->m.insert(value->m)).second ? 1 : 0;
1466}
1467
1468void setbasic_get(CSetBasic *self, int n, basic result)
1469{
1470 result->m = *std::next((self->m).begin(), n);
1471}
1472
1473int setbasic_find(CSetBasic *self, basic value)
1474{
1475 return self->m.find(value->m) != (self->m).end() ? 1 : 0;
1476}
1477
1478int setbasic_erase(CSetBasic *self, const basic value)
1479{
1480 return (self->m.erase(value->m)) ? 1 : 0;
1481}
1482
1483size_t setbasic_size(CSetBasic *self)
1484{
1485 return self->m.size();
1486}
1487
1488// C Wrapper for map_basic_basic
1489
1493
1494CMapBasicBasic *mapbasicbasic_new()
1495{
1496 return new CMapBasicBasic;
1497}
1498
1499void mapbasicbasic_free(CMapBasicBasic *self)
1500{
1501 delete self;
1502}
1503
1504void mapbasicbasic_insert(CMapBasicBasic *self, const basic key,
1505 const basic mapped)
1506{
1507 (self->m)[key->m] = mapped->m;
1508}
1509
1510int mapbasicbasic_get(CMapBasicBasic *self, const basic key, basic mapped)
1511{
1512 auto it = self->m.find(key->m);
1513 if (it != self->m.end()) {
1514 mapped->m = it->second;
1515 return 1;
1516 }
1517 return 0;
1518}
1519
1520size_t mapbasicbasic_size(CMapBasicBasic *self)
1521{
1522 return self->m.size();
1523}
1524
1525// ----------------------
1526
1527CWRAPPER_OUTPUT_TYPE basic_get_args(const basic self, CVecBasic *args)
1528{
1529 CWRAPPER_BEGIN
1530 args->m = self->m->get_args();
1531 CWRAPPER_END
1532}
1533
1534CWRAPPER_OUTPUT_TYPE basic_free_symbols(const basic self, CSetBasic *symbols)
1535{
1536 CWRAPPER_BEGIN
1537 symbols->m = SymEngine::free_symbols(*(self->m));
1538 CWRAPPER_END
1539}
1540
1541CWRAPPER_OUTPUT_TYPE basic_function_symbols(CSetBasic *symbols,
1542 const basic self)
1543{
1544 CWRAPPER_BEGIN
1545 symbols->m = SymEngine::atoms<SymEngine::FunctionSymbol>(*(self->m));
1546 CWRAPPER_END
1547}
1548
1549size_t basic_hash(const basic self)
1550{
1551 return static_cast<size_t>(self->m->hash());
1552}
1553
1554CWRAPPER_OUTPUT_TYPE basic_subs(basic s, const basic e,
1555 const CMapBasicBasic *mapbb)
1556{
1557 CWRAPPER_BEGIN
1558 s->m = e->m->subs(mapbb->m);
1559 CWRAPPER_END
1560}
1561
1562CWRAPPER_OUTPUT_TYPE basic_subs2(basic s, const basic e, const basic a,
1563 const basic b)
1564{
1565 CWRAPPER_BEGIN
1566 s->m = e->m->subs({{a->m, b->m}});
1567 CWRAPPER_END
1568}
1569
1570CWRAPPER_OUTPUT_TYPE function_symbol_set(basic s, const char *c,
1571 const CVecBasic *arg)
1572{
1573 CWRAPPER_BEGIN
1574 s->m = function_symbol(c, arg->m);
1575 CWRAPPER_END
1576}
1577
1578char *function_symbol_get_name(const basic b)
1579{
1580 SYMENGINE_ASSERT(is_a<FunctionSymbol>(*(b->m)));
1581 std::string str = down_cast<const FunctionSymbol &>(*(b->m)).get_name();
1582 auto cc = new char[str.length() + 1];
1583 std::strcpy(cc, str.c_str());
1584 return cc;
1585}
1586
1587CWRAPPER_OUTPUT_TYPE basic_coeff(basic c, const basic b, const basic x,
1588 const basic n)
1589{
1590 CWRAPPER_BEGIN
1591 c->m = SymEngine::coeff(*(b->m), *(x->m), *(n->m));
1592 CWRAPPER_END
1593}
1594
1595// ----------------------
1596
1597CWRAPPER_OUTPUT_TYPE vecbasic_linsolve(CVecBasic *sol, const CVecBasic *sys,
1598 const CVecBasic *sym)
1599{
1600 CWRAPPER_BEGIN
1601 vec_basic vb = sym->m;
1602 SYMENGINE_ASSERT(
1603 std::all_of(vb.cbegin(), vb.cend(),
1604 [](RCP<const Basic> b) { return is_a<const Symbol>(*b); }));
1605 vec_sym vs(vb.size());
1606 for (unsigned i = 0; i < vb.size(); i++)
1607 vs[i] = rcp_static_cast<const Symbol>(vb[i]);
1608 sol->m = SymEngine::linsolve(sys->m, vs);
1609 CWRAPPER_END
1610}
1611
1612CWRAPPER_OUTPUT_TYPE basic_solve_poly(CSetBasic *r, const basic f,
1613 const basic s)
1614{
1615 CWRAPPER_BEGIN
1616 SYMENGINE_ASSERT(is_a<Symbol>(*(s->m)));
1617 RCP<const Set> set
1618 = SymEngine::solve_poly(f->m, rcp_static_cast<const Symbol>(s->m));
1619 if (not is_a<FiniteSet>(*set)) {
1620 return SYMENGINE_NOT_IMPLEMENTED;
1621 }
1622 r->m = down_cast<const FiniteSet &>(*set).get_container();
1623 CWRAPPER_END
1624}
1625
1626// ----------------------
1627
1628char *ascii_art_str()
1629{
1630 std::string str = SymEngine::ascii_art();
1631 auto cc = new char[str.length() + 1];
1632 std::strcpy(cc, str.c_str());
1633 return cc;
1634}
1635
1636// Cwrapper for ntheory
1637
1638CWRAPPER_OUTPUT_TYPE ntheory_gcd(basic s, const basic a, const basic b)
1639{
1640 CWRAPPER_BEGIN
1641 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1642 SYMENGINE_ASSERT(is_a<Integer>(*(b->m)));
1643 s->m = SymEngine::gcd(down_cast<const Integer &>(*(a->m)),
1644 down_cast<const Integer &>(*(b->m)));
1645 CWRAPPER_END
1646}
1647
1648CWRAPPER_OUTPUT_TYPE ntheory_lcm(basic s, const basic a, const basic b)
1649{
1650 CWRAPPER_BEGIN
1651 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1652 SYMENGINE_ASSERT(is_a<Integer>(*(b->m)));
1653 s->m = SymEngine::lcm(down_cast<const Integer &>(*(a->m)),
1654 down_cast<const Integer &>(*(b->m)));
1655 CWRAPPER_END
1656}
1657
1658CWRAPPER_OUTPUT_TYPE ntheory_gcd_ext(basic g, basic s, basic t, const basic a,
1659 const basic b)
1660{
1661 CWRAPPER_BEGIN
1662 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1663 SYMENGINE_ASSERT(is_a<Integer>(*(b->m)));
1665 SymEngine::gcd_ext(SymEngine::outArg(g_), SymEngine::outArg(s_),
1666 SymEngine::outArg(t_),
1667 down_cast<const Integer &>(*(a->m)),
1668 down_cast<const Integer &>(*(b->m)));
1669 g->m = g_;
1670 s->m = s_;
1671 t->m = t_;
1672 CWRAPPER_END
1673}
1674
1675CWRAPPER_OUTPUT_TYPE ntheory_nextprime(basic s, const basic a)
1676{
1677 CWRAPPER_BEGIN
1678 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1679 s->m = SymEngine::nextprime(down_cast<const Integer &>(*(a->m)));
1680 CWRAPPER_END
1681}
1682
1683CWRAPPER_OUTPUT_TYPE ntheory_mod(basic s, const basic n, const basic d)
1684{
1685 CWRAPPER_BEGIN
1686 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1687 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1688 s->m = SymEngine::mod(down_cast<const Integer &>(*(n->m)),
1689 down_cast<const Integer &>(*(d->m)));
1690 CWRAPPER_END
1691}
1692
1693CWRAPPER_OUTPUT_TYPE ntheory_quotient(basic s, const basic n, const basic d)
1694{
1695 CWRAPPER_BEGIN
1696 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1697 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1698 s->m = SymEngine::quotient(down_cast<const Integer &>(*(n->m)),
1699 down_cast<const Integer &>(*(d->m)));
1700 CWRAPPER_END
1701}
1702
1703CWRAPPER_OUTPUT_TYPE ntheory_quotient_mod(basic q, basic r, const basic n,
1704 const basic d)
1705{
1706 CWRAPPER_BEGIN
1707 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1708 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1710 SymEngine::quotient_mod(SymEngine::outArg(q_), SymEngine::outArg(r_),
1711 down_cast<const Integer &>(*(n->m)),
1712 down_cast<const Integer &>(*(d->m)));
1713 q->m = q_;
1714 r->m = r_;
1715 CWRAPPER_END
1716}
1717
1718CWRAPPER_OUTPUT_TYPE ntheory_mod_f(basic s, const basic n, const basic d)
1719{
1720 CWRAPPER_BEGIN
1721 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1722 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1723 s->m = SymEngine::mod_f(down_cast<const Integer &>(*(n->m)),
1724 down_cast<const Integer &>(*(d->m)));
1725 CWRAPPER_END
1726}
1727
1728CWRAPPER_OUTPUT_TYPE ntheory_quotient_f(basic s, const basic n, const basic d)
1729{
1730 CWRAPPER_BEGIN
1731 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1732 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1733 s->m = SymEngine::quotient_f(down_cast<const Integer &>(*(n->m)),
1734 down_cast<const Integer &>(*(d->m)));
1735 CWRAPPER_END
1736}
1737
1738CWRAPPER_OUTPUT_TYPE ntheory_quotient_mod_f(basic q, basic r, const basic n,
1739 const basic d)
1740{
1741 CWRAPPER_BEGIN
1742 SYMENGINE_ASSERT(is_a<Integer>(*(n->m)));
1743 SYMENGINE_ASSERT(is_a<Integer>(*(d->m)));
1745 SymEngine::quotient_mod_f(SymEngine::outArg(q_), SymEngine::outArg(r_),
1746 down_cast<const Integer &>(*(n->m)),
1747 down_cast<const Integer &>(*(d->m)));
1748 q->m = q_;
1749 r->m = r_;
1750 CWRAPPER_END
1751}
1752
1753int ntheory_mod_inverse(basic b, const basic a, const basic m)
1754{
1755 int ret_val;
1756 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1757 SYMENGINE_ASSERT(is_a<Integer>(*(m->m)));
1759 ret_val = SymEngine::mod_inverse(SymEngine::outArg(b_),
1760 down_cast<const Integer &>(*(a->m)),
1761 down_cast<const Integer &>(*(m->m)));
1762 b->m = b_;
1763 return ret_val;
1764}
1765
1766CWRAPPER_OUTPUT_TYPE ntheory_fibonacci(basic s, unsigned long a)
1767{
1768 CWRAPPER_BEGIN
1769 s->m = SymEngine::fibonacci(a);
1770 CWRAPPER_END
1771}
1772
1773CWRAPPER_OUTPUT_TYPE ntheory_fibonacci2(basic g, basic s, unsigned long a)
1774{
1775 CWRAPPER_BEGIN
1777 SymEngine::fibonacci2(SymEngine::outArg(g_), SymEngine::outArg(s_), a);
1778 g->m = g_;
1779 s->m = s_;
1780 CWRAPPER_END
1781}
1782
1783CWRAPPER_OUTPUT_TYPE ntheory_lucas(basic s, unsigned long a)
1784{
1785 CWRAPPER_BEGIN
1786 s->m = SymEngine::lucas(a);
1787 CWRAPPER_END
1788}
1789
1790CWRAPPER_OUTPUT_TYPE ntheory_lucas2(basic g, basic s, unsigned long a)
1791{
1792 CWRAPPER_BEGIN
1794 SymEngine::lucas2(SymEngine::outArg(g_), SymEngine::outArg(s_), a);
1795 g->m = g_;
1796 s->m = s_;
1797 CWRAPPER_END
1798}
1799
1800CWRAPPER_OUTPUT_TYPE ntheory_binomial(basic s, const basic a, unsigned long b)
1801{
1802 CWRAPPER_BEGIN
1803 SYMENGINE_ASSERT(is_a<Integer>(*(a->m)));
1804 s->m = SymEngine::binomial(down_cast<const Integer &>(*(a->m)), b);
1805 CWRAPPER_END
1806}
1807
1808CWRAPPER_OUTPUT_TYPE ntheory_factorial(basic s, unsigned long n)
1809{
1810 CWRAPPER_BEGIN
1811 s->m = SymEngine::factorial(n);
1812 CWRAPPER_END
1813}
1814
1816CWRAPPER_OUTPUT_TYPE basic_evalf(basic s, const basic b, unsigned long bits,
1817 int real)
1818{
1819
1820 CWRAPPER_BEGIN
1821 s->m = SymEngine::evalf(*(b->m), bits, (SymEngine::EvalfDomain)real);
1822 CWRAPPER_END
1823}
1824
1825CWRAPPER_OUTPUT_TYPE basic_as_numer_denom(basic numer, basic denom,
1826 const basic x)
1827{
1828 CWRAPPER_BEGIN
1829 SymEngine::as_numer_denom(x->m, SymEngine::outArg(numer->m),
1830 SymEngine::outArg(denom->m));
1831 CWRAPPER_END
1832}
1833
1837
1838CLambdaRealDoubleVisitor *lambda_real_double_visitor_new()
1839{
1840 return new CLambdaRealDoubleVisitor();
1841}
1842
1843void lambda_real_double_visitor_init(CLambdaRealDoubleVisitor *self,
1844 const CVecBasic *args,
1845 const CVecBasic *exprs, int perform_cse)
1846{
1847 self->m.init(args->m, exprs->m, perform_cse);
1848}
1849
1850void lambda_real_double_visitor_call(CLambdaRealDoubleVisitor *self,
1851 double *const outs,
1852 const double *const inps)
1853{
1854 self->m.call(outs, inps);
1855}
1856
1857void lambda_real_double_visitor_free(CLambdaRealDoubleVisitor *self)
1858{
1859 delete self;
1860}
1861
1862#ifdef HAVE_SYMENGINE_LLVM
1863// double
1864struct CLLVMDoubleVisitor {
1866};
1867
1868CLLVMDoubleVisitor *llvm_double_visitor_new()
1869{
1870 return new CLLVMDoubleVisitor();
1871}
1872
1873void llvm_double_visitor_init(CLLVMDoubleVisitor *self, const CVecBasic *args,
1874 const CVecBasic *exprs, int perform_cse,
1875 int opt_level)
1876{
1877 self->m.init(args->m, exprs->m, perform_cse, opt_level);
1878}
1879
1880void llvm_double_visitor_call(CLLVMDoubleVisitor *self, double *const outs,
1881 const double *const inps)
1882{
1883 self->m.call(outs, inps);
1884}
1885
1886void llvm_double_visitor_free(CLLVMDoubleVisitor *self)
1887{
1888 delete self;
1889}
1890// float
1891struct CLLVMFloatVisitor {
1893};
1894
1895CLLVMFloatVisitor *llvm_float_visitor_new()
1896{
1897 return new CLLVMFloatVisitor();
1898}
1899
1900void llvm_float_visitor_init(CLLVMFloatVisitor *self, const CVecBasic *args,
1901 const CVecBasic *exprs, int perform_cse,
1902 int opt_level)
1903{
1904 self->m.init(args->m, exprs->m, perform_cse, opt_level);
1905}
1906
1907void llvm_float_visitor_call(CLLVMFloatVisitor *self, float *const outs,
1908 const float *const inps)
1909{
1910 self->m.call(outs, inps);
1911}
1912
1913void llvm_float_visitor_free(CLLVMFloatVisitor *self)
1914{
1915 delete self;
1916}
1917#ifdef SYMENGINE_HAVE_LLVM_LONG_DOUBLE
1918// long double
1919struct CLLVMLongDoubleVisitor {
1921};
1922
1923CLLVMLongDoubleVisitor *llvm_long_double_visitor_new()
1924{
1925 return new CLLVMLongDoubleVisitor();
1926}
1927
1928void llvm_long_double_visitor_init(CLLVMLongDoubleVisitor *self,
1929 const CVecBasic *args,
1930 const CVecBasic *exprs, int perform_cse,
1931 int opt_level)
1932{
1933 self->m.init(args->m, exprs->m, perform_cse, opt_level);
1934}
1935
1936void llvm_long_double_visitor_call(CLLVMLongDoubleVisitor *self,
1937 long double *const outs,
1938 const long double *const inps)
1939{
1940 self->m.call(outs, inps);
1941}
1942
1943void llvm_long_double_visitor_free(CLLVMLongDoubleVisitor *self)
1944{
1945 delete self;
1946}
1947#endif
1948#endif
1949
1950CWRAPPER_OUTPUT_TYPE basic_cse(CVecBasic *replacement_syms,
1951 CVecBasic *replacement_exprs,
1952 CVecBasic *reduced_exprs, const CVecBasic *exprs)
1953{
1954 CWRAPPER_BEGIN
1955 vec_pair replacements;
1956 SymEngine::cse(replacements, reduced_exprs->m, exprs->m);
1957 for (auto &p : replacements) {
1958 replacement_syms->m.push_back(p.first);
1959 replacement_exprs->m.push_back(p.second);
1960 }
1961 CWRAPPER_END
1962}
1964void symengine_print_stack_on_segfault()
1965{
1966 SymEngine::print_stack_on_segfault();
1967}
1968}
T all_of(T... args)
T begin(T... args)
T c_str(T... args)
The lowest unit of symbolic representation.
Definition basic.h:97
std::string __str__() const
Definition basic.cpp:46
static RCP< const Basic > loads(const std::string &)
Creates an instance of a serialized string.
Definition basic.cpp:61
ComplexBase Class for deriving all complex classes.
Definition complex.h:16
Complex Double Class to hold std::complex<double> values.
Complex Class.
Definition complex.h:33
static RCP< const Number > from_mpq(const rational_class re, const rational_class im)
Definition complex.cpp:93
static RCP< const Number > from_two_rats(const Rational &re, const Rational &im)
Definition complex.cpp:104
static RCP< const Number > from_two_nums(const Number &re, const Number &im)
Definition complex.cpp:109
Integer Class.
Definition integer.h:19
Rational Class.
Definition rational.h:16
static RCP< const Number > from_mpq(const rational_class &i)
Definition rational.cpp:23
static RCP< const Number > from_two_ints(const Integer &n, const Integer &d)
Definition rational.cpp:44
RealDouble Class to hold double values.
Definition real_double.h:20
T end(T... args)
T erase(T... args)
T find(T... args)
T insert(T... args)
T move(T... args)
Main namespace for SymEngine package.
Definition add.cpp:19
RCP< const Integer > nextprime(const Integer &a)
Definition ntheory.cpp:172
RCP< const Reals > reals()
Definition sets.h:560
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition mul.cpp:431
RCP< const EmptySet > emptyset()
Definition sets.h:590
RCP< const Set > finiteset(const set_basic &container)
Definition sets.h:602
void quotient_mod_f(const Ptr< RCP< const Integer > > &q, const Ptr< RCP< const Integer > > &r, const Integer &n, const Integer &d)
Definition ntheory.cpp:100
RCP< const Integer > gcd(const Integer &a, const Integer &b)
Greatest Common Divisor.
Definition ntheory.cpp:31
RCP< const Basic > max(const vec_basic &arg)
Canonicalize Max:
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
Definition basic-inl.h:21
RCP< const Integer > mod(const Integer &n, const Integer &d)
modulo round toward zero
Definition ntheory.cpp:66
void lucas2(const Ptr< RCP< const Integer > > &g, const Ptr< RCP< const Integer > > &s, unsigned long n)
Lucas number n and n-1.
Definition ntheory.cpp:134
RCP< const Integer > lucas(unsigned long n)
Lucas number.
Definition ntheory.cpp:127
RCP< const Integer > quotient_f(const Integer &n, const Integer &d)
Definition ntheory.cpp:93
RCP< const Integers > integers()
Definition sets.h:572
void hash_combine(hash_t &seed, const T &v)
Definition basic-inl.h:95
RCP< const Integer > fibonacci(unsigned long n)
Fibonacci number.
Definition ntheory.cpp:110
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
Definition add.cpp:495
void gcd_ext(const Ptr< RCP< const Integer > > &g, const Ptr< RCP< const Integer > > &s, const Ptr< RCP< const Integer > > &t, const Integer &a, const Integer &b)
Extended GCD.
Definition ntheory.cpp:38
RCP< const Integer > mod_f(const Integer &n, const Integer &d)
modulo round toward -inf
Definition ntheory.cpp:86
RCP< const Integer > quotient(const Integer &n, const Integer &d)
Definition ntheory.cpp:71
bool is_a(const Basic &b)
Templatised version to check is_a type.
Definition basic-inl.h:36
RCP< const Integer > lcm(const Integer &a, const Integer &b)
Least Common Multiple.
Definition ntheory.cpp:49
RCP< const Integer > binomial(const Integer &n, unsigned long k)
Binomial Coefficient.
Definition ntheory.cpp:145
RCP< const Rationals > rationals()
Definition sets.h:566
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition mul.cpp:352
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition symbol.h:82
void fibonacci2(const Ptr< RCP< const Integer > > &g, const Ptr< RCP< const Integer > > &s, unsigned long n)
Fibonacci n and n-1.
Definition ntheory.cpp:117
RCP< const Complexes > complexes()
Definition sets.h:554
RCP< const Integer > factorial(unsigned long n)
Factorial.
Definition ntheory.cpp:153
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition add.cpp:425
void quotient_mod(const Ptr< RCP< const Integer > > &q, const Ptr< RCP< const Integer > > &r, const Integer &n, const Integer &d)
Definition ntheory.cpp:76
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition basic-inl.h:29
RCP< const Basic > min(const vec_basic &arg)
Canonicalize Min:
bool is_a_Complex(const Basic &b)
Definition complex.h:24
std::enable_if< std::is_integral< T >::value, RCP< constInteger > >::type integer(T i)
Definition integer.h:197
RCP< const Constant > constant(const std::string &name)
inline version to return Constant
Definition constants.h:53
int mod_inverse(const Ptr< RCP< const Integer > > &b, const Integer &a, const Integer &m)
inverse modulo
Definition ntheory.cpp:56
RCP< const Set > interval(const RCP< const Number > &start, const RCP< const Number > &end, const bool left_open=false, const bool right_open=false)
Definition sets.h:611
T next(T... args)
T push_back(T... args)
T length(T... args)
T strcmp(T... args)
T strcpy(T... args)
Our less operator (<):
Definition basic.h:228
T ~vector(T... args)