diff --git a/.gitignore b/.gitignore index 6e11ef8b..de2d805b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,59 @@ +# http://www.gnu.org/software/automake + +Makefile.in + +# http://www.gnu.org/software/autoconf + +/autom4te.cache +/aclocal.m4 +/compile +/configure +/depcomp +/install-sh +/missing +/stamp-h1 + *.sublime-workspace -.DS_Store +config.* + +libtool +Makefile + +*.sublime-workspace + +bertini2 +b2_class_test +b2_classic_compatibility_test +b2_timing_test +test_tree_interactive + +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +serialization_test* + +/config + +# Python folders +/python/test/.idea +/.deps/* + +# Python files +*.pyc + + + +*.dirstamp +*.deps *~ +.DS_Store + # Compiled Object files *.slo *.lo @@ -33,3 +83,4 @@ *.exe *.out *.app +python/autom4te.cache diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..1e62b3d7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "python/minieigen"] + path = python/minieigen +url=https://github.com/eudoxos/minieigen.git diff --git a/core/.gitignore b/core/.gitignore index 4a891ad6..395b7f82 100644 --- a/core/.gitignore +++ b/core/.gitignore @@ -18,9 +18,12 @@ config.* libtool Makefile +b2_timing_test b2_class_test test_tree_interactive - +settings_test +tracking_basics_test +b2_classic_compatibility_test m4/libtool.m4 m4/ltoptions.m4 @@ -29,6 +32,10 @@ m4/ltversion.m4 m4/lt~obsolete.m4 serialization_test* +*.log +.libs/* + +*.trs /config @@ -36,6 +43,7 @@ serialization_test* *.dirstamp *.deps + *~ @@ -66,4 +74,4 @@ serialization_test* # Executables *.exe *.out -*.app \ No newline at end of file +*.app diff --git a/core/configure.ac b/core/configure.ac index dd0893ba..69330512 100644 --- a/core/configure.ac +++ b/core/configure.ac @@ -3,8 +3,8 @@ -#we're building b2, version 2.0-alpha2, and the corresponding email is dan brake's -AC_INIT([b2], [2.0-alpha2], [danielthebrake@gmail.com],[b2], [http://github.com/bertiniteam/b2]) +#we're building b2, version 2.0-alpha3, and the corresponding email is dan brake's +AC_INIT([b2], [2.0-alpha3], [danielthebrake@gmail.com],[b2], [http://github.com/bertiniteam/b2]) # Force autoconf to be at least this version number: diff --git a/core/doc/b2_review_CODE_NAME.tex b/core/doc/b2_review_CODE_NAME.tex new file mode 100644 index 00000000..33fea83a --- /dev/null +++ b/core/doc/b2_review_CODE_NAME.tex @@ -0,0 +1,160 @@ +\documentclass{article} + +\usepackage{amssymb,amsmath} + +\oddsidemargin 0.0in +\textwidth 6.5in +\headheight -0.5in +\topmargin 0.5in +\headsep 0.0in +\textheight 9.2in +\parskip 3mm +\pagestyle{empty} + + +%%%%%%%%%%%%%%%%%%% +%%%%% INSTRUCTIONS %%%%% +%%%%%%%%%%%%%%%%%%% + +% REVIEWER: Please fill out the following fields. The form will then be filled in automatically upon compilation. +% The goal of this review is to determine whether the code under review is adequate for inclusion into the develop branch of b2. +% If you have any hesitations on any yes/no question, mark no and explain your concerns. +% Please work with the author(s) of the code under review to resolve any issues. +% A final copy of all reviews must be submitted to Dan Bates before the pull request for the code under review is accepted. +% Copies of the final review forms will be kept in the repo for future reference. +% +% If you have questions, please contact Dan Bates. + + +\newcommand\you{ Dan Bates, bates@math.colostate.edu } %your name, email +\newcommand\class{ Example Class } %name of the class, file, or module you are reviewing +\newcommand\revdate{ 21 February 2015 } %date you are completing the review + +%SCOPE +\newcommand\goals{ a,b,c } %brief but complete list of goals for the code under review +\newcommand\goalsAppropriate{ y/n } %Are these goals appropriate for this code -- yes or no? +\newcommand\goalsMet{ y/n } %Were all goals met -- yes or no? +\newcommand\goalsComments{ asdf } %Comments about goals and scope + +%COMPILATION +\newcommand\compileSuccess{ y/n } %Does the code compile -- yes or no? +\newcommand\compileComments{ asdf } %Comments about compilation + +%TESTING +\newcommand\testSuccess{ y/n } %Does the code pass the provided tests -- yes or no? +\newcommand\testGeneral{ y/n } %Do the provided tests adequately measure general circumstances -- yes or no? +\newcommand\testEdge { y/n } %Do the provided tests adequately include edge cases -- yes or no? +\newcommand\testComments{ asdf } %Comments about tests + +%DOCUMENTATION +\newcommand\docAdequate{ y/n } %Is the code adequately commented -- yes or no? +\newcommand\docComments{ asdf } %Comments about documentation + +%STYLE +\newcommand\styleAdequate{ y/n } %Does the code conform adequately to the b2 style conventions -- yes or no? +\newcommand\styleComments{ asdf } %Comments about style + +%OTHER COMMENTS +\newcommand\otherComments{ asdf } %Other comments + +%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%% END OF REVIEWER SECTION %%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +\newcommand\bb{{bertini2\ }} + +\begin{document} + +\noindent +{\bf \bb review}\\ +Code: \class\\ +Reviewer: \you \\ +Date: \revdate + +\noindent\hrulefill + +\noindent +{\bf Scope} + +\noindent +\underbar{Goals}: \goals + +\noindent +\underbar{Are these goals appropriate}? \goalsAppropriate + +\noindent +\underbar{Were these goals met}? \goalsMet + +\noindent +\underbar{Comments}: \\ \goalsComments + +\noindent\hrulefill + + + +\noindent +{\bf Compilation} + +\noindent +\underbar{Does the code compile?} \compileSuccess + +\noindent +\underbar{Comments}:\\ \compileComments + +\noindent\hrulefill + + + +\noindent +{\bf Testing} + +\noindent +\underbar{Does the code pass the provided tests?} \testSuccess + +\noindent +\underbar{Do the provided tests adequately measure general circumstances?} \testGeneral + +\noindent +\underbar{Do the provided tests adequately include edge cases?} \testEdge + +\noindent +\underbar{Comments}: \\ \testComments + +\noindent\hrulefill + + + +\noindent +{\bf Documentation} + +\noindent +\underbar{Is the code adequately commented?} \docAdequate + +\noindent +\underbar{Comments}: \\ \docComments + +\noindent\hrulefill + + + +\noindent +{\bf Style} + +\noindent +\underbar{Does the code conform adequately to the b2 style conventions?} \styleAdequate + +\noindent +\underbar{Comments}:\\ \styleComments + +\noindent\hrulefill + + + +\noindent +{\bf Other comments}\\ \otherComments + + +\end{document} \ No newline at end of file diff --git a/core/include/bertini2/mpfr_complex.hpp b/core/include/bertini2/mpfr_complex.hpp index 62d2be36..0be17178 100644 --- a/core/include/bertini2/mpfr_complex.hpp +++ b/core/include/bertini2/mpfr_complex.hpp @@ -1079,7 +1079,51 @@ namespace Eigen { - + namespace internal { + template<> + struct abs2_impl + { + static inline mpfr_float run(const bertini::complex& x) + { + return real(x)*real(x) + imag(x)*imag(x); + } + }; + + + template<> inline bertini::complex random() + { + return bertini::complex::rand(); + } + + template<> inline bertini::complex random(const bertini::complex& a, const bertini::complex& b) + { + return a + (b-a) * random(); + } + + template<> + struct conj_helper + { + typedef bertini::complex Scalar; + EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const + { return c + pmul(x,y); } + + EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const + { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::imag(x)*numext::real(y) - numext::real(x)*numext::imag(y)); } + }; + + template<> + struct conj_helper + { + typedef bertini::complex Scalar; + EIGEN_STRONG_INLINE Scalar pmadd(const Scalar& x, const Scalar& y, const Scalar& c) const + { return c + pmul(x,y); } + + EIGEN_STRONG_INLINE Scalar pmul(const Scalar& x, const Scalar& y) const + { return Scalar(numext::real(x)*numext::real(y) + numext::imag(x)*numext::imag(y), numext::real(x)*numext::imag(y) - numext::imag(x)*numext::real(y)); } + }; + + } // re: namespace internal + } diff --git a/core/m4/lx_find_mpi.m4 b/core/m4/lx_find_mpi.m4 deleted file mode 100644 index 01fd72a3..00000000 --- a/core/m4/lx_find_mpi.m4 +++ /dev/null @@ -1,205 +0,0 @@ -################################################################################################# -# Copyright (c) 2010, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory -# Written by Todd Gamblin, tgamblin@llnl.gov. -# LLNL-CODE-417602 -# All rights reserved. -# -# This file is part of Libra. For details, see http://github.com/tgamblin/libra. -# Please also read the LICENSE file for further information. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this list of -# conditions and the disclaimer below. -# * Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the disclaimer (as noted below) in the documentation and/or other materials -# provided with the distribution. -# * Neither the name of the LLNS/LLNL nor the names of its contributors may be used to endorse -# or promote products derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -# LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -################################################################################################# - -# -# LX_FIND_MPI() -# ------------------------------------------------------------------------ -# This macro finds an MPI compiler and extracts includes and libraries from -# it for use in automake projects. The script exports the following variables: -# -# AC_DEFINE variables: -# HAVE_MPI AC_DEFINE'd to 1 if we found MPI -# -# AC_SUBST variables: -# MPICC Name of MPI compiler -# MPI_CFLAGS Includes and defines for MPI C compilation -# MPI_CLDFLAGS Libraries and library paths for linking MPI C programs -# -# MPICXX Name of MPI C++ compiler -# MPI_CXXFLAGS Includes and defines for MPI C++ compilation -# MPI_CXXLDFLAGS Libraries and library paths for linking MPI C++ programs -# -# MPIF77 Name of MPI Fortran 77 compiler -# MPI_F77FLAGS Includes and defines for MPI Fortran 77 compilation -# MPI_F77LDFLAGS Libraries and library paths for linking MPI Fortran 77 programs -# -# MPIFC Name of MPI Fortran compiler -# MPI_FFLAGS Includes and defines for MPI Fortran compilation -# MPI_FLDFLAGS Libraries and library paths for linking MPI Fortran programs -# -# Shell variables output by this macro: -# have_C_mpi 'yes' if we found MPI for C, 'no' otherwise -# have_CXX_mpi 'yes' if we found MPI for C++, 'no' otherwise -# have_F77_mpi 'yes' if we found MPI for F77, 'no' otherwise -# have_F_mpi 'yes' if we found MPI for Fortran, 'no' otherwise -# -AC_DEFUN([LX_FIND_MPI], -[ -AC_LANG_CASE( -[C], [ -AC_REQUIRE([AC_PROG_CC]) -if [[ ! -z "$MPICC" ]]; then -LX_QUERY_MPI_COMPILER(MPICC, [$MPICC], C) -else -LX_QUERY_MPI_COMPILER(MPICC, [mpicc mpiicc mpixlc mpipgcc], C) -fi -], -[C++], [ -AC_REQUIRE([AC_PROG_CXX]) -if [[ ! -z "$MPICXX" ]]; then -LX_QUERY_MPI_COMPILER(MPICXX, [$MPICXX], CXX) -else -LX_QUERY_MPI_COMPILER(MPICXX, [mpicxx mpiCC mpic++ mpig++ mpiicpc mpipgCC mpixlC], CXX) -fi -], -[F77], [ -AC_REQUIRE([AC_PROG_F77]) -if [[ ! -z "$MPIF77" ]]; then -LX_QUERY_MPI_COMPILER(MPIF77, [$MPIF77], F77) -else -LX_QUERY_MPI_COMPILER(MPIF77, [mpif77 mpiifort mpixlf77 mpixlf77_r], F77) -fi -], -[Fortran], [ -AC_REQUIRE([AC_PROG_FC]) -if [[ ! -z "$MPIFC" ]]; then -LX_QUERY_MPI_COMPILER(MPIFC, [$MPIFC], F) -else -mpi_default_fc="mpif95 mpif90 mpigfortran mpif2003" -mpi_intel_fc="mpiifort" -mpi_xl_fc="mpixlf95 mpixlf95_r mpixlf90 mpixlf90_r mpixlf2003 mpixlf2003_r" -mpi_pg_fc="mpipgf95 mpipgf90" -LX_QUERY_MPI_COMPILER(MPIFC, [$mpi_default_fc $mpi_intel_fc $mpi_xl_fc $mpi_pg_fc], F) -fi -]) -]) - - -# -# LX_QUERY_MPI_COMPILER([compiler-var-name], [compiler-names], [output-var-prefix]) -# ------------------------------------------------------------------------ -# AC_SUBST variables: -# MPI_FLAGS Includes and defines for MPI compilation -# MPI_LDFLAGS Libraries and library paths for linking MPI C programs -# -# Shell variables output by this macro: -# found_mpi_flags 'yes' if we were able to get flags, 'no' otherwise -# -AC_DEFUN([LX_QUERY_MPI_COMPILER], -[ -# Try to find a working MPI compiler from the supplied names -AC_PATH_PROGS($1, [$2], [not-found]) - -# Figure out what the compiler responds to to get it to show us the compile -# and link lines. After this part of the macro, we'll have a valid -# lx_mpi_command_line -echo -n "Checking whether $$1 responds to '-showme:compile'... " -lx_mpi_compile_line=`$$1 -showme:compile 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -lx_mpi_link_line=`$$1 -showme:link 2>/dev/null` -else -echo no -echo -n "Checking whether $$1 responds to '-showme'... " -lx_mpi_command_line=`$$1 -showme 2>/dev/null` -if [[ "$?" -ne 0 ]]; then -echo no -echo -n "Checking whether $$1 responds to '-compile-info'... " -lx_mpi_compile_line=`$$1 -compile-info 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -lx_mpi_link_line=`$$1 -link-info 2>/dev/null` -else -echo no -echo -n "Checking whether $$1 responds to '-show'... " -lx_mpi_command_line=`$$1 -show 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -else -echo no -fi -fi -else -echo yes -fi -fi - -if [[ ! -z "$lx_mpi_compile_line" -a ! -z "$lx_mpi_link_line" ]]; then -lx_mpi_command_line="$lx_mpi_compile_line $lx_mpi_link_line" -fi - -if [[ ! -z "$lx_mpi_command_line" ]]; then -# Now extract the different parts of the MPI command line. Do these separately in case we need to -# parse them all out in future versions of this macro. -lx_mpi_defines=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-D\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_includes=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-I\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_link_paths=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-L\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_libs=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-l\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_link_args=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-Wl,\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` - -# Create variables and clean up newlines and multiple spaces -MPI_$3FLAGS="$lx_mpi_defines $lx_mpi_includes" -MPI_$3LDFLAGS="$lx_mpi_link_paths $lx_mpi_libs $lx_mpi_link_args" -MPI_$3FLAGS=` echo "$MPI_$3FLAGS" | tr '\n' ' ' | sed 's/^[[ \t]]*//;s/[[ \t]]*$//' | sed 's/ +/ /g'` -MPI_$3LDFLAGS=`echo "$MPI_$3LDFLAGS" | tr '\n' ' ' | sed 's/^[[ \t]]*//;s/[[ \t]]*$//' | sed 's/ +/ /g'` - -OLD_CPPFLAGS=$CPPFLAGS -OLD_LIBS=$LIBS -CPPFLAGS=$MPI_$3FLAGS -LIBS=$MPI_$3LDFLAGS - -AC_TRY_LINK([#include ], -[int rank, size; -MPI_Comm_rank(MPI_COMM_WORLD, &rank); -MPI_Comm_size(MPI_COMM_WORLD, &size);], -[# Add a define for testing at compile time. -AC_DEFINE([HAVE_MPI], [1], [Define to 1 if you have MPI libs and headers.]) -have_$3_mpi='yes'], -[# zero out mpi flags so we don't link against the faulty library. -MPI_$3FLAGS="" -MPI_$3LDFLAGS="" -have_$3_mpi='no']) - -# AC_SUBST everything. -AC_SUBST($1) -AC_SUBST(MPI_$3FLAGS) -AC_SUBST(MPI_$3LDFLAGS) - -LIBS=$OLD_LIBS -CPPFLAGS=$OLD_CPPFLAGS -else -echo Unable to find suitable MPI Compiler. Try setting $1. -have_$3_mpi='no' -fi -]) - - diff --git a/core/test/classes/differentiate_test.cpp b/core/test/classes/differentiate_test.cpp index 538ad7ab..b651f4d2 100644 --- a/core/test/classes/differentiate_test.cpp +++ b/core/test/classes/differentiate_test.cpp @@ -38,7 +38,7 @@ #include #include -#include +#include diff --git a/python/.gitignore b/python/.gitignore new file mode 100644 index 00000000..caa53498 --- /dev/null +++ b/python/.gitignore @@ -0,0 +1,75 @@ +# http://www.gnu.org/software/automake + +Makefile.in + +# http://www.gnu.org/software/autoconf + +autom4te.cache +aclocal.m4 +compile +configure +depcomp +install-sh +missing +stamp-h1 + +config.* + +libtool +Makefile + +b2_class_test +test_tree_interactive + + +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 + +serialization_test* + +/config + +.DS_Store +*.dirstamp +*.deps + +*~ + + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + + +# Python folder +%src +*.pyc +.idea \ No newline at end of file diff --git a/python/Makefile.am b/python/Makefile.am index 21dcbd00..000d0de8 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -8,7 +8,7 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # -AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/minieigen/src ACLOCAL_AMFLAGS = -I m4 @@ -25,7 +25,7 @@ include_HEADERS = lib_LTLIBRARIES = EXTRA_LTLIBRARIES = lib_LIBRARIES = - +pyexec_LTLIBRARIES = #see https://www.gnu.org/software/automake/manual/html_node/Suffixes.html SUFFIXES = .cpp .hpp diff --git a/python/configure.ac b/python/configure.ac index e9c78f6e..92cb68a7 100644 --- a/python/configure.ac +++ b/python/configure.ac @@ -3,8 +3,8 @@ -#we're building pybertini, version 2.0.0, and the corresponding email is dan brake's -AC_INIT([pybertini], [0.0.1.2015.09.19.dev], [danielthebrake@gmail.com],[pybertini], [http://github.com/bertiniteam/b2]) +#we're building pybertini, version 1.0.alpha0, and the corresponding email is dan brake's +AC_INIT([pybertini], [1.0.alpha0], [danielthebrake@gmail.com],[pybertini], [http://github.com/bertiniteam/b2]) # Force autoconf to be at least this version number: @@ -50,8 +50,8 @@ AC_PROG_MKDIR_P #fire up libtool LT_INIT - - +#query python's install location. +AM_PATH_PYTHON #this calls a file in the m4/ directory, which sets up the MPI wrapper stuffs @@ -85,9 +85,7 @@ AC_SEARCH_LIBS([cos], [m], [], [ ]) # look for a header file in Eigen, and croak if fail to find. -AC_LANG_PUSH([C++]) -AC_CHECK_HEADERS([eigen3/Eigen/Dense],[],AC_MSG_ERROR([unable to find Eigen 3 (eigen3/Eigen/Dense)]),[]) -AC_LANG_POP([C++]) +AX_EIGEN AX_BOOST_BASE([1.55],, [AC_MSG_ERROR([bertini2 needs Boost at least 1.55, but it was not found in your system])]) diff --git a/python/include/bertini_python.hpp b/python/include/bertini_python.hpp new file mode 100644 index 00000000..e67df146 --- /dev/null +++ b/python/include/bertini_python.hpp @@ -0,0 +1,37 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/bertini_python.hpp: the main header file for the python interface for bertini. + +#ifndef BERTINI_PYTHON_HPP +#define BERTINI_PYTHON_HPP + +#include "python_common.hpp" +#include "containers_export.hpp" +#include "mpfr_export.hpp" +#include "minieigen_export.hpp" +#include "function_tree.hpp" +#include "system_export.hpp" +#include "parser_export.hpp" + + +#endif + + diff --git a/python/include/containers_export.hpp b/python/include/containers_export.hpp new file mode 100644 index 00000000..49078482 --- /dev/null +++ b/python/include/containers_export.hpp @@ -0,0 +1,75 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/containers_export.hpp: Exports all needed containers from Bertini 2.0 to python. + +#ifndef Xcode_b2_export_containers_hpp +#define Xcode_b2_export_containers_hpp + + +#include + +#include "python_common.hpp" + + + + +void ExportContainers() +{ + // std::vector of Rational Node ptrs + class_< std::vector > >("ListRational") + .def(vector_indexing_suite< std::vector > , true >()) + ; + + // The VariableGroup deque container + class_< bertini::VariableGroup >("VariableGroup") + .def(vector_indexing_suite< bertini::VariableGroup, true >()) + ; + + // std::vector of ints + class_< std::vector >("ListInt") + .def(vector_indexing_suite< std::vector , true >()) + ; + + // std::vector of VariableGroups + class_< std::vector >("ListVariableGroup") + .def(vector_indexing_suite< std::vector , true >()) + ; + + // std::vector of Function Node ptrs + class_< std::vector > >("ListFunction") + .def(vector_indexing_suite< std::vector > , true >()) + ; + + // std::vector of Jacobian Node ptrs + class_< std::vector > >("ListJacobian") + .def(vector_indexing_suite< std::vector > , true >()) + ; + +}; + + + + + + + + +#endif diff --git a/python/include/function_tree.hpp b/python/include/function_tree.hpp new file mode 100644 index 00000000..f57c14cb --- /dev/null +++ b/python/include/function_tree.hpp @@ -0,0 +1,89 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/function_tree.hpp: Header file for all node types. + +#ifndef BERTINI_PYTHON_FUNCTION_TREE_HPP +#define BERTINI_PYTHON_FUNCTION_TREE_HPP + +#include "python_common.hpp" +#include + +#include "node_export.hpp" +#include "symbol_export.hpp" +#include "operator_export.hpp" +#include "root_export.hpp" + + + +namespace bertini{ + namespace python{ + + using namespace bertini::node; + using Node = Node; + using Nodeptr = std::shared_ptr; + void SetupFunctionTree() + { + // Tell Python that pointers to derived Nodes can be used as Node pointers when passed to methods + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + } + + + + + + + } +} + + +#endif diff --git a/python/include/minieigen_export.hpp b/python/include/minieigen_export.hpp new file mode 100644 index 00000000..57fd31ab --- /dev/null +++ b/python/include/minieigen_export.hpp @@ -0,0 +1,69 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/minieigen_export.hpp: Header file for exposing the eigen data types needed for bertini. + + + + +#ifndef Xcode_b2_minieigen_export_hpp +#define Xcode_b2_minieigen_export_hpp + +#include + +#include "common.hpp" +#include "converters.hpp" +#include "visitors.hpp" + +#include "python_common.hpp" + +namespace bertini{ + namespace python{ + + + void ExportMinieigen() + { + // minieigen methods for converting python sequence into Eigen vector or matrix + custom_VectorAnyAny_from_sequence>(); + custom_VectorAnyAny_from_sequence>(); + custom_MatrixAnyAny_from_sequence>(); + custom_MatrixAnyAny_from_sequence>(); + + + // Eigen Vector of type dbl or mpfr + class_>("VectorXd","/*TODO*/", + py::init<>()).def(VectorVisitor>()); + class_>("VectorXmp","/*TODO*/", + py::init<>()).def(VectorVisitor>()); + + // Eigen Matrix of type dbl or mpfr + class_>("MatrixXd","/*TODO*/", + py::init<>()).def(MatrixVisitor>()); + class_>("MatrixXmp","/*TODO*/", + py::init<>()).def(MatrixVisitor>()); + + }; + + + } +} + + +#endif diff --git a/python/include/mpfr_export.hpp b/python/include/mpfr_export.hpp new file mode 100644 index 00000000..c7676369 --- /dev/null +++ b/python/include/mpfr_export.hpp @@ -0,0 +1,341 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/mpfr_export.hpp: Header file for exposing all multiprecision data types, those from boost and bertini::complex. + +#ifndef Xcode_b2_mpfr_export_hpp +#define Xcode_b2_mpfr_export_hpp + +#include "python_common.hpp" + +namespace bertini{ + namespace python{ + + using namespace boost::python; + + + void ExportMpfr(); + + + // NOTE: Must redefine all aritmethic operators to support expresion templating in the mp data types + + + + + /** + A base visitor exposing methods common to all multiprecision data types. Mostly arithmetic and printing methods. + + */ + template + class MPFRBaseVisitor: public def_visitor > + { + public: + template + void visit(PyClass& cl) const; + + + private: + static MPFRBaseT __neg__(const MPFRBaseT& a){ return -a; }; + + static MPFRBaseT __add__(const MPFRBaseT& a, const MPFRBaseT& b){ return a+b; }; + static MPFRBaseT __iadd__(MPFRBaseT& a, const MPFRBaseT& b){ a+=b; return a; }; + static MPFRBaseT __sub__(const MPFRBaseT& a, const MPFRBaseT& b){ return a-b; }; + static MPFRBaseT __isub__(MPFRBaseT& a, const MPFRBaseT& b){ a-=b; return a; }; + static MPFRBaseT __mul__(const MPFRBaseT& a, const MPFRBaseT& b){ return a*b; }; + static MPFRBaseT __imul__(MPFRBaseT& a, const MPFRBaseT& b){ a*=b; return a; }; + + static MPFRBaseT __abs__(MPFRBaseT const& x){ return abs(x);} + + static std::string __str__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << self; + return ss.str(); + }; + + + }; + + + + + + /** + A base visitor exposing methods common to all float multiprecision data types. These include trancendental functions and precision method. + */ + template + class MPFRFloatBaseVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + private: + static MPFRBaseT __div__(const MPFRBaseT& a, const MPFRBaseT& b){ return a/b; }; + static MPFRBaseT __idiv__(MPFRBaseT& a, const MPFRBaseT& b){ a/=b; return a; }; + static MPFRBaseT __pow__(const MPFRBaseT& a, const MPFRBaseT& b){ return pow(a,b); }; + + static MPFRBaseT __log__(MPFRBaseT const& x){ return log(x);} + static MPFRBaseT __exp__(MPFRBaseT const& x){ return exp(x);} + static MPFRBaseT __sqrt__(MPFRBaseT const& x){ return sqrt(x);} + + static MPFRBaseT __sin__(MPFRBaseT const& x){ return sin(x);} + static MPFRBaseT __cos__(MPFRBaseT const& x){ return cos(x);} + static MPFRBaseT __tan__(MPFRBaseT const& x){ return tan(x);} + + static MPFRBaseT __asin__(MPFRBaseT const& x){ return asin(x);} + static MPFRBaseT __acos__(MPFRBaseT const& x){ return acos(x);} + static MPFRBaseT __atan__(MPFRBaseT const& x){ return atan(x);} + + static MPFRBaseT __sinh__(MPFRBaseT const& x){ return sinh(x);} + static MPFRBaseT __cosh__(MPFRBaseT const& x){ return cosh(x);} + static MPFRBaseT __tanh__(MPFRBaseT const& x){ return tanh(x);} + + unsigned (MPFRBaseT::*bmpprec1)() const= &MPFRBaseT::precision; + void (MPFRBaseT::*bmpprec2)(unsigned) = &MPFRBaseT::precision; + + + + }; + + + + + + /** + Visitor exposing important methods from the boost::multiprecision::mpz_int class + */ + template + class MPFRIntVisitor: public def_visitor> + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + + private: + static MPFRBaseT __add_int(const MPFRBaseT& a, const int& b){ return a+b; }; + static MPFRBaseT __iadd_int(MPFRBaseT& a, const int& b){ a+=b; return a; }; + static MPFRBaseT __radd_int(const MPFRBaseT& b, const int& a){ return a+b; }; + static MPFRBaseT __sub_int(const MPFRBaseT& a, const int& b){ return a-b; }; + static MPFRBaseT __isub_int(MPFRBaseT& a, const int& b){ a-=b; return a; }; + static MPFRBaseT __rsub_int(const MPFRBaseT& b, const int& a){ return a-b; }; + static MPFRBaseT __mul_int(const MPFRBaseT& a, const int& b){ return a*b; }; + static MPFRBaseT __imul_int(MPFRBaseT& a, const int& b){ a*=b; return a; }; + static MPFRBaseT __rmul_int(const MPFRBaseT& b, const int& a){ return a*b; }; + static MPFRBaseT __pow__(const MPFRBaseT& a, const int& b){ return pow(a,b); }; + + static std::string __repr__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << self.str(0,std::ios::scientific); + return ss.str(); + }; + + }; + + + + + + /** + Visitor exposing important methods from the boost::multiprecision::mpq_rational class + */ + template + class MPFRRationalVisitor: public def_visitor> + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + + private: + static MPFRBaseT __add_int(const MPFRBaseT& a, const int& b){ return a+b; }; + static MPFRBaseT __iadd_int(MPFRBaseT& a, const int& b){ a+=b; return a; }; + static MPFRBaseT __radd_int(const MPFRBaseT& b, const int& a){ return a+b; }; + static MPFRBaseT __sub_int(const MPFRBaseT& a, const int& b){ return a-b; }; + static MPFRBaseT __isub_int(MPFRBaseT& a, const int& b){ a-=b; return a; }; + static MPFRBaseT __rsub_int(const MPFRBaseT& b, const int& a){ return a-b; }; + static MPFRBaseT __mul_int(const MPFRBaseT& a, const int& b){ return a*b; }; + static MPFRBaseT __imul_int(MPFRBaseT& a, const int& b){ a*=b; return a; }; + static MPFRBaseT __rmul_int(const MPFRBaseT& b, const int& a){ return a*b; }; + static MPFRBaseT __div_int(const MPFRBaseT& a, const int& b){ return a/b; }; + static MPFRBaseT __idiv_int(MPFRBaseT& a, const int& b){ a/=b; return a; }; + static MPFRBaseT __rdiv_int(const MPFRBaseT& b, const int& a){ return a/b; }; + + static MPFRBaseT __div__(const MPFRBaseT& a, const MPFRBaseT& b){ return a/b; }; + static MPFRBaseT __idiv__(MPFRBaseT& a, const MPFRBaseT& b){ a/=b; return a; }; + + static MPFRBaseT __add_mpint(const MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ return a+b; }; + static MPFRBaseT __iadd_mpint(MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ a+=b; return a; }; + static MPFRBaseT __radd_mpint(const MPFRBaseT& b, const boost::multiprecision::mpz_int& a){ return a+b; }; + static MPFRBaseT __sub_mpint(const MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ return a-b; }; + static MPFRBaseT __isub_mpint(MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ a-=b; return a; }; + static MPFRBaseT __rsub_mpint(const MPFRBaseT& b, const boost::multiprecision::mpz_int& a){ return a-b; }; + static MPFRBaseT __mul_mpint(const MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ return a*b; }; + static MPFRBaseT __imul_mpint(MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ a*=b; return a; }; + static MPFRBaseT __rmul_mpint(const MPFRBaseT& b, const boost::multiprecision::mpz_int& a){ return a*b; }; + static MPFRBaseT __div_mpint(const MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ return a/b; }; + static MPFRBaseT __idiv_mpint(MPFRBaseT& a, const boost::multiprecision::mpz_int& b){ a/=b; return a; }; + + static std::string __repr__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << self.str(0,std::ios::scientific); + return ss.str(); + }; + + }; + + + + + + + /** + Visitor exposing important methods from the bmp class, where bmp is defined in the bertini core. This is the boost multiprecision real float class. + */ + template + class MPFRFloatVisitor: public def_visitor> + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + + private: + static MPFRBaseT __add_int(const MPFRBaseT& a, const int& b){ return a+b; }; + static MPFRBaseT __iadd_int(MPFRBaseT& a, const int& b){ a+=b; return a; }; + static MPFRBaseT __radd_int(const MPFRBaseT& b, const int& a){ return a+b; }; + static MPFRBaseT __sub_int(const MPFRBaseT& a, const int& b){ return a-b; }; + static MPFRBaseT __isub_int(MPFRBaseT& a, const int& b){ a-=b; return a; }; + static MPFRBaseT __rsub_int(const MPFRBaseT& b, const int& a){ return a-b; }; + static MPFRBaseT __mul_int(const MPFRBaseT& a, const int& b){ return a*b; }; + static MPFRBaseT __imul_int(MPFRBaseT& a, const int& b){ a*=b; return a; }; + static MPFRBaseT __rmul_int(const MPFRBaseT& b, const int& a){ return a*b; }; + static MPFRBaseT __div_int(const MPFRBaseT& a, const int& b){ return a/b; }; + static MPFRBaseT __idiv_int(MPFRBaseT& a, const int& b){ a/=b; return a; }; + static MPFRBaseT __rdiv_int(const MPFRBaseT& b, const int& a){ return a/b; }; + static MPFRBaseT __pow_int(const MPFRBaseT& a, const int& b){ return pow(a,b); }; + + + static std::string __repr__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << self.str(0,std::ios::scientific); + return ss.str(); + }; + + unsigned (*def_prec1)() = &MPFRBaseT::default_precision; + void (*def_prec2)(unsigned) = &MPFRBaseT::default_precision; + }; + + + + + + + + + /** + Visitor exposing important methods from the bertini::complex + */ + template + class MPFRComplexVisitor: public def_visitor> + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + private: + static MPFRBaseT __add_float(const MPFRBaseT& a, const mpfr_float& b){ return a+b; }; + static MPFRBaseT __iadd_float(MPFRBaseT& a, const mpfr_float& b){ a+=b; return a; }; + static MPFRBaseT __radd_float(const MPFRBaseT& b, const mpfr_float& a){ return a+b; }; + static MPFRBaseT __sub_float(const MPFRBaseT& a, const mpfr_float& b){ return a-b; }; + static MPFRBaseT __isub_float(MPFRBaseT& a, const mpfr_float& b){ a-=b; return a; }; + static MPFRBaseT __rsub_float(const MPFRBaseT& b, const mpfr_float& a){ return a-b; }; + static MPFRBaseT __mul_float(const MPFRBaseT& a, const mpfr_float& b){ return a*b; }; + static MPFRBaseT __imul_float(MPFRBaseT& a, const mpfr_float& b){ a*=b; return a; }; + static MPFRBaseT __rmul_float(const MPFRBaseT& b, const mpfr_float& a){ return a*b; }; + static MPFRBaseT __div_float(const MPFRBaseT& a, const mpfr_float& b){ return a/b; }; + static MPFRBaseT __idiv_float(MPFRBaseT& a, const mpfr_float& b){ a/=b; return a; }; + static MPFRBaseT __rdiv_float(const MPFRBaseT& b, const mpfr_float& a){ return a/b; }; + static MPFRBaseT __pow_int(const MPFRBaseT& a, const int& b){ return pow(a,b); }; + static MPFRBaseT __pow_float(const MPFRBaseT& a, const mpfr_float& b){ return pow(a,b); }; + + static std::string __str__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << self; + return ss.str(); + } + + static std::string __repr__(const object& obj) + { + std::ostringstream oss; + const MPFRBaseT& self=extract(obj)(); + std::stringstream ss; + ss << "(" << real(self).str(0,std::ios::scientific) << ", " << imag(self).str(0,std::ios::scientific) << ")"; + return ss.str(); + } + + mpfr_float (MPFRBaseT::*getreal)() const = &MPFRBaseT::real; + void (MPFRBaseT::*setreal)(const mpfr_float&) = &MPFRBaseT::real; + mpfr_float (MPFRBaseT::*getimag)() const = &MPFRBaseT::imag; + void (MPFRBaseT::*setimag)(const mpfr_float&) = &MPFRBaseT::imag; + + void set_real(MPFRBaseT &c, mpfr_float const& r) { c.real(r);} + mpfr_float get_real(MPFRBaseT const&c) { return c.real();} + + void set_imag(MPFRBaseT &c, mpfr_float const& r) { c.imag(r);} + mpfr_float get_imag(MPFRBaseT const&c) { return c.imag();} + }; + + } +} + + + +#endif diff --git a/python/include/node.hpp b/python/include/node.hpp new file mode 100644 index 00000000..46d49b45 --- /dev/null +++ b/python/include/node.hpp @@ -0,0 +1,160 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/node.hpp: the header file for the python interface for Node class. + + +#ifndef Python_b2_node_hpp +#define Python_b2_node_hpp + +#include "function_tree.hpp" + + +namespace bertini{ + namespace python{ + + using namespace boost::python; + using namespace bertini::node; + + using Node = node::Node; + using NodePtr = std::shared_ptr; + + struct NodeWrap : Node, wrapper + { + void Reset() + { + if (override Reset = this->get_override("Reset")) + Reset(); // *note* + + Node::Reset(); + } + + void default_Reset() + { + return this->Node::Reset(); + } + + void print(std::ostream& target) const + { + this->get_override("print")(); + } + }; // re: NodeWrap + + // Addition operators + std::shared_ptr(*addNodeNode)(std::shared_ptr, const std::shared_ptr&) = &operator+; + std::shared_ptr(*addNodeDouble)(std::shared_ptr, double) = &operator+; + std::shared_ptr(*addNodeDbl)(std::shared_ptr, dbl) = &operator+; + std::shared_ptr(*addNodeMpfr)(std::shared_ptr, mpfr) = &operator+; + std::shared_ptr(*addNodeInt)(std::shared_ptr, int) = &operator+; + inline std::shared_ptr iaddNodeNode(std::shared_ptr lhs, const std::shared_ptr & rhs) + { + return lhs += rhs; + } + inline std::shared_ptr iaddNodeDouble(std::shared_ptr lhs, double rhs) + { + return lhs += rhs; + } + inline node::SumOperator iaddSumNode(node::SumOperator lhs, const std::shared_ptr & rhs) + { + return lhs += rhs; + } + + // Subtraction operators + std::shared_ptr(*subNodeNode)(std::shared_ptr, const std::shared_ptr&) = &operator-; + std::shared_ptr(*subNodeDouble)(std::shared_ptr, double) = &operator-; + std::shared_ptr(*subNodeDbl)(std::shared_ptr, dbl) = &operator-; + std::shared_ptr(*subNodeMpfr)(std::shared_ptr, mpfr) = &operator-; + std::shared_ptr(*subNodeInt)(std::shared_ptr, int) = &operator-; + inline std::shared_ptr isubNodeNode(std::shared_ptr lhs, const std::shared_ptr & rhs) + { + return lhs -= rhs; + } + inline std::shared_ptr isubNodeDouble(std::shared_ptr lhs, double rhs) + { + return lhs -= rhs; + } + inline node::SumOperator isubSumNode(node::SumOperator lhs, const std::shared_ptr & rhs) + { + return lhs -= rhs; + } + + + // Negate operator + std::shared_ptr(*negNode)(const std::shared_ptr &) = &operator-; + + + + + // Multiplication operators + std::shared_ptr(*multNodeNode)(std::shared_ptr, const std::shared_ptr&) = &operator*; + std::shared_ptr(*multNodeDouble)(std::shared_ptr, double) = &operator*; + std::shared_ptr(*multNodeDbl)(std::shared_ptr, dbl) = &operator*; + std::shared_ptr(*multNodeMpfr)(std::shared_ptr, mpfr) = &operator*; + std::shared_ptr(*multNodeInt)(std::shared_ptr, int) = &operator*; + inline std::shared_ptr imultNodeNode(std::shared_ptr lhs, const std::shared_ptr & rhs) + { + return lhs *= rhs; + } + inline std::shared_ptr imultNodeDouble(std::shared_ptr lhs, double rhs) + { + return lhs *= rhs; + } + std::shared_ptr(*imultMultNode)(std::shared_ptr &, const std::shared_ptr &) = &operator*=; + + // Division operators + std::shared_ptr(*divNodeNode)(std::shared_ptr, const std::shared_ptr&) = &operator/; + std::shared_ptr(*divNodeDouble)(std::shared_ptr, double) = &operator/; + std::shared_ptr(*divNodeDbl)(std::shared_ptr, dbl) = &operator/; + std::shared_ptr(*divNodeMpfr)(std::shared_ptr, mpfr) = &operator/; + std::shared_ptr(*divNodeInt)(std::shared_ptr, int) = &operator/; + inline std::shared_ptr idivNodeNode(std::shared_ptr lhs, const std::shared_ptr & rhs) + { + return lhs /= rhs; + } + inline std::shared_ptr idivNodeDouble(std::shared_ptr lhs, double rhs) + { + return lhs /= rhs; + } + std::shared_ptr(*idivMultNode)(std::shared_ptr &, const std::shared_ptr &) = &operator/=; + + // Power operators + std::shared_ptr(*powNodeNode)(const std::shared_ptr &, const std::shared_ptr&) = &pow; + std::shared_ptr(*powNodeDouble)(const std::shared_ptr&, double) = &pow; + std::shared_ptr(*powNodeDbl)(const std::shared_ptr&, dbl) = &pow; + std::shared_ptr(*powNodeMpfr)(const std::shared_ptr&, mpfr) = &pow; + std::shared_ptr(*powNodeInt)( std::shared_ptr const&, int) = &pow; + + // Transcindental operators + std::shared_ptr(*expNodeNode)(const std::shared_ptr &) = &exp; + std::shared_ptr(*logNodeNode)(const std::shared_ptr &) = &log; + std::shared_ptr(*sinNodeNode)(const std::shared_ptr &) = &sin; + std::shared_ptr(*asinNodeNode)(const std::shared_ptr &) = &asin; + std::shared_ptr(*cosNodeNode)(const std::shared_ptr &) = &cos; + std::shared_ptr(*acosNodeNode)(const std::shared_ptr &) = &acos; + std::shared_ptr(*tanNodeNode)(const std::shared_ptr &) = &tan; + std::shared_ptr(*atanNodeNode)(const std::shared_ptr &) = &atan; + + + } // re: python +} // re: bertini + + +#endif diff --git a/python/include/node_export.hpp b/python/include/node_export.hpp new file mode 100644 index 00000000..0466095d --- /dev/null +++ b/python/include/node_export.hpp @@ -0,0 +1,204 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/node_export.hpp: Header file for exposing Node class to python. + +#ifndef Xcode_b2_node_visitors_hpp +#define Xcode_b2_node_visitors_hpp + +#include +#include + + +#include "python_common.hpp" + +namespace bertini{ + namespace python{ + + + using namespace bertini::node; + + using Node = Node; + using Nodeptr = std::shared_ptr; + + void ExportNode(); + + + + + + + + + + + template + class NodeVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + private: + + static int Deg0(NodeBaseT& self) { return self.Degree();} + int (NodeBaseT::*Deg1)(std::shared_ptr const&) const= &NodeBaseT::Degree; + int (NodeBaseT::*Deg2)(VariableGroup const&) const = &NodeBaseT::Degree; + + static bool IsHom0(NodeBaseT& self) { return self.IsHomogeneous();} + bool (NodeBaseT::*IsHom1)(std::shared_ptr const&) const= &NodeBaseT::IsHomogeneous; + bool (NodeBaseT::*IsHom2)(VariableGroup const& vars) const= &NodeBaseT::IsHomogeneous; + + static bool IsPoly0(NodeBaseT& self) { return self.IsPolynomial();} + bool (NodeBaseT::*IsPoly1)(std::shared_ptr const&) const= &NodeBaseT::IsPolynomial; + bool (NodeBaseT::*IsPoly2)(VariableGroup const& vars) const= &NodeBaseT::IsPolynomial; + + // Can't create member function pointer to Eval with zero arguments because implementation + // uses default arguments + template + static T Eval0(NodeBaseT& self) { return self.template Eval();} + + // Use templating to return member function pointer to Eval + template + using Eval1_ptr = T (NodeBaseT::*)(std::shared_ptr); + template + static Eval1_ptr return_Eval1_ptr() + { + return &NodeBaseT::template Eval; + }; + + + + // Addition operators + Nodeptr(*addNodeNode)(Nodeptr, const Nodeptr&) = &operator+; + Nodeptr(*addNodeDouble)(Nodeptr, double) = &operator+; + Nodeptr(*addNodeDbl)(Nodeptr, dbl) = &operator+; + Nodeptr(*addNodeMpfr)(Nodeptr, mpfr) = &operator+; + Nodeptr(*addNodeInt)(Nodeptr, int) = &operator+; + static Nodeptr iaddNodeNode(Nodeptr lhs, const Nodeptr & rhs) + { + return lhs += rhs; + } + static Nodeptr iaddNodeDouble(Nodeptr lhs, double rhs) + { + return lhs += rhs; + } + static SumOperator iaddSumNode(SumOperator lhs, const Nodeptr & rhs) + { + return lhs += rhs; + } + + // Subtraction operators + Nodeptr(*subNodeNode)(Nodeptr, const Nodeptr&) = &operator-; + Nodeptr(*subNodeDouble)(Nodeptr, double) = &operator-; + Nodeptr(*subNodeDbl)(Nodeptr, dbl) = &operator-; + Nodeptr(*subNodeMpfr)(Nodeptr, mpfr) = &operator-; + Nodeptr(*subNodeInt)(Nodeptr, int) = &operator-; + static Nodeptr isubNodeNode(Nodeptr lhs, const Nodeptr & rhs) + { + return lhs -= rhs; + } + static Nodeptr isubNodeDouble(Nodeptr lhs, double rhs) + { + return lhs -= rhs; + } + static SumOperator isubSumNode(SumOperator lhs, const Nodeptr & rhs) + { + return lhs -= rhs; + } + + + // Negate operator + Nodeptr(*negNode)(const Nodeptr &) = &operator-; + + + + + // Multiplication operators + Nodeptr(*multNodeNode)(Nodeptr, const Nodeptr&) = &operator*; + Nodeptr(*multNodeDouble)(Nodeptr, double) = &operator*; + Nodeptr(*multNodeDbl)(Nodeptr, dbl) = &operator*; + Nodeptr(*multNodeMpfr)(Nodeptr, mpfr) = &operator*; + Nodeptr(*multNodeInt)(Nodeptr, int) = &operator*; + static Nodeptr imultNodeNode(Nodeptr lhs, const Nodeptr & rhs) + { + return lhs *= rhs; + } + static Nodeptr imultNodeDouble(Nodeptr lhs, double rhs) + { + return lhs *= rhs; + } + Nodeptr(*imultMultNode)(std::shared_ptr &, const Nodeptr &) = &operator*=; + + // Division operators + Nodeptr(*divNodeNode)(Nodeptr, const Nodeptr&) = &operator/; + Nodeptr(*divNodeDouble)(Nodeptr, double) = &operator/; + Nodeptr(*divNodeDbl)(Nodeptr, dbl) = &operator/; + Nodeptr(*divNodeMpfr)(Nodeptr, mpfr) = &operator/; + Nodeptr(*divNodeInt)(Nodeptr, int) = &operator/; + static Nodeptr idivNodeNode(Nodeptr lhs, const Nodeptr & rhs) + { + return lhs /= rhs; + } + static Nodeptr idivNodeDouble(Nodeptr lhs, double rhs) + { + return lhs /= rhs; + } + Nodeptr(*idivMultNode)(std::shared_ptr &, const Nodeptr &) = &operator/=; + + // Power operators + Nodeptr(*powNodeNode)(const Nodeptr &, const Nodeptr&) = &pow; + Nodeptr(*powNodeDouble)(const Nodeptr&, double) = &pow; + Nodeptr(*powNodeDbl)(const Nodeptr&, dbl) = &pow; + Nodeptr(*powNodeMpfr)(const Nodeptr&, mpfr) = &pow; + Nodeptr(*powNodeInt)( Nodeptr const&, int) = &pow; + + // Transcendental operators + Nodeptr(*expNodeNode)(const Nodeptr &) = &exp; + Nodeptr(*logNodeNode)(const Nodeptr &) = &log; + Nodeptr(*sinNodeNode)(const Nodeptr &) = &sin; + Nodeptr(*asinNodeNode)(const Nodeptr &) = &asin; + Nodeptr(*cosNodeNode)(const Nodeptr &) = &cos; + Nodeptr(*acosNodeNode)(const Nodeptr &) = &acos; + Nodeptr(*tanNodeNode)(const Nodeptr &) = &tan; + Nodeptr(*atanNodeNode)(const Nodeptr &) = &atan; + + + }; + + } +} + + + + + + + + +#endif diff --git a/python/include/operator.hpp b/python/include/operator.hpp new file mode 100644 index 00000000..9cada186 --- /dev/null +++ b/python/include/operator.hpp @@ -0,0 +1,104 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/operator.hpp: the header file for the python interface for operator classes. + +#ifndef Python_b2_operator_hpp +#define Python_b2_operator_hpp + + +#include "function_tree.hpp" + +namespace bertini{ + namespace python{ + + using namespace boost::python; + using namespace bertini::node; + + // UnaryOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(unOpDeg1Overloads, node::UnaryOperator::Degree, 0, 1) + int (node::UnaryOperator::*unOpDeg1)(std::shared_ptr const&) const= &bertini::node::UnaryOperator::Degree; + int (node::UnaryOperator::*unOpDeg2)(VariableGroup const&) const = &bertini::node::UnaryOperator::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(unOpIsHom1Overloads, node::UnaryOperator::IsHomogeneous, 0, 1) + bool (node::UnaryOperator::*unOpIsHom1)(std::shared_ptr const&) const= &bertini::node::UnaryOperator::IsHomogeneous; + bool (node::UnaryOperator::*unOpIsHom2)(VariableGroup const& vars) const= &bertini::node::UnaryOperator::IsHomogeneous; + + // SumOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(sumDeg1Overloads, node::SumOperator::Degree, 0, 1) + int (node::SumOperator::*sumDeg1)(std::shared_ptr const&) const= &bertini::node::SumOperator::Degree; + int (node::SumOperator::*sumDeg2)(VariableGroup const&) const = &bertini::node::SumOperator::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(sumIsHom1Overloads, node::SumOperator::IsHomogeneous, 0, 1) + bool (node::SumOperator::*sumIsHom1)(std::shared_ptr const&) const= &bertini::node::SumOperator::IsHomogeneous; + bool (node::SumOperator::*sumIsHom2)(VariableGroup const& vars) const= &bertini::node::SumOperator::IsHomogeneous; + void (node::SumOperator::*sumAddChild1)(std::shared_ptr child) = &node::SumOperator::AddChild; + void (node::SumOperator::*sumAddChild2)(std::shared_ptr child, bool) = &node::SumOperator::AddChild; + + // NegOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(negIsHom1Overloads, node::NegateOperator::IsHomogeneous, 0, 1) + bool (node::NegateOperator::*negIsHom1)(std::shared_ptr const&) const= &bertini::node::NegateOperator::IsHomogeneous; + bool (node::NegateOperator::*negIsHom2)(VariableGroup const& vars) const= &bertini::node::NegateOperator::IsHomogeneous; + + // MultOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(multDeg1Overloads, node::MultOperator::Degree, 0, 1) + int (node::MultOperator::*multDeg1)(std::shared_ptr const&) const= &bertini::node::MultOperator::Degree; + int (node::MultOperator::*multDeg2)(VariableGroup const&) const = &bertini::node::MultOperator::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(multIsHom1Overloads, node::MultOperator::IsHomogeneous, 0, 1) + bool (node::MultOperator::*multIsHom1)(std::shared_ptr const&) const= &bertini::node::MultOperator::IsHomogeneous; + bool (node::MultOperator::*multIsHom2)(VariableGroup const& vars) const= &bertini::node::MultOperator::IsHomogeneous; + void (node::MultOperator::*multAddChild1)(std::shared_ptr child) = &node::MultOperator::AddChild; + void (node::MultOperator::*multAddChild2)(std::shared_ptr child, bool) = &node::MultOperator::AddChild; + + // PowerOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(powDeg1Overloads, node::PowerOperator::Degree, 0, 1) + int (node::PowerOperator::*powDeg1)(std::shared_ptr const&) const= &bertini::node::PowerOperator::Degree; + int (node::PowerOperator::*powDeg2)(VariableGroup const&) const = &bertini::node::PowerOperator::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(powIsHom1Overloads, node::PowerOperator::IsHomogeneous, 0, 1) + bool (node::PowerOperator::*powIsHom1)(std::shared_ptr const&) const= &bertini::node::PowerOperator::IsHomogeneous; + bool (node::PowerOperator::*powIsHom2)(VariableGroup const& vars) const= &bertini::node::PowerOperator::IsHomogeneous; + + // IntegerPowerOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(intpowDeg1Overloads, node::IntegerPowerOperator::Degree, 0, 1) + int (node::IntegerPowerOperator::*intpowDeg1)(std::shared_ptr const&) const= &bertini::node::IntegerPowerOperator::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(intpowIsHom1Overloads, node::IntegerPowerOperator::IsHomogeneous, 0, 1) + bool (node::IntegerPowerOperator::*intpowIsHom1)(std::shared_ptr const&) const= &bertini::node::IntegerPowerOperator::IsHomogeneous; + bool (node::IntegerPowerOperator::*intpowIsHom2)(VariableGroup const& vars) const= &bertini::node::IntegerPowerOperator::IsHomogeneous; + + // SqrtOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(sqrtDeg1Overloads, node::SqrtOperator::Degree, 0, 1) + int (node::SqrtOperator::*sqrtDeg1)(std::shared_ptr const&) const= &bertini::node::SqrtOperator::Degree; + + // ExpOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(expDeg1Overloads, node::ExpOperator::Degree, 0, 1) + int (node::ExpOperator::*expDeg1)(std::shared_ptr const&) const= &bertini::node::ExpOperator::Degree; + + // LogOperator class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(logDeg1Overloads, node::LogOperator::Degree, 0, 1) + int (node::LogOperator::*logDeg1)(std::shared_ptr const&) const= &bertini::node::LogOperator::Degree; + + + + + + + + } // re: python +} // re: bertini + + +#endif diff --git a/python/include/operator_export.hpp b/python/include/operator_export.hpp new file mode 100644 index 00000000..9d2d2a75 --- /dev/null +++ b/python/include/operator_export.hpp @@ -0,0 +1,158 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/operator_export.hpp: Header file for exposing operator nodes to python. + + + + +#ifndef Xcode_b2_operator_visitors_hpp +#define Xcode_b2_operator_visitors_hpp + +#include +#include +#include + +#include "python_common.hpp" + +namespace bertini{ + namespace python{ + + using namespace boost::python; + using namespace bertini::node; + + using Node = Node; + using Nodeptr = std::shared_ptr; + + + + + void ExportOperators(); + + + + + + /** + UnaryOperator class(abstract) + */ + template + class UnaryOpVisitor: public def_visitor > + { + public: + template + void visit(PyClass& cl) const; + }; + + + + + /** NaryOperator class(abstract) + */ + template + class NaryOpVisitor: public def_visitor > + { + public: + template + void visit(PyClass& cl) const; + }; + + + + + + /** + SumOperator and MultOperator classes + */ + template + class SumMultOpVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + + + private: + void (NodeBaseT::*addChild2)(std::shared_ptr child, bool) = &NodeBaseT::AddChild; + + }; + + + + + /** + PowerOperator class + */ + template + class PowerOpVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + }; + + + /** + IntegerPowerOperator class + */ + template + class IntPowOpVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + private: + std::string (NodeBaseT::*getexp)() const = &NodeBaseT::exponent; + void (NodeBaseT::*setexp)(const std::string &) = &NodeBaseT::set_exponent; + + }; + + + + } //re: namespace python +}//re: namespace bertini + + + + + + + + + + + +#endif diff --git a/python/include/parser_export.hpp b/python/include/parser_export.hpp new file mode 100644 index 00000000..6d805e6e --- /dev/null +++ b/python/include/parser_export.hpp @@ -0,0 +1,74 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/parser_export.hpp: Header file for exposing a method for parsing an input file to a system to python. + + + + +#ifndef Xcode_b2_parser_export_hpp +#define Xcode_b2_parser_export_hpp +#include + + +#include +#include + + + +#include "python_common.hpp" + + +namespace bertini{ + namespace python{ + + using namespace bertini; + + ///////////// Parser Exposure ///////////////////// + template + ResultT Parser(std::string str) + { + ResultT res; + std::string::const_iterator iter = str.begin(); + std::string::const_iterator end = str.end(); + ParserT P; + phrase_parse(iter, end, P, boost::spirit::ascii::space, res); + + return res; + }; + + + + + void ExportParsers() + { + def("parse_system", &Parser >); + }; + + } +} + +#endif diff --git a/python/include/python_common.hpp b/python/include/python_common.hpp new file mode 100644 index 00000000..6fafe492 --- /dev/null +++ b/python/include/python_common.hpp @@ -0,0 +1,58 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/python_common.hpp: A common header file for all python exposure files + + +#ifndef Xcode_b2_python_common_hpp +#define Xcode_b2_python_common_hpp + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + + +#include +#include + + +using namespace boost::python; +typedef bertini::mpfr_float bmp; + + + + + +#endif diff --git a/python/include/root.hpp b/python/include/root.hpp new file mode 100644 index 00000000..682ced5e --- /dev/null +++ b/python/include/root.hpp @@ -0,0 +1,45 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/root.hpp: the header file for the python interface for root classes. + +#ifndef Python_b2_roots_hpp +#define Python_b2_roots_hpp + +#include "function_tree.hpp" + +namespace bertini{ + namespace python{ + + using namespace boost::python; + + // Function class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(funcDeg1Overloads, node::Function::Degree, 0, 1) + int (node::Function::*funcDeg1)(std::shared_ptr const&) const= &bertini::node::Function::Degree; + int (node::Function::*funcDeg2)(VariableGroup const&) const = &bertini::node::Function::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(funcIsHom1Overloads, node::Function::IsHomogeneous, 0, 1) + bool (node::Function::*funcIsHom1)(std::shared_ptr const&) const= &bertini::node::Function::IsHomogeneous; + bool (node::Function::*funcIsHom2)(VariableGroup const& vars) const= &bertini::node::Function::IsHomogeneous; + + + + } // re: python +} // re: bertini + +#endif diff --git a/python/include/root_export.hpp b/python/include/root_export.hpp new file mode 100644 index 00000000..08a2f99c --- /dev/null +++ b/python/include/root_export.hpp @@ -0,0 +1,79 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/root_export.hpp: Header file for exposing root nodes to python. + + + + +#ifndef Xcode_b2_root_export_hpp +#define Xcode_b2_root_export_hpp +#include +#include + +#include "python_common.hpp" + +namespace bertini{ + namespace python{ + + using namespace boost::python; + using namespace bertini::node; + + using Node = Node; + using Nodeptr = std::shared_ptr; + + void ExportRoots(); + + + /** + Function class + */ + template + class FunctionVisitor: public def_visitor > + { + public: + template + void visit(PyClass& cl) const; + }; + + + + /** + Jacobian class + */ + template + class JacobianVisitor: public def_visitor > + { + public: + template + void visit(PyClass& cl) const; + }; + + + } +} + +#endif diff --git a/python/include/symbol.hpp b/python/include/symbol.hpp new file mode 100644 index 00000000..9e8d9901 --- /dev/null +++ b/python/include/symbol.hpp @@ -0,0 +1,80 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/symbol.hpp: the header file for the python interface for symbol classes. + +#ifndef Python_b2_symbol_hpp +#define Python_b2_symbol_hpp + +#include "function_tree.hpp" + + +namespace bertini{ + namespace python{ + + using namespace boost::python; + // Number class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(numberDeg1Overloads, node::Number::Degree, 0, 1) + int (bertini::node::Number::*numberDeg1)(std::shared_ptr const&) const= &bertini::node::Number::Degree; + int (bertini::node::Number::*numberDeg2)(VariableGroup const&) const = &bertini::node::Number::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(numberIsHom1Overloads, node::Number::IsHomogeneous, 0, 1) + bool (bertini::node::Number::*numberIsHom1)(std::shared_ptr const&) const= &bertini::node::Number::IsHomogeneous; + bool (bertini::node::Number::*numberIsHom2)(VariableGroup const& vars) const= &bertini::node::Number::IsHomogeneous; + + // Pi class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(piDeg1Overloads, node::special_number::Pi::Degree, 0, 1) + int (node::special_number::Pi::*piDeg1)(std::shared_ptr const&) const= &bertini::node::special_number::Pi::Degree; + int (node::special_number::Pi::*piDeg2)(VariableGroup const&) const = &bertini::node::special_number::Pi::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(piIsHom1Overloads, node::special_number::Pi::IsHomogeneous, 0, 1) + bool (node::special_number::Pi::*piIsHom1)(std::shared_ptr const&) const= &bertini::node::special_number::Pi::IsHomogeneous; + bool (node::special_number::Pi::*piIsHom2)(VariableGroup const& vars) const= &bertini::node::special_number::Pi::IsHomogeneous; + + // E class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(eDeg1Overloads, node::special_number::E::Degree, 0, 1) + int (node::special_number::E::*eDeg1)(std::shared_ptr const&) const= &bertini::node::special_number::E::Degree; + int (node::special_number::E::*eDeg2)(VariableGroup const&) const = &bertini::node::special_number::E::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(eIsHom1Overloads, node::special_number::E::IsHomogeneous, 0, 1) + bool (node::special_number::E::*eIsHom1)(std::shared_ptr const&) const= &bertini::node::special_number::E::IsHomogeneous; + bool (node::special_number::E::*eIsHom2)(VariableGroup const& vars) const= &bertini::node::special_number::E::IsHomogeneous; + + // Variable class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(varDeg1Overloads, node::Variable::Degree, 0, 1) + int (node::Variable::*varDeg1)(std::shared_ptr const&) const= &bertini::node::Variable::Degree; + int (node::Variable::*varDeg2)(VariableGroup const&) const = &bertini::node::Variable::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(varIsHom1Overloads, node::Variable::IsHomogeneous, 0, 1) + bool (node::Variable::*varIsHom1)(std::shared_ptr const&) const= &bertini::node::Variable::IsHomogeneous; + bool (node::Variable::*varIsHom2)(VariableGroup const& vars) const= &bertini::node::Variable::IsHomogeneous; + + // Differential class + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(diffDeg1Overloads, node::Differential::Degree, 0, 1) + int (node::Differential::*diffDeg1)(std::shared_ptr const&) const= &bertini::node::Differential::Degree; + int (node::Differential::*diffDeg2)(VariableGroup const&) const = &bertini::node::Differential::Degree; + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(diffIsHom1Overloads, node::Differential::IsHomogeneous, 0, 1) + bool (node::Differential::*diffIsHom1)(std::shared_ptr const&) const= &bertini::node::Differential::IsHomogeneous; + bool (node::Differential::*diffIsHom2)(VariableGroup const& vars) const= &bertini::node::Differential::IsHomogeneous; + + + + + + } // re: python +} // re: bertini + + +#endif diff --git a/python/include/symbol_export.hpp b/python/include/symbol_export.hpp new file mode 100644 index 00000000..6aa19cb8 --- /dev/null +++ b/python/include/symbol_export.hpp @@ -0,0 +1,145 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/symbol_export.hpp: Header file for exposing symbol nodes to python. + + + + +#ifndef Xcode_b2_symbol_visitors_hpp +#define Xcode_b2_symbol_visitors_hpp +#include +#include +#include +#include +#include + + + +#include "python_common.hpp" + + +namespace bertini{ + namespace python{ + + using namespace bertini::node; + using mpz_int = boost::multiprecision::mpz_int; + using mpq_rational = boost::multiprecision::mpq_rational; + + + + void ExportSymbols(); + + + + + /** + NamedSymbol class(abstract) + */ + template + class NamedSymbolVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + private: + std::string (NodeBaseT::*getname)() const = &NodeBaseT::name; + void (NodeBaseT::*setname)(const std::string &) = &NodeBaseT::name; + + }; + + + + /** + Integer class + */ + template + class IntegerVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + }; + + + + + /** + Rational class + */ + template + class RationalVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + }; + + + + + /** + Variable class + */ + template + class VariableVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + }; + + + + /** + Differential class + */ + template + class DifferentialVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + }; + + }//namespace python +} // namespace bertini + +#endif diff --git a/python/include/system.hpp b/python/include/system.hpp new file mode 100644 index 00000000..97c783d0 --- /dev/null +++ b/python/include/system.hpp @@ -0,0 +1,59 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/system.hpp: the header file for the python interface for System classes. + +#ifndef Python_b2_system_hpp +#define Python_b2_system_hpp + +#include "function_tree.hpp" + +#include +#include + + + +namespace bertini{ + namespace python{ + + template using Vec = Eigen::Matrix; + template using Mat = Eigen::Matrix; + using VariableGroup = std::deque< std::shared_ptr >; + + using dbl = std::complex; + using mpfr = bertini::complex; + + using namespace boost::python; + + + void (bertini::System::*sysAddFunc1)(std::shared_ptr const&) = &bertini::System::AddFunction; + void (bertini::System::*sysAddFunc2)(std::shared_ptr const&) = &bertini::System::AddFunction; + + template Vec (bertini::System::*sysEval1)(const Vec &) = &bertini::System::Eval; + template Vec (bertini::System::*sysEval2)(const Vec &, const T &) = &bertini::System::Eval; + + template Mat (bertini::System::*sysJac1)(const Vec &) = &bertini::System::Jacobian; + template Mat (bertini::System::*sysJac2)(const Vec &, const T &) = &bertini::System::Jacobian; + + std::vector (bertini::System::*sysDeg1)() const = &bertini::System::Degrees; + std::vector (bertini::System::*sysDeg2)(VariableGroup const&) const = &bertini::System::Degrees; + } // re: python +} // re: bertini + +#endif diff --git a/python/include/system_export.hpp b/python/include/system_export.hpp new file mode 100644 index 00000000..7077b623 --- /dev/null +++ b/python/include/system_export.hpp @@ -0,0 +1,159 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/system_export.hpp: Header file for exposing systems to python, including start systems. + + + + +#ifndef Xcode_b2_system_export_hpp +#define Xcode_b2_system_export_hpp +#include +#include + + + + + +#include "python_common.hpp" + + +namespace bertini{ + namespace python{ + + using namespace bertini; + + template using Vec = Eigen::Matrix; + template using Mat = Eigen::Matrix; + using VariableGroup = std::deque< std::shared_ptr >; + + using dbl = std::complex; + using mpfr = bertini::complex; + + + + + void ExportSystem(); + + + + + + + /** + System class + */ + template + class SystemVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + private: + void (bertini::System::*sysAddFunc1)(std::shared_ptr const&) = &bertini::System::AddFunction; + void (bertini::System::*sysAddFunc2)(std::shared_ptr const&) = &bertini::System::AddFunction; + + +// Vec (System::*sysEval1)(const Vec &) = &System::template Eval; +// Vec (System::*sysEval1)(const Vec &) = &System::template Eval; + + std::vector (bertini::System::*sysDeg1)() const = &bertini::System::Degrees; + std::vector (bertini::System::*sysDeg2)(VariableGroup const&) const = &bertini::System::Degrees; + + // Eval functions + template + using Eval1_ptr = Vec (SystemBaseT::*)(const Vec&); + template + static Eval1_ptr return_Eval1_ptr() + { + return &SystemBaseT::template Eval; + }; + + template + using Eval2_ptr = Vec (SystemBaseT::*)(const Vec&, const T &); + template + static Eval2_ptr return_Eval2_ptr() + { + return &SystemBaseT::template Eval; + }; + + + // Jacobian Eval functions + template + using Jac1_ptr = Mat (SystemBaseT::*)(const Vec&); + template + static Jac1_ptr return_Jac1_ptr() + { + return &SystemBaseT::template Jacobian; + }; + + template + using Jac2_ptr = Mat (SystemBaseT::*)(const Vec&, const T &); + template + static Jac2_ptr return_Jac2_ptr() + { + return &SystemBaseT::template Jacobian; + }; + + }; + + + + + + + + /** + StartSystem class + */ + template + class StartSystemVisitor: public def_visitor > + { + friend class def_visitor_access; + + public: + template + void visit(PyClass& cl) const; + + + private: + template + using GenStart_ptr = Vec (SystemBaseT::*)(size_t) const; + template + static GenStart_ptr return_GenStart_ptr() + { + return &SystemBaseT::template StartPoint; + }; + }; + + } +} + + +#endif diff --git a/python/m4/ax_eigen.m4 b/python/m4/ax_eigen.m4 new file mode 100644 index 00000000..c3ac7804 --- /dev/null +++ b/python/m4/ax_eigen.m4 @@ -0,0 +1,93 @@ +# +# SYNOPSIS +# +# AX_EIGEN() +# +# DESCRIPTION +# +# Check for the Eigen linear algebra library. +# +# +# LICENSE +# +# Copyright Daniel Brake 2016 +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +AC_DEFUN([AX_EIGEN], + [ +AC_ARG_WITH([eigen], + [AS_HELP_STRING([--with-eigen@<:@=ARG@:>@], + [Use the Eigen linear algebra library from a standard location (ARG=yes), + from the given location (ARG=), + or disable it (ARG=no) + @<:@ARG=yes@:>@ ])], + [ + if test "$withval" = "no"; then + want_eigen="no" + elif test "$withval" = "yes"; then + want_eigen="yes" + ac_eigen_path="" + else + want_eigen="yes" + ac_eigen_path="$withval" + fi + ], + [want_eigen="yes"]) + + +if test "x$want_eigen" = "xyes"; then + + CPPFLAGS_SAVED="$CPPFLAGS" + + AC_REQUIRE([AC_PROG_CXX]) + AC_LANG_PUSH(C++) + + found_eigen_dir=no + if test "$ac_eigen_path" != ""; then + + if test -d "$ac_eigen_path/Eigen"; then + EIGEN_CPPFLAGS="-I$ac_eigen_path" + found_eigen_dir=yes; + else + if test -d "$ac_eigen_path/eigen3/Eigen"; then + EIGEN_CPPFLAGS="-I$ac_eigen_path/eigen3" + found_eigen_dir=yes; + fi + fi + + else + for ac_eigen_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_eigen_path_tmp/include/eigen3/Eigen"; then + EIGEN_CPPFLAGS="-I$ac_eigen_path_tmp/include/eigen3" + found_eigen_dir=yes; + break; + fi + done + fi + + if test "x$found_eigen_dir" = "xyes"; then + CPPFLAGS="$CPPFLAGS $EIGEN_CPPFLAGS" + else + AC_MSG_ERROR([unable to find Eigen directory]) + fi + + AC_CHECK_HEADERS([Eigen/Dense], + [ + succeeded=yes; + export CPPFLAGS; + ], + [ + CPPFLAGS="$CPPFLAGS_SAVED"; + export CPPFLAGS; + AC_MSG_ERROR([unable to include Eigen]) + ]) + AC_LANG_POP([C++]) +fi + +]) + + diff --git a/python/m4/lx_find_mpi.m4 b/python/m4/lx_find_mpi.m4 deleted file mode 100644 index 01fd72a3..00000000 --- a/python/m4/lx_find_mpi.m4 +++ /dev/null @@ -1,205 +0,0 @@ -################################################################################################# -# Copyright (c) 2010, Lawrence Livermore National Security, LLC. -# Produced at the Lawrence Livermore National Laboratory -# Written by Todd Gamblin, tgamblin@llnl.gov. -# LLNL-CODE-417602 -# All rights reserved. -# -# This file is part of Libra. For details, see http://github.com/tgamblin/libra. -# Please also read the LICENSE file for further information. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this list of -# conditions and the disclaimer below. -# * Redistributions in binary form must reproduce the above copyright notice, this list of -# conditions and the disclaimer (as noted below) in the documentation and/or other materials -# provided with the distribution. -# * Neither the name of the LLNS/LLNL nor the names of its contributors may be used to endorse -# or promote products derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS -# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -# LAWRENCE LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -################################################################################################# - -# -# LX_FIND_MPI() -# ------------------------------------------------------------------------ -# This macro finds an MPI compiler and extracts includes and libraries from -# it for use in automake projects. The script exports the following variables: -# -# AC_DEFINE variables: -# HAVE_MPI AC_DEFINE'd to 1 if we found MPI -# -# AC_SUBST variables: -# MPICC Name of MPI compiler -# MPI_CFLAGS Includes and defines for MPI C compilation -# MPI_CLDFLAGS Libraries and library paths for linking MPI C programs -# -# MPICXX Name of MPI C++ compiler -# MPI_CXXFLAGS Includes and defines for MPI C++ compilation -# MPI_CXXLDFLAGS Libraries and library paths for linking MPI C++ programs -# -# MPIF77 Name of MPI Fortran 77 compiler -# MPI_F77FLAGS Includes and defines for MPI Fortran 77 compilation -# MPI_F77LDFLAGS Libraries and library paths for linking MPI Fortran 77 programs -# -# MPIFC Name of MPI Fortran compiler -# MPI_FFLAGS Includes and defines for MPI Fortran compilation -# MPI_FLDFLAGS Libraries and library paths for linking MPI Fortran programs -# -# Shell variables output by this macro: -# have_C_mpi 'yes' if we found MPI for C, 'no' otherwise -# have_CXX_mpi 'yes' if we found MPI for C++, 'no' otherwise -# have_F77_mpi 'yes' if we found MPI for F77, 'no' otherwise -# have_F_mpi 'yes' if we found MPI for Fortran, 'no' otherwise -# -AC_DEFUN([LX_FIND_MPI], -[ -AC_LANG_CASE( -[C], [ -AC_REQUIRE([AC_PROG_CC]) -if [[ ! -z "$MPICC" ]]; then -LX_QUERY_MPI_COMPILER(MPICC, [$MPICC], C) -else -LX_QUERY_MPI_COMPILER(MPICC, [mpicc mpiicc mpixlc mpipgcc], C) -fi -], -[C++], [ -AC_REQUIRE([AC_PROG_CXX]) -if [[ ! -z "$MPICXX" ]]; then -LX_QUERY_MPI_COMPILER(MPICXX, [$MPICXX], CXX) -else -LX_QUERY_MPI_COMPILER(MPICXX, [mpicxx mpiCC mpic++ mpig++ mpiicpc mpipgCC mpixlC], CXX) -fi -], -[F77], [ -AC_REQUIRE([AC_PROG_F77]) -if [[ ! -z "$MPIF77" ]]; then -LX_QUERY_MPI_COMPILER(MPIF77, [$MPIF77], F77) -else -LX_QUERY_MPI_COMPILER(MPIF77, [mpif77 mpiifort mpixlf77 mpixlf77_r], F77) -fi -], -[Fortran], [ -AC_REQUIRE([AC_PROG_FC]) -if [[ ! -z "$MPIFC" ]]; then -LX_QUERY_MPI_COMPILER(MPIFC, [$MPIFC], F) -else -mpi_default_fc="mpif95 mpif90 mpigfortran mpif2003" -mpi_intel_fc="mpiifort" -mpi_xl_fc="mpixlf95 mpixlf95_r mpixlf90 mpixlf90_r mpixlf2003 mpixlf2003_r" -mpi_pg_fc="mpipgf95 mpipgf90" -LX_QUERY_MPI_COMPILER(MPIFC, [$mpi_default_fc $mpi_intel_fc $mpi_xl_fc $mpi_pg_fc], F) -fi -]) -]) - - -# -# LX_QUERY_MPI_COMPILER([compiler-var-name], [compiler-names], [output-var-prefix]) -# ------------------------------------------------------------------------ -# AC_SUBST variables: -# MPI_FLAGS Includes and defines for MPI compilation -# MPI_LDFLAGS Libraries and library paths for linking MPI C programs -# -# Shell variables output by this macro: -# found_mpi_flags 'yes' if we were able to get flags, 'no' otherwise -# -AC_DEFUN([LX_QUERY_MPI_COMPILER], -[ -# Try to find a working MPI compiler from the supplied names -AC_PATH_PROGS($1, [$2], [not-found]) - -# Figure out what the compiler responds to to get it to show us the compile -# and link lines. After this part of the macro, we'll have a valid -# lx_mpi_command_line -echo -n "Checking whether $$1 responds to '-showme:compile'... " -lx_mpi_compile_line=`$$1 -showme:compile 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -lx_mpi_link_line=`$$1 -showme:link 2>/dev/null` -else -echo no -echo -n "Checking whether $$1 responds to '-showme'... " -lx_mpi_command_line=`$$1 -showme 2>/dev/null` -if [[ "$?" -ne 0 ]]; then -echo no -echo -n "Checking whether $$1 responds to '-compile-info'... " -lx_mpi_compile_line=`$$1 -compile-info 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -lx_mpi_link_line=`$$1 -link-info 2>/dev/null` -else -echo no -echo -n "Checking whether $$1 responds to '-show'... " -lx_mpi_command_line=`$$1 -show 2>/dev/null` -if [[ "$?" -eq 0 ]]; then -echo yes -else -echo no -fi -fi -else -echo yes -fi -fi - -if [[ ! -z "$lx_mpi_compile_line" -a ! -z "$lx_mpi_link_line" ]]; then -lx_mpi_command_line="$lx_mpi_compile_line $lx_mpi_link_line" -fi - -if [[ ! -z "$lx_mpi_command_line" ]]; then -# Now extract the different parts of the MPI command line. Do these separately in case we need to -# parse them all out in future versions of this macro. -lx_mpi_defines=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-D\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_includes=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-I\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_link_paths=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-L\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_libs=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-l\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` -lx_mpi_link_args=` echo "$lx_mpi_command_line" | grep -o -- '\(^\| \)-Wl,\([[^\"[:space:]]]\+\|\"[[^\"[:space:]]]\+\"\)'` - -# Create variables and clean up newlines and multiple spaces -MPI_$3FLAGS="$lx_mpi_defines $lx_mpi_includes" -MPI_$3LDFLAGS="$lx_mpi_link_paths $lx_mpi_libs $lx_mpi_link_args" -MPI_$3FLAGS=` echo "$MPI_$3FLAGS" | tr '\n' ' ' | sed 's/^[[ \t]]*//;s/[[ \t]]*$//' | sed 's/ +/ /g'` -MPI_$3LDFLAGS=`echo "$MPI_$3LDFLAGS" | tr '\n' ' ' | sed 's/^[[ \t]]*//;s/[[ \t]]*$//' | sed 's/ +/ /g'` - -OLD_CPPFLAGS=$CPPFLAGS -OLD_LIBS=$LIBS -CPPFLAGS=$MPI_$3FLAGS -LIBS=$MPI_$3LDFLAGS - -AC_TRY_LINK([#include ], -[int rank, size; -MPI_Comm_rank(MPI_COMM_WORLD, &rank); -MPI_Comm_size(MPI_COMM_WORLD, &size);], -[# Add a define for testing at compile time. -AC_DEFINE([HAVE_MPI], [1], [Define to 1 if you have MPI libs and headers.]) -have_$3_mpi='yes'], -[# zero out mpi flags so we don't link against the faulty library. -MPI_$3FLAGS="" -MPI_$3LDFLAGS="" -have_$3_mpi='no']) - -# AC_SUBST everything. -AC_SUBST($1) -AC_SUBST(MPI_$3FLAGS) -AC_SUBST(MPI_$3LDFLAGS) - -LIBS=$OLD_LIBS -CPPFLAGS=$OLD_CPPFLAGS -else -echo Unable to find suitable MPI Compiler. Try setting $1. -have_$3_mpi='no' -fi -]) - - diff --git a/python/minieigen b/python/minieigen new file mode 160000 index 00000000..ce32110a --- /dev/null +++ b/python/minieigen @@ -0,0 +1 @@ +Subproject commit ce32110aa8fb69985bf48988474b5d64c7a42c2d diff --git a/python/src/Makemodule.am b/python/src/Makemodule.am index 2a2f44e0..79c035f3 100644 --- a/python/src/Makemodule.am +++ b/python/src/Makemodule.am @@ -1,26 +1,53 @@ #this is src/python/Makemodule.am -bertini_python_header_files = +bertini_python_header_files = $(includedir)/bertini_python.hpp \ + $(includedir)/function_tree.hpp \ + $(includedir)/mpfr_export.hpp \ + $(includedir)/node_export.hpp \ + $(includedir)/symbol_export.hpp \ + $(includedir)/operator_export.hpp \ + $(includedir)/root_export.hpp \ + $(includedir)/system_export.hpp + + +bertini_python_source_files = src/bertini_python.cpp \ + src/mpfr_export.cpp \ + src/node_export.cpp \ + src/symbol_export.cpp \ + src/operator_export.cpp \ + src/root_export.cpp \ + src/system_export.cpp \ + minieigen/src/expose-converters.cpp \ + minieigen/src/double-conversion/bignum-dtoa.cc \ + minieigen/src/double-conversion/bignum.cc \ + minieigen/src/double-conversion/cached-powers.cc \ + minieigen/src/double-conversion/diy-fp.cc \ + minieigen/src/double-conversion/double-conversion.cc \ + minieigen/src/double-conversion/fast-dtoa.cc \ + minieigen/src/double-conversion/fixed-dtoa.cc \ + minieigen/src/double-conversion/strtod.cc -bertini_python_source_files = bertini_python = \ $(bertini_python_header_files) \ $(bertini_python_source_files) -lib_LTLIBRARIES += libpybertini.la +pyexec_LTLIBRARIES += pybertini.la +# we are building a PYTHON library. +# so this is explicitly NOT lib_LTLIBRARIES -libpybertini_ladir = $(includedir)/libpybertini_la +pybertini_ladir = $(DESTDIR)/$(bindir) +pybertini_la_HEADERS = +pybertini_la_SOURCES = $(bertini_python_header_files) $(bertini_python_source_files) -libpybertini_la_HEADERS = -libpybertini_la_SOURCES = $(bertini_python_header_files) $(bertini_python_source_files) +pybertini_la_LIBADD = $(BOOST_LDFLAGS) $(PYTHON_LDFLAGS) $(PYTHON_EXTRA_LIBS) -l$(BOOST_PYTHON_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_CHRONO_LIB) $(BOOST_REGEX_LIB) $(BOOST_TIMER_LIB) $(MPI_CXXLDFLAGS) $(BOOST_SERIALIZATION_LIB) -libpybertini_la_LIBADD = $(BOOST_LDFLAGS) $(PYTHON_LDFLAGS) $(PYTHON_EXTRA_LIBS) -l$(BOOST_PYTHON_LIB) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) $(BOOST_CHRONO_LIB) $(BOOST_REGEX_LIB) $(BOOST_TIMER_LIB) $(MPI_CXXLDFLAGS) $(BOOST_SERIALIZATION_LIB) +pybertini_la_LDFLAGS = -module -avoid-version -shared +#the above -module is so that the .so file is generated. it also allows to not use the 'lib' prefix. + +pybertini_la_CXXFLAGS = $(PYTHON_CPPFLAGS) $(BOOST_CPPFLAGS) -libpybertini_la_LDFLAGS = -module -rpath '$(libdir)' -#the above -module is so that the .so file is generated. otherwise, on mac, it may just be the mac format dynamic library. -libpybertini_la_CXXFLAGS = $(PYTHON_CPPFLAGS) $(BOOST_CPPFLAGS) diff --git a/python/src/bertini_python.cpp b/python/src/bertini_python.cpp new file mode 100644 index 00000000..ffe54873 --- /dev/null +++ b/python/src/bertini_python.cpp @@ -0,0 +1,56 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/bertini_python.cpp: the main source file for the python interface for bertini. + + +#include "bertini_python.hpp" + + +namespace bertini +{ + namespace python + { + + + + BOOST_PYTHON_MODULE(pybertini) // this name must match the name of the generated .so file. + { + ExportContainers(); + + ExportMpfr(); + + ExportMinieigen(); + + SetupFunctionTree(); + ExportNode(); + ExportSymbols(); + ExportOperators(); + ExportRoots(); + + ExportSystem(); + + ExportParsers(); + } + + } +} + + diff --git a/python/src/function_tree.cpp b/python/src/function_tree.cpp new file mode 100644 index 00000000..49d6c616 --- /dev/null +++ b/python/src/function_tree.cpp @@ -0,0 +1,59 @@ + +#include "function_tree.hpp" + +using namespace boost::python; + +using dbl = std::complex; +using mpfr = bertini::complex; + +// BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NodeEvalOverloadsMpfr, bertini::node::Node::template Eval, 0, 1); +//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(SumAddChildOverloads, bertini::node::SumOperator::AddChild, 1, 2); +//BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(MultAddChildOverloads, bertini::node::MultOperator::AddChild, 1, 2); + + + +namespace bertini{ + namespace python{ + using Nodeptr = std::shared_ptr; + + + void SetupFunctionTree() + { + // Tell Python that pointers to derived Nodes can be used as Node pointers + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + implicitly_convertible, Nodeptr>(); + implicitly_convertible, Nodeptr>(); + + + + // Expose the deque containers + class_< std::deque< std::shared_ptr< node::Variable > > >("VariableGroup") + .def(vector_indexing_suite< std::deque< std::shared_ptr< node::Variable > >, true >()) + ; + } + + + } +} + diff --git a/python/src/mpfr_export.cpp b/python/src/mpfr_export.cpp new file mode 100644 index 00000000..33c33038 --- /dev/null +++ b/python/src/mpfr_export.cpp @@ -0,0 +1,278 @@ +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// 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 MPFRBaseVisitor::visit(PyClass& cl) const + { + cl + .def("__neg__",&MPFRBaseVisitor::__neg__) + + .def("__add__",&MPFRBaseVisitor::__add__).def("__iadd__",&MPFRBaseVisitor::__iadd__) + .def("__sub__",&MPFRBaseVisitor::__sub__).def("__isub__",&MPFRBaseVisitor::__isub__) + .def("__mul__",&MPFRBaseVisitor::__mul__).def("__imul__",&MPFRBaseVisitor::__imul__) + + .def("__str__", &MPFRBaseVisitor::__str__) + ; + + + def("abs", &MPFRBaseVisitor::__abs__); + + } + + + template + template + void MPFRFloatBaseVisitor::visit(PyClass& cl) const + { + MPFRBaseVisitor().visit(cl); + + cl + .def("__div__",&MPFRFloatBaseVisitor::__div__).def("__idiv__",&MPFRFloatBaseVisitor::__idiv__) + .def("__pow__",&MPFRFloatBaseVisitor::__pow__) + + .def("precision", bmpprec1) + .def("precision", bmpprec2) + ; + + def("exp", &MPFRFloatBaseVisitor::__exp__); + def("log", &MPFRFloatBaseVisitor::__log__); + def("sqrt", &MPFRFloatBaseVisitor::__sqrt__); + + def("sin", &MPFRFloatBaseVisitor::__sin__); + def("cos", &MPFRFloatBaseVisitor::__cos__); + def("tan", &MPFRFloatBaseVisitor::__tan__); + + def("asin", &MPFRFloatBaseVisitor::__asin__); + def("acos", &MPFRFloatBaseVisitor::__acos__); + def("atan", &MPFRFloatBaseVisitor::__atan__); + + def("sinh", &MPFRFloatBaseVisitor::__sinh__); + def("cosh", &MPFRFloatBaseVisitor::__cosh__); + def("tanh", &MPFRFloatBaseVisitor::__tanh__); + + } + + + template + template + void MPFRIntVisitor::visit(PyClass& cl) const + { + MPFRBaseVisitor().visit(cl); + + cl + .def("__add__",&MPFRIntVisitor::__add_int).def("__iadd__",&MPFRIntVisitor::__iadd_int) + .def("__radd__",&MPFRIntVisitor::__radd_int) + .def("__sub__",&MPFRIntVisitor::__sub_int).def("__isub__",&MPFRIntVisitor::__isub_int) + .def("__rsub__",&MPFRIntVisitor::__rsub_int) + .def("__mul__",&MPFRIntVisitor::__mul_int).def("__imul__",&MPFRIntVisitor::__imul_int) + .def("__rmul__",&MPFRIntVisitor::__rmul_int) + .def("__pow__",&MPFRIntVisitor::__pow__) + .def("__repr__", &MPFRIntVisitor::__repr__) + + .def(self < self) + .def(self <= self) + .def(self > self) + .def(self >= self) + .def(self == self) + .def(self != self) + ; + + }; + + + template + template + void MPFRRationalVisitor::visit(PyClass& cl) const + { + MPFRBaseVisitor().visit(cl); + + cl + .def("__add__",&MPFRRationalVisitor::__add_int).def("__iadd__",&MPFRRationalVisitor::__iadd_int) + .def("__radd__",&MPFRRationalVisitor::__radd_int) + .def("__sub__",&MPFRRationalVisitor::__sub_int).def("__isub__",&MPFRRationalVisitor::__isub_int) + .def("__rsub__",&MPFRRationalVisitor::__rsub_int) + .def("__mul__",&MPFRRationalVisitor::__mul_int).def("__imul__",&MPFRRationalVisitor::__imul_int) + .def("__rmul__",&MPFRRationalVisitor::__rmul_int) + .def("__div__",&MPFRRationalVisitor::__div_int).def("__idiv__",&MPFRRationalVisitor::__idiv_int) + .def("__rdiv__",&MPFRRationalVisitor::__rdiv_int) + + .def("__div__",&MPFRRationalVisitor::__div__).def("__idiv__",&MPFRRationalVisitor::__idiv__) + + .def("__add__",&MPFRRationalVisitor::__add_mpint).def("__iadd__",&MPFRRationalVisitor::__iadd_mpint) + .def("__radd__",&MPFRRationalVisitor::__radd_mpint) + .def("__sub__",&MPFRRationalVisitor::__sub_mpint).def("__isub__",&MPFRRationalVisitor::__isub_mpint) + .def("__rsub__",&MPFRRationalVisitor::__rsub_int) + .def("__mul__",&MPFRRationalVisitor::__mul_mpint).def("__imul__",&MPFRRationalVisitor::__imul_mpint) + .def("__rmul__",&MPFRRationalVisitor::__rmul_mpint) + .def("__div__",&MPFRRationalVisitor::__div_mpint).def("__idiv__",&MPFRRationalVisitor::__idiv_mpint) + + .def("__repr__", &MPFRRationalVisitor::__repr__) + + .def(self < self) + .def(self <= self) + .def(self > self) + .def(self >= self) + .def(self == self) + .def(self != self) + ; + + }; + + + + template + template + void MPFRFloatVisitor::visit(PyClass& cl) const + { + MPFRFloatBaseVisitor().visit(cl); + + cl + .def("__add__",&MPFRFloatVisitor::__add_int).def("__iadd__",&MPFRFloatVisitor::__iadd_int) + .def("__radd__",&MPFRFloatVisitor::__radd_int) + .def("__sub__",&MPFRFloatVisitor::__sub_int).def("__isub__",&MPFRFloatVisitor::__isub_int) + .def("__rsub__",&MPFRFloatVisitor::__rsub_int) + .def("__mul__",&MPFRFloatVisitor::__mul_int).def("__imul__",&MPFRFloatVisitor::__imul_int) + .def("__rmul__",&MPFRFloatVisitor::__rmul_int) + .def("__div__",&MPFRFloatVisitor::__div_int).def("__idiv__",&MPFRFloatVisitor::__idiv_int) + .def("__rdiv__",&MPFRFloatVisitor::__rdiv_int) + .def("__pow__",&MPFRFloatVisitor::__pow_int) + + .def("__repr__", &MPFRFloatVisitor::__repr__) + + .def(self < self) + .def(self <= self) + .def(self > self) + .def(self >= self) + .def(self == self) + .def(self != self) + ; + + + // default_precision are defined as free functions in python + def("default_precision", MPFRFloatVisitor::def_prec1); + def("default_precision", MPFRFloatVisitor::def_prec2); + + }; + + + template + template + void MPFRComplexVisitor::visit(PyClass& cl) const + { + MPFRFloatBaseVisitor().visit(cl); + + cl + .def("__add__",&MPFRComplexVisitor::__add_float).def("__iadd__",&MPFRComplexVisitor::__iadd_float) + .def("__radd__",&MPFRComplexVisitor::__radd_float) + .def("__sub__",&MPFRComplexVisitor::__sub_float).def("__isub__",&MPFRComplexVisitor::__isub_float) + .def("__rsub__",&MPFRComplexVisitor::__rsub_float) + .def("__mul__",&MPFRComplexVisitor::__mul_float).def("__imul__",&MPFRComplexVisitor::__imul_float) + .def("__rmul__",&MPFRComplexVisitor::__rmul_float) + .def("__div__",&MPFRComplexVisitor::__div_float).def("__idiv__",&MPFRComplexVisitor::__idiv_float) + .def("__rdiv__",&MPFRComplexVisitor::__rdiv_float) + .def("__pow__",&MPFRComplexVisitor::__pow_int) + .def("__pow__",&MPFRComplexVisitor::__pow_float) + + .def("__repr__", &MPFRComplexVisitor::__repr__) + + .add_property("real", getreal, setreal) + .add_property("imag", getimag, setimag) + ; + + + // All complex specific function are free in python + def("real",&real); + def("imag",&imag); + + def("abs2",&MPFRBaseT::abs2); + def("polar",&polar); + def("norm",&MPFRBaseT::norm); + def("conj",&MPFRBaseT::conj); + def("arg",&arg); + + def("square",&square); + def("cube",&cube); + def("inverse", &inverse); + def("asinh",&asinh); + def("acosh",&acosh); + def("atanh",&atanh); + + } + + + void ExportMpfr() + { + class_("mpfr_int", init<>()) + .def(init()) + .def(init()) + .def(MPFRIntVisitor()) + ; + + class_("mpfr_rational", init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(MPFRRationalVisitor()) + ; + + class_("mpfr_float", init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(MPFRFloatVisitor()) + ; + + class_("mpfr_complex", init<>()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(MPFRComplexVisitor()) + ; + + + + }; + + + } //namespace python +} // namespace bertini + + diff --git a/python/src/node.cpp b/python/src/node.cpp new file mode 100644 index 00000000..39249176 --- /dev/null +++ b/python/src/node.cpp @@ -0,0 +1,133 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/node.cpp: the source file for the python interface for Node class. + +#include + +#include "node.hpp" + + +using namespace boost::python; + +using dbl = std::complex; +using mpfr = bertini::complex; + +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NodeEvalOverloadsDbl, bertini::node::Node::template Eval, 0, 1); +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(NodeEvalOverloadsMPFR, bertini::node::Node::template Eval, 0, 1); + + +namespace bertini{ + namespace python{ + void ExportNode() + { + using namespace bertini::node; + using NodePtr = std::shared_ptr; + + + + class_ >("Node", no_init) + .def("reset", &bertini::node::Node::Reset, &bertini::python::NodeWrap::default_Reset) + + .def("evald", &bertini::node::Node::Eval, + NodeEvalOverloadsDbl(args("DiffVar"), "Eval's docstring")) + .def("evalmp", &bertini::node::Node::Eval, + NodeEvalOverloadsMPFR(args("DiffVar"), "Eval's docstring")) + .def(self_ns::str(self_ns::self)) + .def(self_ns::repr(self_ns::self)) + + .def("__add__",addNodeNode) + .def("__add__",addNodeDouble) + .def("__radd__",addNodeDouble) + .def("__add__",addNodeDbl) + .def("__radd__",addNodeDbl) + .def("__add__",addNodeMpfr) + .def("__radd__",addNodeMpfr) + .def("__add__",addNodeInt) + .def("__radd__",addNodeInt) + .def("__iadd__",&iaddNodeNode) + .def("__iadd__",&iaddNodeDouble) + .def("__iadd__", &iaddSumNode) + + .def("__sub__",subNodeNode) + .def("__sub__",subNodeDouble) + .def("__rsub__",subNodeDouble) + .def("__sub__",subNodeDbl) + .def("__rsub__",subNodeDbl) + .def("__sub__",subNodeMpfr) + .def("__rsub__",subNodeMpfr) + .def("__sub__",subNodeInt) + .def("__rsub__",subNodeInt) + .def("__isub__",&isubNodeNode) + .def("__isub__",&isubNodeDouble) + .def("__isub__", &isubSumNode) + + .def("__mul__",multNodeNode) + .def("__mul__",multNodeDouble) + .def("__rmul__",multNodeDouble) + .def("__mul__",multNodeDbl) + .def("__rmul__",multNodeDbl) + .def("__mul__",multNodeMpfr) + .def("__rmul__",multNodeMpfr) + .def("__mul__",multNodeInt) + .def("__rmul__",multNodeInt) + .def("__imul__",&imultNodeNode) + .def("__imul__",&imultNodeDouble) + .def("__imul__",imultMultNode) + + .def("__div__",divNodeNode) + .def("__div__",divNodeDouble) + .def("__rdiv__",divNodeDouble) + .def("__div__",divNodeDbl) + .def("__rdiv__",divNodeDbl) + .def("__div__",divNodeMpfr) + .def("__rdiv__",divNodeMpfr) + .def("__div__",divNodeInt) + .def("__rdiv__",divNodeInt) + .def("__idiv__",&idivNodeNode) + .def("__idiv__",&idivNodeDouble) + .def("__idiv__",idivMultNode) + + .def("__neg__", negNode) + + .def("__pow__",powNodeNode) + .def("__pow__",powNodeDouble) + .def("__pow__",powNodeDbl) + .def("__pow__",powNodeMpfr) + .def("__pow__",powNodeInt) + + + ; + + def("exp", expNodeNode); + def("log", logNodeNode); + def("sin", sinNodeNode); + def("asin", asinNodeNode); + def("cos", cosNodeNode); + def("acos", acosNodeNode); + def("tan", tanNodeNode); + def("atan", atanNodeNode); + + } + + + + + } // re: python +} // re: bertini diff --git a/python/src/node_export.cpp b/python/src/node_export.cpp new file mode 100644 index 00000000..1cfdc458 --- /dev/null +++ b/python/src/node_export.cpp @@ -0,0 +1,196 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/node_export.cpp: Source file for exposing Node class to python. + +#include + + +#include "node_export.hpp" + +//#include + + +namespace bertini{ + namespace python{ + + // Wrapper struct to allow derived classes to overide methods in python + struct NodeWrap : Node, wrapper + { + void Reset() + { + if (override Reset = this->get_override("Reset")) + Reset(); + + Node::Reset(); + } + void default_Reset(){ return this->Node::Reset();} + + void precision(unsigned int prec) { this->get_override("precision")(prec); } + + int Degree(std::shared_ptr const& v = nullptr) const {return this->get_override("Degree")(v); } + int Degree(VariableGroup const& vars) const {return this->get_override("Degree")(vars); } + + std::shared_ptr Differentiate() {return this->get_override("Differentiate")(); } + + std::vector MultiDegree(VariableGroup const& vars) const {return this->get_override("MultiDegree")(vars); } + + void Homogenize(VariableGroup const& vars, std::shared_ptr const& homvar) { this->get_override("Homogenize")(vars, homvar); } + + bool IsHomogeneous(std::shared_ptr const& v = nullptr) const {return this->get_override("IsHomogeneous")(v); } + bool IsHomogeneous(VariableGroup const& vars) const {return this->get_override("IsHomogeneous")(vars); } + + bool IsPolynomial(std::shared_ptr const&v = nullptr) const {return this->get_override("IsPolynomial")(v); } + bool IsPolynomial(VariableGroup const&v) const {return this->get_override("IsPolynomial")(v); } + + + + }; // re: NodeWrap + + + + + + + + + + + template + template + void NodeVisitor::visit(PyClass& cl) const + { + cl + .def("reset", &NodeBaseT::Reset, &NodeWrap::default_Reset) + .def("precision", &NodeBaseT::precision ) + .def("degree", &Deg0 ) + .def("degree", Deg1) + .def("degree", Deg2 ) + .def("differentiate", &NodeBaseT::Differentiate ) + .def("multidegree", &NodeBaseT::MultiDegree ) + .def("homogenize", &NodeBaseT::Homogenize ) + .def("is_homogeneous", IsHom0 ) + .def("is_homogeneous", IsHom1 ) + .def("is_homogeneous", IsHom2 ) + .def("is_polynomial", IsPoly0 ) + .def("is_polynomial", IsPoly1 ) + .def("is_polynomial", IsPoly2 ) + + .def("evald", &Eval0 ) + .def("evald", return_Eval1_ptr() ) + .def("evalmp", &Eval0 ) + .def("evalmp", return_Eval1_ptr() ) + + .def(self_ns::str(self_ns::self)) + .def(self_ns::repr(self_ns::self)) + + .def("__add__",addNodeNode) + .def("__add__",addNodeDouble) + .def("__radd__",addNodeDouble) + .def("__add__",addNodeDbl) + .def("__radd__",addNodeDbl) + .def("__add__",addNodeMpfr) + .def("__radd__",addNodeMpfr) + .def("__add__",addNodeInt) + .def("__radd__",addNodeInt) + .def("__iadd__",&NodeVisitor::iaddNodeNode) + .def("__iadd__",&NodeVisitor::iaddNodeDouble) + .def("__iadd__", &NodeVisitor::iaddSumNode) + + .def("__sub__",subNodeNode) + .def("__sub__",subNodeDouble) + .def("__rsub__",subNodeDouble) + .def("__sub__",subNodeDbl) + .def("__rsub__",subNodeDbl) + .def("__sub__",subNodeMpfr) + .def("__rsub__",subNodeMpfr) + .def("__sub__",subNodeInt) + .def("__rsub__",subNodeInt) + .def("__isub__",&NodeVisitor::isubNodeNode) + .def("__isub__",&NodeVisitor::isubNodeDouble) + .def("__isub__", &NodeVisitor::isubSumNode) + + .def("__mul__",multNodeNode) + .def("__mul__",multNodeDouble) + .def("__rmul__",multNodeDouble) + .def("__mul__",multNodeDbl) + .def("__rmul__",multNodeDbl) + .def("__mul__",multNodeMpfr) + .def("__rmul__",multNodeMpfr) + .def("__mul__",multNodeInt) + .def("__rmul__",multNodeInt) + .def("__imul__",&NodeVisitor::imultNodeNode) + .def("__imul__",&NodeVisitor::imultNodeDouble) + .def("__imul__",imultMultNode) + + .def("__div__",divNodeNode) + .def("__div__",divNodeDouble) + .def("__rdiv__",divNodeDouble) + .def("__div__",divNodeDbl) + .def("__rdiv__",divNodeDbl) + .def("__div__",divNodeMpfr) + .def("__rdiv__",divNodeMpfr) + .def("__div__",divNodeInt) + .def("__rdiv__",divNodeInt) + .def("__idiv__",&NodeVisitor::idivNodeNode) + .def("__idiv__",&NodeVisitor::idivNodeDouble) + .def("__idiv__",idivMultNode) + + .def("__neg__", negNode) + + .def("__pow__",powNodeNode) + .def("__pow__",powNodeDouble) + .def("__pow__",powNodeDbl) + .def("__pow__",powNodeMpfr) + .def("__pow__",powNodeInt) + ; + + + def("exp", expNodeNode); + def("log", logNodeNode); + def("sin", sinNodeNode); + def("asin", asinNodeNode); + def("cos", cosNodeNode); + def("acos", acosNodeNode); + def("tan", tanNodeNode); + def("atan", atanNodeNode); + + } + + + + + void ExportNode() + { + class_("Node", no_init) + .def(NodeVisitor()) + ; + + }; + + + } //namespace python +} // namespace bertini diff --git a/python/src/operator.cpp b/python/src/operator.cpp new file mode 100644 index 00000000..ecd6650a --- /dev/null +++ b/python/src/operator.cpp @@ -0,0 +1,246 @@ +// python/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/operator.cpp: the source file for the python interface for operator classes. + +#include +#include "operator.hpp" + +using namespace boost::python; +using namespace bertini::node; + + +namespace bertini{ + namespace python{ + + + + + + void ExportOperators() + { + using Nodeptr = std::shared_ptr; + + class_< node::Operator, bases, boost::noncopyable >("Operator", no_init); + + // Unary Operators + class_< node::UnaryOperator, bases, boost::noncopyable >("UnaryOperator", no_init) + .def("reset", &node::UnaryOperator::Reset) + .def("set_child", &node::UnaryOperator::SetChild) + .def("first_child", &node::UnaryOperator::first_child) + .def("degree", unOpDeg1, unOpDeg1Overloads()) + .def("degree", unOpDeg2) + .def("multidegree", &node::UnaryOperator::MultiDegree) + .def("is_homogeneous", unOpIsHom1, unOpIsHom1Overloads()) + .def("is_homogeneous", unOpIsHom2) + .def("homogenize", &node::UnaryOperator::Homogenize) + .def("precision", &node::UnaryOperator::precision) + ; + + + // Binary Operators + class_< BinaryOperator, bases, boost::noncopyable >("BinaryOperator", no_init) + .def("reset", pure_virtual(&BinaryOperator::Reset)) + ; + + + // Nary Operators + class_< node::NaryOperator, bases, bases, boost::noncopyable >("NaryOperator", no_init) + .def("reset", &node::NaryOperator::Reset) + .def("add_child", &node::NaryOperator::AddChild) + .def("first_child", &node::NaryOperator::first_child) + .def("precision", &node::NaryOperator::precision) + .def("children_size", &node::NaryOperator::children_size) + ; + + + + + + // Sum Operator + class_,std::shared_ptr > + ("SumOperator", init<>()) + .def(init &,const std::shared_ptr &>()) + .def(init &,bool,const std::shared_ptr &,bool>()) + + .def("add_child", sumAddChild1) + .def("add_child", sumAddChild2) + + .def("degree", sumDeg1, sumDeg1Overloads()) + .def("degree", sumDeg2) + .def("multidegree", &node::SumOperator::MultiDegree) + .def("is_homogeneous", sumIsHom1, sumIsHom1Overloads()) + .def("is_homogeneous", sumIsHom2) + .def("homogenize", &node::SumOperator::Homogenize) + + .def("differentiate", &node::SumOperator::Differentiate) + +// .def(self += other()) +// .def(self -= other()) + ; + + + // Negate Operator + class_,std::shared_ptr > + ("NegateOperator", init< optional >()) + .def("differentiate", &node::NegateOperator::Differentiate) + .def("is_homogeneous", negIsHom1, negIsHom1Overloads()) + .def("is_homogeneous", negIsHom2) + ; + + + // Multiplication Operator + class_,std::shared_ptr > + ("MultOperator", init<>()) + .def(init &,const std::shared_ptr &>()) + .def(init &,bool,const std::shared_ptr &,bool>()) + + .def("add_child", multAddChild1) + .def("add_child", multAddChild2) + + .def("degree", multDeg1, multDeg1Overloads()) + .def("degree", multDeg2) + .def("is_homogeneous", multIsHom1, multIsHom1Overloads()) + .def("is_homogeneous", multIsHom2) + .def("homogenize", &node::MultOperator::Homogenize) + + .def("differentiate", &MultOperator::Differentiate) + ; + + + // Power Operator(with any exponent) + class_, std::shared_ptr > + ("PowerOperator", init<>()) + .def(init &,const std::shared_ptr &>()) + + .def("set_base", &node::PowerOperator::SetBase) + .def("set_exponent", &node::PowerOperator::SetBase) + + .def("degree", powDeg1, powDeg1Overloads()) + .def("degree", powDeg2) + .def("multidegree", &PowerOperator::MultiDegree) + .def("is_homogeneous", powIsHom1, powIsHom1Overloads()) + .def("is_homogeneous", powIsHom2) + .def("homogenize", &PowerOperator::Homogenize) + .def("precision", &PowerOperator::precision) + + .def("reset", &PowerOperator::Reset) + .def("differentiate", &PowerOperator::Differentiate) + ; + + + // IntegerPower Operator(with integer exponents) + class_, std::shared_ptr > + ("IntegerPowerOperator", init<>()) + .def(init &,optional >()) + + .add_property("exponent", &IntegerPowerOperator::exponent, &IntegerPowerOperator::set_exponent) + + .def("degree", intpowDeg1, intpowDeg1Overloads()) + .def("is_homogeneous", intpowIsHom1, intpowIsHom1Overloads()) + .def("is_homogeneous", powIsHom2) + ; + + + // Sqrt Operator + class_, std::shared_ptr > + ("SqrtOperator", init< optional &> >()) + + .def("degree", sqrtDeg1, sqrtDeg1Overloads()) + + .def("differentiate", &SqrtOperator::Differentiate) + ; + + + // Exp Operator + class_, std::shared_ptr > + ("ExpOperator", init< optional &> >()) + + .def("degree", expDeg1, expDeg1Overloads()) + + .def("differentiate", &ExpOperator::Differentiate) + ; + + + // Log Operator + class_, std::shared_ptr > + ("LogOperator", init< optional &> >()) + + .def("degree", logDeg1, logDeg1Overloads()) + + .def("differentiate", &LogOperator::Differentiate) + ; + + + + // TrigOperator + class_, boost::noncopyable > + ("TrigOperator", no_init) + + .def("degree", &TrigOperator::Degree) + ; + + + + // SinOperator + class_, std::shared_ptr > + ("SinOperator", init< optional &> >()) + + .def("differentiate", &SinOperator::Differentiate) + ; + + + // CosOperator + class_, std::shared_ptr > + ("CosOperator", init< optional &> >()) + + .def("differentiate", &CosOperator::Differentiate) + ; + + + // TanOperator + class_, std::shared_ptr > + ("TanOperator", init< optional &> >()) + + .def("differentiate", &TanOperator::Differentiate) + ; + + + // ArcSinOperator + class_, std::shared_ptr > + ("ArcSinOperator", init< optional &> >()) + + .def("differentiate", &ArcSinOperator::Differentiate) + ; + + + // ArcCosOperator + class_, std::shared_ptr > + ("ArcCosOperator", init< optional &> >()) + + .def("differentiate", &ArcCosOperator::Differentiate) + ; + + + // ArcTanOperator + class_, std::shared_ptr > + ("ArcTanOperator", init< optional &> >()) + + .def("differentiate", &ArcTanOperator::Differentiate) + ; + + } + + } // re: python +} // re: bertini diff --git a/python/src/operator_export.cpp b/python/src/operator_export.cpp new file mode 100644 index 00000000..a63dd1bb --- /dev/null +++ b/python/src/operator_export.cpp @@ -0,0 +1,216 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/operator_export.cpp: Source file for exposing operator nodes to python. + + + +#include +#include "operator_export.hpp" + + + +namespace bertini{ + namespace python{ + + struct UnaryOpWrap : UnaryOperator, wrapper + { + void SetChild(std::shared_ptr new_child) + { + if (override SetChild = this->get_override("SetChild")) + SetChild(new_child); // *note* + + UnaryOperator::SetChild(new_child); + } + void default_SetChild(std::shared_ptr new_child){ return this->UnaryOperator::SetChild(new_child);} + }; // re: NodeWrap + + + struct NaryOpWrap : NaryOperator, wrapper + { + void AddChild(std::shared_ptr child) + { + if (override AddChild = this->get_override("AddChild")) + AddChild(child); // *note* + + NaryOperator::AddChild(child); + } + void default_AddChild(std::shared_ptr child){ return this->NaryOperator::AddChild(child);} + }; // re: NodeWrap + + + + + template + template + void UnaryOpVisitor::visit(PyClass& cl) const + { + cl + .def("set_child", &NodeBaseT::SetChild ) + .def("first_child", &NodeBaseT::first_child ) + ; + } + + template + template + void NaryOpVisitor::visit(PyClass& cl) const + { + cl + .def("add_child", &NodeBaseT::AddChild ) + .def("first_child", &NodeBaseT::first_child ) + .def("children_size", &NodeBaseT::children_size ) + ; + } + + template + template + void SumMultOpVisitor::visit(PyClass& cl) const + { + + cl + .def("add_child", addChild2) + ; + } + + + template + template + void PowerOpVisitor::visit(PyClass& cl) const + { + cl + .def("set_exponent", &PowerOperator::SetExponent) + .def("set_base", &PowerOperator::SetBase) + ; + } + + template + template + void IntPowOpVisitor::visit(PyClass& cl) const + { + cl + .add_property("exponent", getexp, setexp) + ; + } + + + + void ExportOperators() + { + // Operator class + class_, std::shared_ptr >("Operator", no_init) + ; + + // UnaryOperator class + class_, std::shared_ptr >("UnaryOperator", no_init) + .def(UnaryOpVisitor()) + ; + + // BinaryOperator class + class_, std::shared_ptr >("BinaryOperator", no_init) + ; + + // NaryOperator class + class_, std::shared_ptr >("NaryOperator", no_init) + .def(NaryOpVisitor()) + ; + + // SumOperator class + class_, std::shared_ptr >("SumOperator", init() ) + .def(init() ) + + .def(SumMultOpVisitor()) + ; + + // NegateOperator class + class_, std::shared_ptr >("NegateOperator", init() ) + ; + + // MultOperator class + class_, std::shared_ptr >("MultOperator", init() ) + .def(init() ) + + .def(SumMultOpVisitor()) + ; + + // PowerOperator class + class_, std::shared_ptr >("PowerOperator", init() ) + + .def(PowerOpVisitor()) + ; + + // IntegerPowerOperator class + class_, std::shared_ptr >("IntegerPowerOperator", init >() ) + + .def(PowerOpVisitor()) + ; + + // SqrtOperator class + class_, std::shared_ptr >("SqrtOperator", init() ) + ; + + // ExpOperator class + class_, std::shared_ptr >("ExpOperator", init() ) + ; + + // LogOperator class + class_, std::shared_ptr >("LogOperator", init() ) + ; + + + + // TrigOperator class + class_, std::shared_ptr >("TrigOperator", no_init) + ; + + // SinOperator class + class_, std::shared_ptr >("SinOperator", init() ) + ; + // CosOperator class + class_, std::shared_ptr >("CosOperator", init() ) + ; + // TanOperator class + class_, std::shared_ptr >("TanOperator", init() ) + ; + + // ArcSinOperator class + class_, std::shared_ptr >("ArcSinOperator", init() ) + ; + // ArcCosOperator class + class_, std::shared_ptr >("ArcCosOperator", init() ) + ; + // ArcTanOperator class + class_, std::shared_ptr >("ArcTanOperator", init() ) + ; + + + + + } + } //namespace python +} // namespace bertini + + + diff --git a/python/src/root.cpp b/python/src/root.cpp new file mode 100644 index 00000000..0b7c885d --- /dev/null +++ b/python/src/root.cpp @@ -0,0 +1,60 @@ +// python/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/root.cpp: the source file for the python interface for root classes. + +#include +#include "root.hpp" + +using namespace boost::python; +using namespace bertini::node; + + +namespace bertini{ + namespace python{ + + + + void ExportRoots() + { + using Nodeptr = std::shared_ptr; + + + // Function class + class_< Function, bases, std::shared_ptr >("Function", init< optional< std::string > >()) + .def(init< const Nodeptr& >()) + .def("entry_node", &Function::entry_node) + .def("set_root", &Function::SetRoot) + .def("reset", &Function::Reset) + .def("ensure_not_empty", &Function::EnsureNotEmpty) + .def("differentiate", &Function::Differentiate) + .def("degree", funcDeg1, funcDeg1Overloads()) + .def("degree", funcDeg2) + .def("multidegree", &node::Function::MultiDegree) + .def("is_homogeneous", funcIsHom1, funcIsHom1Overloads()) + .def("is_homogeneous", funcIsHom2) + .def("homogenize", &node::Function::Homogenize) + .def("precision", &Function::precision) + ; + + + // Jacobian class + class_< Jacobian, bases, std::shared_ptr >("Jacobian", init< optional< const Nodeptr&> >()) + .def("EvalJ", &Jacobian::EvalJ) + ; + + } + + } // re: python +} // re: bertini \ No newline at end of file diff --git a/python/src/root_export.cpp b/python/src/root_export.cpp new file mode 100644 index 00000000..15d9b66c --- /dev/null +++ b/python/src/root_export.cpp @@ -0,0 +1,84 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/root_export.cpp: Source file for exposing root nodes to python. + + + + +#include +#include "root_export.hpp" + + +namespace bertini{ + namespace python{ + + + + template + template + void FunctionVisitor::visit(PyClass& cl) const + { + cl + .add_property("root", &Function::entry_node, &Function::SetRoot) + .def("ensure_not_empy", &Function::EnsureNotEmpty) + ; + } + + + template + template + void JacobianVisitor::visit(PyClass& cl) const + { + cl + .def("evalJd", &Jacobian::template EvalJ) + .def("evalJmp", &Jacobian::template EvalJ) + ; + } + + + + void ExportRoots() + { + // Function class + class_, std::shared_ptr >("Function", init()) + .def(init() ) + + .def(FunctionVisitor()) + ; + + + // Jacobian class + class_, std::shared_ptr >("Jacobian", init()) + + .def(JacobianVisitor()) + ; + + } + + } +} + diff --git a/python/src/symbol.cpp b/python/src/symbol.cpp new file mode 100644 index 00000000..0058a515 --- /dev/null +++ b/python/src/symbol.cpp @@ -0,0 +1,136 @@ +// python/function_tree.hpp 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/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/symbol.cpp: the source file for the python interface for symbol classes. + +#include + +#include "symbol.hpp" +#include "function_tree.hpp" + + +using namespace boost::python; + + +namespace bertini{ + namespace python{ + + + + void ExportSymbols() + { + + /////// Don't expose abstract classes for now ///////////// + +// // Symbol class(abstract) +// class_,std::shared_ptr, boost::noncopyable>("Symbol", no_init); +// +// +// // NamedSymbol class(abstract) +// class_,std::shared_ptr, boost::noncopyable >("NamedSymbol", no_init) +// .def("print", &bertini::node::NamedSymbol::print) +// ; + + + // Number class(abstract) + class_, boost::noncopyable >("Number", no_init) + .def("degree", numberDeg1, numberDeg1Overloads()) + .def("degree", numberDeg2) + .def("multidegree", &node::Number::MultiDegree) + .def("is_homogeneous", numberIsHom1, numberIsHom1Overloads()) + .def("is_homogeneous", numberIsHom2) + .def("precision", &node::Number::precision) + .def("homogenize", &node::Number::Homogenize) + .def("reset", &node::Number::Reset) + ; + + + // Float class + class_, std::shared_ptr >("Float", init< optional >()) + .def(init()) + .def(init()) + .def(init< bmp, bmp >()) + .def(init< optional >()) + + .def("differentiate", &node::Float::Differentiate) + ; + + + // Pi class + class_ >("Pi", init<>()) + .def("degree", piDeg1, piDeg1Overloads()) + .def("degree", piDeg2) + .def("multidegree", &node::special_number::Pi::MultiDegree) + .def("is_homogeneous", piIsHom1, piIsHom1Overloads()) + .def("is_homogeneous", piIsHom2) + .def("precision", &node::special_number::Pi::precision) + .def("homogenize", &node::special_number::Pi::Homogenize) + .def("reset", &node::special_number::Pi::Reset) + .def("differentiate", &node::special_number::Pi::Differentiate) + ; + + + // E class + class_ >("E", init<>()) + .def("degree", eDeg1, eDeg1Overloads()) + .def("degree", eDeg2) + .def("multidegree", &node::special_number::E::MultiDegree) + .def("is_homogeneous", eIsHom1, eIsHom1Overloads()) + .def("is_homogeneous", eIsHom2) + .def("precision", &node::special_number::E::precision) + .def("homogenize", &node::special_number::E::Homogenize) + .def("reset", &node::special_number::E::Reset) + .def("differentiate", &node::special_number::E::Differentiate) + ; + + + // Variable class + class_, std::shared_ptr >("Variable", init< optional >()) + .def("degree", varDeg1, varDeg1Overloads()) + .def("degree", varDeg2) + .def("multidegree", &node::Variable::MultiDegree) + .def("is_homogeneous", varIsHom1, varIsHom1Overloads()) + .def("is_homogeneous", varIsHom2) + .def("precision", &node::Variable::precision) + .def("homogenize", &node::Variable::Homogenize) + .def("reset", &node::Variable::Reset) + .def("differentiate", &node::Variable::Differentiate) + .def("set_current_value", &node::Variable::set_current_value) + ; + + + // Differential class + class_,std::shared_ptr > + ("Differential", init<>()) + .def(init,std::string>()) + .def("get_variable", &node::Differential::GetVariable) + .def("degree", diffDeg1, diffDeg1Overloads()) + .def("degree", diffDeg2) + .def("multidegree", &node::Differential::MultiDegree) + .def("is_homogeneous", diffIsHom1, diffIsHom1Overloads()) + .def("is_homogeneous", diffIsHom2) + .def("precision", &node::Differential::precision) + .def("homogenize", &node::Differential::Homogenize) + .def("differentiate", &node::Differential::Differentiate) + ; + + } + + } // re: python +} // re: bertini diff --git a/python/src/symbol_export.cpp b/python/src/symbol_export.cpp new file mode 100644 index 00000000..b61306a5 --- /dev/null +++ b/python/src/symbol_export.cpp @@ -0,0 +1,161 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/symbol_export.cpp: Source file for exposing symbol nodes to python. + + + + +#include + +#include "symbol_export.hpp" + + + +namespace bertini{ + namespace python{ + + template + template + void NamedSymbolVisitor::visit(PyClass& cl) const + { + cl + .add_property("name", getname, setname) + ; + } + + + template + template + void RationalVisitor::visit(PyClass& cl) const + { + cl + .def("rand", &NodeBaseT::Rand) + .def("rand_real", &NodeBaseT::RandReal) + ; + } + + + + + template + template + void VariableVisitor::visit(PyClass& cl) const + { + cl + .def("set_current_value", &NodeBaseT::template set_current_value) + .def("set_current_value", &NodeBaseT::template set_current_value) + ; + } + + + template + template + void DifferentialVisitor::visit(PyClass& cl) const + { + cl + .def("get_variable", &NodeBaseT::GetVariable) + ; + } + + + + + void ExportSymbols() + { + + // Symbol class + class_, std::shared_ptr >("Symbol", no_init) + ; + + // NamedSymbol class + class_, std::shared_ptr >("NamedSymbol", no_init) + ; + + // Number class + class_, std::shared_ptr >("Number", no_init) + ; + + // Float class + class_, std::shared_ptr >("Float", init< double, double >()) + .def(init()) + .def(init()) + .def(init< bmp, bmp >()) + .def(init< std::string, std::string >()) + ; + + + // Pi class + class_, std::shared_ptr >("Pi", init<>()) + ; + + + // E class + class_, std::shared_ptr >("E", init<>()) + ; + + + // Integer class + class_, std::shared_ptr >("Integer", init< int >()) + .def(init()) + .def(init()) + ; + + + // Rational class + class_, std::shared_ptr >("Rational", init< int >()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + .def(init()) + + .def(RationalVisitor()) + ; + + + // Variable class + class_, std::shared_ptr >("Variable", init< std::string >()) + .def(VariableVisitor()) + ; + + + // Differential class + class_,std::shared_ptr >("Differential", init,std::string>()) + + .def(DifferentialVisitor()) + ; + + + def("make_pi", &Pi); + def("make_i", &I); + def("make_e", &E); + + }; + + + } //namespace python +} // namespace bertini diff --git a/python/src/system.cpp b/python/src/system.cpp new file mode 100644 index 00000000..30025bf1 --- /dev/null +++ b/python/src/system.cpp @@ -0,0 +1,96 @@ +// python/function_tree.hpp 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/function_tree.hpp. If not, see . +// +// Jeb Collins +// West Texas A&M University +// Mathematics +// Fall 2015 +// +// +// python/system.cpp: the source file for the python interface for System classes. + +#include +#include "system.hpp" + +using namespace boost::python; +using namespace bertini; + + +namespace bertini{ + namespace python{ + + + void ExportSystem() + { + class_< bertini::System, std::shared_ptr >("System", init<>()) + .def("precision", &System::precision) + .def("differentiate", &System::Differentiate) + .def("eval", sysEval1) + .def("eval", sysEval2) + .def("jacobian", sysJac1) + .def("jacobian", sysJac2) + .def("homogenize", &System::Homogenize) + .def("is_homogenous", &System::IsHomogeneous) + .def("is_polynomial", &System::IsPolynomial) + + .def("num_functions", &System::NumFunctions) + .def("num_variables", &System::NumVariables) + .def("num_hom_variables", &System::NumHomVariables) + .def("num_variable_groups", &System::NumVariableGroups) + .def("num_ungrouped_variables", &System::NumUngroupedVariables) + .def("num_hom_variable_groups", &System::NumHomVariableGroups) + .def("num_constants", &System::NumConstants) + .def("num_parameters", &System::NumParameters) + .def("num_implicit_parameters", &System::NumImplicitParameters) + + .def("set_variables_dbl", &System::SetVariables) + .def("set_path_variable_dbl", &System::SetPathVariable) + .def("set_implicit_parameters_dbl", &System::SetImplicitParameters) + + .def("add_variable_group", &System::AddVariableGroup) + .def("add_hom_variable_group", &System::AddHomVariableGroup) + .def("add_ungrouped_variable", &System::AddUngroupedVariable) + .def("add_ungrouped_variables", &System::AddUngroupedVariables) + .def("add_implicit_parameter", &System::AddImplicitParameter) + .def("add_implicit_parameters", &System::AddImplicitParameters) + .def("add_parameter", &System::AddParameter) + .def("add_parameters", &System::AddParameters) + .def("add_subfunction", &System::AddSubfunction) + .def("add_subfunctions", &System::AddSubfunctions) + .def("add_function", sysAddFunc1) + .def("add_function", sysAddFunc2) + .def("add_functions", &System::AddFunctions) + .def("add_constant", &System::AddConstant) + .def("add_constants", &System::AddConstants) + .def("add_path_variable", &System::AddPathVariable) + .def("have_path_variable", &System::HavePathVariable) + + .def("function", &System::Function) + .def("variable_groups", &System::VariableGroups) + .def("hom_variable_groups", &System::HomVariableGroups) + .def("degrees", sysDeg1) + .def("degrees", sysDeg2) + .def("reorder_functions_by_degree_decreasing", &System::ReorderFunctionsByDegreeDecreasing) + .def("reorder_functions_by_degree_increasing", &System::ReorderFunctionsByDegreeIncreasing) + .def("clear_variables", &System::ClearVariables) + .def("copy_variable_structure", &System::CopyVariableStructure) + + + .def(self_ns::str(self_ns::self)) + .def(self_ns::repr(self_ns::self)) + .def(self += self) + .def(self + self) //Test this, operator may not have correct signature + .def(self *= Nd()) + .def(self * Nd()) + .def(Nd() * self) + ; + } + + + }// re: python +}// re: bertini diff --git a/python/src/system_export.cpp b/python/src/system_export.cpp new file mode 100644 index 00000000..64a043b5 --- /dev/null +++ b/python/src/system_export.cpp @@ -0,0 +1,164 @@ +//This file is part of Bertini 2.0. +// +// python/function_tree.hpp 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. +//This file is part of Bertini 2.0. +// +// python/bertini_python.hpp 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/bertini_python.hpp 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/bertini_python.hpp. If not, see . +// +// James Collins +// West Texas A&M University +// Spring 2016 +// +// +// python/system_export.cpp: Source file for exposing systems to python, including start systems. + +#include +#include "system_export.hpp" + + + +namespace bertini{ + namespace python{ + template using Vec = Eigen::Matrix; + + + struct StartSystemWrap : start_system::StartSystem, wrapper + { + size_t NumStartPoints() const {return this->get_override("NumStartPoints")(); } + }; // re: StartSystemWrap + + + + + + template + template + void SystemVisitor::visit(PyClass& cl) const + { + cl + .def("precision", &SystemBaseT::precision) + .def("differentiate", &SystemBaseT::Differentiate) + .def("eval", return_Eval1_ptr() ) + .def("eval", return_Eval1_ptr() ) + .def("eval", return_Eval2_ptr() ) + .def("eval", return_Eval2_ptr() ) + .def("jacobian", return_Jac1_ptr() ) + .def("jacobian", return_Jac1_ptr() ) + .def("jacobian", return_Jac2_ptr() ) + .def("jacobian", return_Jac2_ptr() ) + .def("homogenize", &SystemBaseT::Homogenize) + .def("is_homogenous", &SystemBaseT::IsHomogeneous) + .def("is_polynomial", &SystemBaseT::IsPolynomial) + + .def("num_functions", &SystemBaseT::NumFunctions) + .def("num_variables", &SystemBaseT::NumVariables) + .def("num_hom_variables", &SystemBaseT::NumHomVariables) + .def("num_variable_groups", &SystemBaseT::NumVariableGroups) + .def("num_ungrouped_variables", &SystemBaseT::NumUngroupedVariables) + .def("num_hom_variable_groups", &SystemBaseT::NumHomVariableGroups) + .def("num_constants", &SystemBaseT::NumConstants) + .def("num_parameters", &SystemBaseT::NumParameters) + .def("num_implicit_parameters", &SystemBaseT::NumImplicitParameters) + + .def("set_variables", &SystemBaseT::template SetVariables) + .def("set_variables", &SystemBaseT::template SetVariables) + .def("set_path_variable", &SystemBaseT::template SetPathVariable) + .def("set_path_variable", &SystemBaseT::template SetPathVariable) + .def("set_implicit_parameters", &SystemBaseT::template SetImplicitParameters) + .def("set_implicit_parameters", &SystemBaseT::template SetImplicitParameters) + + .def("add_variable_group", &SystemBaseT::AddVariableGroup) + .def("add_hom_variable_group", &SystemBaseT::AddHomVariableGroup) + .def("add_ungrouped_variable", &SystemBaseT::AddUngroupedVariable) + .def("add_ungrouped_variables", &SystemBaseT::AddUngroupedVariables) + .def("add_implicit_parameter", &SystemBaseT::AddImplicitParameter) + .def("add_implicit_parameters", &SystemBaseT::AddImplicitParameters) + .def("add_parameter", &SystemBaseT::AddParameter) + .def("add_parameters", &SystemBaseT::AddParameters) + .def("add_subfunction", &SystemBaseT::AddSubfunction) + .def("add_subfunctions", &SystemBaseT::AddSubfunctions) + .def("add_function", sysAddFunc1) + .def("add_function", sysAddFunc2) + .def("add_functions", &SystemBaseT::AddFunctions) + .def("add_constant", &SystemBaseT::AddConstant) + .def("add_constants", &SystemBaseT::AddConstants) + .def("add_path_variable", &SystemBaseT::AddPathVariable) + .def("have_path_variable", &SystemBaseT::HavePathVariable) + + .def("function", &SystemBaseT::Function) + .def("variable_groups", &SystemBaseT::VariableGroups) + .def("hom_variable_groups", &SystemBaseT::HomVariableGroups) + .def("degrees", sysDeg1) + .def("degrees", sysDeg2) + .def("reorder_functions_by_degree_decreasing", &SystemBaseT::ReorderFunctionsByDegreeDecreasing) + .def("reorder_functions_by_degree_increasing", &SystemBaseT::ReorderFunctionsByDegreeIncreasing) + .def("clear_variables", &SystemBaseT::ClearVariables) + .def("copy_variable_structure", &SystemBaseT::CopyVariableStructure) + + + .def(self_ns::str(self_ns::self)) + .def(self_ns::repr(self_ns::self)) + .def(self += self) + .def(self + self) + .def(self *= std::shared_ptr()) + .def(self * std::shared_ptr()) + .def(std::shared_ptr() * self) + ; + } + + + + + + template + template + void StartSystemVisitor::visit(PyClass& cl) const + { + cl + .def("num_start_points", &SystemBaseT::NumStartPoints) + .def("start_pointd", return_GenStart_ptr() ) + .def("start_pointmp", return_GenStart_ptr() ) + ; + + + }; + + void ExportSystem() + { + + // System class + class_ >("System", init<>()) + .def(SystemVisitor()) + ; + + // StartSystem class + class_, std::shared_ptr >("StartSystem", no_init) + .def(StartSystemVisitor()) + ; + + // TotalDegree class + class_, std::shared_ptr >("TotalDegree", init()) + .def("random_value", &start_system::TotalDegree::RandomValue) + .def("random_values", &start_system::TotalDegree::RandomValues, return_value_policy()) + ; + + + } + + + } +} \ No newline at end of file diff --git a/python/test/b2_class_test.py b/python/test/b2_class_test.py new file mode 100644 index 00000000..2b9a0d60 --- /dev/null +++ b/python/test/b2_class_test.py @@ -0,0 +1,28 @@ +import mpfr_test +import function_tree_test +import differentiation_test +import system_test +import parser_test +import unittest + + + + + + + + + + + + + + +if __name__ == '__main__': + mods = (mpfr_test,function_tree_test, differentiation_test, system_test, parser_test) + suite = unittest.TestSuite(); + for tests in mods: + thissuite = unittest.TestLoader().loadTestsFromModule(tests); + suite.addTests(thissuite) + + unittest.TextTestRunner(verbosity=2).run(suite) \ No newline at end of file diff --git a/python/test/differentiation_test.py b/python/test/differentiation_test.py new file mode 100644 index 00000000..41b48751 --- /dev/null +++ b/python/test/differentiation_test.py @@ -0,0 +1,132 @@ +from pybertini import * +import numpy as np; +import unittest +import pdb + + +class DiffTest(unittest.TestCase): + def setUp(self): + default_precision(30); + self.x = Variable("x") + self.x.set_current_value(complex(-2.43,.21 )) + self.y = Variable("y") + self.y.set_current_value(complex(4.84, -1.94)) + self.z = Variable('z') + self.z.set_current_value(complex(-6.48, -.731)) + self.p = Variable('p') + self.p.set_current_value(complex(-.321, -.72)) + self.a = Float(complex(3.12, .612)) + self.b = Float(complex(-.823, 2.62)) + self.tol_d = float(1e-14); + + self.x.set_current_value(mpfr_complex("-2.43",".21" )) + self.y.set_current_value(mpfr_complex("4.84", "-1.94")) + self.z.set_current_value(mpfr_complex("-6.48", "-.731")) + self.p.set_current_value(mpfr_complex("-.321", "-.72")) + self.a = Float(mpfr_complex("3.12", ".612")) + self.b = Float(mpfr_complex("-.823", "2.62")) + self.tol_mp = mpfr_float("1e-27"); + + + def test_sum_rule(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = x+y+a; + df = f.differentiate(); + + self.assertLessEqual(np.abs(df.evald(x).real/(1.0)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(x).imag-0), tol_d) + + self.assertLessEqual(abs(df.evalmp(x).real/mpfr_float("1.0")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(x).imag-mpfr_float("0")), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(y).real/(1.0)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(y).imag-0), tol_d) + + self.assertLessEqual(abs(df.evalmp(y).real/mpfr_float("1.0")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(y).imag-mpfr_float("0")), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(z).real-0), tol_d) + self.assertLessEqual(np.abs(df.evald(z).imag-0), tol_d) + + self.assertLessEqual(abs(df.evalmp(z).real-mpfr_float("0.0")), tol_mp) + self.assertLessEqual(abs(df.evalmp(z).imag-mpfr_float("0")), tol_mp) + + def test_power_rule(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = x**2 + y**3; + df = f.differentiate(); + + self.assertLessEqual(np.abs(df.evald(x).real / (-4.86)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(x).imag / (0.42)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(x).real / mpfr_float("-4.86")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(x).imag / mpfr_float("0.42")-1), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(y).real / (58.9860)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(y).imag / (-56.3376)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(y).real / mpfr_float("58.9860")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(y).imag / mpfr_float("-56.3376")-1), tol_mp) + + + def test_prod_rule(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = x**2*y**4 - a*x*y*z**2; + df = f.differentiate(); + + self.assertLessEqual(np.abs(df.evald(x).real / (-559.28968169592)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(x).imag / (3577.05276993648)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(x).real / mpfr_float("-559.28968169592")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(x).imag / mpfr_float("3577.05276993648")-1), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(y).real / (1161.85042980828)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(y).imag / (-3157.24325320476)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(y).real / mpfr_float("1161.85042980828")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(y).imag / mpfr_float("-3157.24325320476")-1), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(z).real / (-520.5265859088)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(z).imag / (84.7479679056)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(z).real / mpfr_float("-520.5265859088")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(z).imag / mpfr_float("84.7479679056")-1), tol_mp) + + + def test_trancendental(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = sin(x*y) + exp(z*y) - log(x*x); + df = f.differentiate(); + + self.assertLessEqual(np.abs(df.evald(x).real / (-17.648420086229721902138620795382021306411662490)-1), 9e-13) + self.assertLessEqual(np.abs(df.evald(x).imag / (-803.11883403426275105632833868183320319093878729)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(x).real / mpfr_float("-17.648420086229721902138620795382021306411662490")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(x).imag / mpfr_float("-803.11883403426275105632833868183320319093878729")-1), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(y).real / (-100.97157179433748763552280062599971478593963953)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(y).imag / (361.98093991820979266721712882115615553425318528)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(y).real / mpfr_float("-100.97157179433748763552280062599971478593963953")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(y).imag / mpfr_float("361.98093991820979266721712882115615553425318528")-1), tol_mp) + + df.reset() + self.assertLessEqual(np.abs(df.evald(z).real / (-2.1642907643013779167501866500194314960002972412e-14)-1), tol_d) + self.assertLessEqual(np.abs(df.evald(z).imag / (2.1105887207247540399884720817624768568595288922e-14)-1), tol_d) + + self.assertLessEqual(abs(df.evalmp(z).real / mpfr_float("-2.1642907643013779167501866500194314960002972412e-14")-1), tol_mp) + self.assertLessEqual(abs(df.evalmp(z).imag / mpfr_float("2.1105887207247540399884720817624768568595288922e-14")-1), tol_mp) diff --git a/python/test/function_tree_test.py b/python/test/function_tree_test.py new file mode 100644 index 00000000..7af4ab1c --- /dev/null +++ b/python/test/function_tree_test.py @@ -0,0 +1,435 @@ +from pybertini import * +import numpy as np; +import unittest + + +class SymbolTest(unittest.TestCase): + def setUp(self): + default_precision(30); + self.x_d = complex(-2.43,.21 ) + self.y_d = complex(4.84, -1.94) + self.z_d = complex(-6.48, -.731) + self.p_d = complex(-.321, -.72) + self.tol_d = float(1e-15); + + self.x_mp = mpfr_complex("-2.43",".21" ) + self.y_mp = mpfr_complex("4.84", "-1.94") + self.z_mp = mpfr_complex("-6.48", "-.731") + self.p_mp = mpfr_complex("-.321", "-.72") + self.tol_mp = mpfr_float("1e-27"); + + + def test_Float_construct(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Float(x_d) + x = Float(4.3, -9e-3) + x = Float(y_mp) + x = Float(mpfr_float("9.3"), mpfr_float("-3")) + x = Float("9.2", "-43.2e2") + + + def test_Float_eval(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Float(x_d); y = Float(y_mp); z = Float(z_d); + + self.assertLessEqual(np.abs(x.evald().real/(-2.43)-1), tol_d) + self.assertLessEqual(np.abs(x.evald().imag/(.21)-1), tol_d) + + self.assertLessEqual(abs(y.evalmp().real/mpfr_float("4.84")-1), tol_mp) + self.assertLessEqual(abs(y.evalmp().imag/mpfr_float("-1.94")-1), tol_mp) + + def test_Float_funcs(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Float(x_d); y = Float(y_mp); z = Float(z_d); + + self.assertEqual(x.degree(), 0) + d = y.differentiate() + self.assertLessEqual(abs(d.evalmp().real-mpfr_float("0")), tol_mp) + self.assertLessEqual(abs(d.evalmp().imag-mpfr_float("0")), tol_mp) + self.assertTrue(y.is_homogeneous()) + self.assertTrue(y.is_polynomial()) + + + + + + def test_Variable_construct(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Variable("x") + + + def test_Variable_eval(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Variable("x"); y = Variable("y"); + x.set_current_value(x_d); x.set_current_value(x_mp) + + self.assertLessEqual(np.abs(x.evald().real/(-2.43)-1), tol_d) + self.assertLessEqual(np.abs(x.evald().imag/(.21)-1), tol_d) + + self.assertLessEqual(abs(x.evalmp().real/mpfr_float("-2.43")-1), tol_mp) + self.assertLessEqual(abs(x.evalmp().imag/mpfr_float(".21")-1), tol_mp) + + def test_Variable_funcs(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Variable("x"); y = Variable("y") + + self.assertEqual(x.degree(), 1) + self.assertEqual(x.degree(x), 1) + self.assertEqual(x.degree(y), 0) + d = y.differentiate() + self.assertTrue(y.is_homogeneous()) + self.assertTrue(y.is_polynomial()) + + + + def test_Pi_construct(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = Pi() + y = make_pi() + + self.assertLessEqual(np.abs(x.evald().real/(3.1415926535897932384626433832795028841971693994)-1), tol_d) + self.assertLessEqual(np.abs(x.evald().imag - (0)), tol_d) + + self.assertLessEqual(abs(x.evalmp().real/mpfr_float("3.1415926535897932384626433832795028841971693994")-1), tol_mp) + self.assertLessEqual(abs(x.evalmp().imag - mpfr_float("0")), tol_mp) + + self.assertLessEqual(np.abs(y.evald().real/(3.1415926535897932384626433832795028841971693994)-1), tol_d) + self.assertLessEqual(np.abs(y.evald().imag - (0)), tol_d) + + self.assertLessEqual(abs(y.evalmp().real/mpfr_float("3.1415926535897932384626433832795028841971693994")-1), tol_mp) + self.assertLessEqual(abs(y.evalmp().imag - mpfr_float("0")), tol_mp) + + + def test_E_construct(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + x = E() + y = make_e() + + self.assertLessEqual(np.abs(x.evald().real/(2.7182818284590452353602874713526624977572470937)-1), tol_d) + self.assertLessEqual(np.abs(x.evald().imag - (0)), tol_d) + + self.assertLessEqual(abs(x.evalmp().real - mpfr_float("2.7182818284590452353602874713526624977572470937")), tol_mp) + self.assertLessEqual(abs(x.evalmp().imag - mpfr_float("0")), tol_mp) + + self.assertLessEqual(np.abs(y.evald().real/(2.7182818284590452353602874713526624977572470937)-1), tol_d) + self.assertLessEqual(np.abs(y.evald().imag - (0)), tol_d) + + self.assertLessEqual(abs(y.evalmp().real/mpfr_float("2.7182818284590452353602874713526624977572470937")-1), tol_mp) + self.assertLessEqual(abs(y.evalmp().imag - mpfr_float("0")), tol_mp) + + + def test_I_construct(self): + x_d = self.x_d; y_d = self.y_d; z_d = self.z_d; p_d = self.p_d; tol_d = self.tol_d; + x_mp = self.x_mp; y_mp = self.y_mp; z_mp = self.z_mp; p_mp = self.p_mp; tol_mp = self.tol_mp; + y = make_i() + + self.assertLessEqual(np.abs(y.evald().real - (0)), tol_d) + self.assertLessEqual(np.abs(y.evald().imag/(1.0)-1), tol_d) + + self.assertLessEqual(abs(y.evalmp().real - mpfr_float("0")), tol_mp) + self.assertLessEqual(abs(y.evalmp().imag/mpfr_float("1.0")-1), tol_mp) + + + + + +class OperatorTest(unittest.TestCase): + def setUp(self): + default_precision(30); + self.x = Variable("x") + self.x.set_current_value(complex(-2.43,.21 )) + self.y = Variable("y") + self.y.set_current_value(complex(4.84, -1.94)) + self.z = Variable("z") + self.z.set_current_value(complex(-6.48, -.731)) + self.p = Variable("p") + self.p.set_current_value(complex(-.321, -.72)) + self.a = Float(complex(3.12, .612)) + self.b = Float(complex(-.823, 2.62)) + self.tol_d = float(9e-14); + + self.x.set_current_value(mpfr_complex("-2.43",".21" )) + self.y.set_current_value(mpfr_complex("4.84", "-1.94")) + self.z.set_current_value(mpfr_complex("-6.48", "-.731")) + self.p.set_current_value(mpfr_complex("-.321", "-.72")) + self.a = Float(mpfr_complex("3.12", ".612")) + self.b = Float(mpfr_complex("-.823", "2.62")) + self.tol_mp = mpfr_float("1e-27"); + + def test_plus(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(x+y+a) + self.assertLessEqual(np.abs(f.evald().real/(5.53)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(-1.118)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real/mpfr_float("5.53")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag/mpfr_float("-1.118")-1), tol_mp) + + f = Function(x+3.87) + self.assertLessEqual(np.abs(f.evald().real/(1.44)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(0.21)-1), tol_d) + + f = Function(x+mpfr_complex("3.87", "-2.1")) + self.assertLessEqual(np.abs(f.evald().real/(1.44)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(-1.89)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real/mpfr_float("1.44")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag/mpfr_float("-1.89")-1), tol_mp) + + f = Function(x+(-5)) + self.assertLessEqual(np.abs(f.evald().real/(-7.43)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(0.21)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real/mpfr_float("-7.43")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag/mpfr_float("0.21")-1), tol_mp) + + f = Function(x); f += y; f += a; + self.assertLessEqual(np.abs(f.evald().real/(5.53)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(-1.118)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real/mpfr_float("5.53")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag/mpfr_float("-1.118")-1), tol_mp) + + f = Function(x); f += 3.87; + self.assertLessEqual(np.abs(f.evald().real/(1.44)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(0.21)-1), tol_d) + + + + def test_sub(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(x-y-a) + self.assertLessEqual(np.abs(f.evald().real/(-10.39)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(1.538)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real/mpfr_float("-10.39")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag/mpfr_float("1.538")-1), tol_mp) + + f = Function(y-3.87) + self.assertLessEqual(np.abs(f.evald().real/(0.97)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(-1.94)-1), tol_d) + + f = Function(y-complex(3.87,0)) + self.assertLessEqual(np.abs(f.evald().real / (0.97)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-1.94)-1), tol_d) + + + f = Function(y-mpfr_complex("3.87", "-2.1")) + self.assertLessEqual(np.abs(f.evald().real / (0.97)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (0.16)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("0.97")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("0.16")-1), tol_mp) + + f = Function(y-(-5)) + self.assertLessEqual(np.abs(f.evald().real / (9.84)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-1.94)-1), tol_d) + + f = Function(x); f -= y; f -= a; + self.assertLessEqual(np.abs(f.evald().real / (-10.39)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (1.538)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-10.39")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("1.538")-1), tol_mp) + + f = Function(y); f -= 3.87; + self.assertLessEqual(np.abs(f.evald().real / (0.97)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-1.94)-1), tol_d) + + + def test_num_times_var(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(a*x*b*y) + + self.assertLessEqual(np.abs(f.evald().real / (3.4011196056)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-110.9953448712)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("3.4011196056")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-110.9953448712")-1), tol_mp) + + def test_var_times_var(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(x*y*z) + self.assertLessEqual(np.abs(f.evald().real / (77.7616926)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-28.8346602)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("77.7616926")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-28.8346602")-1), tol_mp) + + def test_var_div_var(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(x/y) + self.assertLessEqual(np.abs(f.evald().real / (-.44755270475041560619657805305047592426404601827)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-.13600253041648890000441351713180233327939034617)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-.44755270475041560619657805305047592426404601827")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-.13600253041648890000441351713180233327939034617")-1), tol_mp) + + def test_trans_funcs(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(sin(x)) + self.assertLessEqual(np.abs(f.evald().real/(-.66749329633668695550441899166308616328986315948)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag/(-.16020928942503633132090203927960650380076680938)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-.66749329633668695550441899166308616328986315948")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-.16020928942503633132090203927960650380076680938")-1), tol_mp) + + f = Function(cos(y)) + self.assertLessEqual(np.abs(f.evald().real / (0.45194679593300564730917329070452033759984813611)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-3.3798161097977088705360399142708324234265626016)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("0.45194679593300564730917329070452033759984813611")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-3.3798161097977088705360399142708324234265626016")-1), tol_mp) + + f = Function(tan(z)) + self.assertLessEqual(np.abs(f.evald().real / (-.11998086808607765336591715593714295443402911227)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-.63859741450762243500349270264429166927927928889)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-.11998086808607765336591715593714295443402911227")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-.63859741450762243500349270264429166927927928889")-1), tol_mp) + + f = Function(asin(x)) + self.assertLessEqual(np.abs(f.evald().real / (-1.4763431474004472804452143435221887167393328861)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (1.5406263884278099750127157814537559611048741005)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-1.4763431474004472804452143435221887167393328861")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("1.5406263884278099750127157814537559611048741005")-1), tol_mp) + + f = Function(acos(y)) + self.assertLessEqual(np.abs(f.evald().real / (0.38769800860408664087229892623614567735197135529)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (2.3379037587834289977359318611458042347281923566)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("0.38769800860408664087229892623614567735197135529")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("2.3379037587834289977359318611458042347281923566")-1), tol_mp) + + f = Function(atan(z)) + self.assertLessEqual(np.abs(f.evald().real / (-1.4195347801361539102032503530226060969949192059)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-0.16801358511827150554928904776095870747673962940e-1)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-1.4195347801361539102032503530226060969949192059")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-0.16801358511827150554928904776095870747673962940e-1")-1), tol_mp) + + f = Function(exp(y)) + self.assertLessEqual(np.abs(f.evald().real / (-45.639359208255772966298371983389382308765171859)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-117.94721623715960520658000231550940351946595854)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-45.639359208255772966298371983389382308765171859")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-117.94721623715960520658000231550940351946595854")-1), tol_mp) + + f = Function(log(z)) + self.assertLessEqual(np.abs(f.evald().real / (1.8750432590213669716781046977781508038070552297)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-3.0292589170775161726973168096174940982043177322)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("1.8750432590213669716781046977781508038070552297")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-3.0292589170775161726973168096174940982043177322")-1), tol_mp) + + def test_power(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(y**3) + self.assertLessEqual(np.abs(f.evald().real / (58.732432)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-129.035608)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("58.732432")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-129.035608")-1), tol_mp) + + f = Function(pow(y,3)) + self.assertLessEqual(np.abs(f.evald().real / (58.732432)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-129.035608)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("58.732432")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-129.035608")-1), tol_mp) + + f = Function(x**p) + self.assertLessEqual(np.abs(f.evald().real / (-.35190932545709434788093164550270669097948909024)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-6.7687858345625791466707575744042177964518271087)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-.35190932545709434788093164550270669097948909024")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-6.7687858345625791466707575744042177964518271087")-1), tol_mp) + + f = Function(pow(x,p)) + self.assertLessEqual(np.abs(f.evald().real / (-.35190932545709434788093164550270669097948909024)-1), tol_d) + self.assertLessEqual(np.abs(f.evald().imag / (-6.7687858345625791466707575744042177964518271087)-1), tol_d) + + self.assertLessEqual(abs(f.evalmp().real / mpfr_float("-.35190932545709434788093164550270669097948909024")-1), tol_mp) + self.assertLessEqual(abs(f.evalmp().imag / mpfr_float("-6.7687858345625791466707575744042177964518271087")-1), tol_mp) + + + def test_Operator_degree(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(x**3-9*y*y*z*pow(x,4)); + w = VariableGroup(); w.append(x); w.append(y); + self.assertEqual(f.degree(),7) + self.assertEqual(f.degree(x),4) + self.assertEqual(f.degree(y),2) + self.assertEqual(f.degree(z),1) + self.assertEqual(f.degree(w),6) + w = VariableGroup(); w.append(y); w.append(z); + self.assertEqual(f.degree(w),3) + + def test_Operator_ishom(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(y**2 - 9*y*z + 3*x*x - y*82*x - pow(z,2)) + self.assertTrue(f.is_homogeneous()) + f = Function(y**2 - 9*y*z + 3*x*x - y*82*x - pow(z,4)) + self.assertFalse(f.is_homogeneous()) + f = Function(y**2 - 9*y*z + 3*x*x - 5) + self.assertFalse(f.is_homogeneous()) + + def test_Operator_ispoly(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + f = Function(y**2 - 9*y*z + 3*x*x - y*82*x - pow(z,2)) + self.assertTrue(f.is_polynomial()); + + f = Function(x**2*y - 9 + sin(z)) + self.assertFalse(f.is_polynomial()) + + def test_Homogenize(self): + x = self.x; y = self.y; z = self.z; p = self.p; a = self.a; b = self.b; + tol_d = self.tol_d; tol_mp = self.tol_mp; + + h = Variable("h"); + f = Function(x**2 + y**2 + z**2 - 1) + + vars = VariableGroup(); + vars.append(y); vars.append(x); vars.append(z); + + f.homogenize(vars,h); + self.assertEqual(f.degree(h),2) + self.assertTrue(f.is_homogeneous()) + + self.assertFalse(f.is_homogeneous(x)) + self.assertFalse(f.is_homogeneous(y)) + self.assertFalse(f.is_homogeneous(z)) + self.assertFalse(f.is_homogeneous(h)) + + vars.append(h); + self.assertTrue(f.is_homogeneous(vars)) + diff --git a/python/test/mpfr_test.py b/python/test/mpfr_test.py new file mode 100644 index 00000000..8e07f613 --- /dev/null +++ b/python/test/mpfr_test.py @@ -0,0 +1,309 @@ +from pybertini import * +import unittest +import pdb + + +dbltol = 1e-15; +class MPFRFloat(unittest.TestCase): + def setUp(self): + default_precision(30); + self.x = mpfr_float("4.23") + self.y = mpfr_float("-3.86") + self.z = mpfr_float("1.1495") + self.p = mpfr_float(".34") + self.tol = mpfr_float("1e-27"); + + def test_arith_int(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + self.assertLessEqual(abs((x+8) - mpfr_float("12.23")), tol) + self.assertLessEqual(abs((y-2) - mpfr_float("-5.86")), tol) + self.assertLessEqual(abs((8+x) - mpfr_float("12.23")), tol) + self.assertLessEqual(abs((2-y) - mpfr_float("5.86")), tol) + self.assertLessEqual(abs((z*6) - mpfr_float("6.897")), tol) + self.assertLessEqual(abs((6*z) - mpfr_float("6.897")), tol) + self.assertLessEqual(abs((y/3) - mpfr_float("-1.2866666666666666666666666666666667")), tol) + self.assertLessEqual(abs((3/y) - mpfr_float("-.77720207253886010362694300518134714")), tol) + self.assertLessEqual(abs((x**3) - mpfr_float("75.686967")), tol) + + result = mpfr_float(x); + result += 8; + self.assertLessEqual(abs(result - mpfr_float("12.23")), tol) + result = mpfr_float(y); + result -= 2; + self.assertLessEqual(abs(result - mpfr_float("-5.86")), tol) + result = mpfr_float(z); + result *= 6; + self.assertLessEqual(abs(result - mpfr_float("6.897")), tol) + result = mpfr_float(y); + result /= 3; + self.assertLessEqual(abs(result - mpfr_float("-1.2866666666666666666666666666666667")), tol) + + self.assertLessEqual(abs((-z) - mpfr_float("-1.1495")), tol) + + def test_arith_mpfr(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + self.assertLessEqual(abs((x+y) - mpfr_float("0.37")), tol) + self.assertLessEqual(abs((z-y) - mpfr_float("5.0095")), tol) + self.assertLessEqual(abs((z*y) - mpfr_float("-4.437070")), tol) + self.assertLessEqual(abs((y/x) - mpfr_float("-.91252955082742316784869976359338061")), tol) + self.assertLessEqual(abs((x**y) - mpfr_float("0.0038223124228935822000384505727705508")), tol) + self.assertLessEqual(abs((-z) - mpfr_float("-1.1495")), tol) + + result = mpfr_float(x); + result += y; + self.assertLessEqual(abs(result - mpfr_float("0.37")), tol) + result = mpfr_float(z); + result -= y; + self.assertLessEqual(abs(result - mpfr_float("5.0095")), tol) + result = mpfr_float(z); + result *= y; + self.assertLessEqual(abs(result - mpfr_float("-4.437070")), tol) + result = mpfr_float(y); + result /= x; + self.assertLessEqual(abs(result - mpfr_float("-.91252955082742316784869976359338061")), tol) + + + def test_trancendentals(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + self.assertLessEqual(abs((exp(x)) - mpfr_float("68.717232173846461408252914213396109")), tol) + self.assertLessEqual(abs((log(z)) - mpfr_float("0.13932706522109918666170810230684295")), tol) + self.assertLessEqual(abs((sqrt(z)) - mpfr_float("1.0721473779289860297522254519889560")), tol) + + self.assertLessEqual(abs((sin(x)) - mpfr_float("-.88588921129660245121088859729926237")), tol) + self.assertLessEqual(abs((cos(y)) - mpfr_float("-.75285494656729525719980460936483635")), tol) + self.assertLessEqual(abs((tan(z)) - mpfr_float("2.2315038042849919118711153687209483")), tol) + + self.assertLessEqual(abs((asin(p)) - mpfr_float("0.34691689752716170922069696210451452")), tol) + self.assertLessEqual(abs((acos(p)) - mpfr_float("1.2238794292677349100106247295352369")), tol) + self.assertLessEqual(abs((atan(z)) - mpfr_float("0.85483739856328448882289109284144652")), tol) + + self.assertLessEqual(abs((sinh(x)) - mpfr_float("34.351339891649022639414777866662100")), tol) + self.assertLessEqual(abs((cosh(y)) - mpfr_float("23.743209684188284295743755381842167")), tol) + self.assertLessEqual(abs((tanh(z)) - mpfr_float("0.81758837109637920976170104688035086")), tol) + + def test_change_prec(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + default_precision(40); + tol = mpfr_float("1e-37"); + t = mpfr_float("4.23") + self.assertLessEqual(abs(t**(-2) - mpfr_float("0.055888089689206333238323580861682566828183245868")), tol) + default_precision(30); + tol = mpfr_float("1e-27"); + + + + + + + + + + +class MPFRComplex(unittest.TestCase): + def setUp(self): + default_precision(30); + self.x = mpfr_complex("-2.43",".21" ) + self.y = mpfr_complex("4.84", "-1.94") + self.z = mpfr_complex("-6.48", "-.731") + self.p = mpfr_complex("-.321", "-.72") + self.tol = mpfr_float("1e-27"); + + def test_construct(self): + t = mpfr_complex(3.452) + t = mpfr_complex(mpfr_float("-5.6")) + t = mpfr_complex("3.89") + t = mpfr_complex(mpfr_float("2.98"), mpfr_float("-1e-4")) + t = mpfr_complex(3.4, 3.5) + t = mpfr_complex("6e2", mpfr_float("4.32")) + t = mpfr_complex(mpfr_float("4.32"), "6e2") + + def test_arith_mp_float(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + a = mpfr_float("3.12"); b = mpfr_float("-5.92") + res = mpfr_complex(x+a) + self.assertLessEqual(abs(res.real - mpfr_float("0.69")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.21")), tol) + res = mpfr_complex(y-b) + self.assertLessEqual(abs(res.real - mpfr_float("10.76")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.94")), tol) + res = mpfr_complex(a+x) + self.assertLessEqual(abs(res.real - mpfr_float("0.69")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.21")), tol) + res = mpfr_complex(b-y) + self.assertLessEqual(abs(res.real - mpfr_float("-10.76")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("1.94")), tol) + res = mpfr_complex(z*a) + self.assertLessEqual(abs(res.real - mpfr_float("-20.2176")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-2.28072")), tol) + res = mpfr_complex(a*z) + self.assertLessEqual(abs(res.real - mpfr_float("-20.2176")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-2.28072")), tol) + res = mpfr_complex(y/b) + self.assertLessEqual(abs(res.real - mpfr_float("-.81756756756756756756756756756756756756756756757")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float(".3277027027027027027027027027027027027027027027")), tol) + res = mpfr_complex(b/y) + self.assertLessEqual(abs(res.real - mpfr_float("-1.0538301972842157915642975887484736586585850264")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-.42240301296102864372618539714298324334662292381")), tol) + res = mpfr_complex(x**a) + self.assertLessEqual(abs(res.real - mpfr_float("-16.054376621961088182387920766649714821973863952")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.7411284591111236754359685247799914985638458821")), tol) + + + + res = mpfr_complex(x); + res += a; + self.assertLessEqual(abs(res.real - mpfr_float("0.69")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.21")), tol) + res = mpfr_complex(y); + res -= b; + self.assertLessEqual(abs(res.real - mpfr_float("10.76")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.94")), tol) + res = mpfr_complex(z); + res *= a; + self.assertLessEqual(abs(res.real - mpfr_float("-20.2176")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-2.28072")), tol) + res = mpfr_complex(y); + res /= b; + self.assertLessEqual(abs(res.real - mpfr_float("-.81756756756756756756756756756756756756756756757")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float(".3277027027027027027027027027027027027027027027")), tol) + + res = mpfr_complex(x**4); + self.assertLessEqual(abs(res.real - mpfr_float("33.30735228")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-11.96306496")), tol) + + res = mpfr_complex(-z); + self.assertLessEqual(abs(res.real - mpfr_float("6.48")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float(".731")), tol) + + + + def test_arith_mp_complex(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + + res = mpfr_complex(x+y) + self.assertLessEqual(abs(res.real - mpfr_float("2.41")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.73")), tol) + res = mpfr_complex(y-z) + self.assertLessEqual(abs(res.real - mpfr_float("11.32")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.209")), tol) + res = mpfr_complex(y+x) + self.assertLessEqual(abs(res.real - mpfr_float("2.41")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.73")), tol) + res = mpfr_complex(z-y) + self.assertLessEqual(abs(res.real - mpfr_float("-11.32")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("1.209")), tol) + res = mpfr_complex(z*x) + self.assertLessEqual(abs(res.real - mpfr_float("15.89991")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.41553")), tol) + res = mpfr_complex(x*z) + self.assertLessEqual(abs(res.real - mpfr_float("15.89991")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float(".41553")), tol) + res = mpfr_complex(y/x) + self.assertLessEqual(abs(res.real - mpfr_float("-2.0454866364094805849722642460917801311144730207")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.62158345940494200706001008572869389813414019163")), tol) + res = mpfr_complex(x/y) + self.assertLessEqual(abs(res.real - mpfr_float("-.44755270475041560619657805305047592426404601827")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-.13600253041648890000441351713180233327939034617")), tol) + res = mpfr_complex(y**z) + self.assertLessEqual(abs(res.real - mpfr_float("0.0000051612634484879218649489640888954160904291899461")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.16242051733741136410199105656393042124100116889e-4")), tol) + + + + res = mpfr_complex(x); + res += y; + self.assertLessEqual(abs(res.real - mpfr_float("2.41")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.73")), tol) + res = mpfr_complex(y); + res -= z; + self.assertLessEqual(abs(res.real - mpfr_float("11.32")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-1.209")), tol) + res = mpfr_complex(z); + res *= x; + self.assertLessEqual(abs(res.real - mpfr_float("15.89991")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float(".41553")), tol) + res = mpfr_complex(y); + res /= x; + self.assertLessEqual(abs(res.real - mpfr_float("-2.0454866364094805849722642460917801311144730207")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.62158345940494200706001008572869389813414019163")), tol) + + + def test_trancendentals(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + + res = exp(x) + self.assertLessEqual(abs(res.real - mpfr_float("0.086102743899954532232498058731947255067424332219")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.018352149302889219131202317785160051395400089327")), tol) + res = log(y) + self.assertLessEqual(abs(res.real - mpfr_float("1.6514099178148475691128039277241118340531698491")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-0.38121862770417378405072154507774424569831993182")), tol) + res = sqrt(z) + self.assertLessEqual(abs(res.real - mpfr_float("0.14335482322754515813189359093523204816185445814")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-2.5496177371015053245565185485769652617478797292")), tol) + res = sin(x) + self.assertLessEqual(abs(res.real - mpfr_float("-0.66749329633668695550441899166308616328986315948")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-0.16020928942503633132090203927960650380076680938")), tol) + res = cos(y) + self.assertLessEqual(abs(res.real - mpfr_float("0.45194679593300564730917329070452033759984813611")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-3.3798161097977088705360399142708324234265626016")), tol) + res = tan(z) + self.assertLessEqual(abs(res.real - mpfr_float("-0.11998086808607765336591715593714295443402911227")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-0.63859741450762243500349270264429166927927928889")), tol) + res = asin(x) + self.assertLessEqual(abs(res.real - mpfr_float("-1.4763431474004472804452143435221887167393328861")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("1.5406263884278099750127157814537559611048741005")), tol) + res = acos(y) + self.assertLessEqual(abs(res.real - mpfr_float("0.38769800860408664087229892623614567735197135529")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("2.3379037587834289977359318611458042347281923566")), tol) + res = atan(z) + self.assertLessEqual(abs(res.real - mpfr_float("-1.4195347801361539102032503530226060969949192059")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-0.016801358511827150554928904776095870747673962940")), tol) + res = sinh(x) + self.assertLessEqual(abs(res.real - mpfr_float("-5.5116175435238027338707341903303682792175349461")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("1.1931117850318239903301857156967336540973461581")), tol) + res = cosh(y) + self.assertLessEqual(abs(res.real - mpfr_float("-22.821106324812396153305984541517740047129741299")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-58.969920999917202046449299163531439999586349377")), tol) + res = tanh(z) + self.assertLessEqual(abs(res.real - mpfr_float("-.99999948909538256503828034023523935671055767287")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-0.0000046773288796255165542679839050497228616710086412")), tol) + res = square(z) + self.assertLessEqual(abs(res.real - mpfr_float("41.456039")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("9.47376")), tol) + res = cube(z) + self.assertLessEqual(abs(res.real - mpfr_float("-261.70981416")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("-91.694329309")), tol) + + + + + + def test_misc_funcs(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + + res = norm(x) + self.assertLessEqual(abs(res - mpfr_float("5.949")), tol) + res = abs2(x) + self.assertLessEqual(abs(res - mpfr_float("5.949")), tol) + res = conj(x) + self.assertLessEqual(abs(res.real - x.real), tol) + self.assertLessEqual(abs(res.imag - (-x.imag)), tol) + res = polar(mpfr_float("3.21"), mpfr_float("-5.62")) + self.assertLessEqual(abs(res.real - mpfr_float("2.5295931897050156212406076422629449344206513531")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("1.9761726378527774897831544771425943545375239972")), tol) + res = arg(y) + self.assertLessEqual(abs(res - mpfr_float("-.38121862770417378405072154507774424569831993182")), tol) + res = inverse(z) + self.assertLessEqual(abs(res.real - mpfr_float("-0.15238180880075963272315628064317633672297417498")), tol) + self.assertLessEqual(abs(res.imag - mpfr_float("0.017189984912554828938368401412062021935878722517")), tol) + + def test_change_prec(self): + x = self.x; y = self.y; z = self.z; p = self.p; tol = self.tol; + default_precision(45); + tol = mpfr_float("1e-37"); + t = mpfr_complex("-2.43",".21") + t = t**(-2); + self.assertLessEqual(abs(t.real - mpfr_float("0.16560329111110602501494676510297183141930819429")), tol) + self.assertLessEqual(abs(t.imag - mpfr_float("0.028838165251841866149715852522538399390278791818")), tol) + default_precision(30); + tol = mpfr_float("1e-27"); diff --git a/python/test/parser_test.py b/python/test/parser_test.py new file mode 100644 index 00000000..05ef2607 --- /dev/null +++ b/python/test/parser_test.py @@ -0,0 +1,29 @@ +__author__ = 'jcollins' + +from pybertini import * +import unittest +import numpy as np +import pdb + + +class ParserTest(unittest.TestCase): + def setUp(self): + self.tol_d = 1e-15; + + + + def test_create_system(self): + tol_d = self.tol_d; + input = 'function f, g; variable_group x,y,z; f = 3*x*y*z; g = x^2 + y^2 + z^2 - 1;'; + sys = parse_system(input); + + vals = VectorXd((complex(-2.43,.21 ),complex(4.84, -1.94),complex(-6.48, -.731))) + sysEval = sys.eval(vals); + + self.assertLessEqual(np.abs(sysEval[0].real / (233.2850778)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[0].imag / (-86.5039806)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[1].real / (65.978839)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[1].imag / (-10.32604)-1), tol_d) + + sys.differentiate() + sysJac = sys.jacobian(vals) diff --git a/python/test/system_test.py b/python/test/system_test.py new file mode 100644 index 00000000..1a9eeea1 --- /dev/null +++ b/python/test/system_test.py @@ -0,0 +1,179 @@ +__author__ = 'jcollins' + +from pybertini import * +import unittest +import numpy as np +import pdb + + +class SystemTest(unittest.TestCase): + def setUp(self): + self.toldbl = 1e-15; + self.x = Variable("x"); + self.y = Variable("y"); + self.z = Variable("z"); + self.a = Float(4.897, 1.23) + + self.f = Function(self.x*self.y); + self.g = Function(pow(self.x,2)*self.y - self.a*self.z*self.x); + + def test_system_create(self): + self.x = Variable("x"); + self.y = Variable("y"); + self.f = Function(self.x*self.y); + + s = System(); + s.add_ungrouped_variable(self.x); + s.add_ungrouped_variable(self.y); + s.add_function(self.f) + + + def test_system_eval(self): + exact_real = (-32.841085, -150.5480559) + exact_imag = (-26.66705, -258.97936865) + + s = System(); + s.add_ungrouped_variable(self.x); + s.add_ungrouped_variable(self.y); + s.add_ungrouped_variable(self.z); + s.add_function(self.f) + s.add_function(self.g) + + v = VectorXd.Zero(3); + v[0] = complex(3.5,2.89); v[1] = complex(-9.32,.0765); v[2] = complex(5.4,-2.13); + + e = s.eval(v) + + self.assertTrue(np.abs(e[0].real - exact_real[0]) < self.toldbl*np.abs(exact_real[0])); + self.assertTrue(np.abs(e[0].imag - exact_imag[0]) < self.toldbl*np.abs(exact_imag[0])); + self.assertTrue(np.abs(e[1].real - exact_real[1]) < self.toldbl*np.abs(exact_real[1])); + self.assertTrue(np.abs(e[1].imag - exact_imag[1]) < self.toldbl*np.abs(exact_imag[1])); + + + s = parse_system('function f1, f2; variable_group x,y,z; f1 = x*y; f2 = x^2*y - z*x;') + self.toldbl = mpfr_float('1e-27'); + exact_real = (mpfr_float('-32.841085'), mpfr_float('-62.9317230')) + exact_imag = (mpfr_float('-26.66705'), mpfr_float('-196.39641065')) + self.a = mpfr_complex('4.897', '1.23') + v = VectorXmp((mpfr_complex('3.5', '2.89'), mpfr_complex('-9.32', '.0765'), mpfr_complex('5.4', '-2.13'))); + + e = s.eval(v) + + self.assertLessEqual(abs(e[0].real / exact_real[0]-1) , self.toldbl); + self.assertLessEqual(abs(e[0].imag / exact_imag[0]-1) , self.toldbl); + self.assertLessEqual(abs(e[1].real / exact_real[1]-1) , self.toldbl); + self.assertLessEqual(abs(e[1].imag / exact_imag[1]-1) , self.toldbl); + + + + + + def test_system_Jac(self): + exact_real = ((-9.32, 3.5, 0), \ + (-94.745870,3.8979,-13.5848)) + exact_imag = ((.0765, 2.89, 0),\ + (-49.54549,20.230,-18.45733)) + + s = System(); + s.add_ungrouped_variable(self.x); + s.add_ungrouped_variable(self.y); + s.add_ungrouped_variable(self.z); + s.add_function(self.f) + s.add_function(self.g) + + v = VectorXd.Zero(3); + v[0] = complex(3.5,2.89); v[1] = complex(-9.32,.0765); v[2] = complex(5.4,-2.13); + + s.differentiate(); + e = s.jacobian(v) + + self.assertTrue(np.abs(e[0][0].real - exact_real[0][0]) <= self.toldbl*np.abs(exact_real[0][0])); + self.assertTrue(np.abs(e[0][0].imag - exact_imag[0][0]) <= self.toldbl*np.abs(exact_imag[0][0])); + self.assertTrue(np.abs(e[0][1].real - exact_real[0][1]) <= self.toldbl*np.abs(exact_real[0][1])); + self.assertTrue(np.abs(e[0][1].imag - exact_imag[0][1]) <= self.toldbl*np.abs(exact_imag[0][1])); + self.assertTrue(np.abs(e[0][2].real - exact_real[0][2]) <= self.toldbl*np.abs(exact_real[0][2])); + self.assertTrue(np.abs(e[0][2].imag - exact_imag[0][2]) <= self.toldbl*np.abs(exact_imag[0][2])); + self.assertTrue(np.abs(e[1][0].real - exact_real[1][0]) <= self.toldbl*np.abs(exact_real[1][0])); + self.assertTrue(np.abs(e[1][0].imag - exact_imag[1][0]) <= self.toldbl*np.abs(exact_imag[1][0])); + self.assertTrue(np.abs(e[1][1].real - exact_real[1][1]) <= self.toldbl*np.abs(exact_real[1][1])); + self.assertTrue(np.abs(e[1][1].imag - exact_imag[1][1]) <= self.toldbl*np.abs(exact_imag[1][1])); + self.assertTrue(np.abs(e[1][2].real - exact_real[1][2]) <= self.toldbl*np.abs(exact_real[1][2])); + self.assertTrue(np.abs(e[1][2].imag - exact_imag[1][2]) <= self.toldbl*np.abs(exact_imag[1][2])); + + + + + s = parse_system('function f1, f2; variable_group x,y,z; f1 = x*y; f2 = x^2*y - z*x;') + self.toldbl = mpfr_float('1e-27'); + exact_real = ((mpfr_float('-9.32'), mpfr_float('3.5'), mpfr_float('0')), \ + (mpfr_float('-71.082170'),mpfr_float('3.8979'),mpfr_float('-3.5'))) + exact_imag = ((mpfr_float('.0765'), mpfr_float('2.89'), mpfr_float('0')),\ + (mpfr_float('-51.20410'),mpfr_float('20.230'),mpfr_float('-2.89'))) + v = VectorXmp((mpfr_complex('3.5', '2.89'), mpfr_complex('-9.32', '.0765'), mpfr_complex('5.4', '-2.13'))); + + s.differentiate(); + e = s.jacobian(v); + + self.assertLessEqual(abs(e[0][0].real / exact_real[0][0]-1) , self.toldbl); + self.assertLessEqual(abs(e[0][0].imag / exact_imag[0][0]-1) , self.toldbl); + self.assertLessEqual(abs(e[0][1].real / exact_real[0][1]-1) , self.toldbl); + self.assertLessEqual(abs(e[0][1].imag / exact_imag[0][1]-1) , self.toldbl); + self.assertLessEqual(abs(e[0][2].real ) , self.toldbl); + self.assertLessEqual(abs(e[0][2].imag ) , self.toldbl); + self.assertLessEqual(abs(e[1][0].real / exact_real[1][0]-1) , self.toldbl); + self.assertLessEqual(abs(e[1][0].imag / exact_imag[1][0]-1) , self.toldbl); + self.assertLessEqual(abs(e[1][1].real / exact_real[1][1]-1) , self.toldbl); + self.assertLessEqual(abs(e[1][1].imag / exact_imag[1][1]-1) , self.toldbl); + self.assertLessEqual(abs(e[1][2].real / exact_real[1][2]-1) , self.toldbl); + self.assertLessEqual(abs(e[1][2].imag / exact_imag[1][2]-1) , self.toldbl); + + + + def test_add_systems(self): + x = self.x; y = self.y; + s1 = System(); s2 = System(); + + vars = VariableGroup(); + vars.append(x); vars.append(y); + + s1.add_variable_group(vars) + s1.add_function(y+1) + s1.add_function(x*y) + + s2.add_variable_group(vars) + s2.add_function(-y-1) + s2.add_function(-x*y) + + s1 += s2; + values = VectorXd((2,3)) + v = s1.eval(values) + + self.assertEqual(v[0], 0.0) + self.assertEqual(v[1], 0.0) + + deg = s1.degrees() + self.assertEqual(len(deg),2) + + self.assertEqual(deg[0], 1) + self.assertEqual(deg[1], 2) + + + def test_mult_system_node(self): + tol_d = self.toldbl; + sys = parse_system('function f1, f2; variable_group x,y,z; f1 = x+2; f2 = y*y;') + + z = Variable("z"); + sys *= Float(2); + + vals = VectorXd((complex(-2.43,.21 ),complex(4.84, -1.94),complex(-6.48, -.731))) + sysEval = sys.eval(vals); + + self.assertLessEqual(np.abs(sysEval[0].real / (-.86)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[0].imag / (0.42)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[1].real / (39.3240)-1), tol_d) + self.assertLessEqual(np.abs(sysEval[1].imag / (-37.5584)-1), tol_d) + + + + +