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