//This file is part of Bertini 2. // //python/mpfr_export.cpp is free software: you can redistribute it and/or modify //it under the terms of the GNU General Public License as published by //the Free Software Foundation, either version 3 of the License, or //(at your option) any later version. // //python/mpfr_export.cpp is distributed in the hope that it will be useful, //but WITHOUT ANY WARRANTY; without even the implied warranty of //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //GNU General Public License for more details. // //You should have received a copy of the GNU General Public License //along with python/mpfr_export.cpp. If not, see . // // Copyright(C) 2016-2018 by Bertini2 Development Team // // See for a copy of the license, // as well as COPYING. Bertini2 is provided with permitted // additional terms in the b2/licenses/ directory. // individual authors of this file include: // // silviana amethyst // University of Wisconsin - Eau Claire // Fall 2017, Spring 2018 // // James Collins // West Texas A&M University // Spring 2016 // // // // python/mpfr_export.cpp: Source file for exposing all multiprecision data types, those from boost and bertini::complex. #include "mpfr_export.hpp" namespace bertini{ namespace python{ template template void PrecisionVisitor::visit(PyClass& cl) const { cl .def("precision", get_prec) .def("precision", set_prec) ; } template template void RealStrVisitor::visit(PyClass& cl) const { cl .def("__str__", &RealStrVisitor::__str__) .def("__repr__", &RealStrVisitor::__repr__) ; } template template void EqualitySelfVisitor::visit(PyClass& cl) const { cl .def(self == self) .def(self != self) ; } template template void EqualityVisitor::visit(PyClass& cl) const { cl .def(self == other()) .def(self != other()) .def(other() == self) .def(other() != self) ; } template template void RingVisitor::visit(PyClass& cl) const { cl .def("__add__",&RingVisitor::__add__) .def("__iadd__",&RingVisitor::__iadd__) .def("__radd__",&RingVisitor::__radd__) .def("__sub__",&RingVisitor::__sub__) .def("__isub__",&RingVisitor::__isub__) .def("__rsub__",&RingVisitor::__rsub__) .def("__mul__",&RingVisitor::__mul__) .def("__imul__",&RingVisitor::__imul__) .def("__rmul__",&RingVisitor::__rmul__) ; } template template void RingSelfVisitor::visit(PyClass& cl) const { cl .def("__add__",&RingSelfVisitor::__add__) .def("__iadd__",&RingSelfVisitor::__iadd__) .def("__sub__",&RingSelfVisitor::__sub__) .def("__isub__",&RingSelfVisitor::__isub__) .def("__mul__",&RingSelfVisitor::__mul__) .def("__imul__",&RingSelfVisitor::__imul__) .def("__neg__",&RingSelfVisitor::__neg__) ; } template template void RealFreeVisitor::visit(PyClass& cl) const { def("abs", &RealFreeVisitor::__abs__); // free } template template void FieldVisitor::visit(PyClass& cl) const { cl .def("__div__",&FieldVisitor::__div__) .def("__idiv__",&FieldVisitor::__idiv__) .def("__rdiv__",&FieldVisitor::__rdiv__) .def("__truediv__",&FieldVisitor::__div__) .def("__itruediv__",&FieldVisitor::__idiv__) .def("__rtruediv__",&FieldVisitor::__rdiv__) .def(RingVisitor()) ; } template template void FieldSelfVisitor::visit(PyClass& cl) const { cl .def("__div__",&FieldSelfVisitor::div) .def("__idiv__",&FieldSelfVisitor::idiv) .def("__truediv__",&FieldSelfVisitor::div) .def("__itruediv__",&FieldSelfVisitor::idiv) .def(RingSelfVisitor()) ; } template template void PowVisitor::visit(PyClass& cl) const { cl .def("__pow__",&PowVisitor::__pow__) ; } template template void GreatLessVisitor::visit(PyClass& cl) const { cl .def(self < other()) .def(self <= other()) .def(self > other()) .def(self >= other()) .def(other() < self) .def(other() <= self) .def(other() > self) .def(other() >= self) ; } template template void GreatLessSelfVisitor::visit(PyClass& cl) const { cl .def(self < self) .def(self <= self) .def(self > self) .def(self >= self) ; } template template void TranscendentalVisitor::visit(PyClass& cl) const { def("exp", &TranscendentalVisitor::__exp__); def("log", &TranscendentalVisitor::__log__); def("sqrt", &TranscendentalVisitor::__sqrt__); def("sin", &TranscendentalVisitor::__sin__); def("cos", &TranscendentalVisitor::__cos__); def("tan", &TranscendentalVisitor::__tan__); def("asin", &TranscendentalVisitor::__asin__); def("acos", &TranscendentalVisitor::__acos__); def("atan", &TranscendentalVisitor::__atan__); def("sinh", &TranscendentalVisitor::__sinh__); def("cosh", &TranscendentalVisitor::__cosh__); def("tanh", &TranscendentalVisitor::__tanh__); def("asinh",&TranscendentalVisitor::__asinh__); def("acosh",&TranscendentalVisitor::__acosh__); def("atanh",&TranscendentalVisitor::__atanh__); } template template void ComplexVisitor::visit(PyClass& cl) const { // MPFRFloatBaseVisitor().visit(cl); cl .add_property("real", &ComplexVisitor::get_real, &ComplexVisitor::set_real) .add_property("imag", &ComplexVisitor::get_imag, &ComplexVisitor::set_imag) .def("__str__", &ComplexVisitor::__str__) .def("__repr__", &ComplexVisitor::__repr__) ; // these complex-specific functions are free in python using boost::multiprecision::real; using boost::multiprecision::imag; mpfr_float (*reeeal)(const T&) = &boost::multiprecision::real; mpfr_float (*imaaag)(const T&) = &boost::multiprecision::real; def("real",reeeal); //,return_value_policy() def("imag",imaaag); //,return_value_policy() // and then a few more free functions // def("abs2",&T::abs2); mpfr_complex (*pooolar)(const mpfr_float&,const mpfr_float&) = &boost::multiprecision::polar; def("polar",pooolar); // def("norm",&T::norm); def("conj",&ComplexVisitor::conj); mpfr_float (*aaaarg)(const T&) = &boost::multiprecision::arg; def("arg",aaaarg); // def("square",&square); // def("cube",&cube); // def("inverse", &inverse); def("abs", &ComplexVisitor::__abs__); // free } template unsigned get_precision_vector(Eigen::Ref> x) { return bertini::Precision(x); } #define IMPLICITLY_CONVERTIBLE(T1,T2) \ boost::python::implicitly_convertible(); void ExposeFreeNumFns() { unsigned (*def_prec1)() = &bertini::DefaultPrecision; void (*def_prec2)(unsigned) = &bertini::DefaultPrecision; def("default_precision", def_prec1); def("default_precision", def_prec2); } void ExposeInt() { using T = mpz_int; class_("Int", init<>()) .def(init()) .def(init()) .def(RealStrVisitor()) .def(RingSelfVisitor()) .def(PowVisitor()) .def(GreatLessSelfVisitor()) .def(GreatLessVisitor()) .def(EqualitySelfVisitor()) .def(EqualityVisitor()) .def(RealFreeVisitor()) ; } void ExposeRational() { using T = mpq_rational; class_("Rational", init<>()) .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def(RealStrVisitor()) .def(FieldSelfVisitor()) .def(FieldVisitor()) // .def(PowVisitor()) // deliberately commented out... // pow(Q,Z) not defined... .def(GreatLessSelfVisitor()) .def(GreatLessVisitor()) .def(GreatLessVisitor()) .def(EqualitySelfVisitor()) .def(EqualityVisitor()) .def(EqualityVisitor()) .def(RealFreeVisitor()) ; } void ExposeFloat() { using T = mpfr_float; class_("Float", init<>()) .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def(RealStrVisitor()) .def(PrecisionVisitor()) .def(FieldSelfVisitor()) .def(FieldVisitor()) .def(FieldVisitor()) .def(FieldVisitor()) .def(PowVisitor()) .def(PowVisitor()) .def(TranscendentalVisitor()) .def(GreatLessSelfVisitor()) .def(GreatLessVisitor()) .def(GreatLessVisitor()) .def(RealFreeVisitor()) ; eigenpy::registerNewType(); eigenpy::registerCommonUfunc(); eigenpy::registerCast(false); eigenpy::registerCast(true); eigenpy::registerCast(false); eigenpy::registerCast(true);; eigenpy::registerCast(false); eigenpy::registerCast(true); IMPLICITLY_CONVERTIBLE(int,T); IMPLICITLY_CONVERTIBLE(long,T); IMPLICITLY_CONVERTIBLE(int64_t,T); eigenpy::EigenToPyConverter>::registration(); eigenpy::EigenToPyConverter>::registration(); eigenpy::EigenFromPyConverter>::registration(); eigenpy::EigenFromPyConverter>::registration(); } size_t get_default_align(){return EIGENPY_DEFAULT_ALIGN_BYTES;} void ExposeComplex() { using T = bertini::mpfr_complex; class_("Complex", init<>()) .def(init()) // this should probably be made an explicit constructor rather than implicit .def(init()) .def(init()) .def(init()) .def(init()) // this should probably be made an explicit constructor rather than implicit .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def(init()) .def(ComplexVisitor()) .def(FieldSelfVisitor()) .def(FieldVisitor()) .def(FieldVisitor()) .def(FieldVisitor()) .def(FieldVisitor()) .def(PowVisitor()) .def(PowVisitor()) .def(PowVisitor()) .def(TranscendentalVisitor()) .def(PrecisionVisitor()) ; eigenpy::registerNewType(); eigenpy::registerUfunct_without_comparitors(); // eigenpy::registerCast(false); eigenpy::registerCast(true); // eigenpy::registerCast(false); eigenpy::registerCast(true); // eigenpy::registerCast(false); eigenpy::registerCast(true); IMPLICITLY_CONVERTIBLE(int,T); IMPLICITLY_CONVERTIBLE(long,T); IMPLICITLY_CONVERTIBLE(int64_t,T); eigenpy::EigenToPyConverter>::registration(); eigenpy::EigenToPyConverter>::registration(); eigenpy::EigenFromPyConverter>::registration(); eigenpy::EigenFromPyConverter>::registration(); eigenpy::exposeType(); eigenpy::exposeType(); boost::python::def("precision", &get_precision_vector, "get the precision of a vector of complexes"); boost::python::def("default_align_bytes", &get_default_align); } void ExportMpfr() { scope current_scope; std::string new_submodule_name(extract(current_scope.attr("__name__"))); new_submodule_name.append(".multiprec"); object new_submodule(borrowed(PyImport_AddModule(new_submodule_name.c_str()))); current_scope.attr("multiprec") = new_submodule; scope new_submodule_scope = new_submodule; ExposeInt(); ExposeFloat(); ExposeRational(); ExposeComplex(); ExposeFreeNumFns(); }; #undef IMPLICITLY_CONVERTIBLE } //namespace python } // namespace bertini