├── .clang-format ├── .gitignore ├── .mailmap ├── .travis.yml ├── AUTHORS ├── CMakeLists.txt ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SymForth ├── SymForth.md ├── SymForth_expandv.png ├── SymForth_sm_expand.png └── sm_tok.py ├── SymForth_expandv.png ├── appveyor.yml ├── benchmarks ├── CMakeLists.txt ├── add1.cpp ├── bench.cpp ├── bench_eval_double.cpp ├── diff_cache.cpp ├── eval_double1.cpp ├── expand1.cpp ├── expand1.nb ├── expand2.cpp ├── expand2.m ├── expand2.mpl ├── expand2_ginac.cpp ├── expand2b.cpp ├── expand3.cpp ├── expand4.nb ├── expand5.nb ├── expand6.cpp ├── expand6.m ├── expand6.mpl ├── expand6_ginac.cpp ├── expand6b.cpp ├── expand6b.m ├── expand6b.mpl ├── expand6b_ginac.cpp ├── expand7.cpp ├── expand7.m ├── expand7.mpl ├── expand7_ginac.cpp ├── expandv.cpp ├── lwbench.cpp ├── lwbench_ginac.cpp ├── matrix_add1.cpp ├── matrix_add1_ginac.cpp ├── matrix_add2.cpp ├── matrix_add2_ginac.cpp ├── matrix_mul1.cpp ├── matrix_mul1_ginac.cpp ├── matrix_mul2.cpp ├── matrix_mul2_ginac.cpp ├── nonius.h++ ├── ntheorybench.cpp ├── parsing.cpp ├── series.cpp ├── series_expansion_sincos_flint.cpp ├── series_expansion_sincos_piranha.cpp ├── series_expansion_sinp.cpp ├── sm_expand.cpp ├── symbench.cpp ├── symbench.m ├── symbench.nb ├── symbench_ginac.cpp ├── symengine_bench.cpp ├── symengine_bench.m ├── symengine_bench.mpl └── symengine_bench_ginac.cpp ├── bin ├── appveyor-download.cmd ├── install_travis.sh ├── release_authors.sh ├── test_cling_notebook.sh ├── test_format_local.sh ├── test_make_install.py ├── test_matchpycpp_gen_tests.sh ├── test_travis.sh ├── travis_clang_format.sh ├── trigger_feedstock.sh └── update_authors.sh ├── binder ├── environment.yml └── postBuild ├── cmake ├── FindARB.cmake ├── FindBFD.cmake ├── FindECM.cmake ├── FindEXECINFO.cmake ├── FindFLINT.cmake ├── FindGMP.cmake ├── FindLINKH.cmake ├── FindMPC.cmake ├── FindMPFR.cmake ├── FindPIRANHA.cmake ├── FindPRIMESIEVE.cmake ├── FindPTHREAD.cmake ├── FindTCMALLOC.cmake ├── LibFindMacros.cmake ├── SymEngineConfig.cmake.in ├── SymEngineConfigVersion.cmake.in ├── UserOverride.cmake ├── checkclang.cpp ├── checkcxx11.cpp ├── checkgmpxx.cpp ├── checkstdtostring.cpp └── cotire.cmake ├── codecov.yml ├── doc ├── Doxyfile ├── Makefile ├── conf.py ├── design.md └── style_guide.md ├── notebooks └── symengine.ipynb └── symengine ├── CMakeLists.txt ├── add.cpp ├── add.h ├── as_real_imag.cpp ├── basic-inl.h ├── basic-methods.inc ├── basic.cpp ├── basic.h ├── complex.cpp ├── complex.h ├── complex_double.cpp ├── complex_double.h ├── complex_mpc.cpp ├── complex_mpc.h ├── constants.cpp ├── constants.h ├── cse.cpp ├── cwrapper.cpp ├── cwrapper.h ├── dense_matrix.cpp ├── derivative.cpp ├── derivative.h ├── dict.cpp ├── dict.h ├── diophantine.cpp ├── diophantine.h ├── eval.cpp ├── eval.h ├── eval_arb.cpp ├── eval_arb.h ├── eval_double.cpp ├── eval_double.h ├── eval_mpc.cpp ├── eval_mpc.h ├── eval_mpfr.cpp ├── eval_mpfr.h ├── expand.cpp ├── expression.cpp ├── expression.h ├── fields.cpp ├── fields.h ├── finitediff.cpp ├── finitediff.h ├── flint_wrapper.h ├── functions.cpp ├── functions.h ├── infinity.cpp ├── infinity.h ├── integer.cpp ├── integer.h ├── lambda_double.h ├── llvm_double.cpp ├── llvm_double.h ├── logic.cpp ├── logic.h ├── matrix.cpp ├── matrix.h ├── monomials.cpp ├── monomials.h ├── mp_boost.cpp ├── mp_class.h ├── mp_wrapper.cpp ├── mp_wrapper.h ├── mul.cpp ├── mul.h ├── nan.cpp ├── nan.h ├── ntheory.cpp ├── ntheory.h ├── number.cpp ├── number.h ├── numer_denom.cpp ├── parser.h ├── parser ├── parser.cpp ├── parser.h ├── parser.tab.cc ├── parser.tab.hh ├── parser.yy ├── parser_old.cpp ├── parser_stype.h ├── tokenizer.cpp ├── tokenizer.h └── tokenizer.re ├── polys ├── basic_conversions.cpp ├── basic_conversions.h ├── cancel.h ├── msymenginepoly.cpp ├── msymenginepoly.h ├── uexprpoly.cpp ├── uexprpoly.h ├── uintpoly.cpp ├── uintpoly.h ├── uintpoly_flint.cpp ├── uintpoly_flint.h ├── uintpoly_piranha.cpp ├── uintpoly_piranha.h ├── upolybase.h ├── uratpoly.cpp ├── uratpoly.h └── usymenginepoly.h ├── pow.cpp ├── pow.h ├── printers.h ├── printers ├── codegen.cpp ├── codegen.h ├── latex.cpp ├── latex.h ├── mathml.cpp ├── mathml.h ├── strprinter.cpp └── strprinter.h ├── rational.cpp ├── rational.h ├── real_double.cpp ├── real_double.h ├── real_mpfr.cpp ├── real_mpfr.h ├── rewrite.cpp ├── rings.cpp ├── rings.h ├── series.cpp ├── series.h ├── series_flint.cpp ├── series_flint.h ├── series_generic.cpp ├── series_generic.h ├── series_piranha.cpp ├── series_piranha.h ├── series_visitor.h ├── sets.cpp ├── sets.h ├── solve.cpp ├── solve.h ├── sparse_matrix.cpp ├── subs.h ├── symbol.cpp ├── symbol.h ├── symengine_assert.h ├── symengine_casts.h ├── symengine_config.h.in ├── symengine_config_cling.h.in ├── symengine_exception.h ├── symengine_rcp.cpp ├── symengine_rcp.h ├── tests ├── CMakeLists.txt ├── basic │ ├── CMakeLists.txt │ ├── test_arit.cpp │ ├── test_as_numer_denom.cpp │ ├── test_as_real_imag.cpp │ ├── test_basic.cpp │ ├── test_count_ops.cpp │ ├── test_cse.cpp │ ├── test_fields.cpp │ ├── test_functions.cpp │ ├── test_infinity.cpp │ ├── test_integer.cpp │ ├── test_integer_class.cpp │ ├── test_nan.cpp │ ├── test_number.cpp │ ├── test_parser.cpp │ ├── test_poly.cpp │ ├── test_rational.cpp │ ├── test_relationals.cpp │ ├── test_series.cpp │ ├── test_series_expansion_UP.cpp │ ├── test_series_expansion_URatF.cpp │ ├── test_series_expansion_URatP.cpp │ ├── test_series_generic.cpp │ ├── test_sets.cpp │ ├── test_solve.cpp │ └── test_subs.cpp ├── cwrapper │ ├── CMakeLists.txt │ └── test_cwrapper.c ├── eval │ ├── CMakeLists.txt │ ├── test_eval_arb.cpp │ ├── test_eval_double.cpp │ ├── test_eval_mpc.cpp │ ├── test_eval_mpfr.cpp │ ├── test_evalf.cpp │ └── test_lambda_double.cpp ├── expression │ ├── CMakeLists.txt │ └── test_expression.cpp ├── finitediff │ ├── CMakeLists.txt │ └── test_finitediff.cpp ├── logic │ ├── CMakeLists.txt │ └── test_logic.cpp ├── matrix │ ├── CMakeLists.txt │ └── test_matrix.cpp ├── ntheory │ ├── CMakeLists.txt │ ├── test_diophantine.cpp │ └── test_ntheory.cpp ├── polynomial │ ├── CMakeLists.txt │ ├── test_basic_conversions.cpp │ ├── test_cancel.cpp │ ├── test_mexprpoly.cpp │ ├── test_mintpoly.cpp │ ├── test_uexprpoly.cpp │ ├── test_uintpoly.cpp │ ├── test_uintpoly_flint.cpp │ ├── test_uintpoly_piranha.cpp │ ├── test_uratpoly.cpp │ ├── test_uratpoly_flint.cpp │ └── test_uratpoly_piranha.cpp ├── printing │ ├── CMakeLists.txt │ ├── test_ccode.cpp │ └── test_printing.cpp └── rcp │ ├── CMakeLists.txt │ └── test_rcp.cpp ├── type_codes.inc ├── utilities ├── catch │ ├── .gitattributes │ ├── CMakeLists.txt │ ├── catch.cpp │ └── catch.hpp ├── matchpycpp │ ├── CMakeLists.txt │ ├── README.md │ ├── autogen_tests │ │ ├── CMakeLists.txt │ │ ├── test_case001.cpp │ │ ├── test_case002.cpp │ │ ├── test_case003.cpp │ │ ├── test_case004.cpp │ │ ├── test_case005.cpp │ │ ├── test_case006.cpp │ │ └── test_case007.cpp │ ├── bipartite.h │ ├── common.h │ ├── cpp_code_generation.py │ ├── environment.yml │ ├── generate_tests.py │ ├── generator_trick.h │ ├── hopcroft_karp.h │ ├── many_to_one.h │ ├── substitution.h │ ├── symengine_printer.py │ ├── tests │ │ ├── .gitkeep │ │ ├── CMakeLists.txt │ │ ├── bipartite │ │ │ ├── CMakeLists.txt │ │ │ └── test_bipartite.cpp │ │ └── hopcroft_karp │ │ │ ├── CMakeLists.txt │ │ │ └── test_hopcroft_karp.cpp │ └── utils.h └── teuchos │ ├── CMakeLists.txt │ ├── Teuchos_Assert.hpp │ ├── Teuchos_ConfigDefs.hpp │ ├── Teuchos_ConstTypeTraits.hpp │ ├── Teuchos_DLLExportMacro.h │ ├── Teuchos_ENull.hpp │ ├── Teuchos_Exceptions.hpp │ ├── Teuchos_NullIteratorTraits.hpp │ ├── Teuchos_Ptr.cpp │ ├── Teuchos_Ptr.hpp │ ├── Teuchos_PtrDecl.hpp │ ├── Teuchos_RCP.hpp │ ├── Teuchos_RCPDecl.hpp │ ├── Teuchos_RCPNode.cpp │ ├── Teuchos_RCPNode.hpp │ ├── Teuchos_TestForException.cpp │ ├── Teuchos_TestForException.hpp │ ├── Teuchos_TypeNameTraits.cpp │ ├── Teuchos_TypeNameTraits.hpp │ ├── Teuchos_any.hpp │ ├── Teuchos_config.h.in │ ├── Teuchos_dyn_cast.cpp │ ├── Teuchos_dyn_cast.hpp │ ├── Teuchos_getBaseObjVoidPtr.hpp │ ├── Teuchos_map.hpp │ ├── Teuchos_stacktrace.cpp │ ├── Teuchos_stacktrace.hpp │ └── Teuchos_toString.hpp ├── visitor.cpp └── visitor.h /.clang-format: -------------------------------------------------------------------------------- 1 | # version: 3.8 2 | # exclude: cmake/* 3 | # exclude: symengine/utilities/* 4 | # include: *.h 5 | # include: *.hpp 6 | # include: *.cpp 7 | 8 | Language: Cpp 9 | AccessModifierOffset: -4 10 | AlignAfterOpenBracket: true 11 | AlignConsecutiveAssignments: false 12 | AlignEscapedNewlinesLeft: false 13 | AlignOperands: true 14 | AlignTrailingComments: true 15 | AllowAllParametersOfDeclarationOnNextLine: true 16 | AllowShortBlocksOnASingleLine: false 17 | AllowShortCaseLabelsOnASingleLine: false 18 | AllowShortFunctionsOnASingleLine: Empty 19 | AllowShortIfStatementsOnASingleLine: false 20 | AllowShortLoopsOnASingleLine: false 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakBeforeMultilineStrings: false 23 | AlwaysBreakTemplateDeclarations: true 24 | BinPackArguments: true 25 | BinPackParameters: true 26 | BreakBeforeBinaryOperators: All 27 | BreakBeforeBraces: Linux 28 | BreakBeforeTernaryOperators: true 29 | BreakConstructorInitializersBeforeComma: false 30 | ColumnLimit: 80 31 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 32 | ConstructorInitializerIndentWidth: 4 33 | ContinuationIndentWidth: 4 34 | Cpp11BracedListStyle: true 35 | DerivePointerAlignment: false 36 | DisableFormat: false 37 | ExperimentalAutoDetectBinPacking: false 38 | IndentCaseLabels: true 39 | IndentWidth: 4 40 | IndentWrappedFunctionNames: false 41 | KeepEmptyLinesAtTheStartOfBlocks: true 42 | MacroBlockBegin: '' 43 | MacroBlockEnd: '' 44 | MaxEmptyLinesToKeep: 1 45 | NamespaceIndentation: None 46 | ObjCBlockIndentWidth: 2 47 | ObjCSpaceAfterProperty: false 48 | ObjCSpaceBeforeProtocolList: true 49 | PenaltyBreakBeforeFirstCallParameter: 19 50 | PenaltyBreakComment: 22312 51 | PenaltyBreakFirstLessLess: 120 52 | PenaltyBreakString: 2123 53 | PenaltyExcessCharacter: 1000000 54 | PenaltyReturnTypeOnItsOwnLine: 60 55 | PointerAlignment: Right 56 | SortIncludes: false 57 | SpaceAfterCStyleCast: false 58 | SpaceBeforeAssignmentOperators: true 59 | SpaceBeforeParens: ControlStatements 60 | SpaceInEmptyParentheses: false 61 | SpacesBeforeTrailingComments: 1 62 | SpacesInAngles: false 63 | SpacesInContainerLiterals: false 64 | SpacesInCStyleCastParentheses: false 65 | SpacesInParentheses: false 66 | SpacesInSquareBrackets: false 67 | Standard: Cpp11 68 | TabWidth: 4 69 | UseTab: Never 70 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | # Prevent git from showing duplicate names with commands like "git shortlog" 2 | # See the manpage of git-shortlog for details. 3 | # The syntax is: 4 | # Name that should be used Bad name 5 | # 6 | # You can skip Bad name if it is the same as the one that should be used, and is unique. 7 | # 8 | # This file is up-to-date if the command git log --format="%aN <%aE>" | sort -u 9 | # gives no duplicates. 10 | Ondřej Čertík 11 | Sushant Hiray 12 | Thilina Bandara Rathnayake 13 | Peter Brady 14 | Isuru Fernando 15 | Shivam Vats 16 | Shivam Vats 17 | Sanka Rasnayaka 18 | AMiT Kumar 19 | Abhinav Agarwal 20 | Abhinav Agarwal 21 | Abhimanyu Siwach 22 | Zhang Yuning 23 | Kunal Singh 24 | Sumith Kulal 25 | Iris Lui 26 | Charles Chen 27 | Nishant Nikhil 28 | Arihant Parsoya 29 | Shikhar Jaiswal 30 | Vishu Sidana 31 | Ritesh Kumar 32 | Siddharth Bhat 33 | Tao He 34 | Ranjith Kumar 35 | Kv Manohar 36 | Kanchana Ruwanpathirana 37 | Dirk Reusch rdbyk 38 | Nilay Pochhi 39 | Jialin Ma 40 | Jialin Ma 41 | Gerrit Ansmann Gerrit Ansmann 42 | Simon Stelter 43 | Rajiv Ranjan Singh Rajiv Ranjan Singh <42106787+iamrajiv@users.noreply.github.com> 44 | Brandon Bocklund 45 | Simon Stelter 46 | Björn Dahlgren 47 | Roger Luo 48 | Jogi Miglani 49 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | All people who contributed to SymEngine by sending at least a patch or more (in 2 | the order of the date of their first contribution). You can generate this file 3 | by: bin/update_authors.sh 4 | 5 | 6 | Ondřej Čertík 7 | Dale Lukas Peterson 8 | Thilina Bandara Rathnayake 9 | Christopher Dembia 10 | Julien Rioux 11 | Sushant Hiray 12 | Thomas Hisch 13 | Vinzent Steinberg 14 | Isuru Fernando 15 | Peter Brady 16 | Shivam Vats 17 | Sumith Kulal 18 | Sanka Rasnayaka 19 | Abinash Meher 20 | Govind Sahai 21 | AMiT Kumar 22 | Francesco Biscani 23 | Connor Behan 24 | Björn Dahlgren 25 | Ralf Stephan 26 | Indrek Mandre 27 | Abhinav Agarwal 28 | Akash Trehan 29 | Srajan Garg 30 | Abhimanyu Siwach 31 | Pradyot Prakash 32 | malayaleecoder 33 | Nishant Nikhil 34 | Zhang Yuning 35 | Charles Chen 36 | Matthew Luszczak 37 | Iris Lui 38 | Rajith Vidanaarachchi 39 | Kunal Singh 40 | Vic Luo 41 | James Stojic 42 | Arihant Parsoya 43 | Ritesh Kumar 44 | Shikhar Jaiswal 45 | Vishu Sidana 46 | Siddharth Bhat 47 | Tao He 48 | Chad Mills 49 | Jean-Paul Pelteret 50 | Ranjith Kumar 51 | Kv Manohar 52 | Kanchana Ruwanpathirana 53 | Melanka Saroad 54 | Dirk Reusch 55 | Gerrit Ansmann 56 | Jialin Ma 57 | Nilay Pochhi 58 | Eeshan Gupta 59 | Ziyi Yan 60 | Andreas Humenberger 61 | Clouds Flowing 62 | Sylvain Corlay 63 | Kieran Kaempen 64 | Alan Hu 65 | Rajiv Ranjan Singh 66 | Francesco Bonazzi 67 | Simon Stelter 68 | Brandon Bocklund 69 | Marcello Mansueto 70 | Steven Lee 71 | Roger Luo 72 | Jogi Miglani 73 | Liam Keegan 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | Please report all bugs, issues, comments and feature requests into our 4 | [issues](https://github.com/sympy/symengine/issues). 5 | 6 | We welcome all Pull Requests, just send the code and we will help you improve 7 | it. You can read the [Style Guide](doc/style_guide.md) and 8 | [Design](doc/design.md) that your code should follow, but do not worry if you 9 | miss anything, we will let you know in the review. 10 | -------------------------------------------------------------------------------- /SymForth/SymForth.md: -------------------------------------------------------------------------------- 1 | Updated code: 2 | 3 | https://github.com/udexon/SymForth/blob/master/benchmarks/sm_expand.cpp 4 | 5 | `std::stack mystack;` has been renamed to: 6 | ``` 7 | std::stack sm_S; 8 | ``` 9 | 10 | User may key in Forth like reverse polish notation at command line and obtain an expression from SymEngine. 11 | 12 | Input: 13 | ``` 14 | $ ./sm_expand x sym: y sym: add: 2 3 + pow: 3 5 + 3 1 + 26 8 15 | ``` 16 | Output: 17 | ``` 18 | Expanding r: 5*x*y**4 + 10*x**2*y**3 + 10*x**3*y**2 + 5*x**4*y + x**5 + y**5 19 | ``` 20 | 21 | 22 | 23 | 24 | 25 | The most significant innovation in this project is the RCP stack, which allows SymEngine objects (RCP=Reference Counted Pointers) to be stored on stack and subsequently manipulated: 26 | ``` 27 | std::stack> RCP_S; 28 | ``` 29 | 30 | From Forth perspective, this leads to "multitype stacks" where the input tokens and string output tokens are stored on a string stack, while the code manages "one stack per type", a hopefully elegant solution for integrating Forth with modern type oriented programming languages: 31 | ``` 32 | std::stack sm_S; 33 | ``` 34 | 35 | Output text copy paste: 36 | ``` 37 | sm_proc: x sym: y sym: add: 2 3 + pow: 3 1 + 26 8 + 38 | sym: TOS x 39 | Expanding: x 40 | sym: TOS y 41 | Expanding: y 42 | In add: Expanding: x + y 43 | +: 5 3 2 5 44 | In pow: 45 | Expanding a: x + y 46 | Expanding: (x + y)**5 47 | 0ms 48 | number of terms: 6 49 | Expanding r: 5*x*y**4 + 10*x**2*y**3 + 10*x**3*y**2 + 5*x**4*y + x**5 + y**5 50 | +: 4 1 3 4 51 | +: 34 8 26 34 52 | sm_S TOS: 34 53 | .../symengine-master/Build$ benchmarks/sm_expand x sym: y sym: add: 2 3 + pow: 3 1 + 26 8 + 54 | ``` 55 | -------------------------------------------------------------------------------- /SymForth/SymForth_expandv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udexon/SymForth/e012a98ec885f7513773cc7e1ef8bfb5463fc876/SymForth/SymForth_expandv.png -------------------------------------------------------------------------------- /SymForth/SymForth_sm_expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udexon/SymForth/e012a98ec885f7513773cc7e1ef8bfb5463fc876/SymForth/SymForth_sm_expand.png -------------------------------------------------------------------------------- /SymForth/sm_tok.py: -------------------------------------------------------------------------------- 1 | def sm_tok(T): 2 | global skk 3 | print len(T) 4 | i=0 5 | L=len(T) 6 | while (i 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::Add; 14 | using SymEngine::Mul; 15 | using SymEngine::Pow; 16 | using SymEngine::Symbol; 17 | using SymEngine::symbol; 18 | using SymEngine::integer; 19 | using SymEngine::multinomial_coefficients; 20 | using SymEngine::RCP; 21 | using SymEngine::rcp_dynamic_cast; 22 | 23 | int main(int argc, char *argv[]) 24 | { 25 | SymEngine::print_stack_on_segfault(); 26 | 27 | RCP x = symbol("x"); 28 | RCP a, c; 29 | int N; 30 | 31 | N = 3000; 32 | a = x; 33 | c = integer(1); 34 | auto t1 = std::chrono::high_resolution_clock::now(); 35 | for (int i = 0; i < N; i++) { 36 | a = add(a, mul(c, pow(x, integer(i)))); 37 | c = mul(c, integer(-1)); 38 | } 39 | auto t2 = std::chrono::high_resolution_clock::now(); 40 | // std::cout << *a << std::endl; 41 | std::cout << std::chrono::duration_cast(t2 - t1) 42 | .count() 43 | << "ms" << std::endl; 44 | std::cout << "number of terms: " 45 | << rcp_dynamic_cast(a)->get_dict().size() << std::endl; 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /benchmarks/bench.cpp: -------------------------------------------------------------------------------- 1 | #define NONIUS_RUNNER 2 | #include "nonius.h++" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::symbol; 14 | using SymEngine::integer; 15 | using SymEngine::RCP; 16 | 17 | NONIUS_BENCHMARK("expand1", [](nonius::chronometer meter) { 18 | auto x = symbol("x"), y = symbol("y"), z = symbol("z"), w = symbol("w"); 19 | auto i60 = integer(60); 20 | std::vector> e(meter.runs()), r(meter.runs()); 21 | for (auto &v : e) { 22 | v = pow(add(add(add(x, y), z), w), i60); 23 | } 24 | meter.measure([&](int i) { r[i] = expand(e[i]); }); 25 | }) 26 | 27 | NONIUS_BENCHMARK("expand2", [](nonius::chronometer meter) { 28 | auto x = symbol("x"), y = symbol("y"), z = symbol("z"), w = symbol("w"); 29 | auto i15 = integer(15); 30 | std::vector> f(meter.runs()), r(meter.runs()); 31 | for (auto &v : f) { 32 | auto e = pow(add(add(add(x, y), z), w), i15); 33 | v = mul(e, add(e, w)); 34 | } 35 | meter.measure([&](int i) { r[i] = expand(f[i]); }); 36 | }) 37 | 38 | NONIUS_BENCHMARK("expand3", [](nonius::chronometer meter) { 39 | auto x = symbol("x"), y = symbol("y"), z = symbol("z"); 40 | auto i100 = integer(100); 41 | std::vector> e(meter.runs()), r(meter.runs()); 42 | for (auto &v : e) { 43 | v = pow(add(add(pow(x, y), pow(y, x)), pow(z, x)), i100); 44 | } 45 | meter.measure([&](int i) { r[i] = expand(e[i]); }); 46 | }) 47 | -------------------------------------------------------------------------------- /benchmarks/bench_eval_double.cpp: -------------------------------------------------------------------------------- 1 | #define NONIUS_RUNNER 2 | #include "nonius.h++" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using SymEngine::Basic; 14 | using SymEngine::symbol; 15 | using SymEngine::integer; 16 | using SymEngine::RCP; 17 | 18 | RCP get_eval_double_expression() 19 | { 20 | RCP e = sin(integer(1)); 21 | 22 | for (int i = 0; i < 10000; i++) { 23 | e = pow(add(mul(add(e, pow(integer(2), integer(-3))), integer(3)), 24 | integer(1)), 25 | div(integer(2), integer(3))); 26 | } 27 | return e; 28 | } 29 | 30 | RCP e = get_eval_double_expression(); 31 | 32 | NONIUS_BENCHMARK("eval_double", [](nonius::chronometer meter) { 33 | double r; 34 | meter.measure([&](int i) { r = eval_double(*e); }); 35 | }) 36 | 37 | NONIUS_BENCHMARK("eval_double_visitor_pattern", [](nonius::chronometer meter) { 38 | double r; 39 | meter.measure([&](int i) { r = eval_double_visitor_pattern(*e); }); 40 | }) 41 | 42 | NONIUS_BENCHMARK("eval_double_single_dispatch", [](nonius::chronometer meter) { 43 | double r; 44 | meter.measure([&](int i) { r = eval_double_single_dispatch(*e); }); 45 | }) 46 | -------------------------------------------------------------------------------- /benchmarks/eval_double1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using SymEngine::Basic; 15 | using SymEngine::Add; 16 | using SymEngine::Mul; 17 | using SymEngine::Pow; 18 | using SymEngine::Symbol; 19 | using SymEngine::umap_basic_num; 20 | using SymEngine::Integer; 21 | using SymEngine::multinomial_coefficients; 22 | using SymEngine::RCP; 23 | using SymEngine::rcp_dynamic_cast; 24 | using SymEngine::integer; 25 | using SymEngine::sin; 26 | using SymEngine::eval_double; 27 | 28 | int main(int argc, char *argv[]) 29 | { 30 | SymEngine::print_stack_on_segfault(); 31 | 32 | RCP e = sin(integer(1)); 33 | double r, r_exact; 34 | 35 | for (int i = 0; i < 10000; i++) 36 | e = pow(add(mul(add(e, pow(integer(2), integer(-3))), integer(3)), 37 | integer(1)), 38 | div(integer(2), integer(3))); 39 | 40 | // Too long: 41 | // std::cout << "Evaluating: " << *e << std::endl; 42 | 43 | auto t1 = std::chrono::high_resolution_clock::now(); 44 | int num = 500; 45 | for (int i = 0; i < num; i++) 46 | r = eval_double(*e); 47 | auto t2 = std::chrono::high_resolution_clock::now(); 48 | std::cout << std::chrono::duration(t2 - t1).count() * 1000 / num 49 | << "ms" << std::endl; 50 | /* 51 | In SymPy for few iterations: 52 | In [7]: sympify("(1 + 3*(1/8 + (1 + 3*(1/8 + (1 + 3*(1/8 + (1 + 3*(1/8 + (1 53 | + 3*(1/8 + sin(1)))^(2/3)))^(2/3)))^(2/3)))^(2/3)))^(2/3)").n(20) 54 | Out[7]: 8.0152751504518535013 55 | 56 | // r_exact = 8.0152751504518535013; 57 | 58 | Here is code to use SymPy for more iterations: 59 | 60 | In [5]: e = sin(1) 61 | 62 | In [6]: for i in range(10): 63 | ...: e = ((e+2**(-S(3)))*3 + 1)**(S(2)/3) 64 | ...: 65 | 66 | In [7]: e.n(20) 67 | Out[7]: 9.6473976427977306146 68 | 69 | But unfortunately SymPy can't do more than perhaps 10 or 20 iterations, 70 | while 71 | we need to test ~10000. However, the numbers seem to converge to 9.85647... 72 | 73 | */ 74 | r_exact = 9.8564741713701043569; 75 | std::cout << "r (double) = " << r << std::endl; 76 | std::cout << "r (exact) = " << r_exact << std::endl; 77 | std::cout << "error = " << std::abs(r - r_exact) << std::endl; 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /benchmarks/expand1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::Add; 14 | using SymEngine::Mul; 15 | using SymEngine::Pow; 16 | using SymEngine::Symbol; 17 | using SymEngine::symbol; 18 | using SymEngine::umap_basic_num; 19 | using SymEngine::Integer; 20 | using SymEngine::integer; 21 | using SymEngine::multinomial_coefficients; 22 | using SymEngine::RCP; 23 | using SymEngine::rcp_dynamic_cast; 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | SymEngine::print_stack_on_segfault(); 28 | 29 | RCP x = symbol("x"); 30 | RCP y = symbol("y"); 31 | RCP z = symbol("z"); 32 | RCP w = symbol("w"); 33 | RCP i60 = integer(60); 34 | 35 | RCP e, r; 36 | 37 | e = pow(add(add(add(x, y), z), w), i60); 38 | 39 | std::cout << "Expanding: " << *e << std::endl; 40 | 41 | auto t1 = std::chrono::high_resolution_clock::now(); 42 | r = expand(e); 43 | auto t2 = std::chrono::high_resolution_clock::now(); 44 | // std::cout << *r << std::endl; 45 | std::cout << std::chrono::duration_cast(t2 - t1) 46 | .count() 47 | << "ms" << std::endl; 48 | std::cout << "number of terms: " 49 | << rcp_dynamic_cast(r)->get_dict().size() << std::endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /benchmarks/expand1.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 8.0' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 157, 7] 13 | NotebookDataLength[ 2095, 78] 14 | NotebookOptionsPosition[ 1684, 58] 15 | NotebookOutlinePosition[ 2021, 73] 16 | CellTagsIndexPosition[ 1978, 70] 17 | WindowFrame->Normal*) 18 | 19 | (* Beginning of Notebook Content *) 20 | Notebook[{ 21 | 22 | Cell[CellGroupData[{ 23 | Cell[BoxData[ 24 | RowBox[{"e", " ", "=", 25 | RowBox[{ 26 | RowBox[{"(", 27 | RowBox[{"y", "+", "x", "+", "z", "+", "w"}], ")"}], "^", 28 | "60"}]}]], "Input", 29 | CellChangeTimes->{{3.5853210932731457`*^9, 3.5853211055605173`*^9}, { 30 | 3.5859133063614388`*^9, 3.5859133067826633`*^9}}], 31 | 32 | Cell[BoxData[ 33 | SuperscriptBox[ 34 | RowBox[{"(", 35 | RowBox[{"w", "+", "x", "+", "y", "+", "z"}], ")"}], "60"]], "Output", 36 | CellChangeTimes->{ 37 | 3.585321106954556*^9, 3.585913307610922*^9, 3.5859133919648952`*^9, 38 | 3.586195599079687*^9, {3.586195670443467*^9, 3.586195683547567*^9}}] 39 | }, Open ]], 40 | 41 | Cell[CellGroupData[{ 42 | 43 | Cell[BoxData[ 44 | RowBox[{"Timing", "[", 45 | RowBox[{ 46 | RowBox[{"g", "=", 47 | RowBox[{"Expand", "[", "e", "]"}]}], ";"}], "]"}]], "Input", 48 | CellChangeTimes->{{3.585321121374816*^9, 3.5853211329822598`*^9}}], 49 | 50 | Cell[BoxData[ 51 | RowBox[{"{", 52 | RowBox[{"0.12400699999999998`", ",", "Null"}], "}"}]], "Output", 53 | CellChangeTimes->{ 54 | 3.585321136069125*^9, 3.585913356976121*^9, 3.5859133920725183`*^9, { 55 | 3.586195603864347*^9, 3.586195632768238*^9}, {3.586195670584958*^9, 56 | 3.586195683698516*^9}}] 57 | }, Open ]] 58 | }, 59 | WindowSize->{740, 867}, 60 | WindowMargins->{{118, Automatic}, {Automatic, 0}}, 61 | FrontEndVersion->"8.0 for Linux x86 (64-bit) (February 23, 2011)", 62 | StyleDefinitions->"Default.nb" 63 | ] 64 | (* End of Notebook Content *) 65 | 66 | (* Internal cache information *) 67 | (*CellTagsOutline 68 | CellTagsIndex->{} 69 | *) 70 | (*CellTagsIndex 71 | CellTagsIndex->{} 72 | *) 73 | (*NotebookFileOutline 74 | Notebook[{ 75 | Cell[CellGroupData[{ 76 | Cell[579, 22, 274, 7, 30, "Input"], 77 | Cell[856, 31, 282, 6, 30, "Output"] 78 | }, Open ]], 79 | Cell[CellGroupData[{ 80 | Cell[1175, 42, 204, 5, 30, "Input"], 81 | Cell[1382, 49, 286, 6, 30, "Output"] 82 | }, Open ]] 83 | } 84 | ] 85 | *) 86 | 87 | (* End of internal cache information *) 88 | -------------------------------------------------------------------------------- /benchmarks/expand2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::Add; 14 | using SymEngine::Mul; 15 | using SymEngine::Pow; 16 | using SymEngine::Symbol; 17 | using SymEngine::symbol; 18 | using SymEngine::umap_basic_num; 19 | using SymEngine::Integer; 20 | using SymEngine::integer; 21 | using SymEngine::multinomial_coefficients; 22 | using SymEngine::RCP; 23 | using SymEngine::rcp_dynamic_cast; 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | int N; 28 | if (argc == 2) { 29 | N = std::atoi(argv[1]); 30 | } else { 31 | N = 15; 32 | } 33 | SymEngine::print_stack_on_segfault(); 34 | 35 | RCP x = symbol("x"); 36 | RCP y = symbol("y"); 37 | RCP z = symbol("z"); 38 | RCP w = symbol("w"); 39 | RCP i = integer(N); 40 | 41 | RCP e, f, r; 42 | 43 | e = pow(add(add(add(x, y), z), w), i); 44 | f = mul(e, add(e, w)); 45 | 46 | // std::cout << "Expanding: " << *f << std::endl; 47 | 48 | auto t1 = std::chrono::high_resolution_clock::now(); 49 | r = expand(f); 50 | auto t2 = std::chrono::high_resolution_clock::now(); 51 | // std::cout << *r << std::endl; 52 | std::cout << std::chrono::duration_cast(t2 - t1) 53 | .count() 54 | << "ms" << std::endl; 55 | std::cout << "number of terms: " 56 | << rcp_dynamic_cast(r)->get_dict().size() << std::endl; 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /benchmarks/expand2.m: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/WolframScript -script 2 | 3 | If[Length[$ScriptCommandLine] == 1, n = 15, n = ToExpression[$ScriptCommandLine[[2]]]]; 4 | 5 | e = (x + y + z + w) ^ n 6 | f = e * (e + w) 7 | 8 | Print[AbsoluteTiming[r = Expand[f]][[1]]*1000] 9 | -------------------------------------------------------------------------------- /benchmarks/expand2.mpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash maple 2 | # Use `maple -q expand2.mpl -D n=15` to run 3 | 4 | e := (x + y + z + w) ^ n: 5 | f := e * (e + w): 6 | 7 | st := time[real](): 8 | f := expand(f): 9 | 1000*(time[real]() - st); 10 | 11 | done 12 | -------------------------------------------------------------------------------- /benchmarks/expand2_ginac.cpp: -------------------------------------------------------------------------------- 1 | // ============================================================================ 2 | // 3 | // Author: Dale Lukas Peterson (dlp), hazelnusse@gmail.com 4 | // 5 | // Description: Quick expansion test 6 | // 7 | // ============================================================================ 8 | #include 9 | #include 10 | #include 11 | using namespace GiNaC; 12 | 13 | // In [1]: from sympy_pyx import Symbol 14 | // In [2]: x = Symbol("x") 15 | // In [3]: y = Symbol("y") 16 | // In [4]: z = Symbol("z") 17 | // In [5]: w = Symbol("w") 18 | // In [6]: e = (x+y+z+w)**15 19 | // In [7]: f = e*(e+w) 20 | // In [8]: f 21 | // Out[8]: (y + x + z + w)^15 * ((y + x + z + w)^15 + w) 22 | // 23 | // In [9]: %time g = f.expand() 24 | // CPU times: user 0.22 s, sys: 0.01 s, total: 0.22 s 25 | // Wall time: 0.22 s 26 | int main(int argc, char *argv[]) 27 | { 28 | int N; 29 | if (argc == 2) { 30 | N = std::atoi(argv[1]); 31 | } else { 32 | N = 15; 33 | } 34 | 35 | symbol x("x"), y("y"), z("z"), w("w"); 36 | ex e = pow(x + y + z + w, N); 37 | ex f = e * (e + w); 38 | // std::cout << e << std::endl; 39 | // std::cout << f << std::endl; 40 | 41 | auto t1 = std::chrono::high_resolution_clock::now(); 42 | ex g = f.expand(); 43 | auto t2 = std::chrono::high_resolution_clock::now(); 44 | std::cout << std::chrono::duration_cast(t2 - t1) 45 | .count() 46 | << "ms" << std::endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /benchmarks/expand2b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using SymEngine::Basic; 15 | using SymEngine::Symbol; 16 | using SymEngine::symbol; 17 | using SymEngine::umap_basic_num; 18 | using SymEngine::Integer; 19 | using SymEngine::integer; 20 | using SymEngine::expr2poly; 21 | using SymEngine::poly_mul; 22 | using SymEngine::umap_vec_mpz; 23 | using SymEngine::RCP; 24 | using SymEngine::print_stack_on_segfault; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | print_stack_on_segfault(); 29 | RCP x = symbol("x"); 30 | RCP y = symbol("y"); 31 | RCP z = symbol("z"); 32 | RCP w = symbol("w"); 33 | RCP i15 = integer(15); 34 | 35 | RCP e, f1, f2, r; 36 | 37 | e = pow(add(add(add(x, y), z), w), i15); 38 | f1 = expand(e); 39 | f2 = expand(add(e, w)); 40 | 41 | umap_basic_num syms; 42 | insert(syms, x, integer(0)); 43 | insert(syms, y, integer(1)); 44 | insert(syms, z, integer(2)); 45 | insert(syms, w, integer(3)); 46 | 47 | umap_vec_mpz P1, P2, C; 48 | 49 | expr2poly(f1, syms, P1); 50 | expr2poly(f2, syms, P2); 51 | std::cout << "poly_mul start" << std::endl; 52 | auto t1 = std::chrono::high_resolution_clock::now(); 53 | poly_mul(P1, P2, C); 54 | auto t2 = std::chrono::high_resolution_clock::now(); 55 | std::cout << "poly_mul stop" << std::endl; 56 | 57 | /* 58 | std::cout << *e << std::endl; 59 | std::cout << *f1 << std::endl; 60 | std::cout << P1 << std::endl; 61 | std::cout << *f2 << std::endl; 62 | std::cout << P2 << std::endl; 63 | std::cout << "RESULT:" << std::endl; 64 | std::cout << C << std::endl; 65 | */ 66 | std::cout << std::chrono::duration_cast(t2 - t1) 67 | .count() 68 | << "ms" << std::endl; 69 | std::cout << "number of terms: " << C.size() << std::endl; 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /benchmarks/expand3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::Add; 14 | using SymEngine::Mul; 15 | using SymEngine::Pow; 16 | using SymEngine::Symbol; 17 | using SymEngine::symbol; 18 | using SymEngine::umap_basic_num; 19 | using SymEngine::Integer; 20 | using SymEngine::integer; 21 | using SymEngine::multinomial_coefficients; 22 | using SymEngine::RCP; 23 | using SymEngine::rcp_dynamic_cast; 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | SymEngine::print_stack_on_segfault(); 28 | 29 | RCP x = symbol("x"); 30 | RCP y = symbol("y"); 31 | RCP z = symbol("z"); 32 | RCP w = symbol("w"); 33 | RCP i100 = integer(100); 34 | 35 | RCP e, r; 36 | 37 | e = pow(add(add(pow(x, y), pow(y, x)), pow(z, x)), i100); 38 | 39 | std::cout << "Expanding: " << *e << std::endl; 40 | 41 | auto t1 = std::chrono::high_resolution_clock::now(); 42 | r = expand(e); 43 | auto t2 = std::chrono::high_resolution_clock::now(); 44 | // std::cout << *r << std::endl; 45 | std::cout << std::chrono::duration_cast(t2 - t1) 46 | .count() 47 | << "ms" << std::endl; 48 | std::cout << "number of terms: " 49 | << rcp_dynamic_cast(r)->get_dict().size() << std::endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /benchmarks/expand4.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 8.0' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 157, 7] 13 | NotebookDataLength[ 1394, 58] 14 | NotebookOptionsPosition[ 1089, 42] 15 | NotebookOutlinePosition[ 1427, 57] 16 | CellTagsIndexPosition[ 1384, 54] 17 | WindowFrame->Normal*) 18 | 19 | (* Beginning of Notebook Content *) 20 | Notebook[{ 21 | 22 | Cell[CellGroupData[{ 23 | Cell[BoxData[ 24 | RowBox[{"Timing", "[", 25 | RowBox[{ 26 | RowBox[{"Expand", "[", 27 | RowBox[{"Times", "@@", 28 | RowBox[{"Table", "[", 29 | RowBox[{ 30 | SuperscriptBox[ 31 | RowBox[{"(", 32 | RowBox[{"c", "+", "x"}], ")"}], "3"], ",", 33 | RowBox[{"{", 34 | RowBox[{"c", ",", "350"}], "}"}]}], "]"}]}], "]"}], ";"}], 35 | "]"}]], "Input"], 36 | 37 | Cell[BoxData[ 38 | RowBox[{"{", 39 | RowBox[{"0.9080569999999994`", ",", "Null"}], "}"}]], "Output", 40 | CellChangeTimes->{3.5855951274232607`*^9}] 41 | }, Open ]] 42 | }, 43 | WindowSize->{740, 867}, 44 | WindowMargins->{{142, Automatic}, {Automatic, 24}}, 45 | FrontEndVersion->"8.0 for Linux x86 (64-bit) (February 23, 2011)", 46 | StyleDefinitions->"Default.nb" 47 | ] 48 | (* End of Notebook Content *) 49 | 50 | (* Internal cache information *) 51 | (*CellTagsOutline 52 | CellTagsIndex->{} 53 | *) 54 | (*CellTagsIndex 55 | CellTagsIndex->{} 56 | *) 57 | (*NotebookFileOutline 58 | Notebook[{ 59 | Cell[CellGroupData[{ 60 | Cell[579, 22, 353, 12, 34, "Input"], 61 | Cell[935, 36, 138, 3, 30, "Output"] 62 | }, Open ]] 63 | } 64 | ] 65 | *) 66 | 67 | (* End of internal cache information *) 68 | 69 | -------------------------------------------------------------------------------- /benchmarks/expand6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::RCP; 14 | using SymEngine::symbol; 15 | using SymEngine::zero; 16 | using SymEngine::map_basic_basic; 17 | using SymEngine::sqrt; 18 | using SymEngine::integer; 19 | using SymEngine::expand; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | SymEngine::print_stack_on_segfault(); 24 | int N; 25 | if (argc == 2) { 26 | N = std::atoi(argv[1]); 27 | } else { 28 | N = 100; 29 | } 30 | 31 | RCP e, f, s, a0, a1; 32 | a0 = symbol("a0"); 33 | a1 = symbol("a1"); 34 | e = add(a0, a1); 35 | f = zero; 36 | for (long long i = 2; i < N; i++) { 37 | std::ostringstream o; 38 | o << "a" << i; 39 | s = symbol(o.str()); 40 | e = add(e, s); 41 | f = add(f, s); 42 | } 43 | f = neg(f); 44 | auto t1 = std::chrono::high_resolution_clock::now(); 45 | e = expand(pow(e, integer(2))); 46 | e = e->subs({{a0, f}}); 47 | e = expand(e); 48 | auto t2 = std::chrono::high_resolution_clock::now(); 49 | 50 | std::cout << std::chrono::duration_cast(t2 - t1) 51 | .count() 52 | << "ms" << std::endl; 53 | std::cout << e->__str__() << std::endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /benchmarks/expand6.m: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/WolframScript -script 2 | 3 | If[Length[$ScriptCommandLine] == 1, n = 100, n = ToExpression[$ScriptCommandLine[[2]]]]; 4 | 5 | a0 = Symbol["a0"]; 6 | a1 = Symbol["a1"]; 7 | 8 | e = a0 + a1; 9 | f = 0; 10 | 11 | Do[f = f + Symbol["a" <> ToString[i]], {i, 2, n - 1}]; 12 | Do[e = e + Symbol["a" <> ToString[i]], {i, 2, n - 1}]; 13 | 14 | f = -f; 15 | 16 | g[e, a0, f] := (e = Expand[e ^ 2]; e = e/.a0->f; e = Expand[e]); 17 | 18 | Print[AbsoluteTiming[r = g[e, a0, f]][[1]] * 1000]; 19 | 20 | -------------------------------------------------------------------------------- /benchmarks/expand6.mpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash maple 2 | # Use `maple -q expand6.mpl -D n=100` to run 3 | 4 | e := a0 + a1: 5 | f := 0: 6 | 7 | for i from 2 to (n - 1) 8 | do 9 | f := f + cat(a, convert(i, string)): 10 | e := e + cat(a, convert(i, string)): 11 | end do: 12 | 13 | f := -f: 14 | e := e ^ 2: 15 | 16 | st := time[real](): 17 | e := expand(e): 18 | e := subs(a0 = f, e): 19 | e := expand(e): 20 | 1000*(time[real]()-st); 21 | 22 | print(e); 23 | 24 | done 25 | -------------------------------------------------------------------------------- /benchmarks/expand6_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -std=c++0x -o expand6_ginac -Wl,--no-as-needed `pkg-config --cflags 5 | // --libs ginac` expand6_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | using GiNaC::ex; 14 | using GiNaC::pow; 15 | using GiNaC::add; 16 | using GiNaC::expand; 17 | using GiNaC::exmap; 18 | using GiNaC::symbol; 19 | using GiNaC::sqrt; 20 | using GiNaC::numeric; 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | int N; 25 | if (argc == 2) { 26 | N = std::atoi(argv[1]); 27 | } else { 28 | N = 100; 29 | } 30 | 31 | ex e, f, s, a0, a1; 32 | a0 = symbol("a0"); 33 | a1 = symbol("a1"); 34 | e = a0 + a1; 35 | f = 0; 36 | for (long long i = 2; i < N; i++) { 37 | std::ostringstream o; 38 | o << "a" << i; 39 | s = symbol(o.str()); 40 | e = e + s; 41 | f = f + s; 42 | } 43 | f = -f; 44 | auto t1 = std::chrono::high_resolution_clock::now(); 45 | e = expand(pow(e, 2)); 46 | e = e.subs(a0 == f); 47 | e = expand(e); 48 | auto t2 = std::chrono::high_resolution_clock::now(); 49 | 50 | std::cout << std::chrono::duration_cast(t2 - t1) 51 | .count() 52 | << "ms" << std::endl; 53 | std::cout << e << std::endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /benchmarks/expand6b.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::RCP; 14 | using SymEngine::symbol; 15 | using SymEngine::zero; 16 | using SymEngine::map_basic_basic; 17 | using SymEngine::sqrt; 18 | using SymEngine::integer; 19 | using SymEngine::expand; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | SymEngine::print_stack_on_segfault(); 24 | int N; 25 | if (argc == 2) { 26 | N = std::atoi(argv[1]); 27 | } else { 28 | N = 100; 29 | } 30 | 31 | RCP e, f, s, a0, a1; 32 | a0 = symbol("a0"); 33 | a1 = symbol("a1"); 34 | e = add(a0, a1); 35 | f = zero; 36 | for (long long i = 2; i < N; i++) { 37 | std::ostringstream o; 38 | o << "a" << i; 39 | s = symbol(o.str()); 40 | e = add(e, sin(s)); 41 | f = add(f, sin(s)); 42 | } 43 | f = neg(f); 44 | auto t1 = std::chrono::high_resolution_clock::now(); 45 | e = expand(pow(e, integer(2))); 46 | e = e->subs({{a0, f}}); 47 | e = expand(e); 48 | auto t2 = std::chrono::high_resolution_clock::now(); 49 | 50 | std::cout << std::chrono::duration_cast(t2 - t1) 51 | .count() 52 | << "ms" << std::endl; 53 | std::cout << e->__str__() << std::endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /benchmarks/expand6b.m: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/WolframScript -script 2 | 3 | If[Length[$ScriptCommandLine] == 1, n = 100, n = ToExpression[$ScriptCommandLine[[2]]]]; 4 | 5 | a0 = Symbol["a0"]; 6 | a1 = Symbol["a1"]; 7 | 8 | e = a0 + a1; 9 | f = 0; 10 | 11 | Do[f = f + sin[Symbol["a" <> ToString[i]]], {i, 2, n - 1}]; 12 | Do[e = e + sin[Symbol["a" <> ToString[i]]], {i, 2, n - 1}]; 13 | 14 | f = -f; 15 | 16 | g[e, a0, f] := (e = Expand[e ^ 2]; e = e/.a0->f; e = Expand[e]); 17 | 18 | Print[AbsoluteTiming[r = g[e, a0, f]][[1]] * 1000]; 19 | 20 | -------------------------------------------------------------------------------- /benchmarks/expand6b.mpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash maple 2 | # Use `maple -q expand6.mpl -D n=100` to run 3 | 4 | e := a0 + a1: 5 | f := 0: 6 | 7 | for i from 2 to (n - 1) 8 | do 9 | f := f + sin(cat(a, convert(i, string))): 10 | e := e + sin(cat(a, convert(i, string))): 11 | end do: 12 | 13 | f := -f: 14 | e := e ^ 2: 15 | 16 | st := time[real](): 17 | e := expand(e): 18 | e := subs(a0 = f, e): 19 | e := expand(e): 20 | 1000*(time[real]()-st); 21 | 22 | print(e); 23 | 24 | done 25 | -------------------------------------------------------------------------------- /benchmarks/expand6b_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -std=c++0x -o expand6b_ginac -Wl,--no-as-needed `pkg-config --cflags 5 | // --libs ginac` expand6b_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | using GiNaC::ex; 14 | using GiNaC::pow; 15 | using GiNaC::add; 16 | using GiNaC::expand; 17 | using GiNaC::exmap; 18 | using GiNaC::symbol; 19 | using GiNaC::sqrt; 20 | using GiNaC::numeric; 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | int N; 25 | if (argc == 2) { 26 | N = std::atoi(argv[1]); 27 | } else { 28 | N = 100; 29 | } 30 | 31 | ex e, f, s, a0, a1; 32 | a0 = symbol("a0"); 33 | a1 = symbol("a1"); 34 | e = a0 + a1; 35 | f = 0; 36 | for (long long i = 2; i < N; i++) { 37 | std::ostringstream o; 38 | o << "a" << i; 39 | s = symbol(o.str()); 40 | e = e + sin(s); 41 | f = f + sin(s); 42 | } 43 | f = -f; 44 | auto t1 = std::chrono::high_resolution_clock::now(); 45 | e = expand(pow(e, 2)); 46 | e = e.subs(a0 == f); 47 | e = expand(e); 48 | auto t2 = std::chrono::high_resolution_clock::now(); 49 | 50 | std::cout << std::chrono::duration_cast(t2 - t1) 51 | .count() 52 | << "ms" << std::endl; 53 | std::cout << e << std::endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /benchmarks/expand7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "symengine/constants.h" 11 | 12 | using SymEngine::Basic; 13 | using SymEngine::RCP; 14 | using SymEngine::symbol; 15 | using SymEngine::zero; 16 | using SymEngine::one; 17 | using SymEngine::map_basic_basic; 18 | using SymEngine::sqrt; 19 | using SymEngine::integer; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | SymEngine::print_stack_on_segfault(); 24 | int N; 25 | if (argc == 2) { 26 | N = std::atoi(argv[1]); 27 | } else { 28 | N = 20; 29 | } 30 | 31 | RCP x = symbol("x"), y = symbol("y"), e, f; 32 | e = pow(add(one, add(mul(sqrt(integer(3)), x), mul(sqrt(integer(5)), y))), 33 | integer(N)); 34 | f = mul(e, add(e, sqrt(integer(7)))); 35 | auto t1 = std::chrono::high_resolution_clock::now(); 36 | f = expand(f); 37 | auto t2 = std::chrono::high_resolution_clock::now(); 38 | 39 | std::cout << std::chrono::duration_cast(t2 - t1) 40 | .count() 41 | << "ms" << std::endl; 42 | // std::cout << f->__str__() << std::endl; 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /benchmarks/expand7.m: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/WolframScript -script 2 | 3 | If[Length[$ScriptCommandLine] == 1, n = 20, n = ToExpression[$ScriptCommandLine[[2]]]]; 4 | 5 | e = (1 + Sqrt[3] * x + Sqrt[5] * y) ^ n; 6 | f = e * (e + Sqrt[7]) 7 | 8 | Print[AbsoluteTiming[r = Expand[f]][[1]] * 1000] 9 | 10 | -------------------------------------------------------------------------------- /benchmarks/expand7.mpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash maple 2 | # Use `maple -q expand7.mpl -D n=20` to run 3 | 4 | e := (1 + sqrt(3) * x + sqrt(5) * y) ^ n: 5 | f := e * (e + sqrt(7)): 6 | 7 | st := time[real](): 8 | f := expand(f): 9 | 1000*(time[real]() - st); 10 | 11 | done 12 | -------------------------------------------------------------------------------- /benchmarks/expand7_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -std=c++0x -o expand6_ginac -Wl,--no-as-needed `pkg-config --cflags 5 | // --libs ginac` expand6_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | using GiNaC::ex; 13 | using GiNaC::pow; 14 | using GiNaC::add; 15 | using GiNaC::expand; 16 | using GiNaC::exmap; 17 | using GiNaC::symbol; 18 | using GiNaC::sqrt; 19 | using GiNaC::numeric; 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | int N; 24 | if (argc == 2) { 25 | N = std::atoi(argv[1]); 26 | } else { 27 | N = 20; 28 | } 29 | 30 | ex e, f, x, y; 31 | x = symbol("x"); 32 | y = symbol("y"); 33 | e = pow((1 + sqrt(ex(3)) * x + sqrt(ex(5)) * y), N); 34 | f = e * (e + sqrt(ex(7))); 35 | 36 | auto t1 = std::chrono::high_resolution_clock::now(); 37 | f = expand(f); 38 | auto t2 = std::chrono::high_resolution_clock::now(); 39 | 40 | std::cout << std::chrono::duration_cast(t2 - t1) 41 | .count() 42 | << "ms" << std::endl; 43 | // std::cout << f << std::endl; 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /benchmarks/matrix_add1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using SymEngine::Basic; 9 | using SymEngine::Integer; 10 | using SymEngine::RCP; 11 | using SymEngine::integer; 12 | using SymEngine::DenseMatrix; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | SymEngine::print_stack_on_segfault(); 17 | 18 | DenseMatrix A = DenseMatrix( 19 | 4, 4, 20 | {integer(1), integer(2), integer(3), integer(4), integer(5), integer(6), 21 | integer(7), integer(8), integer(9), integer(10), integer(11), 22 | integer(12), integer(13), integer(14), integer(15), integer(16)}); 23 | 24 | DenseMatrix B = DenseMatrix( 25 | 4, 4, 26 | {integer(1), integer(2), integer(3), integer(4), integer(5), integer(6), 27 | integer(7), integer(8), integer(9), integer(10), integer(11), 28 | integer(12), integer(13), integer(14), integer(15), integer(16)}); 29 | 30 | DenseMatrix C(4, 4); 31 | 32 | std::cout << "Adding Two Matrices; matrix dimensions: 4 x 4" << std::endl; 33 | 34 | // We are taking an average time since time for a single addition varied in 35 | // a range of 40-50 microseconds 36 | unsigned N = 10000; 37 | auto t1 = std::chrono::high_resolution_clock::now(); 38 | for (unsigned i = 0; i < N; i++) 39 | add_dense_dense(A, B, C); 40 | auto t2 = std::chrono::high_resolution_clock::now(); 41 | 42 | std::cout << std::chrono::duration_cast(t2 - t1) 43 | .count() 44 | / N 45 | << " microseconds" << std::endl; 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /benchmarks/matrix_add1_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -o matrix_add1_ginac -Wl,--no-as-needed `pkg-config --cflags --libs 5 | // ginac` matrix_add1_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace GiNaC; 14 | 15 | int main() 16 | { 17 | matrix A(4, 4), B(4, 4), C(4, 4); 18 | 19 | A = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16; 20 | 21 | B = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16; 22 | 23 | unsigned N = 10000; 24 | 25 | auto t1 = std::chrono::high_resolution_clock::now(); 26 | for (unsigned i = 0; i < N; i++) 27 | C = A.add(B); 28 | ; 29 | auto t2 = std::chrono::high_resolution_clock::now(); 30 | 31 | std::cout << std::chrono::duration_cast(t2 - t1) 32 | .count() 33 | / N 34 | << " microseconds" << std::endl; 35 | } 36 | -------------------------------------------------------------------------------- /benchmarks/matrix_add2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using SymEngine::Basic; 9 | using SymEngine::RCP; 10 | using SymEngine::DenseMatrix; 11 | using SymEngine::symbol; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | SymEngine::print_stack_on_segfault(); 16 | 17 | DenseMatrix A = DenseMatrix(3, 3, {symbol("a"), symbol("b"), symbol("c"), 18 | symbol("d"), symbol("e"), symbol("f"), 19 | symbol("g"), symbol("h"), symbol("i")}); 20 | 21 | DenseMatrix B = DenseMatrix(3, 3, {symbol("x"), symbol("y"), symbol("z"), 22 | symbol("p"), symbol("q"), symbol("r"), 23 | symbol("u"), symbol("v"), symbol("w")}); 24 | 25 | DenseMatrix C(3, 3); 26 | 27 | std::cout << "Adding Two Matrices; matrix dimensions: 3 x 3" << std::endl; 28 | 29 | // We are taking an average time since time for a single addition varied in 30 | // a range of 40-50 microseconds 31 | unsigned N = 10000; 32 | auto t1 = std::chrono::high_resolution_clock::now(); 33 | for (unsigned i = 0; i < N; i++) 34 | add_dense_dense(A, B, C); 35 | auto t2 = std::chrono::high_resolution_clock::now(); 36 | 37 | std::cout << std::chrono::duration_cast(t2 - t1) 38 | .count() 39 | / N 40 | << " microseconds" << std::endl; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /benchmarks/matrix_add2_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -o matrix_add2_ginac -Wl,--no-as-needed `pkg-config --cflags --libs 5 | // ginac` matrix_add2_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace GiNaC; 14 | 15 | int main() 16 | { 17 | matrix A(3, 3), B(3, 3), C(3, 3); 18 | 19 | A = symbol("a"), symbol("b"), symbol("c"), symbol("d"), symbol("e"), 20 | symbol("f"), symbol("g"), symbol("h"), symbol("i"); 21 | 22 | B = symbol("x"), symbol("y"), symbol("z"), symbol("p"), symbol("q"), 23 | symbol("r"), symbol("u"), symbol("v"), symbol("w"); 24 | 25 | unsigned N = 10000; 26 | 27 | auto t1 = std::chrono::high_resolution_clock::now(); 28 | for (unsigned i = 0; i < N; i++) 29 | C = A.add(B); 30 | ; 31 | auto t2 = std::chrono::high_resolution_clock::now(); 32 | 33 | std::cout << std::chrono::duration_cast(t2 - t1) 34 | .count() 35 | / N 36 | << " microseconds" << std::endl; 37 | } 38 | -------------------------------------------------------------------------------- /benchmarks/matrix_mul1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using SymEngine::Basic; 9 | using SymEngine::Integer; 10 | using SymEngine::RCP; 11 | using SymEngine::integer; 12 | using SymEngine::DenseMatrix; 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | SymEngine::print_stack_on_segfault(); 17 | 18 | DenseMatrix A = DenseMatrix( 19 | 4, 4, {integer(-23), integer(67), integer(3), integer(4), integer(54), 20 | integer(61), integer(7), integer(8), integer(32), integer(15), 21 | integer(12), integer(13), integer(100), integer(17), integer(15), 22 | integer(178)}); 23 | 24 | DenseMatrix B 25 | = DenseMatrix(4, 4, {integer(12), integer(22), integer(30), integer(40), 26 | integer(45), integer(6), integer(37), integer(80), 27 | integer(91), integer(10), integer(16), integer(52), 28 | integer(45), integer(14), integer(2), integer(6)}); 29 | 30 | DenseMatrix C(4, 4); 31 | 32 | std::cout << "Multiplying Two Matrices; matrix dimensions: 4 x 4" 33 | << std::endl; 34 | 35 | unsigned N = 10000; 36 | auto t1 = std::chrono::high_resolution_clock::now(); 37 | for (unsigned i = 0; i < N; i++) 38 | mul_dense_dense(A, B, C); 39 | auto t2 = std::chrono::high_resolution_clock::now(); 40 | 41 | std::cout << std::chrono::duration_cast(t2 - t1) 42 | .count() 43 | / N 44 | << " microseconds" << std::endl; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /benchmarks/matrix_mul1_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -o matrix_mul1_ginac -Wl,--no-as-needed `pkg-config --cflags --libs 5 | // ginac` matrix_mul1_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace GiNaC; 14 | 15 | int main() 16 | { 17 | matrix A(4, 4), B(4, 4), C(4, 4); 18 | 19 | A = -23, 67, 3, 4, 54, 61, 7, 8, 32, 15, 12, 13, 100, 17, 15, 178; 20 | 21 | B = 12, 22, 30, 40, 45, 6, 37, 80, 91, 10, 16, 52, 45, 14, 2, 6; 22 | 23 | unsigned N = 10000; 24 | 25 | auto t1 = std::chrono::high_resolution_clock::now(); 26 | for (unsigned i = 0; i < N; i++) 27 | C = A.mul(B); 28 | ; 29 | auto t2 = std::chrono::high_resolution_clock::now(); 30 | 31 | std::cout << std::chrono::duration_cast(t2 - t1) 32 | .count() 33 | / N 34 | << " microseconds" << std::endl; 35 | } 36 | -------------------------------------------------------------------------------- /benchmarks/matrix_mul2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using SymEngine::Basic; 9 | using SymEngine::RCP; 10 | using SymEngine::DenseMatrix; 11 | using SymEngine::symbol; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | SymEngine::print_stack_on_segfault(); 16 | 17 | DenseMatrix A = DenseMatrix(3, 3, {symbol("a"), symbol("b"), symbol("c"), 18 | symbol("d"), symbol("e"), symbol("f"), 19 | symbol("g"), symbol("h"), symbol("i")}); 20 | 21 | DenseMatrix B = DenseMatrix(3, 3, {symbol("x"), symbol("y"), symbol("z"), 22 | symbol("p"), symbol("q"), symbol("r"), 23 | symbol("u"), symbol("v"), symbol("w")}); 24 | 25 | DenseMatrix C(3, 3); 26 | 27 | std::cout << "Multiplying Two Matrices; matrix dimensions: 3 x 3" 28 | << std::endl; 29 | 30 | unsigned N = 10000; 31 | auto t1 = std::chrono::high_resolution_clock::now(); 32 | for (unsigned i = 0; i < N; i++) 33 | mul_dense_dense(A, B, C); 34 | auto t2 = std::chrono::high_resolution_clock::now(); 35 | 36 | std::cout << std::chrono::duration_cast(t2 - t1) 37 | .count() 38 | / N 39 | << " microseconds" << std::endl; 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /benchmarks/matrix_mul2_ginac.cpp: -------------------------------------------------------------------------------- 1 | // To compile on a debian system you need to install libginac-dev first 2 | // $ sudo apt-get install libginac-dev 3 | // Then compile with the following command, 4 | // $ g++ -o matrix_mul2_ginac -Wl,--no-as-needed `pkg-config --cflags --libs 5 | // ginac` matrix_mul2_ginac.cpp 6 | // See this SO answer: http://stackoverflow.com/a/18696743/1895353 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace GiNaC; 14 | 15 | int main() 16 | { 17 | matrix A(3, 3), B(3, 3), C(3, 3); 18 | 19 | A = symbol("a"), symbol("b"), symbol("c"), symbol("d"), symbol("e"), 20 | symbol("f"), symbol("g"), symbol("h"), symbol("i"); 21 | 22 | B = symbol("x"), symbol("y"), symbol("z"), symbol("p"), symbol("q"), 23 | symbol("r"), symbol("u"), symbol("v"), symbol("w"); 24 | 25 | unsigned N = 10000; 26 | 27 | auto t1 = std::chrono::high_resolution_clock::now(); 28 | for (unsigned i = 0; i < N; i++) 29 | C = A.mul(B); 30 | ; 31 | auto t2 = std::chrono::high_resolution_clock::now(); 32 | 33 | std::cout << std::chrono::duration_cast(t2 - t1) 34 | .count() 35 | / N 36 | << " microseconds" << std::endl; 37 | } 38 | -------------------------------------------------------------------------------- /benchmarks/series.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using SymEngine::Basic; 7 | using SymEngine::Symbol; 8 | using SymEngine::UnivariateSeries; 9 | using SymEngine::symbol; 10 | using SymEngine::integer; 11 | using SymEngine::integer_class; 12 | using SymEngine::RCP; 13 | using SymEngine::rcp_dynamic_cast; 14 | using SymEngine::Expression; 15 | using SymEngine::UExprPoly; 16 | using SymEngine::UExprDict; 17 | using SymEngine::map_int_Expr; 18 | using SymEngine::pow; 19 | 20 | int main(int argc, char *argv[]) 21 | { 22 | SymEngine::print_stack_on_segfault(); 23 | 24 | RCP x = symbol("x"); 25 | std::vector v; 26 | int N; 27 | 28 | N = 1000; 29 | for (int i = 0; i < N; ++i) { 30 | Expression coef(i); 31 | v.push_back(coef); 32 | } 33 | 34 | UExprDict c, p(UExprPoly::from_vec(x, v)->get_dict()); 35 | auto t1 = std::chrono::high_resolution_clock::now(); 36 | c = UnivariateSeries::mul(p, p, 1000); 37 | auto t2 = std::chrono::high_resolution_clock::now(); 38 | // std::cout << *a << std::endl; 39 | std::cout << std::chrono::duration_cast(t2 - t1) 40 | .count() 41 | << "ms" << std::endl; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /benchmarks/series_expansion_sincos_flint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using SymEngine::Basic; 14 | using SymEngine::Symbol; 15 | using SymEngine::symbol; 16 | using SymEngine::integer; 17 | using SymEngine::add; 18 | using SymEngine::mul; 19 | using SymEngine::pow; 20 | using SymEngine::sin; 21 | using SymEngine::cos; 22 | using SymEngine::RCP; 23 | using SymEngine::series; 24 | using SymEngine::rcp_dynamic_cast; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | SymEngine::print_stack_on_segfault(); 29 | 30 | RCP x = symbol("x"); 31 | int N = 1000; 32 | auto arg = add(x, pow(x, integer(2))); 33 | auto ex = mul(sin(arg), cos(arg)); 34 | 35 | auto t1 = std::chrono::high_resolution_clock::now(); 36 | auto res = SymEngine::URatPSeriesFlint::series(ex, "x", N); 37 | auto t2 = std::chrono::high_resolution_clock::now(); 38 | // std::cout << *res[N-1] << std::endl; 39 | std::cout << std::chrono::duration_cast(t2 - t1) 40 | .count() 41 | << "ms" << std::endl; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /benchmarks/series_expansion_sincos_piranha.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using SymEngine::Basic; 14 | using SymEngine::Symbol; 15 | using SymEngine::symbol; 16 | using SymEngine::integer; 17 | using SymEngine::add; 18 | using SymEngine::mul; 19 | using SymEngine::pow; 20 | using SymEngine::sin; 21 | using SymEngine::cos; 22 | using SymEngine::RCP; 23 | using SymEngine::series; 24 | using SymEngine::rcp_dynamic_cast; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | SymEngine::print_stack_on_segfault(); 29 | 30 | RCP x = symbol("x"); 31 | int N = 200; 32 | auto arg = add(x, pow(x, integer(2))); 33 | auto ex = mul(sin(arg), cos(arg)); 34 | 35 | auto t1 = std::chrono::high_resolution_clock::now(); 36 | auto res = SymEngine::URatPSeriesPiranha::series(ex, "x", N); 37 | auto t2 = std::chrono::high_resolution_clock::now(); 38 | // std::cout << *res[N-1] << std::endl; 39 | std::cout << std::chrono::duration_cast(t2 - t1) 40 | .count() 41 | << "ms" << std::endl; 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /benchmarks/series_expansion_sinp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef HAVE_SYMENGINE_PIRANHA 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using SymEngine::UPSeriesPiranha; 15 | using SymEngine::Basic; 16 | using SymEngine::Symbol; 17 | using SymEngine::symbol; 18 | using SymEngine::mul; 19 | using SymEngine::sin; 20 | using SymEngine::cos; 21 | using SymEngine::RCP; 22 | using SymEngine::series; 23 | using SymEngine::rcp_dynamic_cast; 24 | using SymEngine::integer; 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | SymEngine::print_stack_on_segfault(); 29 | 30 | RCP x = symbol("x"); 31 | int N = 100; 32 | auto ex = sin(cos(add(x, integer(1)))); 33 | 34 | auto t1 = std::chrono::high_resolution_clock::now(); 35 | auto ex1 = UPSeriesPiranha::series(ex, "x", N); 36 | auto t2 = std::chrono::high_resolution_clock::now(); 37 | // std::cout << *res[N-1] << std::endl; 38 | std::cout << std::chrono::duration_cast(t2 - t1) 39 | .count() 40 | << "ms" << std::endl; 41 | 42 | return 0; 43 | } 44 | #else 45 | 46 | int main(int, char *[]) 47 | { 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /benchmarks/symbench.m: -------------------------------------------------------------------------------- 1 | R1:=( 2 | Clear[f]; 3 | Module[{f}, 4 | f[z_]:=Sqrt[1/3]*z**2+I/3; 5 | AbsoluteTiming[f[f[f[f[f[f[f[f[f[f[I/2]]]]]]]]]]][[1]] 6 | ] 7 | ) 8 | 9 | 10 | R2:=( 11 | Clear[y]; 12 | Module[{hermite}, 13 | hermite[n_,y_]:=If[ n==1, 2*y,If[n==0,1,Expand[2*y*hermite[n-1,y]-2*(n-1)*hermite[n-2,y]]]]; 14 | AbsoluteTiming[hermite[15,y]][[1]] 15 | ] 16 | ) 17 | 18 | 19 | R3:=( 20 | Module[ 21 | {x,y,z,f}, 22 | f=x+y+z; 23 | AbsoluteTiming[Table[f==f,{i,10}]][[1]] 24 | ] 25 | ) 26 | 27 | 28 | R5:=( 29 | Clear[x,y,z,L]; 30 | Module[{L,x,y,z}, 31 | L={x,y,z}; 32 | Do[AppendTo[L, (L[[i]]+L[[i+1]])*L[[i+2]]], {i, 8}]; 33 | AbsoluteTiming[Union[L]][[1]] 34 | ] 35 | ) 36 | 37 | R7:=( 38 | Clear[x,f]; 39 | Module[{f,x}, 40 | f=x^24+34*x^12+45*x^3+9*x^18+34*x^10+32*x^21; 41 | AbsoluteTiming[Table[f/.x->0.5,{i,10^4}]][[1]] 42 | ] 43 | ) 44 | 45 | R8:=( 46 | Clear[x]; 47 | Module[{right, c, est, x, Deltax}, 48 | right[f_,a_,b_,n_]:=(Deltax=(b-a)/n;c = a; 49 | est = 0; 50 | Do[c+= Deltax; est += f/.x->c, {i,n}]est*Deltax); 51 | AbsoluteTiming[right[x^2,0,5,10^4]][[1]] 52 | ] 53 | ) 54 | 55 | S1:=( 56 | Clear[x,y,z,f]; 57 | Module[{e,x,y,z}, 58 | e=(x+y+z+1)^7; 59 | f=e*(e+1); 60 | AbsoluteTiming[Expand[f]][[1]] 61 | ] 62 | ) 63 | 64 | S2:=( 65 | Clear[x,y,z,e]; 66 | Module[{x,y,z,e}, 67 | e=(x^Sin[x]+y^Cos[y]+z^(x+y))^100; 68 | AbsoluteTiming[Expand[e]][[1]] 69 | ] 70 | ) 71 | 72 | S3:=( 73 | Clear[x,y,z,e]; 74 | Module[{x,y,z,e}, 75 | e=(x^y+y^z+z^x)^50; 76 | e = Expand[e]; 77 | AbsoluteTiming[D[e,x]][[1]] 78 | ] 79 | ) 80 | 81 | S3a:=( 82 | Clear[x,y,z,e]; 83 | Module[{x,y,z,e}, 84 | e=(x^y+y^z+z^x)^500; 85 | e = Expand[e]; 86 | AbsoluteTiming[D[e,x]][[1]] 87 | ] 88 | ) 89 | 90 | Print["Time for R1 : \t\t", R1] 91 | Print["Time for R2 : \t\t", R2] 92 | Print["Time for R3 : \t\t", R3] 93 | Print["Time for R5 : \t\t", R5] 94 | Print["Time for R7 : \t\t", R7] 95 | Print["Time for R8 : \t\t", R8] 96 | Print["Time for S1 : \t\t", S1] 97 | Print["Time for S2 : \t\t", S2] 98 | Print["Time for S3 : \t\t", S3] 99 | Print["Time for S3a : \t\t", S3a] -------------------------------------------------------------------------------- /benchmarks/symengine_bench.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This benchmark is used for benchmarking the speed of symbolics and not 3 | for benchmarking series expansion. 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | using SymEngine::Basic; 18 | using SymEngine::Symbol; 19 | using SymEngine::symbol; 20 | using SymEngine::integer; 21 | using SymEngine::add; 22 | using SymEngine::mul; 23 | using SymEngine::pow; 24 | using SymEngine::sin; 25 | using SymEngine::cos; 26 | using SymEngine::RCP; 27 | using SymEngine::series; 28 | using SymEngine::rcp_dynamic_cast; 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | SymEngine::print_stack_on_segfault(); 33 | 34 | RCP x = symbol("x"); 35 | int N; 36 | if (argc == 2) { 37 | N = std::atoi(argv[1]); 38 | } else { 39 | N = 15; 40 | } 41 | auto arg = x; 42 | auto ex = sin(cos(add(integer(1), x))); 43 | 44 | auto t1 = std::chrono::high_resolution_clock::now(); 45 | auto res = SymEngine::UnivariateSeries::series(ex, "x", N); 46 | auto t2 = std::chrono::high_resolution_clock::now(); 47 | std::cout << std::chrono::duration_cast(t2 - t1) 48 | .count() 49 | << "ms" << std::endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /benchmarks/symengine_bench.m: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/WolframScript -script 2 | 3 | If[Length[$ScriptCommandLine] == 1, n = 15, n = ToExpression[$ScriptCommandLine[[2]]]]; 4 | 5 | e = Sin[Cos[x+1]]; 6 | Print[AbsoluteTiming[Series[e, {x, 0, n}];][[1]] * 1000]; 7 | 8 | -------------------------------------------------------------------------------- /benchmarks/symengine_bench.mpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash maple 2 | # Use `maple -q symengine_bench.mpl -D n=15` to run 3 | 4 | e := sin(cos(x+1)): 5 | st := time[real](): 6 | f := series(e, x=0,n): 7 | 1000*(time[real]()-st); 8 | 9 | done 10 | -------------------------------------------------------------------------------- /benchmarks/symengine_bench_ginac.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace GiNaC; 5 | 6 | int main(int argc, char *argv[]) 7 | { 8 | int N; 9 | if (argc == 2) { 10 | N = std::atoi(argv[1]); 11 | } else { 12 | N = 15; 13 | } 14 | 15 | symbol x("x"); 16 | ex e = sin(cos(x + 1)); 17 | 18 | auto t1 = std::chrono::high_resolution_clock::now(); 19 | ex g = e.series(x == 0, N); 20 | auto t2 = std::chrono::high_resolution_clock::now(); 21 | std::cout << std::chrono::duration_cast(t2 - t1) 22 | .count() 23 | << "ms" << std::endl; 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /bin/appveyor-download.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem initiate the retry number 3 | set retryNumber=0 4 | set maxRetries=6 5 | set time=0 6 | 7 | :DOWNLOAD 8 | timeout %time% > NUL 9 | set /a time=2*%time%+1 10 | appveyor DownloadFile %* 11 | 12 | rem problem? 13 | IF NOT ERRORLEVEL 1 GOTO :EOF 14 | @echo Oops, appveyor download exited with code %ERRORLEVEL% - let us try again! 15 | set /a retryNumber=%retryNumber%+1 16 | IF %reTryNumber% LSS %maxRetries% (GOTO :DOWNLOAD) 17 | @echo Sorry, we tried downloading the package for %maxRetries% times and all attempts were unsuccessful! 18 | EXIT /B 1 19 | -------------------------------------------------------------------------------- /bin/release_authors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Prints the list of authors who contributed to a given release. 4 | # You can copy & paste the result into a Markdown document. 5 | # 6 | # To obtain the list of authors who contributed to the v0.3.0 release: 7 | # 8 | # bin/release_authors.sh v0.2.0 v0.3.0 9 | # 10 | # To obtain the list of authors who contributed to upcoming (not yet tagged) 11 | # v0.4.0 release: 12 | # 13 | # bin/release_authors.sh v0.3.0 master 14 | 15 | set -e 16 | 17 | echo "People who contributed to the release:" 18 | git log --reverse --format="* %aN " $1..$2 | awk ' !x[$0]++' 19 | -------------------------------------------------------------------------------- /bin/test_cling_notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export NB_PYTHON_PREFIX=$CONDA_PREFIX 4 | binder/postBuild 5 | jupyter nbconvert --execute --to notebook notebooks/symengine.ipynb 6 | -------------------------------------------------------------------------------- /bin/test_format_local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NAME=`basename "$0"` 4 | 5 | if [ ! -f ".clang-format" ]; then 6 | echo ".clang-format file not found!" 7 | exit 1 8 | fi 9 | 10 | CLANG_FORMAT="clang-format" 11 | 12 | which "clang-format-3.9" > /dev/null && CLANG_FORMAT="clang-format-3.9" 13 | which "clang-format-3.8" > /dev/null && CLANG_FORMAT="clang-format-3.8" 14 | 15 | FILES=`git ls-files | grep -E "\.(cpp|h|hpp|c)$" | grep -Ev "symengine/utilities" | grep -Ev "cmake/"` 16 | 17 | for FILE in $FILES; do 18 | if [ "$NAME" != "pre-commit" ]; then 19 | # if this is not a pre-commit hook format code inplace 20 | $CLANG_FORMAT -i $FILE 21 | else 22 | staged_file=`git show :$FILE` 23 | formatted_file=`cat << EOF | $CLANG_FORMAT 24 | $staged_file 25 | EOF` 26 | if [ "$staged_file" != "$formatted_file" ]; then 27 | actual_file=`cat $FILE` 28 | if [ "$actual_file" != "$staged_file" ]; then 29 | echo "WARNING: $FILE is not formatted properly. Cannot fix formatting as there are unstaged changes" 30 | else 31 | echo "Fixing formatting of $FILE automatically" 32 | $CLANG_FORMAT -i $FILE 33 | git add $FILE 34 | fi 35 | fi 36 | fi 37 | done 38 | 39 | -------------------------------------------------------------------------------- /bin/test_make_install.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | from os.path import join, relpath 3 | import sys 4 | from glob import glob 5 | 6 | # First argument is where symengine header files are installed. 7 | install_dir = sys.argv[1] 8 | 9 | # Second argument is Folder containing symengine header files. 10 | symengine_dir = sys.argv[2] 11 | 12 | installed_files = set([relpath(x, install_dir) for x in glob(join(install_dir, '*.h'))]) 13 | all_files = set([relpath(x, symengine_dir) for x in glob(join(symengine_dir, '*.h'))]) 14 | 15 | difference = all_files - installed_files 16 | 17 | if len(difference) == 0: 18 | print('All files are installed!') 19 | exit(0) 20 | else: 21 | for fl in difference: 22 | print('%s is not installed!' % fl) 23 | exit(1) 24 | -------------------------------------------------------------------------------- /bin/test_matchpycpp_gen_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd symengine/utilities/matchpycpp 6 | python generate_tests.py 7 | cd ../../.. 8 | git diff --exit-code 9 | -------------------------------------------------------------------------------- /bin/travis_clang_format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Entering $(basename $0)" 4 | echo "TEST_CLANG_FORMAT=${TEST_CLANG_FORMAT}" 5 | 6 | if [[ "${TEST_CLANG_FORMAT}" == "yes" ]]; then 7 | 8 | RETURN=0 9 | CLANG_FORMAT="clang-format-3.8" 10 | 11 | if [ ! -f ".clang-format" ]; then 12 | echo ".clang-format file not found!" 13 | exit 1 14 | fi 15 | 16 | FILES=`git ls-files | grep -E "\.(cpp|h|hpp|c)$" | grep -Ev "symengine/utilities" | grep -Ev "cmake/"` 17 | 18 | for FILE in $FILES; do 19 | echo "Processing: $FILE" 20 | 21 | $CLANG_FORMAT $FILE | cmp $FILE >/dev/null 22 | 23 | if [ $? -ne 0 ]; then 24 | echo "[!] INCORRECT FORMATTING! $FILE" >&2 25 | $CLANG_FORMAT -i $FILE 26 | RETURN=1 27 | fi 28 | 29 | done 30 | 31 | if [ $RETURN -ne 0 ]; then 32 | RED='\033[0;31m' 33 | echo -e "\\n${RED}FORMATTING TEST FAILED\\n" 34 | echo "Apply the following diff for correct formatting" 35 | echo "###########################################################################" 36 | git diff | cat 37 | echo "###########################################################################" 38 | else 39 | GREEN='\033[0;32m' 40 | echo -e "\\n${GREEN}FORMATTING TEST PASSED\\n" 41 | fi 42 | exit $RETURN 43 | fi 44 | 45 | exit 0 46 | -------------------------------------------------------------------------------- /bin/trigger_feedstock.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | if [[ "${TRIGGER_FEEDSTOCK}" != "yes" ]]; then 6 | exit 0; 7 | fi 8 | if [[ "${TRAVIS_PULL_REQUEST}" != "false" ]]; then 9 | echo "Testing a pull request, feedstock is not triggered."; 10 | exit 0; 11 | fi 12 | if [[ "${GH_TOKEN}" == "" ]]; then 13 | echo "Testing a fork, feedstock is not triggered."; 14 | exit 0; 15 | fi 16 | 17 | 18 | cd $SOURCE_DIR; 19 | export ver=`git describe --tags` 20 | if [[ $ver == "v"* ]] 21 | then 22 | ver=${ver:1}; 23 | fi 24 | 25 | export commit=`git rev-parse HEAD` 26 | 27 | git config --global user.name "Isuru Fernando" 28 | git config --global user.email "isuruf@gmail.com" 29 | 30 | set +x 31 | git clone "https://${GH_TOKEN}@github.com/symengine/symengine-feedstock.git" feedstock -q 32 | set -x 33 | 34 | cd feedstock 35 | if [[ "${TRAVIS_TAG}" != "" ]]; then 36 | git checkout tagged 37 | else 38 | echo "Testing merge. Not triggering feedstock" 39 | exit 0 40 | # git checkout dev 41 | fi 42 | 43 | sed -ie '1,2d' recipe/meta.yaml 44 | sed -i '1s/^/{% set version = "'${ver}'" %}\n/' recipe/meta.yaml 45 | sed -i '1s/^/{% set commit = "'${commit}'" %}\n/' recipe/meta.yaml 46 | git add recipe/meta.yaml 47 | git commit -m "Update symengine version to ${ver}" 48 | git push -q 49 | 50 | -------------------------------------------------------------------------------- /bin/update_authors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | tmpfile=$(mktemp) 6 | 7 | head -n 5 AUTHORS > $tmpfile 8 | git log --reverse --topo-order --format="%aN <%aE>" | awk ' !x[$0]++' >> $tmpfile 9 | mv $tmpfile AUTHORS 10 | -------------------------------------------------------------------------------- /binder/environment.yml: -------------------------------------------------------------------------------- 1 | name: symengine 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - xeus-cling=0.4.11 6 | - llvmdev=5 7 | - gmp 8 | - mpfr 9 | - mpc 10 | - cmake 11 | - arb 12 | - libflint 13 | - notebook 14 | -------------------------------------------------------------------------------- /binder/postBuild: -------------------------------------------------------------------------------- 1 | set -e 2 | mkdir build 3 | cd build 4 | export LDFLAGS="-Wl,-rpath,${NB_PYTHON_PREFIX}/lib -L${NB_PYTHON_PREFIX}/lib" 5 | cmake -DWITH_COTIRE=no -DBUILD_SHARED_LIBS=yes -DWITH_MPC=yes -DWITH_ARB=yes -DINTEGER_CLASS=flint -DWITH_LLVM=yes -DCMAKE_PREFIX_PATH=${NB_PYTHON_PREFIX} -DCMAKE_INSTALL_PREFIX=${NB_PYTHON_PREFIX} -DBUILD_TESTS=off -DBUILD_BENCHMARKS=off -DCMAKE_INSTALL_LIBDIR=lib .. 6 | make -j4 7 | make install 8 | cd .. 9 | rm -rf build 10 | -------------------------------------------------------------------------------- /cmake/FindARB.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(arb.h arb) 4 | libfind_library(arb arb) 5 | 6 | set(ARB_LIBRARIES ${ARB_LIBRARY}) 7 | set(ARB_INCLUDE_DIRS ${ARB_INCLUDE_DIR}) 8 | set(ARB_TARGETS arb) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(ARB DEFAULT_MSG ARB_LIBRARIES 12 | ARB_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(ARB_INCLUDE_DIR ARB_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindBFD.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(bfd.h bfd) 4 | libfind_library(bfd bfd) 5 | libfind_library(iberty iberty) 6 | libfind_library(z z) 7 | libfind_library(dl dl) 8 | 9 | set(BFD_INCLUDE_DIRS ${BFD_INCLUDE_DIR}) 10 | set(BFD_LIBRARIES ${BFD_LIBRARY}) 11 | set(BFD_TARGETS bfd) 12 | if (IBERTY_LIBRARY) 13 | set(BFD_LIBRARIES ${BFD_LIBRARIES} ${IBERTY_LIBRARY}) 14 | set(BFD_TARGETS ${BFD_TARGETS} iberty) 15 | endif(IBERTY_LIBRARY) 16 | if (Z_LIBRARY) 17 | set(BFD_LIBRARIES ${BFD_LIBRARIES} ${Z_LIBRARY}) 18 | set(BFD_TARGETS ${BFD_TARGETS} z) 19 | endif(Z_LIBRARY) 20 | if (DL_LIBRARY) 21 | set(BFD_LIBRARIES ${BFD_LIBRARIES} ${DL_LIBRARY}) 22 | set(BFD_TARGETS ${BFD_TARGETS} dl) 23 | endif(DL_LIBRARY) 24 | 25 | include(FindPackageHandleStandardArgs) 26 | find_package_handle_standard_args(BFD DEFAULT_MSG 27 | BFD_LIBRARIES BFD_INCLUDE_DIRS) 28 | 29 | mark_as_advanced(BFD_INCLUDE_DIR BFD_LIBRARY) 30 | -------------------------------------------------------------------------------- /cmake/FindECM.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(ecm.h ecm) 4 | libfind_library(ecm ecm) 5 | 6 | set(ECM_LIBRARIES ${ECM_LIBRARY}) 7 | set(ECM_INCLUDE_DIRS ${ECM_INCLUDE_DIR}) 8 | set(ECM_TARGETS ecm) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(ECM DEFAULT_MSG ECM_LIBRARIES 12 | ECM_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(ECM_INCLUDE_DIR ECM_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindEXECINFO.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(execinfo.h execinfo) 4 | set(EXECINFO_INCLUDE_DIRS ${EXECINFO_INCLUDE_DIR}) 5 | include(FindPackageHandleStandardArgs) 6 | 7 | if (CMAKE_SYSTEM_NAME MATCHES "BSD") 8 | libfind_library(execinfo execinfo) 9 | set(EXECINFO_LIBRARIES ${EXECINFO_LIBRARY}) 10 | set(EXECINFO_TARGETS execinfo) 11 | find_package_handle_standard_args(EXECINFO DEFAULT_MSG 12 | EXECINFO_LIBRARIES EXECINFO_INCLUDE_DIRS) 13 | else () 14 | find_package_handle_standard_args(EXECINFO DEFAULT_MSG 15 | EXECINFO_INCLUDE_DIRS) 16 | endif () 17 | 18 | mark_as_advanced(EXECINFO_INCLUDE_DIR EXECINFO_LIBRARY) 19 | -------------------------------------------------------------------------------- /cmake/FindFLINT.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(flint/flint.h flint) 4 | libfind_library(flint flint) 5 | 6 | set(FLINT_LIBRARIES ${FLINT_LIBRARY}) 7 | set(FLINT_INCLUDE_DIRS ${FLINT_INCLUDE_DIR}) 8 | set(FLINT_TARGETS flint) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(FLINT DEFAULT_MSG FLINT_LIBRARIES 12 | FLINT_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(FLINT_INCLUDE_DIR FLINT_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindGMP.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_library(gmp gmp) 4 | set(GMP_LIBRARIES ${GMP_LIBRARY}) 5 | set(GMP_TARGETS gmp) 6 | 7 | if (WITH_GMPXX) 8 | libfind_include(gmpxx.h gmp) 9 | libfind_library(gmpxx gmp) 10 | set(GMP_LIBRARIES ${GMPXX_LIBRARY} ${GMP_LIBRARIES}) 11 | set(GMP_TARGETS ${GMP_TARGETS} gmpxx) 12 | else() 13 | libfind_include(gmp.h gmp) 14 | endif() 15 | 16 | set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) 17 | 18 | include(FindPackageHandleStandardArgs) 19 | find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARIES 20 | GMP_INCLUDE_DIRS) 21 | 22 | mark_as_advanced(GMP_INCLUDE_DIR GMPXX_LIBRARY GMP_LIBRARY) 23 | -------------------------------------------------------------------------------- /cmake/FindLINKH.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(link.h linkh) 4 | 5 | set(LINKH_INCLUDE_DIRS ${LINKH_INCLUDE_DIR}) 6 | 7 | include(FindPackageHandleStandardArgs) 8 | find_package_handle_standard_args(LINKH DEFAULT_MSG LINKH_INCLUDE_DIRS) 9 | 10 | mark_as_advanced(LINKH_INCLUDE_DIR) 11 | -------------------------------------------------------------------------------- /cmake/FindMPC.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(mpc.h mpc) 4 | libfind_library(mpc mpc) 5 | 6 | set(MPC_LIBRARIES ${MPC_LIBRARY}) 7 | set(MPC_INCLUDE_DIRS ${MPC_INCLUDE_DIR}) 8 | set(MPC_TARGETS mpc) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(MPC DEFAULT_MSG MPC_LIBRARIES 12 | MPC_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(MPC_INCLUDE_DIR MPC_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindMPFR.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(mpfr.h mpfr) 4 | libfind_library(mpfr mpfr) 5 | 6 | set(MPFR_LIBRARIES ${MPFR_LIBRARY}) 7 | set(MPFR_INCLUDE_DIRS ${MPFR_INCLUDE_DIR}) 8 | set(MPFR_TARGETS mpfr) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(MPFR DEFAULT_MSG MPFR_LIBRARIES 12 | MPFR_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(MPFR_INCLUDE_DIR MPFR_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindPIRANHA.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(piranha/piranha.hpp piranha) 4 | 5 | set(PIRANHA_INCLUDE_DIRS ${PIRANHA_INCLUDE_DIR}) 6 | 7 | include(FindPackageHandleStandardArgs) 8 | find_package_handle_standard_args(PIRANHA DEFAULT_MSG 9 | PIRANHA_INCLUDE_DIRS) 10 | 11 | mark_as_advanced(PIRANHA_INCLUDE_DIR) 12 | -------------------------------------------------------------------------------- /cmake/FindPRIMESIEVE.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(primesieve.hpp primesieve) 4 | libfind_library(primesieve primesieve) 5 | 6 | set(PRIMESIEVE_LIBRARIES ${PRIMESIEVE_LIBRARY}) 7 | set(PRIMESIEVE_INCLUDE_DIRS ${PRIMESIEVE_INCLUDE_DIR}) 8 | set(PRIMESIEVE_TARGETS primesieve) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(PRIMESIEVE DEFAULT_MSG 12 | PRIMESIEVE_LIBRARIES PRIMESIEVE_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(PRIMESIEVE_INCLUDE_DIR PRIMESIEVE_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindPTHREAD.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_include(pthread.h pthread) 4 | libfind_library(pthread pthread) 5 | 6 | set(PTHREAD_LIBRARIES ${PTHREAD_LIBRARY}) 7 | set(PTHREAD_INCLUDE_DIRS ${PTHREAD_INCLUDE_DIR}) 8 | set(PTHREAD_TARGETS pthread) 9 | 10 | include(FindPackageHandleStandardArgs) 11 | find_package_handle_standard_args(PTHREAD DEFAULT_MSG PTHREAD_LIBRARIES 12 | PTHREAD_INCLUDE_DIRS) 13 | 14 | mark_as_advanced(PTHREAD_INCLUDE_DIR PTHEARD_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/FindTCMALLOC.cmake: -------------------------------------------------------------------------------- 1 | include(LibFindMacros) 2 | 3 | libfind_library(tcmalloc tcmalloc) 4 | set(TCMALLOC_TARGETS tcmalloc) 5 | if (NOT TCMALLOC_LIBRARY) 6 | libfind_library(tcmalloc_minimal tcmalloc) 7 | set(TCMALLOC_LIBRARY ${TCMALLOC_MINIMAL_LIBRARY}) 8 | set(TCMALLOC_TARGETS tcmalloc_minimal) 9 | endif() 10 | set(TCMALLOC_LIBRARIES ${TCMALLOC_LIBRARY}) 11 | find_package_handle_standard_args(TCMALLOC DEFAULT_MSG 12 | TCMALLOC_LIBRARIES) 13 | 14 | mark_as_advanced(TCMALLOC_LIBRARY TCMALLOC_MINIMAL_LIBRARY) 15 | -------------------------------------------------------------------------------- /cmake/LibFindMacros.cmake: -------------------------------------------------------------------------------- 1 | # Macros for finding external libraries 2 | # 3 | # Example usage: 4 | # 5 | # include(LibFindMacros) 6 | # libfind_include(gmpxx.h gmp) 7 | # libfind_library(gmpxx gmp) 8 | # libfind_library(gmp gmp) 9 | # set(GMP_LIBRARIES ${GMPXX_LIBRARY} ${GMP_LIBRARY}) 10 | # set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) 11 | # include(FindPackageHandleStandardArgs) 12 | # find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARIES 13 | # GMP_INCLUDE_DIRS) 14 | # mark_as_advanced(GMP_INCLUDE_DIR GMPXX_LIBRARY GMP_LIBRARY) 15 | # 16 | # The result of the Find*.cmake (e.g. FindGMP.cmake) module should be two 17 | # variables GMP_LIBRARIES and GMP_INCLUDE_DIRS, that the user then uses in the 18 | # following way: 19 | # 20 | # find_package(GMP REQUIRED) 21 | # include_directories(${GMP_INCLUDE_DIRS}) 22 | # set(LIBS ${LIBS} ${GMP_LIBRARIES}) 23 | # # LIBS is later used in target_link_libraries() 24 | 25 | function (libfind_library libname pkg) 26 | string(TOUPPER ${pkg} PKG) 27 | string(TOUPPER ${libname} LIBNAME) 28 | 29 | find_library(${LIBNAME}_LIBRARY 30 | NAMES 31 | ${libname} 32 | ) 33 | 34 | if (NOT TARGET ${libname}) 35 | add_library(${libname} UNKNOWN IMPORTED) 36 | set_property(TARGET ${libname} PROPERTY IMPORTED_LOCATION ${${LIBNAME}_LIBRARY}) 37 | endif() 38 | endfunction() 39 | 40 | function (libfind_include HEADER pkg) 41 | string(TOUPPER ${pkg} PKG) 42 | 43 | find_path(${PKG}_INCLUDE_DIR 44 | NAMES 45 | ${HEADER} 46 | ) 47 | endfunction() 48 | -------------------------------------------------------------------------------- /cmake/SymEngineConfigVersion.cmake.in: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. 8 | # The variable CVF_VERSION must be set before calling configure_file(). 9 | 10 | set(PACKAGE_VERSION @SYMENGINE_VERSION@) 11 | 12 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) 13 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 14 | else() 15 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 16 | if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") 17 | set(PACKAGE_VERSION_EXACT TRUE) 18 | endif() 19 | endif() 20 | 21 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 22 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "@CMAKE_SIZEOF_VOID_P@" STREQUAL "") 23 | return() 24 | endif() 25 | 26 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 27 | if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "@CMAKE_SIZEOF_VOID_P@") 28 | math(EXPR installedBits "@CMAKE_SIZEOF_VOID_P@ * 8") 29 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 30 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 31 | endif() 32 | -------------------------------------------------------------------------------- /cmake/UserOverride.cmake: -------------------------------------------------------------------------------- 1 | # This overrides the default CMake Debug and Release compiler options. 2 | # The user can still specify different options by setting the 3 | # CMAKE_CXX_FLAGS_[RELEASE,DEBUG] variables (on the command line or in the 4 | # CMakeList.txt). This files serves as better CMake defaults and should only be 5 | # modified if the default values are to be changed. Project specific compiler 6 | # flags should be set in the CMakeList.txt by setting the CMAKE_CXX_FLAGS_* 7 | # variables. 8 | 9 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 10 | # g++ 11 | set(common "-Wall -Wextra -Wno-unused-parameter -fno-common") 12 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops") 13 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb") 14 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") 15 | # icpc 16 | set(common "-Wall -fno-common") 17 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -xHOST -O3") 18 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -O0") 19 | elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) 20 | # clang 21 | set(common "-Wall -Wextra -Wno-unused-parameter") 22 | set(CMAKE_CXX_FLAGS_RELEASE_INIT "${common} -O3 -funroll-loops") 23 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "${common} -g -ggdb") 24 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "PGI") 25 | # pgcpp 26 | endif () 27 | -------------------------------------------------------------------------------- /cmake/checkclang.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | -------------------------------------------------------------------------------- /cmake/checkgmpxx.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int main() { 6 | mpz_class m = 1; 7 | std::cout << m; 8 | } -------------------------------------------------------------------------------- /cmake/checkstdtostring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int main() { 4 | std::cout << std::to_string(0) << std::endl; 5 | } 6 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | ignore: 3 | - symengine/tests/.* 4 | - symengine/utilities/.* 5 | - benchmarks/.* 6 | 7 | comment: off 8 | -------------------------------------------------------------------------------- /notebooks/symengine.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Installation\n", 8 | "\n", 9 | "Install `xeus-cling`:\n", 10 | "\n", 11 | " conda install -c conda-forge xeus-cling" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "#include \n", 21 | "using SymEngine::Expression;" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "Expression x(\"x\");" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "auto ex = pow(x+sqrt(Expression(2)), 10);\n", 40 | "ex" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "expand(ex)" 50 | ] 51 | } 52 | ], 53 | "metadata": { 54 | "kernelspec": { 55 | "display_name": "C++17", 56 | "language": "C++17", 57 | "name": "xeus-cling-cpp17" 58 | }, 59 | "language_info": { 60 | "codemirror_mode": "text/x-c++src", 61 | "file_extension": ".cpp", 62 | "mimetype": "text/x-c++src", 63 | "name": "c++", 64 | "version": "-std=c++17" 65 | } 66 | }, 67 | "nbformat": 4, 68 | "nbformat_minor": 2 69 | } 70 | -------------------------------------------------------------------------------- /symengine/basic-methods.inc: -------------------------------------------------------------------------------- 1 | class EvalRealDoubleVisitorFinal; 2 | #define SYMENGINE_INCLUDE_METHODS(SUFFIX) \ 3 | virtual void accept(Visitor &v) const SUFFIX \ 4 | virtual void accept(EvalRealDoubleVisitorFinal &v) const SUFFIX 5 | -------------------------------------------------------------------------------- /symengine/basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace SymEngine 5 | { 6 | 7 | int Basic::__cmp__(const Basic &o) const 8 | { 9 | auto a = this->get_type_code(); 10 | auto b = o.get_type_code(); 11 | if (a == b) { 12 | return this->compare(o); 13 | } else { 14 | // We return the order given by the numerical value of the TypeID enum 15 | // type. 16 | // The types don't need to be ordered in any given way, they just need 17 | // to be ordered. 18 | return a < b ? -1 : 1; 19 | } 20 | } 21 | 22 | std::string Basic::__str__() const 23 | { 24 | return str(*this); 25 | } 26 | 27 | RCP Basic::subs(const map_basic_basic &subs_dict) const 28 | { 29 | return SymEngine::subs(this->rcp_from_this(), subs_dict); 30 | } 31 | 32 | RCP Basic::xreplace(const map_basic_basic &xreplace_dict) const 33 | { 34 | return SymEngine::xreplace(this->rcp_from_this(), xreplace_dict); 35 | } 36 | 37 | const char *get_version() 38 | { 39 | return SYMENGINE_VERSION; 40 | } 41 | 42 | bool is_a_Atom(const Basic &b) 43 | { 44 | return is_a_Number(b) or is_a(b) or is_a(b); 45 | } 46 | 47 | } // SymEngine 48 | -------------------------------------------------------------------------------- /symengine/complex_double.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * \file ComplexDouble.h 3 | * Class for ComplexDouble built on top of Number class 4 | * 5 | **/ 6 | #include 7 | 8 | namespace SymEngine 9 | { 10 | 11 | ComplexDouble::ComplexDouble(std::complex i) 12 | { 13 | SYMENGINE_ASSIGN_TYPEID() 14 | this->i = i; 15 | } 16 | //! Get the real part of the complex number 17 | RCP ComplexDouble::real_part() const 18 | { 19 | return real_double(i.real()); 20 | } 21 | //! Get the imaginary part of the complex number 22 | RCP ComplexDouble::imaginary_part() const 23 | { 24 | return real_double(i.imag()); 25 | } 26 | //! Get the conjugate of the complex number 27 | RCP ComplexDouble::conjugate() const 28 | { 29 | double re = i.real(); 30 | double im = -i.imag(); 31 | return complex_double(std::complex(re, im)); 32 | } 33 | hash_t ComplexDouble::__hash__() const 34 | { 35 | hash_t seed = COMPLEX_DOUBLE; 36 | hash_combine(seed, i.real()); 37 | hash_combine(seed, i.imag()); 38 | return seed; 39 | } 40 | 41 | bool ComplexDouble::__eq__(const Basic &o) const 42 | { 43 | if (is_a(o)) { 44 | const ComplexDouble &s = down_cast(o); 45 | return this->i == s.i; 46 | } 47 | return false; 48 | } 49 | 50 | int ComplexDouble::compare(const Basic &o) const 51 | { 52 | SYMENGINE_ASSERT(is_a(o)) 53 | const ComplexDouble &s = down_cast(o); 54 | if (i == s.i) 55 | return 0; 56 | if (i.real() == s.i.real()) { 57 | return i.imag() < s.i.imag() ? -1 : 1; 58 | } 59 | return i.real() < s.i.real() ? -1 : 1; 60 | } 61 | 62 | RCP complex_double(std::complex x) 63 | { 64 | return make_rcp(x); 65 | } 66 | 67 | } // SymEngine 68 | -------------------------------------------------------------------------------- /symengine/constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file constants.h 3 | * Declare all the special constants in this file 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_CONSTANTS_H 8 | #define SYMENGINE_CONSTANTS_H 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace SymEngine 16 | { 17 | 18 | class Constant : public Basic 19 | { 20 | private: 21 | //! name of Constant 22 | std::string name_; 23 | 24 | public: 25 | IMPLEMENT_TYPEID(CONSTANT) 26 | //! Constant Constructor 27 | Constant(const std::string &name); 28 | //! \return Size of the hash 29 | virtual hash_t __hash__() const; 30 | /*! Equality comparator 31 | * \param o - Object to be compared with 32 | * \return whether the 2 objects are equal 33 | * */ 34 | virtual bool __eq__(const Basic &o) const; 35 | /*! Comparison operator 36 | * \param o - Object to be compared with 37 | * \return `0` if equal, `-1` , `1` according to string compare 38 | * */ 39 | virtual int compare(const Basic &o) const; 40 | //! \return name of the Constant. 41 | inline std::string get_name() const 42 | { 43 | return name_; 44 | } 45 | 46 | virtual vec_basic get_args() const 47 | { 48 | return {}; 49 | } 50 | }; 51 | 52 | //! inline version to return `Constant` 53 | inline RCP constant(const std::string &name) 54 | { 55 | return make_rcp(name); 56 | } 57 | 58 | // Constant Numbers 59 | extern SYMENGINE_EXPORT RCP zero; 60 | extern SYMENGINE_EXPORT RCP one; 61 | extern SYMENGINE_EXPORT RCP minus_one; 62 | extern SYMENGINE_EXPORT RCP I; 63 | 64 | // Symbolic Constants 65 | extern SYMENGINE_EXPORT RCP pi; 66 | extern SYMENGINE_EXPORT RCP E; 67 | extern SYMENGINE_EXPORT RCP EulerGamma; 68 | extern SYMENGINE_EXPORT RCP Catalan; 69 | extern SYMENGINE_EXPORT RCP GoldenRatio; 70 | 71 | // Infinity 72 | extern SYMENGINE_EXPORT RCP Inf; 73 | extern SYMENGINE_EXPORT RCP NegInf; 74 | extern SYMENGINE_EXPORT RCP ComplexInf; 75 | 76 | // Not a Number 77 | extern SYMENGINE_EXPORT RCP Nan; 78 | } // SymEngine 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /symengine/diophantine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file diophantine.h 3 | * Algorithms for Diophantine equations 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_DIOPHANTINE_H 8 | #define SYMENGINE_DIOPHANTINE_H 9 | 10 | #include 11 | 12 | namespace SymEngine 13 | { 14 | 15 | // Solve the diophantine system Ax = 0 and return a basis set for solutions 16 | void homogeneous_lde(std::vector &basis, const DenseMatrix &A); 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /symengine/eval.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file eval.h 3 | * 4 | **/ 5 | #ifndef SYMENGINE_EVAL_H 6 | #define SYMENGINE_EVAL_H 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef HAVE_SYMENGINE_MPFR 13 | #include 14 | #endif // HAVE_SYMENGINE_MPFR 15 | 16 | #ifdef SYMENGINE_HAVE_MPC 17 | #include 18 | #endif // HAVE_SYMENGINE_MPC 19 | 20 | namespace SymEngine 21 | { 22 | 23 | /* 24 | * Evaluates basic b, according to the number of significant bits 25 | * in the given domain 26 | */ 27 | 28 | enum class EvalfDomain { 29 | Complex = 0, 30 | Real = 1, 31 | Symbolic = 2, 32 | }; 33 | 34 | RCP evalf(const Basic &b, unsigned long bits, 35 | EvalfDomain domain = EvalfDomain::Symbolic); 36 | 37 | } // SymEngine 38 | 39 | #endif // SYMENGINE_EVAL_H 40 | -------------------------------------------------------------------------------- /symengine/eval_arb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file eval_arb.h 3 | * Evaluation of numeric expressions using Arb 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_EVAL_ARB_H 8 | #define SYMENGINE_EVAL_ARB_H 9 | 10 | #include 11 | 12 | #ifdef HAVE_SYMENGINE_ARB 13 | #include 14 | #include 15 | 16 | namespace SymEngine 17 | { 18 | 19 | // `result` is returned by value since `arb_t` is defined as an array in 20 | // `arb.h`. 21 | // This design will not change in `arb` and hence will not change in `SymEngine` 22 | // also. 23 | void eval_arb(arb_t result, const Basic &b, long precision = 53); 24 | 25 | } // SymEngine 26 | 27 | #endif // HAVE_SYMENGINE_ARB 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /symengine/eval_double.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file eval_double.h 3 | * 4 | **/ 5 | #ifndef SYMENGINE_EVAL_DOUBLE_H 6 | #define SYMENGINE_EVAL_DOUBLE_H 7 | 8 | #include 9 | 10 | namespace SymEngine 11 | { 12 | 13 | /* 14 | * We have two implementations, the visitor pattern (eval_double) and 15 | * single dispatch (eval_double_single_dispatch). 16 | */ 17 | 18 | double eval_double(const Basic &b); 19 | 20 | double eval_double_single_dispatch(const Basic &b); 21 | 22 | double eval_double_visitor_pattern(const Basic &b); 23 | 24 | std::complex eval_complex_double(const Basic &b); 25 | 26 | } // SymEngine 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /symengine/eval_mpc.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file eval_mpc.h 3 | * Evaluation of numeric expressions using MPC 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_EVAL_MPC_H 8 | #define SYMENGINE_EVAL_MPC_H 9 | 10 | #include 11 | 12 | #ifdef HAVE_SYMENGINE_MPC 13 | #include 14 | #include 15 | 16 | namespace SymEngine 17 | { 18 | 19 | //! Evaluate expression `b` and store it in `result` with rounding mode rnd 20 | // Different precisions for real and imaginary parts of `result` is not 21 | // supported 22 | // Use `mpc_init2` to initialize `result` 23 | void eval_mpc(mpc_ptr result, const Basic &b, mpfr_rnd_t rnd); 24 | 25 | } // SymEngine 26 | 27 | #endif // HAVE_SYMENGINE_MPC 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /symengine/eval_mpfr.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file eval_mpfr.h 3 | * Evaluation of numeric expressions using MPFR 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_EVAL_MPFR_H 8 | #define SYMENGINE_EVAL_MPFR_H 9 | 10 | #include 11 | 12 | #ifdef HAVE_SYMENGINE_MPFR 13 | #include 14 | #include 15 | 16 | namespace SymEngine 17 | { 18 | 19 | void eval_mpfr(mpfr_ptr result, const Basic &b, mpfr_rnd_t rnd); 20 | 21 | } // SymEngine 22 | 23 | #endif // HAVE_SYMENGINE_MPFR 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /symengine/expression.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace SymEngine 5 | { 6 | 7 | namespace detail 8 | { 9 | std::string poly_print(const Expression &x) 10 | { 11 | Precedence prec; 12 | if (prec.getPrecedence(x.get_basic()) == PrecedenceEnum::Add) { 13 | return "(" + x.get_basic()->__str__() + ")"; 14 | } 15 | return x.get_basic()->__str__(); 16 | } 17 | } 18 | 19 | Expression::Expression(const std::string &s) 20 | { 21 | m_basic = parse(s); 22 | } 23 | 24 | } // SymEngine 25 | -------------------------------------------------------------------------------- /symengine/finitediff.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | 6 | namespace SymEngine 7 | { 8 | 9 | vec_basic generate_fdiff_weights_vector(const vec_basic &grid, 10 | const unsigned max_deriv, 11 | const RCP around) 12 | { 13 | // Parameters 14 | // ---------- 15 | // grid: grid point locations 16 | // max_deriv: highest derivative. 17 | // around: location where approximations are to be accurate 18 | // 19 | // Returns 20 | // ------- 21 | // weights[grid_index, deriv_order]: weights of order 0 to max_deriv (column 22 | // major order) 23 | // 24 | // References 25 | // ---------- 26 | // Generation of Finite Difference Formulas on Arbitrarily Spaced Grids 27 | // Bengt Fornberg, Mathematics of compuation, 51, 184, 1988, 699-706 28 | // 29 | const unsigned len_g = numeric_cast(grid.size()); 30 | const unsigned len_w = len_g * (max_deriv + 1); 31 | RCP c1, c4, c5; 32 | c1 = one; 33 | c4 = sub(grid[0], around); 34 | vec_basic weights(len_w); 35 | weights[0] = one; 36 | for (unsigned idx = 1; idx < len_w; ++idx) 37 | weights[idx] = zero; // clear weights 38 | for (unsigned i = 1; i < len_g; ++i) { 39 | const int mn = (i < max_deriv) ? i : max_deriv; // min(i, max_deriv) 40 | RCP c2 = one; 41 | c5 = c4; 42 | c4 = sub(grid[i], around); 43 | for (unsigned j = 0; j < i; ++j) { 44 | const RCP c3 = sub(grid[i], grid[j]); 45 | c2 = mul(c2, c3); 46 | if (j == i - 1) { 47 | for (int k = mn; k >= 1; --k) { 48 | weights[i + k * len_g] 49 | = div(mul(c1, sub(mul(integer(k), 50 | weights[i - 1 + (k - 1) * len_g]), 51 | mul(c5, weights[i - 1 + k * len_g]))), 52 | c2); 53 | } 54 | weights[i] 55 | = mul(minus_one, div(mul(c1, mul(c5, weights[i - 1])), c2)); 56 | } 57 | for (int k = mn; k >= 1; --k) { 58 | weights[j + k * len_g] 59 | = div(sub(mul(c4, weights[j + k * len_g]), 60 | mul(integer(k), weights[j + (k - 1) * len_g])), 61 | c3); 62 | } 63 | weights[j] = div(mul(c4, weights[j]), c3); 64 | } 65 | c1 = c2; 66 | } 67 | return weights; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /symengine/finitediff.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file finitediff.h 3 | * Includes function to generate finitedifference weights 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_FINITEDIFF_H 8 | #define SYMENGINE_FINITEDIFF_H 9 | 10 | #include 11 | 12 | namespace SymEngine 13 | { 14 | 15 | vec_basic generate_fdiff_weights_vector(const vec_basic &grid, 16 | const unsigned max_deriv, 17 | const RCP around); 18 | } 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /symengine/matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace SymEngine 4 | { 5 | 6 | std::string MatrixBase::__str__() const 7 | { 8 | std::ostringstream o; 9 | 10 | for (unsigned i = 0; i < nrows(); i++) { 11 | o << "["; 12 | for (unsigned j = 0; j < ncols() - 1; j++) 13 | o << *this->get(i, j) << ", "; 14 | o << *this->get(i, ncols() - 1) << "]" << std::endl; 15 | } 16 | 17 | return o.str(); 18 | } 19 | 20 | bool MatrixBase::eq(const MatrixBase &other) const 21 | { 22 | if (this->nrows() != other.nrows() or this->ncols() != other.ncols()) 23 | return false; 24 | 25 | for (unsigned i = 0; i < this->nrows(); i++) 26 | for (unsigned j = 0; j < this->ncols(); j++) 27 | if (neq(*this->get(i, j), *(other.get(i, j)))) 28 | return false; 29 | 30 | return true; 31 | } 32 | 33 | } // SymEngine 34 | -------------------------------------------------------------------------------- /symengine/monomials.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace SymEngine 4 | { 5 | 6 | // This is the fastest implementation: 7 | void monomial_mul(const vec_int &A, const vec_int &B, vec_int &C) 8 | { 9 | size_t n = A.size(); 10 | for (size_t i = 0; i < n; ++i) { 11 | C[i] = A[i] + B[i]; 12 | } 13 | } 14 | 15 | /* 16 | // Other implementation of monomial_mul() are below. Those are slightly slower, 17 | // so they are commented out. 18 | 19 | // This is slightly slower than monomial_mul 20 | void monomial_mul2(const vec_int &A, const vec_int &B, vec_int &C) 21 | { 22 | std::transform(A.begin(), A.end(), B.begin(), C.begin(), std::plus()); 23 | } 24 | 25 | // The same as monomial_mul2 26 | void monomial_mul3(const vec_int &A, const vec_int &B, vec_int &C) 27 | { 28 | std::transform(A.begin(), A.end(), B.begin(), C.begin(), 29 | [] (int a, int b) { return a + b; }); 30 | } 31 | */ 32 | 33 | } // SymEngine 34 | -------------------------------------------------------------------------------- /symengine/monomials.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file monomials.h 3 | * Monomial Multiplication 4 | * 5 | **/ 6 | 7 | #ifndef SYMENGINE_MONOMIALS_H 8 | #define SYMENGINE_MONOMIALS_H 9 | 10 | #include 11 | 12 | namespace SymEngine 13 | { 14 | //! Monomial multiplication 15 | void monomial_mul(const vec_int &A, const vec_int &B, vec_int &C); 16 | 17 | } // SymEngine 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /symengine/mp_wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace SymEngine 5 | { 6 | #if SYMENGINE_INTEGER_CLASS == SYMENGINE_FLINT 7 | std::ostream &operator<<(std::ostream &os, const fmpz_wrapper &f) 8 | { 9 | char *c = fmpz_get_str(NULL, 10, f.get_fmpz_t()); 10 | os << std::string(c); 11 | free(c); 12 | return os; 13 | } 14 | 15 | std::ostream &operator<<(std::ostream &os, const fmpq_wrapper &f) 16 | { 17 | char *c = fmpq_get_str(NULL, 10, f.get_fmpq_t()); 18 | os << std::string(c); 19 | free(c); 20 | return os; 21 | } 22 | #elif SYMENGINE_INTEGER_CLASS == SYMENGINE_GMP 23 | 24 | std::ostream &operator<<(std::ostream &os, const mpz_wrapper &f) 25 | { 26 | char *c = mpz_get_str(NULL, 10, f.get_mpz_t()); 27 | os << std::string(c); 28 | free(c); 29 | return os; 30 | } 31 | 32 | std::ostream &operator<<(std::ostream &os, const mpq_wrapper &f) 33 | { 34 | char *c = mpq_get_str(NULL, 10, f.get_mpq_t()); 35 | os << std::string(c); 36 | free(c); 37 | return os; 38 | } 39 | #endif 40 | 41 | } // SymEngine 42 | -------------------------------------------------------------------------------- /symengine/nan.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file nan.h 3 | * 4 | **/ 5 | 6 | #ifndef SYMENGINE_NAN_H 7 | #define SYMENGINE_NAN_H 8 | 9 | #include 10 | #include 11 | 12 | namespace SymEngine 13 | { 14 | 15 | /** 16 | * This serves as a place holder for numeric values that are indeterminate. 17 | * Most operations on NaN, produce another NaN. 18 | **/ 19 | class NaN : public Number 20 | { 21 | public: 22 | IMPLEMENT_TYPEID(NOT_A_NUMBER) 23 | //! Constructs NaN 24 | NaN(); 25 | 26 | //! \return size of the hash 27 | hash_t __hash__() const; 28 | 29 | /*! Equality comparator 30 | * \param o - Object to be compared with 31 | * \return whether the 2 objects are equal 32 | * */ 33 | bool __eq__(const Basic &o) const; 34 | int compare(const Basic &o) const; 35 | 36 | //! \return `true` if `0` 37 | inline bool is_zero() const 38 | { 39 | return false; 40 | } 41 | //! \return `true` if `1` 42 | inline bool is_one() const 43 | { 44 | return false; 45 | } 46 | //! \return `true` if `-1` 47 | inline bool is_minus_one() const 48 | { 49 | return false; 50 | } 51 | 52 | inline bool is_positive() const 53 | { 54 | return false; 55 | } 56 | 57 | inline bool is_negative() const 58 | { 59 | return false; 60 | } 61 | 62 | inline bool is_complex() const 63 | { 64 | return false; 65 | } 66 | //! \return the conjugate if the class is complex 67 | virtual RCP conjugate() const; 68 | inline bool is_exact() const 69 | { 70 | return false; 71 | } 72 | virtual Evaluate &get_eval() const; 73 | 74 | RCP add(const Number &other) const; 75 | RCP mul(const Number &other) const; 76 | RCP div(const Number &other) const; 77 | RCP pow(const Number &other) const; 78 | RCP rpow(const Number &other) const; 79 | }; 80 | 81 | } // SymEngine 82 | #endif 83 | -------------------------------------------------------------------------------- /symengine/number.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace SymEngine 6 | { 7 | 8 | RCP Number::conjugate() const 9 | { 10 | if (not is_complex()) { 11 | return this->rcp_from_this(); 12 | } 13 | throw NotImplementedError("Not Implemented."); 14 | } 15 | 16 | RCP Number::sub(const Number &other) const 17 | { 18 | return add(*other.mul(*integer(-1))); 19 | } 20 | 21 | RCP Number::rsub(const Number &other) const 22 | { 23 | return mul(*integer(-1))->add(other); 24 | } 25 | 26 | RCP Number::div(const Number &other) const 27 | { 28 | return mul(*other.pow(*integer(-1))); 29 | } 30 | 31 | RCP Number::rdiv(const Number &other) const 32 | { 33 | return other.mul(*pow(*integer(-1))); 34 | } 35 | 36 | } // SymEngine 37 | -------------------------------------------------------------------------------- /symengine/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_PARSER_H 2 | #define SYMENGINE_PARSER_H 3 | 4 | #include 5 | 6 | namespace SymEngine 7 | { 8 | 9 | RCP parse(const std::string &s, bool convert_xor = true); 10 | RCP parse_old(const std::string &s, bool convert_xor = true); 11 | } 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /symengine/parser/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_PARSER_PARSER_H 2 | #define SYMENGINE_PARSER_PARSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | namespace SymEngine 14 | { 15 | 16 | /* 17 | To Parse (default) constructor is expensive as it creates all the maps and 18 | tables. If just one expression needs to be parsed, then calling 19 | SymEngine::parse() does the job. But if multiple expressions are to be 20 | parsed, then first initialize SymEngine::Parser and after that call 21 | SymEngine::Parser::parse() repeatedly. 22 | 23 | Example: 24 | 25 | Parser p; 26 | auto r = p.parse("x**2"); 27 | 28 | */ 29 | 30 | class Parser 31 | { 32 | std::string inp; 33 | 34 | public: 35 | Tokenizer m_tokenizer; 36 | RCP res; 37 | 38 | RCP parse(const std::string &input, bool convert_xor = true); 39 | int parse(); 40 | 41 | RCP functionify(const std::string &name, vec_basic ¶ms); 42 | RCP parse_numeric(const std::string &expr); 43 | RCP parse_identifier(const std::string &expr); 44 | std::tuple, RCP> 45 | parse_implicit_mul(const std::string &expr); 46 | 47 | private: 48 | }; 49 | 50 | } // namespace SymEngine 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /symengine/parser/parser.tab.hh: -------------------------------------------------------------------------------- 1 | /* A Bison parser, made by GNU Bison 3.0.4. */ 2 | 3 | /* Bison interface for Yacc-like parsers in C 4 | 5 | Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . */ 19 | 20 | /* As a special exception, you may create a larger work that contains 21 | part or all of the Bison parser skeleton and distribute that work 22 | under terms of your choice, so long as that work isn't itself a 23 | parser generator using the skeleton or a modified version thereof 24 | as a parser skeleton. Alternatively, if you modify or redistribute 25 | the parser skeleton itself, you may (at your option) remove this 26 | special exception, which will cause the skeleton and the resulting 27 | Bison output files to be licensed under the GNU General Public 28 | License without this special exception. 29 | 30 | This special exception was added by the Free Software Foundation in 31 | version 2.2 of Bison. */ 32 | 33 | #ifndef YY_YY_PARSER_TAB_HH_INCLUDED 34 | #define YY_YY_PARSER_TAB_HH_INCLUDED 35 | /* Debug traces. */ 36 | #ifndef YYDEBUG 37 | #define YYDEBUG 0 38 | #endif 39 | #if YYDEBUG 40 | extern int yydebug; 41 | #endif 42 | /* "%code requires" blocks. */ 43 | #line 15 "parser.yy" /* yacc.c:1909 */ 44 | 45 | #include "symengine/parser/parser.h" 46 | 47 | #line 50 "parser.tab.hh" /* yacc.c:1909 */ 48 | 49 | /* Token type. */ 50 | #ifndef YYTOKENTYPE 51 | #define YYTOKENTYPE 52 | enum yytokentype { 53 | END_OF_FILE = 0, 54 | IDENTIFIER = 258, 55 | NUMERIC = 259, 56 | IMPLICIT_MUL = 260, 57 | EQ = 261, 58 | LE = 262, 59 | GE = 263, 60 | UMINUS = 264, 61 | POW = 265, 62 | NOT = 266 63 | }; 64 | #endif 65 | 66 | /* Value type. */ 67 | #if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED 68 | typedef struct SymEngine::YYSTYPE YYSTYPE; 69 | #define YYSTYPE_IS_TRIVIAL 1 70 | #define YYSTYPE_IS_DECLARED 1 71 | #endif 72 | 73 | int yyparse(SymEngine::Parser &p); 74 | 75 | #endif /* !YY_YY_PARSER_TAB_HH_INCLUDED */ 76 | -------------------------------------------------------------------------------- /symengine/parser/parser_stype.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_PARSER_STYPE_H 2 | #define SYMENGINE_PARSER_STYPE_H 3 | 4 | #include 5 | #include "symengine/basic.h" 6 | 7 | namespace SymEngine 8 | { 9 | 10 | struct YYSTYPE { 11 | SymEngine::RCP basic; 12 | SymEngine::vec_basic basic_vec; 13 | std::string string; 14 | // Constructor 15 | YYSTYPE() = default; 16 | // Destructor 17 | ~YYSTYPE() = default; 18 | // Copy constructor and assignment 19 | YYSTYPE(const YYSTYPE &) = default; 20 | YYSTYPE &operator=(const YYSTYPE &) = default; 21 | // Move constructor and assignment 22 | YYSTYPE(YYSTYPE &&) = default; 23 | YYSTYPE &operator=(YYSTYPE &&) = default; 24 | }; 25 | 26 | } // namespace SymEngine 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /symengine/parser/tokenizer.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_TOKENIZER_H 2 | #define SYMENGINE_TOKENIZER_H 3 | 4 | #include 5 | 6 | namespace SymEngine 7 | { 8 | 9 | class Tokenizer 10 | { 11 | unsigned char *cur; 12 | unsigned char *mar; 13 | unsigned char *tok; 14 | 15 | public: 16 | // Set the string to tokenize. The caller must ensure `str` will stay valid 17 | // as long as `lex` is being called. 18 | void set_string(const std::string &str); 19 | 20 | // Get next token. Token ID is returned as function result, the semantic 21 | // value is put into `yylval`. 22 | int lex(YYSTYPE &yylval); 23 | 24 | // Return the current token 25 | std::string token() const 26 | { 27 | return std::string((char *)tok, cur - tok); 28 | } 29 | }; 30 | 31 | } // namespace SymEngine 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /symengine/parser/tokenizer.re: -------------------------------------------------------------------------------- 1 | #include "tokenizer.h" 2 | #include "parser.tab.hh" 3 | 4 | namespace SymEngine 5 | { 6 | 7 | void Tokenizer::set_string(const std::string &str) 8 | { 9 | // The input string must be NULL terminated, otherwise the tokenizer will 10 | // not detect the end of string. After C++11, the std::string is guaranteed 11 | // to end with \0, but we check this here just in case. 12 | SYMENGINE_ASSERT(str[str.size()] == '\0'); 13 | cur = (unsigned char *)(&str[0]); 14 | } 15 | 16 | int Tokenizer::lex(YYSTYPE &yylval) 17 | { 18 | for (;;) { 19 | tok = cur; 20 | /*!re2c 21 | re2c:define:YYCURSOR = cur; 22 | re2c:define:YYMARKER = mar; 23 | re2c:yyfill:enable = 0; 24 | re2c:define:YYCTYPE = "unsigned char"; 25 | 26 | end = "\x00"; 27 | whitespace = [ \t\v\n\r]+; 28 | dig = [0-9]; 29 | char = [\x80-\xff] | [a-zA-Z_]; 30 | operators = "-"|"+"|"/"|"("|")"|"*"|","|"^"|"~"|"<"|">"|"&"|"|"; 31 | 32 | pows = "**"|"@"; 33 | le = "<="; 34 | ge = ">="; 35 | eqs = "=="; 36 | ident = char (char | dig)*; 37 | numeric = (dig*"."?dig+([eE][-+]?dig+)?) | (dig+"."); 38 | implicitmul = numeric ident; 39 | 40 | * { throw SymEngine::ParseError("Unknown token: '"+token()+"'"); } 41 | end { return yytokentype::END_OF_FILE; } 42 | whitespace { continue; } 43 | 44 | // FIXME: 45 | operators { return tok[0]; } 46 | pows { return yytokentype::POW; } 47 | le { return yytokentype::LE; } 48 | ge { return yytokentype::GE; } 49 | eqs { return yytokentype::EQ; } 50 | ident { yylval.string=token(); return yytokentype::IDENTIFIER; } 51 | numeric { yylval.string=token(); return yytokentype::NUMERIC; } 52 | implicitmul { yylval.string=token(); return yytokentype::IMPLICIT_MUL; } 53 | */ 54 | } 55 | } 56 | 57 | } // namespace SymEngine 58 | -------------------------------------------------------------------------------- /symengine/polys/cancel.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_CANCEL_H 2 | #define SYMENGINE_CANCEL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace SymEngine 8 | { 9 | // Declaration of cancel function 10 | template 11 | inline void cancel(const RCP &numer, const RCP &denom, 12 | const Ptr> &result_numer, 13 | const Ptr> &result_denom, 14 | const Ptr> &common) 15 | { 16 | // Converting basic to Poly 17 | umap_basic_num numer_gens = _find_gens_poly(numer); 18 | umap_basic_num denom_gens = _find_gens_poly(denom); 19 | 20 | if (numer_gens.size() != 1 && denom_gens.size() != 1) { 21 | // only considering univariate here 22 | return; 23 | } 24 | RCP numer_var = numer_gens.begin()->first; 25 | RCP denom_var = denom_gens.begin()->first; 26 | 27 | RCP numer_poly = from_basic(numer, numer_var); 28 | RCP denom_poly = from_basic(denom, denom_var); 29 | 30 | // Finding common factors of numer_poly and denom_poly 31 | RCP gcd_poly = gcd_upoly(*numer_poly, *denom_poly); 32 | 33 | // Dividing both by common factors 34 | divides_upoly(*gcd_poly, *numer_poly, outArg(*result_numer)); 35 | divides_upoly(*gcd_poly, *denom_poly, outArg(*result_denom)); 36 | *common = gcd_poly; 37 | } 38 | } 39 | #endif // SYMENGINE_CANCEL_H 40 | -------------------------------------------------------------------------------- /symengine/polys/uexprpoly.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace SymEngine 4 | { 5 | 6 | UExprPoly::UExprPoly(const RCP &var, UExprDict &&dict) 7 | : USymEnginePoly(var, std::move(dict)) 8 | { 9 | SYMENGINE_ASSIGN_TYPEID() 10 | SYMENGINE_ASSERT(is_canonical(get_poly())) 11 | } 12 | 13 | hash_t UExprPoly::__hash__() const 14 | { 15 | hash_t seed = UEXPRPOLY; 16 | 17 | seed += get_var()->hash(); 18 | for (const auto &it : get_poly().dict_) { 19 | hash_t temp = UEXPRPOLY; 20 | hash_combine(temp, it.first); 21 | hash_combine(temp, *(it.second.get_basic())); 22 | seed += temp; 23 | } 24 | return seed; 25 | } 26 | 27 | Expression UExprPoly::max_coef() const 28 | { 29 | Expression curr = get_poly().get_dict().begin()->second; 30 | for (const auto &it : get_poly().get_dict()) 31 | if (curr.get_basic()->__cmp__(*it.second.get_basic())) 32 | curr = it.second; 33 | return curr; 34 | } 35 | 36 | Expression UExprPoly::eval(const Expression &x) const 37 | { 38 | Expression ans = 0; 39 | for (const auto &p : get_poly().get_dict()) { 40 | Expression temp; 41 | temp = pow(x, Expression(p.first)); 42 | ans += p.second * temp; 43 | } 44 | return ans; 45 | } 46 | 47 | bool UExprPoly::is_zero() const 48 | { 49 | return get_poly().empty(); 50 | } 51 | 52 | bool UExprPoly::is_one() const 53 | { 54 | return get_poly().size() == 1 and get_poly().get_dict().begin()->second == 1 55 | and get_poly().get_dict().begin()->first == 0; 56 | } 57 | 58 | bool UExprPoly::is_minus_one() const 59 | { 60 | return get_poly().size() == 1 61 | and get_poly().get_dict().begin()->second == -1 62 | and get_poly().get_dict().begin()->first == 0; 63 | } 64 | 65 | bool UExprPoly::is_integer() const 66 | { 67 | if (get_poly().empty()) 68 | return true; 69 | return get_poly().size() == 1 and get_poly().get_dict().begin()->first == 0; 70 | } 71 | 72 | bool UExprPoly::is_symbol() const 73 | { 74 | return get_poly().size() == 1 and get_poly().get_dict().begin()->first == 1 75 | and get_poly().get_dict().begin()->second == 1; 76 | } 77 | 78 | bool UExprPoly::is_mul() const 79 | { 80 | return get_poly().size() == 1 and get_poly().get_dict().begin()->first != 0 81 | and get_poly().get_dict().begin()->second != 1 82 | and get_poly().get_dict().begin()->second != 0; 83 | } 84 | 85 | bool UExprPoly::is_pow() const 86 | { 87 | return get_poly().size() == 1 and get_poly().get_dict().begin()->second == 1 88 | and get_poly().get_dict().begin()->first != 1 89 | and get_poly().get_dict().begin()->first != 0; 90 | } 91 | 92 | } // SymEngine 93 | -------------------------------------------------------------------------------- /symengine/polys/uintpoly.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace SymEngine 4 | { 5 | 6 | UIntPoly::UIntPoly(const RCP &var, UIntDict &&dict) 7 | : USymEnginePoly(var, std::move(dict)) 8 | { 9 | SYMENGINE_ASSIGN_TYPEID() 10 | SYMENGINE_ASSERT(is_canonical(get_poly())) 11 | } 12 | 13 | hash_t UIntPoly::__hash__() const 14 | { 15 | hash_t seed = UINTPOLY; 16 | 17 | seed += get_var()->hash(); 18 | for (const auto &it : get_poly().dict_) { 19 | hash_t temp = UINTPOLY; 20 | hash_combine(temp, it.first); 21 | hash_combine(temp, mp_get_si(it.second)); 22 | seed += temp; 23 | } 24 | return seed; 25 | } 26 | 27 | bool divides_upoly(const UIntPoly &a, const UIntPoly &b, 28 | const Ptr> &out) 29 | { 30 | if (!(a.get_var()->__eq__(*b.get_var()))) 31 | throw SymEngineException("Error: variables must agree."); 32 | 33 | auto a_poly = a.get_poly(); 34 | auto b_poly = b.get_poly(); 35 | if (a_poly.size() == 0) 36 | return false; 37 | 38 | map_uint_mpz res; 39 | UIntDict tmp; 40 | integer_class q, r; 41 | unsigned int a_deg, b_deg; 42 | 43 | while (b_poly.size() >= a_poly.size()) { 44 | a_deg = a_poly.degree(); 45 | b_deg = b_poly.degree(); 46 | 47 | mp_tdiv_qr(q, r, b_poly.get_lc(), a_poly.get_lc()); 48 | if (r != 0) 49 | return false; 50 | 51 | res[b_deg - a_deg] = q; 52 | UIntDict tmp = UIntDict({{b_deg - a_deg, q}}); 53 | b_poly -= (a_poly * tmp); 54 | } 55 | 56 | if (b_poly.empty()) { 57 | *out = UIntPoly::from_dict(a.get_var(), std::move(res)); 58 | return true; 59 | } else { 60 | return false; 61 | } 62 | } 63 | 64 | } // SymEngine 65 | -------------------------------------------------------------------------------- /symengine/polys/uintpoly_flint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace SymEngine 5 | { 6 | 7 | UIntPolyFlint::UIntPolyFlint(const RCP &var, fzp_t &&dict) 8 | : UFlintPoly(var, std::move(dict)) 9 | { 10 | SYMENGINE_ASSIGN_TYPEID() 11 | } 12 | 13 | hash_t UIntPolyFlint::__hash__() const 14 | { 15 | std::hash str_hash; 16 | hash_t seed = UINTPOLYFLINT; 17 | 18 | seed += get_var()->hash(); 19 | hash_combine(seed, str_hash(get_poly().to_string())); 20 | return seed; 21 | } 22 | 23 | URatPolyFlint::URatPolyFlint(const RCP &var, fqp_t &&dict) 24 | : UFlintPoly(var, std::move(dict)) 25 | { 26 | SYMENGINE_ASSIGN_TYPEID() 27 | } 28 | 29 | hash_t URatPolyFlint::__hash__() const 30 | { 31 | std::hash str_hash; 32 | hash_t seed = URATPOLYFLINT; 33 | 34 | seed += get_var()->hash(); 35 | hash_combine(seed, str_hash(get_poly().to_string())); 36 | return seed; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /symengine/polys/uintpoly_piranha.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace SymEngine 6 | { 7 | 8 | UIntPolyPiranha::UIntPolyPiranha(const RCP &var, pintpoly &&dict) 9 | : UPiranhaPoly(var, std::move(dict)) 10 | { 11 | SYMENGINE_ASSIGN_TYPEID() 12 | } 13 | 14 | hash_t UIntPolyPiranha::__hash__() const 15 | { 16 | hash_t seed = UINTPOLYPIRANHA; 17 | seed += get_poly().hash(); 18 | seed += get_var()->hash(); 19 | return seed; 20 | } 21 | 22 | URatPolyPiranha::URatPolyPiranha(const RCP &var, pratpoly &&dict) 23 | : UPiranhaPoly(var, std::move(dict)) 24 | { 25 | SYMENGINE_ASSIGN_TYPEID() 26 | } 27 | 28 | hash_t URatPolyPiranha::__hash__() const 29 | { 30 | hash_t seed = URATPOLYPIRANHA; 31 | seed += get_poly().hash(); 32 | seed += get_var()->hash(); 33 | return seed; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /symengine/polys/uratpoly.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace SymEngine 4 | { 5 | 6 | URatPoly::URatPoly(const RCP &var, URatDict &&dict) 7 | : USymEnginePoly(var, std::move(dict)) 8 | { 9 | SYMENGINE_ASSIGN_TYPEID() 10 | SYMENGINE_ASSERT(is_canonical(get_poly())) 11 | } 12 | 13 | hash_t URatPoly::__hash__() const 14 | { 15 | hash_t seed = URATPOLY; 16 | 17 | seed += get_var()->hash(); 18 | for (const auto &it : get_poly().dict_) { 19 | hash_t temp = URATPOLY; 20 | hash_combine(temp, it.first); 21 | hash_combine(temp, mp_get_si(get_num(it.second))); 22 | hash_combine(temp, mp_get_si(get_den(it.second))); 23 | seed += temp; 24 | } 25 | return seed; 26 | } 27 | 28 | bool divides_upoly(const URatPoly &a, const URatPoly &b, 29 | const Ptr> &out) 30 | { 31 | if (!(a.get_var()->__eq__(*b.get_var()))) 32 | throw SymEngineException("Error: variables must agree."); 33 | 34 | auto a_poly = a.get_poly(); 35 | auto b_poly = b.get_poly(); 36 | if (a_poly.size() == 0) 37 | return false; 38 | 39 | map_uint_mpq res; 40 | URatDict tmp; 41 | rational_class q, r; 42 | unsigned int a_deg, b_deg; 43 | 44 | while (b_poly.size() >= a_poly.size()) { 45 | a_deg = a_poly.degree(); 46 | b_deg = b_poly.degree(); 47 | q = b_poly.get_lc() / a_poly.get_lc(); 48 | res[b_deg - a_deg] = q; 49 | URatDict tmp = URatDict(map_uint_mpq{{b_deg - a_deg, q}}); 50 | b_poly -= (a_poly * tmp); 51 | } 52 | 53 | if (b_poly.empty()) { 54 | *out = URatPoly::from_dict(a.get_var(), std::move(res)); 55 | return true; 56 | } else { 57 | return false; 58 | } 59 | } 60 | 61 | } // SymEngine 62 | -------------------------------------------------------------------------------- /symengine/polys/uratpoly.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file uratpoly.h 3 | * Class for sparse Polynomial: URatPoly 4 | **/ 5 | #ifndef SYMENGINE_URATPOLY_H 6 | #define SYMENGINE_URATPOLY_H 7 | 8 | #include 9 | 10 | namespace SymEngine 11 | { 12 | 13 | class URatDict : public ODictWrapper 14 | { 15 | 16 | public: 17 | URatDict() SYMENGINE_NOEXCEPT 18 | { 19 | } 20 | ~URatDict() SYMENGINE_NOEXCEPT 21 | { 22 | } 23 | URatDict(URatDict &&other) SYMENGINE_NOEXCEPT 24 | : ODictWrapper(std::move(other)) 25 | { 26 | } 27 | URatDict(const int &i) : ODictWrapper(i) 28 | { 29 | } 30 | URatDict(const map_uint_mpq &p) : ODictWrapper(p) 31 | { 32 | } 33 | URatDict(const rational_class &i) : ODictWrapper(i) 34 | { 35 | } 36 | 37 | URatDict(const URatDict &) = default; 38 | URatDict &operator=(const URatDict &) = default; 39 | 40 | int compare(const URatDict &other) const 41 | { 42 | if (dict_.size() != other.dict_.size()) 43 | return (dict_.size() < other.dict_.size()) ? -1 : 1; 44 | return unified_compare(dict_, other.dict_); 45 | } 46 | }; // URatDict 47 | 48 | class URatPoly : public USymEnginePoly 49 | { 50 | public: 51 | IMPLEMENT_TYPEID(URATPOLY) 52 | //! Constructor of URatPoly class 53 | URatPoly(const RCP &var, URatDict &&dict); 54 | 55 | //! \return size of the hash 56 | hash_t __hash__() const; 57 | }; // URatPoly 58 | 59 | // true & sets `out` to b/a if a exactly divides b, otherwise false & undefined 60 | bool divides_upoly(const URatPoly &a, const URatPoly &b, 61 | const Ptr> &res); 62 | 63 | } // SymEngine 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /symengine/pow.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file pow.h 3 | * Power Class 4 | * 5 | **/ 6 | #ifndef SYMENGINE_POW_H 7 | #define SYMENGINE_POW_H 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace SymEngine 15 | { 16 | 17 | class Pow : public Basic 18 | { 19 | private: 20 | RCP base_, exp_; //! base**exp 21 | 22 | public: 23 | IMPLEMENT_TYPEID(POW) 24 | //! Pow Constructor 25 | Pow(const RCP &base, const RCP &exp); 26 | //! \return Size of the hash 27 | virtual hash_t __hash__() const; 28 | /*! Equality comparator 29 | * \param o - Object to be compared with 30 | * \return whether the 2 objects are equal 31 | * */ 32 | virtual bool __eq__(const Basic &o) const; 33 | virtual int compare(const Basic &o) const; 34 | //! \return `true` if canonical 35 | bool is_canonical(const Basic &base, const Basic &exp) const; 36 | //! \return `base` of `base**exp` 37 | inline RCP get_base() const 38 | { 39 | return base_; 40 | } 41 | //! \return `exp` of `base**exp` 42 | inline RCP get_exp() const 43 | { 44 | return exp_; 45 | } 46 | 47 | virtual vec_basic get_args() const; 48 | }; 49 | 50 | //! \return Pow from `a` and `b` 51 | RCP pow(const RCP &a, const RCP &b); 52 | 53 | //! Returns the natural exponential function `E**x = pow(E, x)` 54 | RCP exp(const RCP &x); 55 | 56 | void multinomial_coefficients(unsigned m, unsigned n, map_vec_uint &r); 57 | void multinomial_coefficients_mpz(unsigned m, unsigned n, map_vec_mpz &r); 58 | //! Expand the power expression 59 | RCP pow_expand(const RCP &self); 60 | //! \return square root of `x` 61 | inline RCP sqrt(const RCP &x) 62 | { 63 | return pow(x, div(one, integer(2))); 64 | } 65 | //! \return cube root of `x` 66 | inline RCP cbrt(const RCP &x) 67 | { 68 | return pow(x, div(one, integer(3))); 69 | } 70 | 71 | } // SymEngine 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /symengine/printers.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_PRINTER_H 2 | #define SYMENGINE_PRINTER_H 3 | 4 | #include 5 | 6 | namespace SymEngine 7 | { 8 | std::string str(const Basic &x); 9 | std::string julia_str(const Basic &x); 10 | std::string ascii_art(); 11 | 12 | std::string mathml(const Basic &x); 13 | 14 | std::string latex(const Basic &x); 15 | 16 | std::string ccode(const Basic &x); 17 | std::string c89code(const Basic &x); 18 | std::string c99code(const Basic &x); 19 | std::string jscode(const Basic &x); 20 | } 21 | 22 | #endif // SYMENGINE_PRINTER_H 23 | -------------------------------------------------------------------------------- /symengine/printers/codegen.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_CODEGEN_H 2 | #define SYMENGINE_CODEGEN_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace SymEngine 9 | { 10 | 11 | class CodePrinter : public BaseVisitor 12 | { 13 | public: 14 | using StrPrinter::str_; 15 | using StrPrinter::apply; 16 | using StrPrinter::bvisit; 17 | void bvisit(const Basic &x); 18 | void bvisit(const Complex &x); 19 | void bvisit(const Interval &x); 20 | void bvisit(const Contains &x); 21 | void bvisit(const Piecewise &x); 22 | void bvisit(const Rational &x); 23 | void bvisit(const EmptySet &x); 24 | void bvisit(const FiniteSet &x); 25 | void bvisit(const UniversalSet &x); 26 | void bvisit(const Abs &x); 27 | void bvisit(const Ceiling &x); 28 | void bvisit(const Truncate &x); 29 | void bvisit(const Max &x); 30 | void bvisit(const Min &x); 31 | void bvisit(const Constant &x); 32 | void bvisit(const NaN &x); 33 | void bvisit(const Equality &x); 34 | void bvisit(const Unequality &x); 35 | void bvisit(const LessThan &x); 36 | void bvisit(const StrictLessThan &x); 37 | void bvisit(const UnivariateSeries &x); 38 | void bvisit(const Derivative &x); 39 | void bvisit(const Subs &x); 40 | void bvisit(const GaloisField &x); 41 | }; 42 | 43 | class C89CodePrinter : public BaseVisitor 44 | { 45 | public: 46 | using CodePrinter::str_; 47 | using CodePrinter::apply; 48 | using CodePrinter::bvisit; 49 | void bvisit(const Infty &x); 50 | void _print_pow(std::ostringstream &o, const RCP &a, 51 | const RCP &b); 52 | }; 53 | 54 | class C99CodePrinter : public BaseVisitor 55 | { 56 | public: 57 | using C89CodePrinter::str_; 58 | using C89CodePrinter::apply; 59 | using C89CodePrinter::bvisit; 60 | void bvisit(const Infty &x); 61 | void _print_pow(std::ostringstream &o, const RCP &a, 62 | const RCP &b); 63 | void bvisit(const Gamma &x); 64 | void bvisit(const LogGamma &x); 65 | }; 66 | 67 | class JSCodePrinter : public BaseVisitor 68 | { 69 | public: 70 | using CodePrinter::str_; 71 | using CodePrinter::apply; 72 | using CodePrinter::bvisit; 73 | void bvisit(const Constant &x); 74 | void _print_pow(std::ostringstream &o, const RCP &a, 75 | const RCP &b); 76 | void bvisit(const Abs &x); 77 | void bvisit(const Sin &x); 78 | void bvisit(const Cos &x); 79 | void bvisit(const Max &x); 80 | void bvisit(const Min &x); 81 | }; 82 | } 83 | 84 | #endif // SYMENGINE_CODEGEN_H 85 | -------------------------------------------------------------------------------- /symengine/printers/latex.h: -------------------------------------------------------------------------------- 1 | #ifndef LATEX_H 2 | #define LATEX_H 3 | 4 | #include 5 | 6 | namespace SymEngine 7 | { 8 | 9 | class LatexPrinter : public BaseVisitor 10 | { 11 | public: 12 | using StrPrinter::bvisit; 13 | 14 | void bvisit(const Symbol &x); 15 | void bvisit(const Rational &x); 16 | void bvisit(const Complex &x); 17 | void bvisit(const ComplexBase &x); 18 | void bvisit(const ComplexDouble &x); 19 | #ifdef HAVE_SYMENGINE_MPC 20 | void bvisit(const ComplexMPC &x); 21 | #endif 22 | void bvisit(const Interval &x); 23 | void bvisit(const Piecewise &x); 24 | void bvisit(const EmptySet &x); 25 | void bvisit(const FiniteSet &x); 26 | void bvisit(const ConditionSet &x); 27 | void bvisit(const Contains &x); 28 | void bvisit(const BooleanAtom &x); 29 | void bvisit(const And &x); 30 | void bvisit(const Or &x); 31 | void bvisit(const Xor &x); 32 | void bvisit(const Not &x); 33 | void bvisit(const Union &x); 34 | void bvisit(const Complement &x); 35 | void bvisit(const ImageSet &x); 36 | void bvisit(const Infty &x); 37 | void bvisit(const NaN &x); 38 | void bvisit(const Constant &x); 39 | void bvisit(const Function &x); 40 | void bvisit(const Abs &x); 41 | void bvisit(const Floor &x); 42 | void bvisit(const Ceiling &x); 43 | void bvisit(const Derivative &x); 44 | void bvisit(const Subs &x); 45 | void bvisit(const Equality &x); 46 | void bvisit(const Unequality &x); 47 | void bvisit(const LessThan &x); 48 | void bvisit(const StrictLessThan &x); 49 | 50 | private: 51 | static const std::vector names_; 52 | 53 | protected: 54 | void print_with_args(const Basic &x, const std::string &join, 55 | std::ostringstream &s); 56 | virtual std::string parenthesize(const std::string &expr); 57 | virtual void _print_pow(std::ostringstream &o, const RCP &a, 58 | const RCP &b); 59 | virtual bool split_mul_coef(); 60 | virtual std::string print_mul(); 61 | virtual std::string print_div(const std::string &num, 62 | const std::string &den, bool paren); 63 | }; 64 | } 65 | 66 | #endif // LATEX_H 67 | -------------------------------------------------------------------------------- /symengine/printers/mathml.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_MATHML_H 2 | #define SYMENGINE_MATHML_H 3 | 4 | #include 5 | #include 6 | 7 | namespace SymEngine 8 | { 9 | class MathMLPrinter : public BaseVisitor 10 | { 11 | protected: 12 | std::ostringstream s; 13 | 14 | public: 15 | static const std::vector names_; 16 | void bvisit(const Basic &x); 17 | void bvisit(const Symbol &x); 18 | void bvisit(const Integer &x); 19 | void bvisit(const Rational &x); 20 | void bvisit(const ComplexBase &x); 21 | void bvisit(const Interval &x); 22 | void bvisit(const Piecewise &x); 23 | void bvisit(const EmptySet &x); 24 | void bvisit(const FiniteSet &x); 25 | void bvisit(const ConditionSet &x); 26 | void bvisit(const Contains &x); 27 | void bvisit(const BooleanAtom &x); 28 | void bvisit(const And &x); 29 | void bvisit(const Or &x); 30 | void bvisit(const Xor &x); 31 | void bvisit(const Not &x); 32 | void bvisit(const Union &x); 33 | void bvisit(const Complement &x); 34 | void bvisit(const ImageSet &x); 35 | void bvisit(const Add &x); 36 | void bvisit(const Mul &x); 37 | void bvisit(const Pow &x); 38 | void bvisit(const Constant &x); 39 | void bvisit(const Function &x); 40 | void bvisit(const FunctionSymbol &x); 41 | void bvisit(const Derivative &x); 42 | // void bvisit(const Subs &x); 43 | void bvisit(const RealDouble &x); 44 | void bvisit(const Equality &x); 45 | void bvisit(const Unequality &x); 46 | void bvisit(const LessThan &x); 47 | void bvisit(const StrictLessThan &x); 48 | #ifdef HAVE_SYMENGINE_MPFR 49 | void bvisit(const RealMPFR &x); 50 | #endif 51 | // void bvisit(const NumberWrapper &x); 52 | std::string apply(const Basic &b); 53 | }; 54 | } 55 | 56 | #endif // SYMENGINE_MATHML_H 57 | -------------------------------------------------------------------------------- /symengine/rings.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file rings.h 3 | * Polynomial Manipulation 4 | * 5 | **/ 6 | #ifndef SYMENGINE_RINGS_H 7 | #define SYMENGINE_RINGS_H 8 | 9 | #include 10 | 11 | namespace SymEngine 12 | { 13 | 14 | //! Converts expression `p` into a polynomial `P`, with symbols `sym` 15 | void expr2poly(const RCP &p, umap_basic_num &syms, 16 | umap_vec_mpz &P); 17 | 18 | //! Multiply two polynomials: `C = A*B` 19 | void poly_mul(const umap_vec_mpz &A, const umap_vec_mpz &B, umap_vec_mpz &C); 20 | 21 | } // SymEngine 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /symengine/symbol.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace SymEngine 5 | { 6 | 7 | Symbol::Symbol(const std::string &name) : name_{name} 8 | { 9 | SYMENGINE_ASSIGN_TYPEID() 10 | } 11 | 12 | hash_t Symbol::__hash__() const 13 | { 14 | hash_t seed = 0; 15 | hash_combine(seed, name_); 16 | return seed; 17 | } 18 | 19 | bool Symbol::__eq__(const Basic &o) const 20 | { 21 | if (is_a(o)) 22 | return name_ == down_cast(o).name_; 23 | return false; 24 | } 25 | 26 | int Symbol::compare(const Basic &o) const 27 | { 28 | SYMENGINE_ASSERT(is_a(o)) 29 | const Symbol &s = down_cast(o); 30 | if (name_ == s.name_) 31 | return 0; 32 | return name_ < s.name_ ? -1 : 1; 33 | } 34 | 35 | RCP Symbol::as_dummy() const 36 | { 37 | return dummy(name_); 38 | } 39 | 40 | size_t Dummy::count_ = 0; 41 | 42 | Dummy::Dummy() : Symbol("_Dummy_" + to_string(count_)) 43 | { 44 | SYMENGINE_ASSIGN_TYPEID() 45 | count_ += 1; 46 | dummy_index = count_; 47 | } 48 | 49 | Dummy::Dummy(const std::string &name) : Symbol("_" + name) 50 | { 51 | SYMENGINE_ASSIGN_TYPEID() 52 | count_ += 1; 53 | dummy_index = count_; 54 | } 55 | 56 | hash_t Dummy::__hash__() const 57 | { 58 | hash_t seed = 0; 59 | hash_combine(seed, get_name()); 60 | hash_combine(seed, dummy_index); 61 | return seed; 62 | } 63 | 64 | bool Dummy::__eq__(const Basic &o) const 65 | { 66 | if (is_a(o)) 67 | return ((get_name() == down_cast(o).get_name()) 68 | and (dummy_index == down_cast(o).get_index())); 69 | return false; 70 | } 71 | 72 | int Dummy::compare(const Basic &o) const 73 | { 74 | SYMENGINE_ASSERT(is_a(o)) 75 | const Dummy &s = down_cast(o); 76 | if (get_name() == s.get_name()) { 77 | if (dummy_index == s.get_index()) 78 | return 0; 79 | return dummy_index < s.get_index() ? -1 : 1; 80 | } 81 | return get_name() < s.get_name() ? -1 : 1; 82 | } 83 | 84 | } // SymEngine 85 | -------------------------------------------------------------------------------- /symengine/symbol.h: -------------------------------------------------------------------------------- 1 | /** 2 | * \file symbol.h 3 | * Class Symbol 4 | * 5 | **/ 6 | #ifndef SYMENGINE_SYMBOL_H 7 | #define SYMENGINE_SYMBOL_H 8 | 9 | #include 10 | 11 | namespace SymEngine 12 | { 13 | 14 | class Symbol : public Basic 15 | { 16 | private: 17 | //! name of Symbol 18 | std::string name_; 19 | 20 | public: 21 | IMPLEMENT_TYPEID(SYMBOL) 22 | //! Symbol Constructor 23 | explicit Symbol(const std::string &name); 24 | //! \return Size of the hash 25 | virtual hash_t __hash__() const; 26 | /*! Equality comparator 27 | * \param o - Object to be compared with 28 | * \return whether the 2 objects are equal 29 | * */ 30 | virtual bool __eq__(const Basic &o) const; 31 | 32 | /*! Comparison operator 33 | * \param o - Object to be compared with 34 | * \return `0` if equal, `-1` , `1` according to string compare 35 | * */ 36 | virtual int compare(const Basic &o) const; 37 | //! \return name of the Symbol. 38 | inline const std::string &get_name() const 39 | { 40 | return name_; 41 | } 42 | 43 | virtual vec_basic get_args() const 44 | { 45 | return {}; 46 | } 47 | RCP as_dummy() const; 48 | }; 49 | 50 | class Dummy : public Symbol 51 | { 52 | private: 53 | //! Dummy count 54 | static size_t count_; 55 | //! Dummy index 56 | size_t dummy_index; 57 | 58 | public: 59 | IMPLEMENT_TYPEID(DUMMY) 60 | //! Dummy Constructors 61 | explicit Dummy(); 62 | explicit Dummy(const std::string &name); 63 | //! \return Size of the hash 64 | virtual hash_t __hash__() const; 65 | /*! Equality comparator 66 | * \param o - Object to be compared with 67 | * \return whether the 2 objects are equal 68 | * */ 69 | virtual bool __eq__(const Basic &o) const; 70 | /*! Comparison operator 71 | * \param o - Object to be compared with 72 | * \return `0` if equal, `-1` , `1` according to string compare 73 | * */ 74 | virtual int compare(const Basic &o) const; 75 | size_t get_index() const 76 | { 77 | return dummy_index; 78 | } 79 | }; 80 | 81 | //! inline version to return `Symbol` 82 | inline RCP symbol(const std::string &name) 83 | { 84 | return make_rcp(name); 85 | } 86 | 87 | //! inline version to return `Dummy` 88 | inline RCP dummy() 89 | { 90 | return make_rcp(); 91 | } 92 | 93 | inline RCP dummy(const std::string &name) 94 | { 95 | return make_rcp(name); 96 | } 97 | 98 | } // SymEngine 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /symengine/symengine_assert.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_ASSERT_H 2 | #define SYMENGINE_ASSERT_H 3 | 4 | // SYMENGINE_ASSERT uses internal functions to perform as assert 5 | // so that there is no effect with NDEBUG 6 | #if defined(WITH_SYMENGINE_ASSERT) 7 | 8 | #if !defined(SYMENGINE_ASSERT) 9 | #define stringize(s) #s 10 | #define XSTR(s) stringize(s) 11 | #define SYMENGINE_ASSERT(cond) \ 12 | { \ 13 | if (!(cond)) { \ 14 | std::cerr << "SYMENGINE_ASSERT failed: " << __FILE__ \ 15 | << "\nfunction " << __func__ << "(), line number " \ 16 | << __LINE__ << " at \n" \ 17 | << XSTR(cond) << "\n"; \ 18 | abort(); \ 19 | } \ 20 | } 21 | #endif // !defined(SYMENGINE_ASSERT) 22 | 23 | #if !defined(SYMENGINE_ASSERT_MSG) 24 | #define SYMENGINE_ASSERT_MSG(cond, msg) \ 25 | { \ 26 | if (!(cond)) { \ 27 | std::cerr << "SYMENGINE_ASSERT failed: " << __FILE__ \ 28 | << "\nfunction " << __func__ << "(), line number " \ 29 | << __LINE__ << " at \n" \ 30 | << XSTR(cond) << "\n" \ 31 | << "ERROR MESSAGE:\n" \ 32 | << msg << "\n"; \ 33 | abort(); \ 34 | } \ 35 | } 36 | #endif // !defined(SYMENGINE_ASSERT_MSG) 37 | 38 | #else // defined(WITH_SYMENGINE_ASSERT) 39 | 40 | #define SYMENGINE_ASSERT(cond) 41 | #define SYMENGINE_ASSERT_MSG(cond, msg) 42 | 43 | #endif // defined(WITH_SYMENGINE_ASSERT) 44 | 45 | #define SYMENGINE_ERROR(description) \ 46 | std::cerr << description; \ 47 | std::cerr << "\n"; \ 48 | abort(); 49 | 50 | #endif // SYMENGINE_ASSERT_H 51 | -------------------------------------------------------------------------------- /symengine/symengine_config_cling.h.in: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_CONFIG_CLING_HPP 2 | #define SYMENGINE_CONFIG_CLING_HPP 3 | 4 | #pragma cling add_library_path(@SYMENGINE_CLING_LIBRARY_DIR@) 5 | #pragma cling load("@CMAKE_SHARED_LIBRARY_PREFIX@symengine") 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /symengine/symengine_exception.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_EXCEPTION_H 2 | #define SYMENGINE_EXCEPTION_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef enum { 9 | SYMENGINE_NO_EXCEPTION = 0, 10 | SYMENGINE_RUNTIME_ERROR = 1, 11 | SYMENGINE_DIV_BY_ZERO = 2, 12 | SYMENGINE_NOT_IMPLEMENTED = 3, 13 | SYMENGINE_DOMAIN_ERROR = 4, 14 | SYMENGINE_PARSE_ERROR = 5, 15 | } symengine_exceptions_t; 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | 21 | #ifdef __cplusplus 22 | 23 | #include 24 | #include 25 | 26 | namespace SymEngine 27 | { 28 | 29 | class SymEngineException : public std::exception 30 | { 31 | std::string m_msg; 32 | symengine_exceptions_t ec; 33 | 34 | public: 35 | SymEngineException(const std::string &msg, symengine_exceptions_t error) 36 | : m_msg(msg), ec(error) 37 | { 38 | } 39 | SymEngineException(const std::string &msg) 40 | : SymEngineException(msg, SYMENGINE_RUNTIME_ERROR) 41 | { 42 | } 43 | const char *what() const throw() 44 | { 45 | return m_msg.c_str(); 46 | } 47 | symengine_exceptions_t error_code() 48 | { 49 | return ec; 50 | } 51 | }; 52 | 53 | class DivisionByZeroError : public SymEngineException 54 | { 55 | public: 56 | DivisionByZeroError(const std::string &msg) 57 | : SymEngineException(msg, SYMENGINE_DIV_BY_ZERO) 58 | { 59 | } 60 | }; 61 | 62 | class NotImplementedError : public SymEngineException 63 | { 64 | public: 65 | NotImplementedError(const std::string &msg) 66 | : SymEngineException(msg, SYMENGINE_NOT_IMPLEMENTED) 67 | { 68 | } 69 | }; 70 | 71 | class DomainError : public SymEngineException 72 | { 73 | public: 74 | DomainError(const std::string &msg) 75 | : SymEngineException(msg, SYMENGINE_DOMAIN_ERROR) 76 | { 77 | } 78 | }; 79 | 80 | class ParseError : public SymEngineException 81 | { 82 | public: 83 | ParseError(const std::string &msg) 84 | : SymEngineException(msg, SYMENGINE_PARSE_ERROR) 85 | { 86 | } 87 | }; 88 | } 89 | #endif // __cplusplus 90 | #endif // SYMENGINE_EXCEPTION_H 91 | -------------------------------------------------------------------------------- /symengine/symengine_rcp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef WITH_SYMENGINE_TEUCHOS 4 | #include 5 | #endif 6 | 7 | namespace SymEngine 8 | { 9 | 10 | #ifdef WITH_SYMENGINE_RCP 11 | 12 | void print_stack_on_segfault() 13 | { 14 | #ifdef WITH_SYMENGINE_TEUCHOS 15 | Teuchos::print_stack_on_segfault(); 16 | #endif 17 | } 18 | 19 | #endif 20 | 21 | } // SymEngine 22 | -------------------------------------------------------------------------------- /symengine/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(BEFORE ${symengine_SOURCE_DIR}) 2 | # Include Catch headers: 3 | include_directories(BEFORE ${catch_SOURCE_DIR}) 4 | 5 | add_subdirectory(rcp) 6 | add_subdirectory(basic) 7 | add_subdirectory(ntheory) 8 | add_subdirectory(matrix) 9 | add_subdirectory(printing) 10 | add_subdirectory(polynomial) 11 | add_subdirectory(eval) 12 | add_subdirectory(cwrapper) 13 | add_subdirectory(expression) 14 | add_subdirectory(logic) 15 | add_subdirectory(finitediff) 16 | -------------------------------------------------------------------------------- /symengine/tests/basic/test_count_ops.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | 3 | #include 4 | 5 | using SymEngine::Basic; 6 | using SymEngine::RCP; 7 | using SymEngine::symbol; 8 | using SymEngine::integer; 9 | using SymEngine::one; 10 | using SymEngine::I; 11 | using SymEngine::pi; 12 | using SymEngine::count_ops; 13 | 14 | TEST_CASE("CountOps", "[count_ops]") 15 | { 16 | RCP x = symbol("x"); 17 | RCP y = symbol("y"); 18 | RCP i2 = integer(2); 19 | RCP r1; 20 | 21 | r1 = add(add(one, x), y); 22 | REQUIRE(count_ops({r1}) == 2); 23 | 24 | r1 = add(add(x, x), y); 25 | REQUIRE(count_ops({r1}) == 2); 26 | 27 | r1 = mul(mul(x, x), y); 28 | REQUIRE(count_ops({r1}) == 2); 29 | 30 | r1 = mul(mul(i2, x), y); 31 | REQUIRE(count_ops({r1}) == 2); 32 | 33 | r1 = add(add(I, one), sin(x)); 34 | REQUIRE(count_ops({r1}) == 3); 35 | 36 | r1 = add(add(mul(i2, I), one), sin(x)); 37 | REQUIRE(count_ops({r1}) == 4); 38 | 39 | r1 = add(I, pi); 40 | REQUIRE(count_ops({r1}) == 1); 41 | 42 | r1 = pow(pi, pi); 43 | REQUIRE(count_ops({r1}) == 1); 44 | 45 | REQUIRE(count_ops({x, y}) == 0); 46 | } 47 | -------------------------------------------------------------------------------- /symengine/tests/basic/test_integer.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | 3 | #include 4 | #include 5 | 6 | using SymEngine::SymEngineException; 7 | using SymEngine::print_stack_on_segfault; 8 | using SymEngine::RCP; 9 | using SymEngine::Integer; 10 | using SymEngine::integer; 11 | using SymEngine::integer_class; 12 | using SymEngine::isqrt; 13 | 14 | TEST_CASE("isqrt: integer", "[integer]") 15 | { 16 | RCP i10 = integer(10); 17 | RCP i19 = integer(19); 18 | RCP i25 = integer(25); 19 | 20 | REQUIRE(eq(*isqrt(*i10), *integer(3))); 21 | REQUIRE(eq(*isqrt(*i19), *integer(4))); 22 | REQUIRE(eq(*isqrt(*i25), *integer(5))); 23 | } 24 | 25 | TEST_CASE("i_nth_root: integer", "[integer]") 26 | { 27 | RCP i7 = integer(7); 28 | RCP i9 = integer(9); 29 | RCP i10 = integer(10); 30 | RCP r; 31 | 32 | REQUIRE(i_nth_root(outArg(r), *i7, 2) == 0); 33 | REQUIRE(eq(*r, *integer(2))); 34 | 35 | REQUIRE(i_nth_root(outArg(r), *i9, 2) != 0); 36 | REQUIRE(eq(*r, *integer(3))); 37 | 38 | REQUIRE(i_nth_root(outArg(r), *i9, 3) == 0); 39 | REQUIRE(eq(*r, *integer(2))); 40 | 41 | REQUIRE(i_nth_root(outArg(r), *i10, 2) == 0); 42 | REQUIRE(eq(*r, *integer(3))); 43 | } 44 | 45 | TEST_CASE("perfect_power_square: integer", "[integer]") 46 | { 47 | RCP i7 = integer(7); 48 | RCP i8 = integer(8); 49 | RCP i9 = integer(9); 50 | RCP i10 = integer(10); 51 | 52 | REQUIRE(perfect_square(*i7) == 0); 53 | REQUIRE(perfect_power(*i7) == 0); 54 | REQUIRE(perfect_square(*i8) == 0); 55 | REQUIRE(perfect_power(*i8) != 0); 56 | REQUIRE(perfect_square(*i9) != 0); 57 | REQUIRE(perfect_power(*i9) != 0); 58 | REQUIRE(perfect_square(*i10) == 0); 59 | REQUIRE(perfect_power(*i10) == 0); 60 | } 61 | 62 | TEST_CASE("iabs: integer", "[integer]") 63 | { 64 | RCP _i5 = integer(-5); 65 | RCP _i9 = integer(-9); 66 | RCP i12 = integer(12); 67 | 68 | REQUIRE(eq(*iabs(*_i5), *integer(5))); 69 | REQUIRE(eq(*iabs(*_i9), *integer(9))); 70 | REQUIRE(eq(*iabs(*i12), *integer(12))); 71 | } 72 | 73 | TEST_CASE("fix#461: integer", "[integer]") 74 | { 75 | RCP ir; 76 | 77 | long lmax = std::numeric_limits::max(); 78 | ir = integer(lmax); 79 | REQUIRE(integer_class(lmax) == ir->as_integer_class()); 80 | 81 | unsigned long ulmax = std::numeric_limits::max(); 82 | ir = integer(ulmax); 83 | REQUIRE(integer_class(ulmax) == ir->as_integer_class()); 84 | 85 | int imax = std::numeric_limits::max(); 86 | ir = integer(imax); 87 | REQUIRE(integer_class(imax) == ir->as_integer_class()); 88 | 89 | integer_class val(12345); 90 | ir = integer(val); 91 | REQUIRE(val == ir->as_integer_class()); 92 | } 93 | -------------------------------------------------------------------------------- /symengine/tests/basic/test_poly.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using SymEngine::SymEngineException; 11 | using SymEngine::Basic; 12 | using SymEngine::Add; 13 | using SymEngine::Mul; 14 | using SymEngine::Pow; 15 | using SymEngine::Symbol; 16 | using SymEngine::symbol; 17 | using SymEngine::umap_basic_num; 18 | using SymEngine::Integer; 19 | using SymEngine::integer; 20 | using SymEngine::map_vec_mpz; 21 | using SymEngine::expr2poly; 22 | using SymEngine::vec_int; 23 | using SymEngine::monomial_mul; 24 | using SymEngine::poly_mul; 25 | using SymEngine::umap_vec_mpz; 26 | using SymEngine::RCP; 27 | using SymEngine::rcp_dynamic_cast; 28 | using SymEngine::print_stack_on_segfault; 29 | 30 | TEST_CASE("monomial_mul: poly", "[poly]") 31 | { 32 | vec_int a, b, c, d; 33 | a = {1, 2, 3, 4}; 34 | b = {2, 3, 2, 5}; 35 | c = {0, 0, 0, 0}; 36 | 37 | monomial_mul(a, b, c); 38 | 39 | d = {3, 5, 5, 9}; 40 | REQUIRE(c == d); 41 | d = {5, 6, 5, 5}; 42 | REQUIRE(c != d); 43 | 44 | umap_vec_mpz m; 45 | m[a] = 4; 46 | } 47 | 48 | TEST_CASE("expand: poly", "[poly]") 49 | { 50 | RCP x = symbol("x"); 51 | RCP y = symbol("y"); 52 | RCP z = symbol("z"); 53 | RCP w = symbol("w"); 54 | RCP i4 = integer(2); 55 | 56 | RCP e, f1, f2, r; 57 | 58 | e = pow(add(add(add(x, y), z), w), i4); 59 | f1 = expand(e); 60 | f2 = expand(add(e, w)); 61 | 62 | umap_basic_num syms; 63 | insert(syms, x, integer(0)); 64 | insert(syms, y, integer(1)); 65 | insert(syms, z, integer(2)); 66 | insert(syms, w, integer(3)); 67 | 68 | umap_vec_mpz P1, P2, C; 69 | 70 | expr2poly(f1, syms, P1); 71 | expr2poly(f2, syms, P2); 72 | std::cout << "poly_mul start" << std::endl; 73 | auto t1 = std::chrono::high_resolution_clock::now(); 74 | poly_mul(P1, P2, C); 75 | auto t2 = std::chrono::high_resolution_clock::now(); 76 | std::cout << "poly_mul stop" << std::endl; 77 | 78 | /* 79 | std::cout << *e << std::endl; 80 | std::cout << *f1 << std::endl; 81 | std::cout << P1 << std::endl; 82 | std::cout << *f2 << std::endl; 83 | std::cout << P2 << std::endl; 84 | std::cout << "RESULT:" << std::endl; 85 | std::cout << C << std::endl; 86 | */ 87 | std::cout << std::chrono::duration_cast(t2 - t1) 88 | .count() 89 | << "ms" << std::endl; 90 | } 91 | -------------------------------------------------------------------------------- /symengine/tests/basic/test_series.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using SymEngine::Basic; 11 | using SymEngine::Integer; 12 | using SymEngine::integer; 13 | using SymEngine::rational; 14 | using SymEngine::Symbol; 15 | using SymEngine::Number; 16 | using SymEngine::symbol; 17 | using SymEngine::Add; 18 | using SymEngine::RCP; 19 | using SymEngine::add; 20 | using SymEngine::sin; 21 | using SymEngine::cos; 22 | using SymEngine::series; 23 | using SymEngine::down_cast; 24 | 25 | TEST_CASE("Expression series expansion interface", "[Expansion interface]") 26 | { 27 | RCP x = symbol("x"), y = symbol("y"); 28 | auto ex = div(integer(1), add(integer(1), x)); 29 | 30 | auto ser = series(ex, x, 10); 31 | 32 | REQUIRE(down_cast(*(ser->get_coeff(7))).is_minus_one()); 33 | REQUIRE(down_cast(*(ser->as_dict()[8])).is_one()); 34 | REQUIRE(ser->as_basic()->__str__() 35 | == "1 - x + x**2 - x**3 + x**4 - x**5 + x**6 - x**7 + x**8 - x**9"); 36 | } 37 | -------------------------------------------------------------------------------- /symengine/tests/cwrapper/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_cwrapper) 2 | 3 | add_executable(${PROJECT_NAME} test_cwrapper.c) 4 | target_link_libraries(${PROJECT_NAME} symengine) 5 | add_test(${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}) 6 | -------------------------------------------------------------------------------- /symengine/tests/eval/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_eval) 2 | 3 | if (HAVE_SYMENGINE_MPFR) 4 | add_executable(test_eval_mpfr test_eval_mpfr.cpp) 5 | target_link_libraries(test_eval_mpfr symengine catch) 6 | add_test(test_eval_mpfr ${PROJECT_BINARY_DIR}/test_eval_mpfr) 7 | endif() 8 | 9 | if (HAVE_SYMENGINE_ARB) 10 | add_executable(test_eval_arb test_eval_arb.cpp) 11 | target_link_libraries(test_eval_arb symengine catch) 12 | add_test(test_eval_arb ${PROJECT_BINARY_DIR}/test_eval_arb) 13 | endif() 14 | 15 | if (HAVE_SYMENGINE_MPC) 16 | add_executable(test_eval_mpc test_eval_mpc.cpp) 17 | target_link_libraries(test_eval_mpc symengine catch) 18 | add_test(test_eval_mpc ${PROJECT_BINARY_DIR}/test_eval_mpc) 19 | endif() 20 | 21 | add_executable(test_evalf test_evalf.cpp) 22 | target_link_libraries(test_evalf symengine catch) 23 | add_test(test_evalf ${PROJECT_BINARY_DIR}/test_evalf) 24 | 25 | add_executable(test_eval_double test_eval_double.cpp) 26 | target_link_libraries(test_eval_double symengine catch) 27 | add_test(test_eval_double ${PROJECT_BINARY_DIR}/test_eval_double) 28 | 29 | add_executable(test_lambda_double test_lambda_double.cpp) 30 | target_link_libraries(test_lambda_double symengine catch) 31 | add_test(test_lambda_double ${PROJECT_BINARY_DIR}/test_lambda_double) 32 | -------------------------------------------------------------------------------- /symengine/tests/expression/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_expression) 2 | 3 | add_executable(${PROJECT_NAME} test_expression.cpp) 4 | target_link_libraries(${PROJECT_NAME} symengine catch) 5 | add_test(${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}) 6 | -------------------------------------------------------------------------------- /symengine/tests/finitediff/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_finitediff) 2 | 3 | add_executable(${PROJECT_NAME} test_finitediff.cpp) 4 | target_link_libraries(${PROJECT_NAME} symengine catch) 5 | add_test(${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}) 6 | -------------------------------------------------------------------------------- /symengine/tests/finitediff/test_finitediff.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using SymEngine::div; 8 | using SymEngine::eq; 9 | using SymEngine::integer; 10 | using SymEngine::vec_basic; 11 | 12 | TEST_CASE("finitediff: generate_fdiff_weights_vector", "[finitediff]") 13 | { 14 | vec_basic grid{integer(-1), integer(0), integer(1)}; 15 | auto weights = generate_fdiff_weights_vector(grid, 2, integer(0)); 16 | REQUIRE(weights.size() == 9); 17 | 18 | REQUIRE(eq(*weights[0], *integer(0))); 19 | REQUIRE(eq(*weights[1], *integer(1))); 20 | REQUIRE(eq(*weights[2], *integer(0))); 21 | 22 | REQUIRE(eq(*weights[3], *div(integer(-1), integer(2)))); 23 | REQUIRE(eq(*weights[4], *integer(0))); 24 | REQUIRE(eq(*weights[5], *div(integer(1), integer(2)))); 25 | 26 | REQUIRE(eq(*weights[6], *integer(1))); 27 | REQUIRE(eq(*weights[7], *integer(-2))); 28 | REQUIRE(eq(*weights[8], *integer(1))); 29 | 30 | vec_basic grid7{integer(0), integer(1), integer(2), integer(3), 31 | integer(4), integer(5), integer(6)}; 32 | auto weights7 = generate_fdiff_weights_vector(grid7, 2, integer(3)); 33 | REQUIRE(weights7.size() == 3 * 7); 34 | 35 | REQUIRE(eq(*weights7[7], *div(integer(-1), integer(60)))); 36 | REQUIRE(eq(*weights7[8], *div(integer(3), integer(20)))); 37 | REQUIRE(eq(*weights7[9], *div(integer(-3), integer(4)))); 38 | REQUIRE(eq(*weights7[10], *integer(0))); 39 | REQUIRE(eq(*weights7[11], *div(integer(3), integer(4)))); 40 | REQUIRE(eq(*weights7[12], *div(integer(-3), integer(20)))); 41 | REQUIRE(eq(*weights7[13], *div(integer(1), integer(60)))); 42 | 43 | REQUIRE(eq(*weights7[14], *div(integer(1), integer(90)))); 44 | REQUIRE(eq(*weights7[15], *div(integer(-3), integer(20)))); 45 | REQUIRE(eq(*weights7[16], *div(integer(3), integer(2)))); 46 | REQUIRE(eq(*weights7[17], *div(integer(-49), integer(18)))); 47 | REQUIRE(eq(*weights7[18], *div(integer(3), integer(2)))); 48 | REQUIRE(eq(*weights7[19], *div(integer(-3), integer(20)))); 49 | REQUIRE(eq(*weights7[20], *div(integer(1), integer(90)))); 50 | } 51 | -------------------------------------------------------------------------------- /symengine/tests/logic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_logic) 2 | 3 | add_executable(test_logic test_logic.cpp) 4 | target_link_libraries(test_logic symengine catch) 5 | add_test(test_logic ${PROJECT_BINARY_DIR}/test_logic) 6 | -------------------------------------------------------------------------------- /symengine/tests/matrix/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_matrix) 2 | 3 | add_executable(test_matrix test_matrix.cpp) 4 | target_link_libraries(test_matrix symengine catch) 5 | add_test(test_matrix ${PROJECT_BINARY_DIR}/test_matrix) 6 | -------------------------------------------------------------------------------- /symengine/tests/ntheory/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_ntheory) 2 | 3 | add_executable(test_ntheory test_ntheory.cpp) 4 | target_link_libraries(test_ntheory symengine catch) 5 | add_test(test_ntheory ${PROJECT_BINARY_DIR}/test_ntheory) 6 | 7 | add_executable(test_diophantine test_diophantine.cpp) 8 | target_link_libraries(test_diophantine symengine catch) 9 | add_test(test_diophantine ${PROJECT_BINARY_DIR}/test_diophantine) 10 | -------------------------------------------------------------------------------- /symengine/tests/polynomial/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_polynomial) 2 | 3 | add_executable(test_uintpoly test_uintpoly.cpp) 4 | target_link_libraries(test_uintpoly symengine catch) 5 | add_test(test_uintpoly ${PROJECT_BINARY_DIR}/test_uintpoly) 6 | 7 | add_executable(test_uratpoly test_uratpoly.cpp) 8 | target_link_libraries(test_uratpoly symengine catch) 9 | add_test(test_uratpoly ${PROJECT_BINARY_DIR}/test_uratpoly) 10 | 11 | add_executable(test_mintpoly test_mintpoly.cpp) 12 | target_link_libraries(test_mintpoly symengine catch) 13 | add_test(test_mintpoly ${PROJECT_BINARY_DIR}/test_mintpoly) 14 | 15 | add_executable(test_uexprpoly test_uexprpoly.cpp) 16 | target_link_libraries(test_uexprpoly symengine catch) 17 | add_test(test_uexprpoly ${PROJECT_BINARY_DIR}/test_uexprpoly) 18 | 19 | add_executable(test_mexprpoly test_mexprpoly.cpp) 20 | target_link_libraries(test_mexprpoly symengine catch) 21 | add_test(test_mexprpoly ${PROJECT_BINARY_DIR}/test_mexprpoly) 22 | 23 | add_executable(test_basic_conversions test_basic_conversions.cpp) 24 | target_link_libraries(test_basic_conversions symengine catch) 25 | add_test(test_basic_conversions ${PROJECT_BINARY_DIR}/test_basic_conversions) 26 | 27 | if (WITH_FLINT) 28 | add_executable(test_uintpoly_flint test_uintpoly_flint.cpp) 29 | target_link_libraries(test_uintpoly_flint symengine catch) 30 | add_test(test_uintpoly_flint ${PROJECT_BINARY_DIR}/test_uintpoly_flint) 31 | 32 | add_executable(test_uratpoly_flint test_uratpoly_flint.cpp) 33 | target_link_libraries(test_uratpoly_flint symengine catch) 34 | add_test(test_uratpoly_flint ${PROJECT_BINARY_DIR}/test_uratpoly_flint) 35 | 36 | add_executable(test_cancel test_cancel.cpp) 37 | target_link_libraries(test_cancel symengine catch) 38 | add_test(test_cancel ${PROJECT_BINARY_DIR}/test_cancel) 39 | endif() 40 | 41 | if (WITH_PIRANHA) 42 | add_executable(test_uintpoly_piranha test_uintpoly_piranha.cpp) 43 | target_link_libraries(test_uintpoly_piranha symengine catch) 44 | add_test(test_uintpoly_piranha ${PROJECT_BINARY_DIR}/test_uintpoly_piranha) 45 | 46 | add_executable(test_uratpoly_piranha test_uratpoly_piranha.cpp) 47 | target_link_libraries(test_uratpoly_piranha symengine catch) 48 | add_test(test_uratpoly_piranha ${PROJECT_BINARY_DIR}/test_uratpoly_piranha) 49 | endif() 50 | -------------------------------------------------------------------------------- /symengine/tests/polynomial/test_cancel.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | using SymEngine::Basic; 8 | using SymEngine::RCP; 9 | using SymEngine::UIntPolyFlint; 10 | using SymEngine::cancel; 11 | using SymEngine::exp; 12 | using SymEngine::integer; 13 | using SymEngine::mul; 14 | using SymEngine::pow; 15 | using SymEngine::sub; 16 | using SymEngine::symbol; 17 | 18 | using namespace SymEngine::literals; 19 | 20 | TEST_CASE("cancel", "[Basic]") 21 | { 22 | RCP x = symbol("x"); 23 | RCP y = symbol("y"); 24 | RCP numer, denom, common; 25 | 26 | // 2*x / x = 2 / 1 27 | cancel(mul(x, integer(2)), x, outArg(numer), outArg(denom), outArg(common)); 28 | REQUIRE(numer->__str__() == "2"); 29 | REQUIRE(denom->__str__() == "1"); 30 | REQUIRE(common->__str__() == "x"); 31 | 32 | // (x**2 - 4) / (x + 2) = x - 2 33 | cancel(sub(mul(x, x), integer(4)), add(x, integer(2)), outArg(numer), 34 | outArg(denom), outArg(common)); 35 | REQUIRE(numer->__str__() == "x - 2"); 36 | REQUIRE(denom->__str__() == "1"); 37 | REQUIRE(common->__str__() == "x + 2"); 38 | 39 | // (x**2 - 4) / (x - 2) = x + 2 40 | cancel(sub(mul(x, x), integer(4)), sub(x, integer(2)), outArg(numer), 41 | outArg(denom), outArg(common)); 42 | REQUIRE(numer->__str__() == "x + 2"); 43 | REQUIRE(denom->__str__() == "1"); 44 | REQUIRE(common->__str__() == "x - 2"); 45 | 46 | // (x**2 + x + 1) / (x + 1) = x - 1 47 | cancel(sub(pow(x, 3), integer(1)), sub(pow(x, 2), integer(1)), 48 | outArg(numer), outArg(denom), outArg(common)); 49 | REQUIRE(numer->__str__() == "x**2 + x + 1"); 50 | REQUIRE(denom->__str__() == "x + 1"); 51 | REQUIRE(common->__str__() == "x - 1"); 52 | 53 | // (exp(2*x) + 2*exp(x) + 1) / (exp(x) + 1) = exp(x) + 1 54 | cancel( 55 | add(add(exp(mul(integer(2), x)), mul(integer(2), exp(x))), integer(1)), 56 | add(exp(x), integer(1)), outArg(numer), outArg(denom), outArg(common)); 57 | REQUIRE(numer->__str__() == "exp(x) + 1"); 58 | REQUIRE(denom->__str__() == "1"); 59 | REQUIRE(common->__str__() == "exp(x) + 1"); 60 | } 61 | -------------------------------------------------------------------------------- /symengine/tests/printing/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_printing) 2 | 3 | add_executable(test_printing test_printing.cpp) 4 | target_link_libraries(test_printing symengine catch) 5 | add_test(test_printing ${PROJECT_BINARY_DIR}/test_printing) 6 | 7 | add_executable(test_ccode test_ccode.cpp) 8 | target_link_libraries(test_ccode symengine catch) 9 | add_test(test_ccode ${PROJECT_BINARY_DIR}/test_ccode) 10 | -------------------------------------------------------------------------------- /symengine/tests/rcp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_rcp) 2 | 3 | add_executable(${PROJECT_NAME} test_rcp.cpp) 4 | target_link_libraries(${PROJECT_NAME} symengine catch) 5 | add_test(${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}) 6 | 7 | -------------------------------------------------------------------------------- /symengine/utilities/catch/.gitattributes: -------------------------------------------------------------------------------- 1 | catch.hpp binary 2 | -------------------------------------------------------------------------------- /symengine/utilities/catch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(catch) 2 | 3 | set(SRC 4 | catch.cpp 5 | ) 6 | 7 | add_library(catch STATIC ${SRC}) 8 | target_link_libraries(catch symengine) 9 | -------------------------------------------------------------------------------- /symengine/utilities/catch/catch.cpp: -------------------------------------------------------------------------------- 1 | // This tells Catch to provide a main() - only do this in one cpp file: 2 | // User defined macros can be added in this file 3 | 4 | #define CATCH_CONFIG_RUNNER 5 | #define CATCH_CONFIG_SFINAE 6 | #include "catch.hpp" 7 | 8 | #include 9 | #include 10 | 11 | #if defined(HAVE_SYMENGINE_MPFR) 12 | #include 13 | #endif // HAVE_SYMENGINE_MPFR 14 | 15 | #if defined(HAVE_SYMENGINE_ARB) 16 | #include 17 | #endif // HAVE_SYMENGINE_ARB 18 | 19 | using SymEngine::print_stack_on_segfault; 20 | 21 | int main(int argc, char* argv[]) 22 | { 23 | print_stack_on_segfault(); 24 | int result = Catch::Session().run( argc, argv ); 25 | 26 | #if defined(HAVE_SYMENGINE_MPFR) 27 | mpfr_free_cache(); 28 | #endif // HAVE_SYMENGINE_MPFR 29 | 30 | #if defined(HAVE_SYMENGINE_ARB) 31 | flint_cleanup(); 32 | #endif // HAVE_SYMENGINE_ARB 33 | 34 | return result; 35 | } 36 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(matchpycpp) 2 | 3 | include_directories(BEFORE ${symengine_SOURCE_DIR}) 4 | include_directories(BEFORE ${symengine_BINARY_DIR}) 5 | include_directories(BEFORE ${teuchos_SOURCE_DIR}) 6 | include_directories(BEFORE ${teuchos_BINARY_DIR}) 7 | 8 | set(SRC 9 | ) 10 | 11 | set(HEADER 12 | bipartite.h 13 | common.h 14 | generator_trick.h 15 | many_to_one.h 16 | substitution.h 17 | util.h 18 | ) 19 | 20 | include_directories(BEFORE ${matchpycpp_BINARY_DIR}) 21 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/README.md: -------------------------------------------------------------------------------- 1 | # MatchPyCpp library. 2 | 3 | This module is a partial translation into C++ of 4 | [MatchPy](https://github.com/HPAC/matchpy). It provides tools to generate 5 | decision trees out of MatchPy patterns defined using SymPy expressions. In 6 | particular, the generated code represents the decision tree of a many-to-one 7 | matcher of MatchPy, which is an object able to perform many 8 | associative-commutative matchings at the same time. 9 | 10 | The class `CppCodeGenerator` in `cpp_code_generation.py` is responsible for 11 | generating C++ decision trees, mimicking MatchPy's `CodeGenerator` class. 12 | 13 | ## Usage example 14 | 15 | Clone MatchPy and checkout some past commit (the current wrapper in SymPy is not compatible with the latest MatchPy commit): 16 | 17 | ```bash 18 | git clone https://github.com/HPAC/matchpy 19 | cd matchpy 20 | git checkout 419c103 21 | ``` 22 | 23 | Make sure that MatchPy is in the `PYTHONPATH`. 24 | 25 | Import the MatchPy wrapper from SymPy: 26 | 27 | ```python 28 | from sympy.integrals.rubi.utility_function import * 29 | from sympy.integrals.rubi.symbol import WC 30 | ``` 31 | 32 | Note: the `utility_function` module needs to be imported as the link between SymPy and MatchPy expressions is defined there. 33 | 34 | Import MatchPy and create a many-to-one matcher object: 35 | 36 | ```python 37 | from matchpy import * 38 | 39 | matcher = ManyToOneMatcher() 40 | ``` 41 | 42 | Define SymPy variables and a MatchPy-SymPy wilcard `w`: 43 | 44 | ```python 45 | w = WC("w") 46 | x, y, z = symbols("x y z") 47 | ``` 48 | 49 | Add some expressions to the many-to-one matcher: 50 | 51 | ```python 52 | matcher.add(Pattern(x+y)) 53 | matcher.add(Pattern(2**w)) 54 | ``` 55 | 56 | Use MatchPy to match an expression: 57 | 58 | ```python 59 | >>> list(matcher.match(2**z)) 60 | [(Pattern(2**w), {'w': z})] 61 | ``` 62 | 63 | which means that pattern `2**w` matches the expression `2**z` with substitution `{'w': z}`. 64 | 65 | The C++ code performing the same matching can be generated with: 66 | 67 | ```python 68 | from cpp_code_generation import CppCodeGenerator 69 | cg = CppCodeGenerator(matcher) 70 | part1, part2 = cg.generate_code() 71 | ``` 72 | 73 | Now write `part1` and `part2` to a file: 74 | 75 | ```python 76 | fout = open("sample_matching_test.cpp", "w") 77 | fout.write(part1) 78 | fout.write(part2) 79 | fout.close() 80 | ``` 81 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/autogen_tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(matchpycpp_tests) 2 | include_directories(BEFORE ${catch_SOURCE_DIR}) 3 | 4 | add_executable(test_case001 test_case001.cpp) 5 | target_link_libraries(test_case001 symengine catch) 6 | add_test(test_case001 test_case001) 7 | 8 | add_executable(test_case002 test_case002.cpp) 9 | target_link_libraries(test_case002 symengine catch) 10 | add_test(test_case002 test_case002) 11 | 12 | add_executable(test_case003 test_case003.cpp) 13 | target_link_libraries(test_case003 symengine catch) 14 | add_test(test_case003 test_case003) 15 | 16 | add_executable(test_case004 test_case004.cpp) 17 | target_link_libraries(test_case004 symengine catch) 18 | add_test(test_case004 test_case004) 19 | 20 | add_executable(test_case005 test_case005.cpp) 21 | target_link_libraries(test_case005 symengine catch) 22 | add_test(test_case005 test_case005) 23 | 24 | add_executable(test_case006 test_case006.cpp) 25 | target_link_libraries(test_case006 symengine catch) 26 | add_test(test_case006 test_case006) 27 | 28 | add_executable(test_case007 test_case007.cpp) 29 | target_link_libraries(test_case007 symengine catch) 30 | add_test(test_case007 test_case007) 31 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/autogen_tests/test_case001.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was automatically generated: DO NOT EDIT. 3 | * 4 | * Use symengine/utilities/matchpycpp/generate_tests.py to generate this file. 5 | * 6 | * Decision tree matching expressions: 7 | * ['x'] 8 | * 9 | * Wildcards: 10 | * [] 11 | */ 12 | #include "catch.hpp" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | RCP x = symbol("x"); 25 | RCP y = symbol("y"); 26 | 27 | generator> 28 | match_root(const RCP &subject) 29 | { 30 | generator> result; 31 | Deque subjects; 32 | subjects.push_front(subject); 33 | SubstitutionMultiset subst0; 34 | // State 2194 35 | if (subjects.size() >= 1 && eq(*subjects[0], *x)) { 36 | RCP tmp1 = subjects.front(); 37 | subjects.pop_front(); 38 | // State 2195 39 | if (subjects.size() == 0) { 40 | // 0: x 41 | result.push_back(make_tuple(0, subst0)); 42 | } 43 | subjects.push_front(tmp1); 44 | } 45 | return result; 46 | } 47 | 48 | TEST_CASE("GeneratedMatchPyTest1", "") 49 | { 50 | generator> ret; 51 | SubstitutionMultiset substitution; 52 | 53 | // Pattern x matching x with substitution {}: 54 | ret = match_root(x); 55 | REQUIRE(ret.size() > 0); 56 | REQUIRE(get<0>(ret[0]) == 0); 57 | substitution = get<1>(ret[0]); 58 | 59 | // Pattern y not matching: 60 | ret = match_root(y); 61 | REQUIRE(ret.size() == 0); 62 | } 63 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/autogen_tests/test_case002.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was automatically generated: DO NOT EDIT. 3 | * 4 | * Use symengine/utilities/matchpycpp/generate_tests.py to generate this file. 5 | * 6 | * Decision tree matching expressions: 7 | * ['x**y'] 8 | * 9 | * Wildcards: 10 | * [] 11 | */ 12 | #include "catch.hpp" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | RCP x = symbol("x"); 25 | RCP y = symbol("y"); 26 | RCP z = symbol("z"); 27 | 28 | generator> 29 | match_root(const RCP &subject) 30 | { 31 | generator> result; 32 | Deque subjects; 33 | subjects.push_front(subject); 34 | SubstitutionMultiset subst0; 35 | // State 2196 36 | if (subjects.size() >= 1 && is_a(*subjects[0])) { 37 | RCP tmp1 = subjects.front(); 38 | subjects.pop_front(); 39 | Deque subjects2 = get_deque(tmp1); 40 | // State 2197 41 | if (subjects2.size() >= 1 && eq(*subjects2[0], *x)) { 42 | RCP tmp3 = subjects2.front(); 43 | subjects2.pop_front(); 44 | // State 2198 45 | if (subjects2.size() >= 1 && eq(*subjects2[0], *y)) { 46 | RCP tmp4 = subjects2.front(); 47 | subjects2.pop_front(); 48 | // State 2199 49 | if (subjects2.size() == 0) { 50 | // State 2200 51 | if (subjects.size() == 0) { 52 | // 0: x**y 53 | result.push_back(make_tuple(0, subst0)); 54 | } 55 | } 56 | subjects2.push_front(tmp4); 57 | } 58 | subjects2.push_front(tmp3); 59 | } 60 | subjects.push_front(tmp1); 61 | } 62 | return result; 63 | } 64 | 65 | TEST_CASE("GeneratedMatchPyTest2", "") 66 | { 67 | generator> ret; 68 | SubstitutionMultiset substitution; 69 | 70 | // Pattern x**y matching x**y with substitution {}: 71 | ret = match_root(pow(x, y)); 72 | REQUIRE(ret.size() > 0); 73 | REQUIRE(get<0>(ret[0]) == 0); 74 | substitution = get<1>(ret[0]); 75 | 76 | // Pattern x**z not matching: 77 | ret = match_root(pow(x, z)); 78 | REQUIRE(ret.size() == 0); 79 | } 80 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/autogen_tests/test_case005.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was automatically generated: DO NOT EDIT. 3 | * 4 | * Use symengine/utilities/matchpycpp/generate_tests.py to generate this file. 5 | * 6 | * Decision tree matching expressions: 7 | * ['x**w'] 8 | * 9 | * Wildcards: 10 | * ['w'] 11 | */ 12 | #include "catch.hpp" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | RCP x = symbol("x"); 25 | RCP y = symbol("y"); 26 | 27 | generator> 28 | match_root(const RCP &subject) 29 | { 30 | generator> result; 31 | Deque subjects; 32 | subjects.push_front(subject); 33 | SubstitutionMultiset subst0; 34 | // State 2217 35 | if (subjects.size() >= 1 && is_a(*subjects[0])) { 36 | RCP tmp1 = subjects.front(); 37 | subjects.pop_front(); 38 | Deque subjects2 = get_deque(tmp1); 39 | // State 2218 40 | if (subjects2.size() >= 1 && eq(*subjects2[0], *x)) { 41 | RCP tmp3 = subjects2.front(); 42 | subjects2.pop_front(); 43 | // State 2219 44 | if (subjects2.size() >= 1) { 45 | RCP tmp4 = subjects2.front(); 46 | subjects2.pop_front(); 47 | SubstitutionMultiset subst1 = SubstitutionMultiset(subst0); 48 | if (!try_add_variable(subst1, "i2", tmp4)) { 49 | // State 2220 50 | if (subjects2.size() == 0) { 51 | // State 2221 52 | if (subjects.size() == 0) { 53 | SubstitutionMultiset tmp_subst; 54 | tmp_subst["w"] = subst1["i2"]; 55 | // 0: x**w 56 | result.push_back(make_tuple(0, tmp_subst)); 57 | } 58 | } 59 | } 60 | subjects2.push_front(tmp4); 61 | } 62 | subjects2.push_front(tmp3); 63 | } 64 | subjects.push_front(tmp1); 65 | } 66 | return result; 67 | } 68 | 69 | TEST_CASE("GeneratedMatchPyTest5", "") 70 | { 71 | generator> ret; 72 | SubstitutionMultiset substitution; 73 | 74 | // Pattern x + y not matching: 75 | ret = match_root(add(x, y)); 76 | REQUIRE(ret.size() == 0); 77 | 78 | // Pattern x**w matching x**2 with substitution {}: 79 | ret = match_root(pow(x, integer(2))); 80 | REQUIRE(ret.size() > 0); 81 | REQUIRE(get<0>(ret[0]) == 0); 82 | substitution = get<1>(ret[0]); 83 | 84 | // Pattern x**w matching x**3 with substitution {}: 85 | ret = match_root(pow(x, integer(3))); 86 | REQUIRE(ret.size() > 0); 87 | REQUIRE(get<0>(ret[0]) == 0); 88 | substitution = get<1>(ret[0]); 89 | } 90 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/common.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_UTILITIES_MATCHPYCPP_COMMON_H_ 2 | #define SYMENGINE_UTILITIES_MATCHPYCPP_COMMON_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include "substitution.h" 15 | 16 | using namespace std; 17 | using namespace SymEngine; 18 | 19 | template 20 | using generator = vector; 21 | 22 | // Assuming TLeft = TRight, otherwise 23 | // Node should be tuple> 24 | #define TYPES_DERIVED_FROM_TLEFT_TRIGHT \ 25 | typedef tuple Node; \ 26 | typedef vector NodeList; \ 27 | typedef set NodeSet; \ 28 | typedef tuple Edge; 29 | 30 | constexpr int LEFT = 0; 31 | constexpr int RIGHT = 1; 32 | 33 | typedef deque> Deque; 34 | 35 | Deque get_deque(const RCP &expr) 36 | { 37 | vec_basic v = expr->get_args(); 38 | Deque d(v.begin(), v.end()); 39 | return d; 40 | } 41 | 42 | #endif /* SYMENGINE_UTILITIES_MATCHPYCPP_COMMON_H_ */ 43 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/environment.yml: -------------------------------------------------------------------------------- 1 | name: matchpycpp 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - python 3.6.* 6 | - pip: 7 | - git+git://github.com/sympy/sympy.git@a22a512c#egg=sympy 8 | - git+git://github.com/HPAC/matchpy.git@419c103#egg=matchpy 9 | 10 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/generator_trick.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERATOR_TRICK_H 2 | #define GENERATOR_TRICK_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | class GeneratorTrick 10 | { 11 | public: 12 | GeneratorTrick() 13 | { 14 | generator_stop = false; 15 | } 16 | virtual ~GeneratorTrick(){}; 17 | 18 | std::shared_ptr next() 19 | { 20 | if (current == nullptr) { 21 | start(); 22 | } 23 | while (true) { 24 | if (generator_stop) { 25 | break; 26 | } 27 | current(); 28 | if (yield_queue.size() > 0) { 29 | std::shared_ptr front 30 | = std::make_shared(yield_queue.front()); 31 | yield_queue.pop_front(); 32 | return front; 33 | } 34 | } 35 | return nullptr; 36 | } 37 | 38 | void yield(T value) 39 | { 40 | yield_queue.push_back(value); 41 | } 42 | 43 | protected: 44 | bool generator_stop; 45 | std::function current; 46 | 47 | private: 48 | std::deque yield_queue; 49 | virtual void start() = 0; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/substitution.h: -------------------------------------------------------------------------------- 1 | #ifndef SYMENGINE_UTILITIES_MATCHPYCPP_SUBSTITUTION_H_ 2 | #define SYMENGINE_UTILITIES_MATCHPYCPP_SUBSTITUTION_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | using namespace std; 13 | using namespace SymEngine; 14 | 15 | typedef map SubstitutionMultiset; 16 | 17 | int try_add_variable(SubstitutionMultiset &subst, const string &variable_name, 18 | const multiset_basic &replacement) 19 | { 20 | auto elem = subst.find(variable_name); 21 | if (elem == subst.end()) { 22 | subst[variable_name] = replacement; 23 | } else { 24 | const multiset_basic &existing_value = elem->second; 25 | return unified_eq(existing_value, replacement); 26 | } 27 | return 0; 28 | } 29 | 30 | int try_add_variable(SubstitutionMultiset &subst, const string &variable_name, 31 | const vector> &replacement) 32 | { 33 | multiset_basic new_repl; 34 | new_repl.insert(replacement.begin(), replacement.end()); 35 | return try_add_variable(subst, variable_name, new_repl); 36 | } 37 | 38 | int try_add_variable(SubstitutionMultiset &subst, const string &variable_name, 39 | const RCP &replacement) 40 | { 41 | multiset_basic new_repl = {replacement}; 42 | return try_add_variable(subst, variable_name, new_repl); 43 | } 44 | 45 | SubstitutionMultiset 46 | substitution_union(const SubstitutionMultiset &subst, 47 | const vector &others) 48 | { 49 | SubstitutionMultiset new_subst = subst; 50 | for (const SubstitutionMultiset &other : others) { 51 | for (const pair &p : other) { 52 | int ret = try_add_variable(new_subst, p.first, p.second); 53 | assert(ret == 0); 54 | } 55 | } 56 | return new_subst; 57 | } 58 | 59 | #endif /* SYMENGINE_UTILITIES_MATCHPYCPP_SUBSTITUTION_H_ */ 60 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/symengine_printer.py: -------------------------------------------------------------------------------- 1 | from sympy.printing.pycode import PythonCodePrinter 2 | from sympy.printing.printer import Printer 3 | from sympy import Add, Mul 4 | 5 | 6 | class SymEnginePrinter(Printer): 7 | 8 | def _print_Pow(self, expr): 9 | return "pow({0}, {1})".format(self._print(expr.base), self._print(expr.exp)) 10 | 11 | def _print_Add(self, expr): 12 | if len(expr.args) != 2: 13 | return "add({}, {})".format( 14 | self._print(expr.args[0]), 15 | self._print(Add.fromiter(expr.args[1:])) 16 | ) 17 | return "add({}, {})".format( 18 | self._print(expr.args[0]), 19 | self._print(expr.args[1]), 20 | ) 21 | 22 | def _print_Mul(self, expr): 23 | if len(expr.args) >= 2: 24 | return "mul({}, {})".format( 25 | self._print(expr.args[0]), 26 | self._print(Mul.fromiter(expr.args[1:])), 27 | ) 28 | else: 29 | return self._print(expr.args[0]) 30 | 31 | def _print_Integer(self, expr): 32 | return "integer({})".format(expr) 33 | 34 | def _print_int(self, expr): 35 | return self._print_Integer(expr) 36 | 37 | 38 | def symengine_print(expr): 39 | printer = SymEnginePrinter() 40 | return printer.doprint(expr) 41 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udexon/SymForth/e012a98ec885f7513773cc7e1ef8bfb5463fc876/symengine/utilities/matchpycpp/tests/.gitkeep -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(BEFORE ${catch_SOURCE_DIR}) 2 | 3 | add_subdirectory(bipartite) 4 | add_subdirectory(hopcroft_karp) 5 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/bipartite/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_bipartite) 2 | 3 | add_executable(${PROJECT_NAME} test_bipartite.cpp) 4 | target_link_libraries(${PROJECT_NAME} symengine catch) 5 | add_test(${PROJECT_NAME} ${PROJECT_NAME}) 6 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/bipartite/test_bipartite.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | TEST_CASE("BipartiteGraph", "") 8 | { 9 | SECTION("Test 1") 10 | { 11 | map, bool> m = {{make_tuple(0, 1), true}, 12 | {make_tuple(1, 0), true}, 13 | {make_tuple(1, 1), true}, 14 | {make_tuple(2, 0), true}, 15 | {make_tuple(2, 1), true}}; 16 | BipartiteGraph bg(m); 17 | 18 | vector> expected = {{{1, 0}, {0, 1}}, 19 | {{1, 0}, {2, 1}}, 20 | {{0, 1}, {2, 0}}, 21 | {{2, 0}, {1, 1}}}; 22 | generator> result = enum_maximum_matchings_iter(bg); 23 | REQUIRE(result.size() == expected.size()); 24 | } 25 | 26 | SECTION("Test 2") 27 | { 28 | map, bool> m = {{make_tuple(0, 0), true}, 29 | {make_tuple(1, 1), true}, 30 | {make_tuple(2, 0), true}}; 31 | BipartiteGraph bg(m); 32 | 33 | vector> expected = {{{0, 0}, {1, 1}}, {{1, 1}, {2, 0}}}; 34 | generator> result = enum_maximum_matchings_iter(bg); 35 | REQUIRE(result.size() == expected.size()); 36 | } 37 | 38 | SECTION("Test 3") 39 | { 40 | map, bool> m = {{make_tuple(0, 0), true}, 41 | {make_tuple(1, 1), true}, 42 | {make_tuple(2, 0), true}, 43 | {make_tuple(2, 1), true}}; 44 | BipartiteGraph bg(m); 45 | 46 | vector> expected 47 | = {{{0, 0}, {1, 1}}, {{1, 1}, {2, 0}}, {{0, 0}, {2, 1}}}; 48 | generator> result = enum_maximum_matchings_iter(bg); 49 | REQUIRE(result.size() == expected.size()); 50 | } 51 | 52 | SECTION("Test 4") 53 | { 54 | map, bool> m = {}; 55 | BipartiteGraph bg(m); 56 | 57 | generator> result = enum_maximum_matchings_iter(bg); 58 | REQUIRE(result.empty()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/hopcroft_karp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(test_hopcroft_karp) 2 | 3 | add_executable(${PROJECT_NAME} test_hopcroft_karp.cpp) 4 | target_link_libraries(${PROJECT_NAME} symengine catch) 5 | add_test(${PROJECT_NAME} ${PROJECT_BINARY_DIR}/${PROJECT_NAME}) 6 | -------------------------------------------------------------------------------- /symengine/utilities/matchpycpp/tests/hopcroft_karp/test_hopcroft_karp.cpp: -------------------------------------------------------------------------------- 1 | #include "catch.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | TEST_CASE("Hopcroft Karp algorithm", 9 | "Testing the implementation of the Hopcroft Karp algorithm.") 10 | { 11 | SECTION("Test 1") 12 | { 13 | map> graph = {{0, {"v0", "v1"}}, 14 | {1, {"v0", "v4"}}, 15 | {2, {"v2", "v3"}}, 16 | {3, {"v0", "v4"}}, 17 | {4, {"v0", "v3"}}}; 18 | map expected 19 | = {{0, "v1"}, {1, "v4"}, {2, "v2"}, {3, "v0"}, {4, "v3"}}; 20 | HopcroftKarp hk(graph); 21 | int matchings = hk.hopcroft_karp(); 22 | REQUIRE(hk.pair_left == expected); 23 | REQUIRE(matchings == 5); 24 | } 25 | SECTION("Test 2") 26 | { 27 | map> graph 28 | = {{'A', {1, 2}}, {'B', {2, 3}}, {'C', {2}}, {'D', {3, 4, 5, 6}}, 29 | {'E', {4, 7}}, {'F', {7}}, {'G', {7}}}; 30 | map expected 31 | = {{'A', 1}, {'B', 3}, {'C', 2}, {'D', 5}, {'E', 4}, {'F', 7}}; 32 | HopcroftKarp hk(graph); 33 | int matchings = hk.hopcroft_karp(); 34 | REQUIRE(hk.pair_left == expected); 35 | REQUIRE(matchings == 6); 36 | } 37 | SECTION("Test 3") 38 | { 39 | map> graph 40 | = {{1, {'a', 'c'}}, {2, {'a', 'c'}}, {3, {'c', 'b'}}, {4, {'e'}}}; 41 | map expected = {{1, 'a'}, {2, 'c'}, {3, 'b'}, {4, 'e'}}; 42 | HopcroftKarp hk(graph); 43 | int matchings = hk.hopcroft_karp(); 44 | REQUIRE(hk.pair_left == expected); 45 | REQUIRE(matchings == 4); 46 | } 47 | SECTION("Test 4") 48 | { 49 | map> graph 50 | = {{'A', {3, 4}}, {'B', {3, 4}}, {'C', {3}}, {'D', {1, 5, 7}}, 51 | {'E', {1, 2, 7}}, {'F', {2, 8}}, {'G', {6}}, {'H', {2, 4, 8}}}; 52 | map expected = {{'A', 3}, {'B', 4}, {'D', 1}, {'E', 7}, 53 | {'F', 8}, {'G', 6}, {'H', 2}}; 54 | HopcroftKarp hk(graph); 55 | int matchings = hk.hopcroft_karp(); 56 | REQUIRE(hk.pair_left == expected); 57 | REQUIRE(matchings == 7); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(teuchos) 2 | 3 | set(SRC 4 | Teuchos_dyn_cast.cpp 5 | Teuchos_Ptr.cpp 6 | Teuchos_RCPNode.cpp 7 | Teuchos_TestForException.cpp 8 | Teuchos_TypeNameTraits.cpp 9 | Teuchos_stacktrace.cpp 10 | ) 11 | 12 | set(HEADERS 13 | Teuchos_any.hpp 14 | Teuchos_Assert.hpp 15 | Teuchos_ConfigDefs.hpp 16 | Teuchos_ConstTypeTraits.hpp 17 | Teuchos_DLLExportMacro.h 18 | Teuchos_dyn_cast.hpp 19 | Teuchos_ENull.hpp 20 | Teuchos_Exceptions.hpp 21 | Teuchos_getBaseObjVoidPtr.hpp 22 | Teuchos_map.hpp 23 | Teuchos_NullIteratorTraits.hpp 24 | Teuchos_Ptr.hpp 25 | Teuchos_PtrDecl.hpp 26 | Teuchos_RCP.hpp 27 | Teuchos_RCPDecl.hpp 28 | Teuchos_RCPNode.hpp 29 | Teuchos_stacktrace.hpp 30 | Teuchos_TestForException.hpp 31 | Teuchos_toString.hpp 32 | Teuchos_TypeNameTraits.hpp 33 | ) 34 | 35 | if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) 36 | # Must suppress strick aliasing warnings for this file! 37 | SET_SOURCE_FILES_PROPERTIES( 38 | Teuchos_stacktrace.cpp 39 | PROPERTIES COMPILE_FLAGS -fno-strict-aliasing 40 | ) 41 | endif() 42 | 43 | # Configure Teuchos using our CMake options: 44 | configure_file(Teuchos_config.h.in Teuchos_config.h) 45 | # Include the config file: 46 | include_directories(BEFORE ${teuchos_BINARY_DIR}) 47 | 48 | add_library(teuchos STATIC ${SRC}) 49 | 50 | 51 | include(GNUInstallDirs) 52 | 53 | install(TARGETS teuchos 54 | EXPORT SymEngineTargets 55 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 56 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 57 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 58 | ) 59 | 60 | if (NOT WITH_SYMENGINE_RCP) 61 | install(FILES ${HEADERS} "${teuchos_BINARY_DIR}/Teuchos_config.h" 62 | DESTINATION include/symengine/utilities/teuchos) 63 | endif() 64 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_ConstTypeTraits.hpp: -------------------------------------------------------------------------------- 1 | // @HEADER 2 | // *********************************************************************** 3 | // 4 | // Teuchos: Common Tools Package 5 | // Copyright (2004) Sandia Corporation 6 | // 7 | // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 | // license for use of this work by or on behalf of the U.S. Government. 9 | // 10 | // Redistribution and use in source and binary forms, with or without 11 | // modification, are permitted provided that the following conditions are 12 | // met: 13 | // 14 | // 1. Redistributions of source code must retain the above copyright 15 | // notice, this list of conditions and the following disclaimer. 16 | // 17 | // 2. Redistributions in binary form must reproduce the above copyright 18 | // notice, this list of conditions and the following disclaimer in the 19 | // documentation and/or other materials provided with the distribution. 20 | // 21 | // 3. Neither the name of the Corporation nor the names of the 22 | // contributors may be used to endorse or promote products derived from 23 | // this software without specific prior written permission. 24 | // 25 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | // 37 | // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 38 | // 39 | // *********************************************************************** 40 | // @HEADER 41 | 42 | #ifndef TEUCHOS_CONST_TYPE_TRAITS_HPP 43 | #define TEUCHOS_CONST_TYPE_TRAITS_HPP 44 | 45 | 46 | #include "Teuchos_ConfigDefs.hpp" 47 | 48 | 49 | namespace Teuchos { 50 | 51 | 52 | /** \brief Traits class that strips 'const' off of a type. 53 | * 54 | * See "Modern C++ Design", 2001, by Andrei Alexandrescu. 55 | * 56 | * \ingroup teuchos_language_support_grp 57 | */ 58 | template 59 | class ConstTypeTraits { 60 | private: 61 | /** \brief . */ 62 | template struct UnConst 63 | { typedef U Result; }; 64 | /** \brief . */ 65 | template struct UnConst 66 | { typedef U Result; }; 67 | public: 68 | /** \brief . */ 69 | typedef typename UnConst::Result NonConstType; 70 | }; 71 | 72 | 73 | } // end namespace Teuchos 74 | 75 | 76 | #endif // TEUCHOS_CONST_TYPE_TRAITS_HPP 77 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_DLLExportMacro.h: -------------------------------------------------------------------------------- 1 | #if defined (_WIN32) && defined (BUILD_SHARED_LIBS) 2 | # if defined(TEUCHOS_LIB_EXPORTS_MODE) 3 | # define TEUCHOS_LIB_DLL_EXPORT __declspec(dllexport) 4 | # else 5 | # define TEUCHOS_LIB_DLL_EXPORT __declspec(dllimport) 6 | # endif 7 | #else 8 | # define TEUCHOS_LIB_DLL_EXPORT 9 | #endif 10 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_ENull.hpp: -------------------------------------------------------------------------------- 1 | // @HEADER 2 | // *********************************************************************** 3 | // 4 | // Teuchos: Common Tools Package 5 | // Copyright (2004) Sandia Corporation 6 | // 7 | // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 | // license for use of this work by or on behalf of the U.S. Government. 9 | // 10 | // Redistribution and use in source and binary forms, with or without 11 | // modification, are permitted provided that the following conditions are 12 | // met: 13 | // 14 | // 1. Redistributions of source code must retain the above copyright 15 | // notice, this list of conditions and the following disclaimer. 16 | // 17 | // 2. Redistributions in binary form must reproduce the above copyright 18 | // notice, this list of conditions and the following disclaimer in the 19 | // documentation and/or other materials provided with the distribution. 20 | // 21 | // 3. Neither the name of the Corporation nor the names of the 22 | // contributors may be used to endorse or promote products derived from 23 | // this software without specific prior written permission. 24 | // 25 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | // 37 | // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 38 | // 39 | // *********************************************************************** 40 | // @HEADER 41 | 42 | #ifndef TEUCHOS_ENULL_HPP 43 | #define TEUCHOS_ENULL_HPP 44 | 45 | #include "Teuchos_ConfigDefs.hpp" 46 | 47 | namespace Teuchos { 48 | 49 | /** \brief Used to initialize a RCP object to NULL using an 50 | * implicit conversion! 51 | * 52 | * \relates RCP 53 | */ 54 | enum ENull { null }; 55 | 56 | } // end namespace Teuchos 57 | 58 | #endif // TEUCHOS_ENULL_HPP 59 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_Ptr.cpp: -------------------------------------------------------------------------------- 1 | // @HEADER 2 | // *********************************************************************** 3 | // 4 | // Teuchos: Common Tools Package 5 | // Copyright (2004) Sandia Corporation 6 | // 7 | // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 | // license for use of this work by or on behalf of the U.S. Government. 9 | // 10 | // Redistribution and use in source and binary forms, with or without 11 | // modification, are permitted provided that the following conditions are 12 | // met: 13 | // 14 | // 1. Redistributions of source code must retain the above copyright 15 | // notice, this list of conditions and the following disclaimer. 16 | // 17 | // 2. Redistributions in binary form must reproduce the above copyright 18 | // notice, this list of conditions and the following disclaimer in the 19 | // documentation and/or other materials provided with the distribution. 20 | // 21 | // 3. Neither the name of the Corporation nor the names of the 22 | // contributors may be used to endorse or promote products derived from 23 | // this software without specific prior written permission. 24 | // 25 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | // 37 | // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 38 | // 39 | // *********************************************************************** 40 | // @HEADER 41 | 42 | 43 | #include "Teuchos_Ptr.hpp" 44 | #include "Teuchos_Assert.hpp" 45 | #include "Teuchos_Exceptions.hpp" 46 | 47 | 48 | void Teuchos::PtrPrivateUtilityPack::throw_null( const std::string &type_name ) 49 | { 50 | TEUCHOS_TEST_FOR_EXCEPTION( 51 | true, NullReferenceError, 52 | "Ptr<"<::assert_not_null() : You can not" 53 | " call operator->() or operator*() if get()==NULL!" ); 54 | } 55 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_dyn_cast.cpp: -------------------------------------------------------------------------------- 1 | // @HEADER 2 | // *********************************************************************** 3 | // 4 | // Teuchos: Common Tools Package 5 | // Copyright (2004) Sandia Corporation 6 | // 7 | // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 8 | // license for use of this work by or on behalf of the U.S. Government. 9 | // 10 | // Redistribution and use in source and binary forms, with or without 11 | // modification, are permitted provided that the following conditions are 12 | // met: 13 | // 14 | // 1. Redistributions of source code must retain the above copyright 15 | // notice, this list of conditions and the following disclaimer. 16 | // 17 | // 2. Redistributions in binary form must reproduce the above copyright 18 | // notice, this list of conditions and the following disclaimer in the 19 | // documentation and/or other materials provided with the distribution. 20 | // 21 | // 3. Neither the name of the Corporation nor the names of the 22 | // contributors may be used to endorse or promote products derived from 23 | // this software without specific prior written permission. 24 | // 25 | // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 26 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 29 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | // 37 | // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 38 | // 39 | // *********************************************************************** 40 | // @HEADER 41 | 42 | #include "Teuchos_dyn_cast.hpp" 43 | #include "Teuchos_Assert.hpp" 44 | 45 | /** We throw a m_bad_cast, which is a subclass of bad_cast. 46 | This is necessary, since bad_cast lacks the appropriate 47 | constructor for use with the TEUCHOS_TEST_FOR_EXCEPTION macro. 48 | */ 49 | void Teuchos::dyn_cast_throw_exception( 50 | const std::string &T_from, 51 | const std::string &T_from_concr, 52 | const std::string &T_to 53 | ) 54 | { 55 | TEUCHOS_TEST_FOR_EXCEPTION( 56 | true, m_bad_cast 57 | ,"dyn_cast<" << T_to << ">(" << T_from 58 | << ") : Error, the object with the concrete type \'" 59 | << T_from_concr << "\' (passed in through the interface type \'" << T_from << "\') " 60 | " does not support the interface \'" 61 | << T_to << "\' and the dynamic cast failed!" ); 62 | } 63 | -------------------------------------------------------------------------------- /symengine/utilities/teuchos/Teuchos_stacktrace.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2010, Ondrej Certik 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Sandia Corporation nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #ifndef TEUCHOS_STACKTRACE_HPP 30 | #define TEUCHOS_STACKTRACE_HPP 31 | 32 | /*! \file Teuchos_stacktrace.hpp 33 | 34 | \brief Functions for returning stacktrace info (GCC only initially). 35 | */ 36 | 37 | #include "Teuchos_ConfigDefs.hpp" 38 | 39 | 40 | #ifdef HAVE_TEUCHOS_STACKTRACE 41 | 42 | 43 | /*! \defgroup TeuchosStackTrace_grp Utility code for generating stacktraces. 44 | * 45 | * \ingroup teuchos_language_support_grp 46 | */ 47 | 48 | namespace Teuchos { 49 | 50 | 51 | /** \brief Stores the current stacktrace into an internal global variable. 52 | * 53 | * \ingroup TeuchosStackTrace_grp 54 | */ 55 | void store_stacktrace(); 56 | 57 | /** \brief Returns the last stored stacktrace as a string. 58 | * 59 | * \ingroup TeuchosStackTrace_grp 60 | */ 61 | std::string get_stored_stacktrace(); 62 | 63 | /** \brief Returns the current stacktrace as a string. 64 | * 65 | * \param impl_stacktrace_depth [in] The stacktrace depth to remove from the 66 | * stacktrace printout to avoid showing users implementation functions in the 67 | * stacktrace. 68 | * 69 | * \ingroup TeuchosStackTrace_grp 70 | */ 71 | std::string get_stacktrace(int impl_stacktrace_depth=0); 72 | 73 | /** \brief Prints the current stacktrace to stdout. 74 | * 75 | * \ingroup TeuchosStackTrace_grp 76 | */ 77 | void show_stacktrace(); 78 | 79 | /** \brief Prints the current stacktrace to stdout on segfault. 80 | * 81 | * \ingroup TeuchosStackTrace_grp 82 | */ 83 | void print_stack_on_segfault(); 84 | 85 | } // end namespace Teuchos 86 | 87 | #endif // HAVE_TEUCHOS_STACKTRACE 88 | 89 | #endif // TEUCHOS_STACKTRACE_HPP 90 | 91 | --------------------------------------------------------------------------------