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>
14 using SymEngine::LLVMDoubleVisitor;
15 using SymEngine::LLVMFloatVisitor;
16 #ifdef HAVE_SYMENGINE_LLVM_LONG_DOUBLE
17 using SymEngine::LLVMLongDoubleVisitor;
18 #endif
19 #endif
20 
21 #define xstr(s) str(s)
22 #define str(s) #s
23 
24 using SymEngine::Basic;
25 using SymEngine::Complex;
30 using SymEngine::down_cast;
31 using SymEngine::function_symbol;
33 using SymEngine::has_symbol;
34 using SymEngine::Integer;
35 using SymEngine::integer_class;
37 using SymEngine::Number;
39 using SymEngine::rational_class;
40 using SymEngine::RCP;
42 using SymEngine::Symbol;
43 using SymEngine::zero;
44 #ifdef HAVE_SYMENGINE_MPFR
45 using SymEngine::mpfr_class;
47 #endif // HAVE_SYMENGINE_MPFR
48 #ifdef HAVE_SYMENGINE_MPC
50 #endif // HAVE_SYMENGINE_MPC
52 using SymEngine::is_a;
53 using SymEngine::rcp_static_cast;
55 using SymEngine::Set;
59 using SymEngine::vec_sym;
60 #if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
61 using SymEngine::get_mpq_t;
62 using SymEngine::get_mpz_t;
63 #endif
64 using SymEngine::ccode;
65 using SymEngine::diag;
66 using SymEngine::eye;
67 using SymEngine::jscode;
68 using SymEngine::julia_str;
69 using SymEngine::latex;
70 using SymEngine::mathml;
71 using SymEngine::mp_get_si;
72 using SymEngine::mp_get_ui;
73 using SymEngine::numeric_cast;
74 using SymEngine::ones;
75 using SymEngine::parse;
76 using SymEngine::SymEngineException;
77 using SymEngine::zeros;
78 
79 namespace SymEngine
80 {
81 
82 template <typename T>
83 inline bool is_aligned(T *p, size_t n = alignof(T))
84 {
85  return 0 == reinterpret_cast<uintptr_t>(p) % n;
86 }
87 
88 static std::string _str(const Basic &a)
89 {
90  return a.__str__();
91 }
92 } // namespace SymEngine
93 
94 extern "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 
110 struct CRCPBasic {
111  SymEngine::RCP<const SymEngine::Basic> m;
112 };
113 
114 struct CSetBasic {
116 };
117 
118 static_assert(sizeof(CRCPBasic) == sizeof(CRCPBasic_C),
119  "Size of 'basic' is not correct");
122  "Alignment of 'basic' is not correct");
123 
124 void basic_new_stack(basic s)
125 {
126  new (s) CRCPBasic();
127 }
128 
129 void basic_free_stack(basic s)
130 {
131  s->m.~RCP();
132 }
133 
134 basic_struct *basic_new_heap()
135 {
136  return new CRCPBasic();
137 }
138 
139 void basic_free_heap(basic_struct *s)
140 {
141  delete s;
142 }
143 
144 const char *symengine_version()
145 {
146  return SYMENGINE_VERSION;
147 }
148 
149 void basic_const_set(basic s, const char *c)
150 {
151  s->m = SymEngine::constant(std::string(c));
152 }
153 
154 void basic_const_zero(basic s)
155 {
156  s->m = SymEngine::zero;
157 }
158 
159 void basic_const_one(basic s)
160 {
161  s->m = SymEngine::one;
162 }
163 
164 void basic_const_minus_one(basic s)
165 {
166  s->m = SymEngine::minus_one;
167 }
168 
169 void basic_const_I(basic s)
170 {
171  s->m = SymEngine::I;
172 }
173 
174 void basic_const_pi(basic s)
175 {
176  s->m = SymEngine::pi;
177 }
178 
179 void basic_const_E(basic s)
180 {
181  s->m = SymEngine::E;
182 }
183 
184 void basic_const_EulerGamma(basic s)
185 {
186  s->m = SymEngine::EulerGamma;
187 }
188 
189 void basic_const_Catalan(basic s)
190 {
191  s->m = SymEngine::Catalan;
192 }
193 
194 void basic_const_GoldenRatio(basic s)
195 {
196  s->m = SymEngine::GoldenRatio;
197 }
198 
199 void basic_const_infinity(basic s)
200 {
201  s->m = SymEngine::Inf;
202 }
203 
204 void basic_const_neginfinity(basic s)
205 {
206  s->m = SymEngine::NegInf;
207 }
208 
209 void basic_const_complex_infinity(basic s)
210 {
211  s->m = SymEngine::ComplexInf;
212 }
213 
214 void basic_const_nan(basic s)
215 {
216  s->m = SymEngine::Nan;
217 }
218 
219 TypeID 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 
232 char *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 
248 TypeID basic_get_type(const basic s)
249 {
250  return static_cast<TypeID>(s->m->get_type_code());
251 }
252 
253 CWRAPPER_OUTPUT_TYPE symbol_set(basic s, const char *c)
254 {
255  CWRAPPER_BEGIN
256  s->m = SymEngine::symbol(std::string(c));
257  CWRAPPER_END
258 }
259 
260 int 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 
266 int 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 
272 int 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 
278 int 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 
284 int basic_has_symbol(const basic e, const basic s)
285 {
286  return (int)(has_symbol(*(e->m), *(s->m)));
287 }
288 
289 CWRAPPER_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 
296 CWRAPPER_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
304 CWRAPPER_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 
312 CWRAPPER_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 
319 CWRAPPER_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 
326 double 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 
334 CWRAPPER_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);
339  s->m = SymEngine::real_mpfr(std::move(mc));
340  CWRAPPER_END
341 }
342 
343 CWRAPPER_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 
350 double 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 
358 CWRAPPER_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 
365 CWRAPPER_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 
374 mpfr_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 
382 CWRAPPER_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 
390 CWRAPPER_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 
398 signed 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 
404 unsigned 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
411 CWRAPPER_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 
421 CWRAPPER_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 
428 CWRAPPER_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 
435 CWRAPPER_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
447 CWRAPPER_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 
456 CWRAPPER_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 
464 CWRAPPER_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 
473 CWRAPPER_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
483 CWRAPPER_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 
491 dcomplex 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 
502 char *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 
511 CWRAPPER_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 
519 CWRAPPER_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 
528 CWRAPPER_OUTPUT_TYPE basic_assign(basic a, const basic b)
529 {
530  CWRAPPER_BEGIN
531  a->m = b->m;
532  CWRAPPER_END
533 }
534 
535 CWRAPPER_OUTPUT_TYPE basic_parse(basic b, const char *str)
536 {
537  CWRAPPER_BEGIN
538  b->m = SymEngine::parse(str);
539  CWRAPPER_END
540 }
541 
542 CWRAPPER_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 
553 CWRAPPER_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 
560 CWRAPPER_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 
567 CWRAPPER_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 
574 CWRAPPER_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 
581 CWRAPPER_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 
588 int basic_eq(const basic a, const basic b)
589 {
590  return SymEngine::eq(*(a->m), *(b->m)) ? 1 : 0;
591 }
592 
593 int 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 
606 IMPLEMENT_ONE_ARG_FUNC(expand)
607 IMPLEMENT_ONE_ARG_FUNC(neg)
608 IMPLEMENT_ONE_ARG_FUNC(abs)
609 IMPLEMENT_ONE_ARG_FUNC(erf)
610 IMPLEMENT_ONE_ARG_FUNC(erfc)
611 IMPLEMENT_ONE_ARG_FUNC(sin)
612 IMPLEMENT_ONE_ARG_FUNC(cos)
613 IMPLEMENT_ONE_ARG_FUNC(tan)
614 IMPLEMENT_ONE_ARG_FUNC(csc)
615 IMPLEMENT_ONE_ARG_FUNC(sec)
616 IMPLEMENT_ONE_ARG_FUNC(cot)
617 IMPLEMENT_ONE_ARG_FUNC(asin)
618 IMPLEMENT_ONE_ARG_FUNC(acos)
619 IMPLEMENT_ONE_ARG_FUNC(asec)
620 IMPLEMENT_ONE_ARG_FUNC(acsc)
621 IMPLEMENT_ONE_ARG_FUNC(atan)
622 IMPLEMENT_ONE_ARG_FUNC(acot)
623 IMPLEMENT_ONE_ARG_FUNC(sinh)
624 IMPLEMENT_ONE_ARG_FUNC(cosh)
625 IMPLEMENT_ONE_ARG_FUNC(tanh)
626 IMPLEMENT_ONE_ARG_FUNC(csch)
627 IMPLEMENT_ONE_ARG_FUNC(sech)
628 IMPLEMENT_ONE_ARG_FUNC(coth)
629 IMPLEMENT_ONE_ARG_FUNC(asinh)
630 IMPLEMENT_ONE_ARG_FUNC(acosh)
631 IMPLEMENT_ONE_ARG_FUNC(asech)
632 IMPLEMENT_ONE_ARG_FUNC(acsch)
633 IMPLEMENT_ONE_ARG_FUNC(atanh)
634 IMPLEMENT_ONE_ARG_FUNC(acoth)
635 IMPLEMENT_ONE_ARG_FUNC(lambertw)
636 IMPLEMENT_ONE_ARG_FUNC(zeta)
637 IMPLEMENT_ONE_ARG_FUNC(dirichlet_eta)
638 IMPLEMENT_ONE_ARG_FUNC(gamma)
639 IMPLEMENT_ONE_ARG_FUNC(loggamma)
640 IMPLEMENT_ONE_ARG_FUNC(sqrt)
641 IMPLEMENT_ONE_ARG_FUNC(cbrt)
642 IMPLEMENT_ONE_ARG_FUNC(exp)
643 IMPLEMENT_ONE_ARG_FUNC(log)
644 IMPLEMENT_ONE_ARG_FUNC(floor)
645 IMPLEMENT_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 
655 IMPLEMENT_TWO_ARG_FUNC(atan2)
656 IMPLEMENT_TWO_ARG_FUNC(kronecker_delta)
657 IMPLEMENT_TWO_ARG_FUNC(lowergamma)
658 IMPLEMENT_TWO_ARG_FUNC(uppergamma)
659 IMPLEMENT_TWO_ARG_FUNC(beta)
660 IMPLEMENT_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 
678 IMPLEMENT_STR_CONVERSION(str, _str)
679 IMPLEMENT_STR_CONVERSION(str_julia, julia_str)
680 IMPLEMENT_STR_CONVERSION(str_mathml, mathml)
681 IMPLEMENT_STR_CONVERSION(str_latex, latex)
682 IMPLEMENT_STR_CONVERSION(str_ccode, ccode)
683 IMPLEMENT_STR_CONVERSION(str_jscode, jscode)
684 
685 void basic_str_free(char *s)
686 {
687  delete[] s;
688 }
689 
690 void bool_set_true(basic s)
691 {
692  s->m = SymEngine::boolTrue;
693 }
694 
695 void bool_set_false(basic s)
696 {
697  s->m = SymEngine::boolFalse;
698 }
699 
700 CWRAPPER_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 
714 CWRAPPER_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 
721 void basic_set_emptyset(basic s)
722 {
723  s->m = SymEngine::emptyset();
724 }
725 
726 void basic_set_universalset(basic s)
727 {
728  s->m = SymEngine::emptyset();
729 }
730 
731 void basic_set_complexes(basic s)
732 {
733  s->m = SymEngine::complexes();
734 }
735 
736 void basic_set_reals(basic s)
737 {
738  s->m = SymEngine::reals();
739 }
740 
741 void basic_set_rationals(basic s)
742 {
743  s->m = SymEngine::rationals();
744 }
745 
746 void basic_set_integers(basic s)
747 {
748  s->m = SymEngine::integers();
749 }
750 
751 CWRAPPER_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 
759 CWRAPPER_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 
768 CWRAPPER_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 
776 CWRAPPER_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 
783 int 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 
791 int 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 
799 int 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 
807 int 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 
815 CWRAPPER_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 
822 CWRAPPER_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 
829 CWRAPPER_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 
836 CWRAPPER_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 
843 CWRAPPER_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 
850 int 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 
899 int is_a_Number(const basic s)
900 {
901  return (int)is_a_Number(*(s->m));
902 }
903 int is_a_Integer(const basic c)
904 {
905  return is_a<Integer>(*(c->m));
906 }
907 int is_a_Rational(const basic c)
908 {
909  return is_a<Rational>(*(c->m));
910 }
911 int is_a_Symbol(const basic c)
912 {
913  return is_a<Symbol>(*(c->m));
914 }
915 int is_a_Complex(const basic c)
916 {
917  return is_a<Complex>(*(c->m));
918 }
919 int is_a_RealDouble(const basic c)
920 {
921  return is_a<RealDouble>(*(c->m));
922 }
923 int is_a_ComplexDouble(const basic c)
924 {
925  return is_a<ComplexDouble>(*(c->m));
926 }
927 int 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 }
935 int 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 }
943 int 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 
950 struct CVectorInt {
952 };
953 
954 CVectorInt *vectorint_new()
955 {
956  return new CVectorInt;
957 }
958 
959 int 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 
969 CVectorInt *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 
980 void vectorint_placement_free(CVectorInt *self)
981 {
982  self->m.~vector<int>();
983 }
984 
985 void vectorint_free(CVectorInt *self)
986 {
987  delete self;
988 }
989 
990 void vectorint_push_back(CVectorInt *self, int value)
991 {
992  self->m.push_back(value);
993 }
994 
995 int vectorint_get(CVectorInt *self, int n)
996 {
997  return self->m[n];
998 }
999 
1000 // C wrapper for vec_basic
1001 
1002 struct CVecBasic {
1004 };
1005 
1006 CVecBasic *vecbasic_new()
1007 {
1008  return new CVecBasic;
1009 }
1010 
1011 void vecbasic_free(CVecBasic *self)
1012 {
1013  delete self;
1014 }
1015 
1016 CWRAPPER_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 
1025 CWRAPPER_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 
1035 CWRAPPER_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 
1043 CWRAPPER_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 
1051 size_t vecbasic_size(CVecBasic *self)
1052 {
1053  return self->m.size();
1054 }
1055 
1056 CWRAPPER_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 
1063 CWRAPPER_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 
1070 CWRAPPER_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 
1077 CWRAPPER_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 
1094 CDenseMatrix *dense_matrix_new()
1095 {
1096  return new CDenseMatrix();
1097 }
1098 
1099 CDenseMatrix *dense_matrix_new_vec(unsigned rows, unsigned cols, CVecBasic *l)
1100 {
1101  return new CDenseMatrix({{rows, cols, l->m}});
1102 }
1103 
1104 CDenseMatrix *dense_matrix_new_rows_cols(unsigned rows, unsigned cols)
1105 {
1106  return new CDenseMatrix({{rows, cols}});
1107 }
1108 
1109 CSparseMatrix *sparse_matrix_new()
1110 {
1111  return new CSparseMatrix;
1112 }
1113 
1114 void dense_matrix_free(CDenseMatrix *self)
1115 {
1116  delete self;
1117 }
1118 
1119 void sparse_matrix_free(CSparseMatrix *self)
1120 {
1121  delete self;
1122 }
1123 
1124 void sparse_matrix_init(CSparseMatrix *s)
1125 {
1126  s->m = SymEngine::CSRMatrix();
1127 }
1128 
1129 void 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 
1136 CWRAPPER_OUTPUT_TYPE dense_matrix_set(CDenseMatrix *s, const CDenseMatrix *d)
1137 {
1138  CWRAPPER_BEGIN
1139  s->m = d->m;
1140  CWRAPPER_END
1141 }
1142 
1143 char *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 
1151 char *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 
1159 CWRAPPER_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 
1167 CWRAPPER_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 
1176 CWRAPPER_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 
1185 CWRAPPER_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 
1194 CWRAPPER_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 
1203 CWRAPPER_OUTPUT_TYPE dense_matrix_det(basic s, const CDenseMatrix *mat)
1204 {
1205  CWRAPPER_BEGIN
1206  s->m = mat->m.det();
1207  CWRAPPER_END
1208 }
1209 CWRAPPER_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 }
1216 CWRAPPER_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 }
1224 CWRAPPER_OUTPUT_TYPE
1225 dense_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 
1240 CWRAPPER_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 
1248 CWRAPPER_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 
1256 CWRAPPER_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 
1263 CWRAPPER_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 
1270 unsigned long int dense_matrix_rows(const CDenseMatrix *s)
1271 {
1272  return s->m.nrows();
1273 }
1274 
1275 unsigned long int dense_matrix_cols(const CDenseMatrix *s)
1276 {
1277  return s->m.ncols();
1278 }
1279 
1280 CWRAPPER_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 
1290 CWRAPPER_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 
1300 CWRAPPER_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 
1310 CWRAPPER_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 
1320 CWRAPPER_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 
1330 CWRAPPER_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 
1340 CWRAPPER_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 
1349 CWRAPPER_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 
1361 CWRAPPER_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 
1371 CWRAPPER_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 
1381 CWRAPPER_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 }
1390 CWRAPPER_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 
1402 CWRAPPER_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 
1412 CWRAPPER_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 
1422 CWRAPPER_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 
1431 int is_a_DenseMatrix(const CDenseMatrix *c)
1432 {
1433  return is_a<DenseMatrix>(c->m);
1434 }
1435 
1436 int is_a_SparseMatrix(const CSparseMatrix *c)
1437 {
1438  return is_a<CSRMatrix>(c->m);
1439 }
1440 
1441 int dense_matrix_eq(CDenseMatrix *lhs, CDenseMatrix *rhs)
1442 {
1443  return (lhs->m) == (rhs->m);
1444 }
1445 
1446 int sparse_matrix_eq(CSparseMatrix *lhs, CSparseMatrix *rhs)
1447 {
1448  return (lhs->m) == (rhs->m);
1449 }
1450 
1451 // C Wrapper for set_basic
1452 
1453 CSetBasic *setbasic_new()
1454 {
1455  return new CSetBasic;
1456 }
1457 
1458 void setbasic_free(CSetBasic *self)
1459 {
1460  delete self;
1461 }
1462 
1463 int setbasic_insert(CSetBasic *self, const basic value)
1464 {
1465  return (self->m.insert(value->m)).second ? 1 : 0;
1466 }
1467 
1468 void setbasic_get(CSetBasic *self, int n, basic result)
1469 {
1470  result->m = *std::next((self->m).begin(), n);
1471 }
1472 
1473 int setbasic_find(CSetBasic *self, basic value)
1474 {
1475  return self->m.find(value->m) != (self->m).end() ? 1 : 0;
1476 }
1477 
1478 int setbasic_erase(CSetBasic *self, const basic value)
1479 {
1480  return (self->m.erase(value->m)) ? 1 : 0;
1481 }
1482 
1483 size_t setbasic_size(CSetBasic *self)
1484 {
1485  return self->m.size();
1486 }
1487 
1488 // C Wrapper for map_basic_basic
1489 
1492 };
1493 
1494 CMapBasicBasic *mapbasicbasic_new()
1495 {
1496  return new CMapBasicBasic;
1497 }
1498 
1499 void mapbasicbasic_free(CMapBasicBasic *self)
1500 {
1501  delete self;
1502 }
1503 
1504 void mapbasicbasic_insert(CMapBasicBasic *self, const basic key,
1505  const basic mapped)
1506 {
1507  (self->m)[key->m] = mapped->m;
1508 }
1509 
1510 int 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 
1520 size_t mapbasicbasic_size(CMapBasicBasic *self)
1521 {
1522  return self->m.size();
1523 }
1524 
1525 // ----------------------
1526 
1527 CWRAPPER_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 
1534 CWRAPPER_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 
1541 CWRAPPER_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 
1549 size_t basic_hash(const basic self)
1550 {
1551  return static_cast<size_t>(self->m->hash());
1552 }
1553 
1554 CWRAPPER_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 
1562 CWRAPPER_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 
1570 CWRAPPER_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 
1578 char *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 
1587 CWRAPPER_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 
1597 CWRAPPER_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 
1612 CWRAPPER_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 
1628 char *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 
1638 CWRAPPER_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 
1648 CWRAPPER_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 
1658 CWRAPPER_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)));
1664  SymEngine::RCP<const Integer> g_, s_, t_;
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 
1675 CWRAPPER_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 
1683 CWRAPPER_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 
1693 CWRAPPER_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 
1703 CWRAPPER_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)));
1709  SymEngine::RCP<const Integer> q_, r_;
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 
1718 CWRAPPER_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 
1728 CWRAPPER_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 
1738 CWRAPPER_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)));
1744  SymEngine::RCP<const Integer> q_, r_;
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 
1753 int 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)));
1758  SymEngine::RCP<const Integer> b_;
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 
1766 CWRAPPER_OUTPUT_TYPE ntheory_fibonacci(basic s, unsigned long a)
1767 {
1768  CWRAPPER_BEGIN
1769  s->m = SymEngine::fibonacci(a);
1770  CWRAPPER_END
1771 }
1772 
1773 CWRAPPER_OUTPUT_TYPE ntheory_fibonacci2(basic g, basic s, unsigned long a)
1774 {
1775  CWRAPPER_BEGIN
1776  SymEngine::RCP<const Integer> g_, s_;
1777  SymEngine::fibonacci2(SymEngine::outArg(g_), SymEngine::outArg(s_), a);
1778  g->m = g_;
1779  s->m = s_;
1780  CWRAPPER_END
1781 }
1782 
1783 CWRAPPER_OUTPUT_TYPE ntheory_lucas(basic s, unsigned long a)
1784 {
1785  CWRAPPER_BEGIN
1786  s->m = SymEngine::lucas(a);
1787  CWRAPPER_END
1788 }
1789 
1790 CWRAPPER_OUTPUT_TYPE ntheory_lucas2(basic g, basic s, unsigned long a)
1791 {
1792  CWRAPPER_BEGIN
1793  SymEngine::RCP<const Integer> g_, s_;
1794  SymEngine::lucas2(SymEngine::outArg(g_), SymEngine::outArg(s_), a);
1795  g->m = g_;
1796  s->m = s_;
1797  CWRAPPER_END
1798 }
1799 
1800 CWRAPPER_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 
1808 CWRAPPER_OUTPUT_TYPE ntheory_factorial(basic s, unsigned long n)
1809 {
1810  CWRAPPER_BEGIN
1811  s->m = SymEngine::factorial(n);
1812  CWRAPPER_END
1813 }
1814 
1816 CWRAPPER_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 
1825 CWRAPPER_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 
1836 };
1837 
1838 CLambdaRealDoubleVisitor *lambda_real_double_visitor_new()
1839 {
1840  return new CLambdaRealDoubleVisitor();
1841 }
1842 
1843 void 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 
1850 void 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 
1857 void lambda_real_double_visitor_free(CLambdaRealDoubleVisitor *self)
1858 {
1859  delete self;
1860 }
1861 
1862 #ifdef HAVE_SYMENGINE_LLVM
1863 // double
1864 struct CLLVMDoubleVisitor {
1865  SymEngine::LLVMDoubleVisitor m;
1866 };
1867 
1868 CLLVMDoubleVisitor *llvm_double_visitor_new()
1869 {
1870  return new CLLVMDoubleVisitor();
1871 }
1872 
1873 void 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 
1880 void llvm_double_visitor_call(CLLVMDoubleVisitor *self, double *const outs,
1881  const double *const inps)
1882 {
1883  self->m.call(outs, inps);
1884 }
1885 
1886 void llvm_double_visitor_free(CLLVMDoubleVisitor *self)
1887 {
1888  delete self;
1889 }
1890 // float
1891 struct CLLVMFloatVisitor {
1892  SymEngine::LLVMFloatVisitor m;
1893 };
1894 
1895 CLLVMFloatVisitor *llvm_float_visitor_new()
1896 {
1897  return new CLLVMFloatVisitor();
1898 }
1899 
1900 void 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 
1907 void llvm_float_visitor_call(CLLVMFloatVisitor *self, float *const outs,
1908  const float *const inps)
1909 {
1910  self->m.call(outs, inps);
1911 }
1912 
1913 void llvm_float_visitor_free(CLLVMFloatVisitor *self)
1914 {
1915  delete self;
1916 }
1917 #ifdef SYMENGINE_HAVE_LLVM_LONG_DOUBLE
1918 // long double
1919 struct CLLVMLongDoubleVisitor {
1920  SymEngine::LLVMLongDoubleVisitor m;
1921 };
1922 
1923 CLLVMLongDoubleVisitor *llvm_long_double_visitor_new()
1924 {
1925  return new CLLVMLongDoubleVisitor();
1926 }
1927 
1928 void 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 
1936 void 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 
1943 void llvm_long_double_visitor_free(CLLVMLongDoubleVisitor *self)
1944 {
1945  delete self;
1946 }
1947 #endif
1948 #endif
1949 
1950 CWRAPPER_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 }
1964 void symengine_print_stack_on_segfault()
1965 {
1966  SymEngine::print_stack_on_segfault();
1967 }
1968 }
T all_of(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
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 move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
bool is_a_Number(const Basic &b)
Definition: number.h:130
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
RCP< const Basic > cbrt(const RCP< const Basic > &arg)
Definition: pow.h:66
RCP< const Complexes > complexes()
Definition: sets.h:554
RCP< const Integer > nextprime(const Integer &a)
Definition: ntheory.cpp:173
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:118
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Symbol > symbol(const std::string &name)
inline version to return Symbol
Definition: symbol.h:82
RCP< const Reals > reals()
Definition: sets.h:560
RCP< const Integer > gcd(const Integer &a, const Integer &b)
Greatest Common Divisor.
Definition: ntheory.cpp:32
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:67
RCP< const EmptySet > emptyset()
Definition: sets.h:590
RCP< const Integers > integers()
Definition: sets.h:572
RCP< const Basic > sqrt(const RCP< const Basic > &arg)
Definition: pow.h:61
RCP< const Integer > lucas(unsigned long n)
Lucas number.
Definition: ntheory.cpp:128
RCP< const Integer > quotient_f(const Integer &n, const Integer &d)
Definition: ntheory.cpp:94
RCP< const Integer > fibonacci(unsigned long n)
Fibonacci number.
Definition: ntheory.cpp:111
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
Definition: add.cpp:495
RCP< const Integer > mod_f(const Integer &n, const Integer &d)
modulo round toward -inf
Definition: ntheory.cpp:87
RCP< const Integer > quotient(const Integer &n, const Integer &d)
Definition: ntheory.cpp:72
int mod_inverse(const Ptr< RCP< const Integer >> &b, const Integer &a, const Integer &m)
inverse modulo
Definition: ntheory.cpp:57
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:50
RCP< const Integer > binomial(const Integer &n, unsigned long k)
Binomial Coefficient.
Definition: ntheory.cpp:146
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:101
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Integer > factorial(unsigned long n)
Factorial.
Definition: ntheory.cpp:154
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425
RCP< const Constant > constant(const std::string &name)
inline version to return Constant
Definition: constants.h:53
tribool is_zero(const Basic &b, const Assumptions *assumptions=nullptr)
Check if a number is zero.
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:39
RCP< const Set > finiteset(const set_basic &container)
Definition: sets.h:602
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
Definition: basic-inl.h:29
RCP< const Basic > expand(const RCP< const Basic > &self, bool deep=true)
Expands self
Definition: expand.cpp:369
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
RCP< const Rationals > rationals()
Definition: sets.h:566
void quotient_mod(const Ptr< RCP< const Integer >> &q, const Ptr< RCP< const Integer >> &r, const Integer &n, const Integer &d)
Definition: ntheory.cpp:77
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:135
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