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