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