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