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