Commit 16c4ceb9 authored by Ben Huber's avatar Ben Huber

split python.cpp into several files

parent 68a62241
Pipeline #729 passed with stages
in 8 minutes and 28 seconds
// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.
/**
* @file
* @brief Definition of the python bindings of tensor factorizations.
*/
#include "misc.h"
using namespace internal;
void expose_factorizations() {
class_<TensorFactorisation, boost::noncopyable>("TensorFactorisation", boost::python::no_init)
.def("__rlshift__", +[](TensorFactorisation &_rhs, object &_lhs){
std::vector<IndexedTensor<Tensor>*> tmp = extract<std::vector<IndexedTensor<Tensor>*>>(_lhs);
_rhs(tmp);
})
;
class_<SVD, bases<TensorFactorisation>, boost::noncopyable>("SVD_temporary", boost::python::no_init);
def("SVD", +[](IndexedTensor<Tensor> &_rhs)->TensorFactorisation*{
return new SVD(std::move(_rhs));
}, return_value_policy<manage_new_object, // result is treated as a new object
with_custodian_and_ward_postcall<0,1>>()); // but the argument will not be destroyed before the result is destroyed
class_<QR, bases<TensorFactorisation>, boost::noncopyable>("QR_temporary", boost::python::no_init);
def("QR", +[](IndexedTensor<Tensor> &_rhs)->TensorFactorisation*{
return new QR(std::move(_rhs));
}, return_value_policy<manage_new_object, // result is treated as a new object
with_custodian_and_ward_postcall<0,1>>()); // but the argument will not be destroyed before the result is destroyed
class_<RQ, bases<TensorFactorisation>, boost::noncopyable>("RQ_temporary", boost::python::no_init);
def("RQ", +[](IndexedTensor<Tensor> &_rhs)->TensorFactorisation*{
return new RQ(std::move(_rhs));
}, return_value_policy<manage_new_object, // result is treated as a new object
with_custodian_and_ward_postcall<0,1>>()); // but the argument will not be destroyed before the result is destroyed
class_<QC, bases<TensorFactorisation>, boost::noncopyable>("QC_temporary", boost::python::no_init);
def("QC", +[](IndexedTensor<Tensor> &_rhs)->TensorFactorisation*{
return new QC(std::move(_rhs));
}, return_value_policy<manage_new_object, // result is treated as a new object
with_custodian_and_ward_postcall<0,1>>()); // but the argument will not be destroyed before the result is destroyed
class_<CQ, bases<TensorFactorisation>, boost::noncopyable>("CQ_temporary", boost::python::no_init);
def("CQ", +[](IndexedTensor<Tensor> &_rhs)->TensorFactorisation*{
return new CQ(std::move(_rhs));
}, return_value_policy<manage_new_object, // result is treated as a new object
with_custodian_and_ward_postcall<0,1>>()); // but the argument will not be destroyed before the result is destroyed
enum_<Tensor::Representation>("Representation", "Possible representations of Tensor objects.")
.value("Dense", Tensor::Representation::Dense)
.value("Sparse", Tensor::Representation::Sparse)
;
enum_<Tensor::Initialisation>("Initialisation", "Possible initialisations of new Tensor objects.")
.value("Zero", Tensor::Initialisation::Zero)
.value("None", Tensor::Initialisation::None)
;
}
// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.
/**
* @file
* @brief Definition of the Tensor python bindings.
*/
#include "misc.h"
void expose_indexedTensors() {
// --------------------------------------------------------------- index
class_<Index>("Index",
"helper class to define objects to be used in indexed expressions"
)
.def(init<int64_t>())
.def("__pow__", &Index::operator^, "i**d changes the index i to span d indices in the current expression")
.def("__xor__", &Index::operator^, "i^d changes the index i to span d indices in the current expression")
.def("__div__", &Index::operator/, "i/n changes the index i to span 1/n of all the indices of the current object")
.def("__and__", &Index::operator&, "i&d changes the index i to span all but d indices of the current object")
.def("__str__", static_cast<std::string (*)(const Index &)>(&misc::to_string<Index>))
;
implicitly_convertible<int64_t, Index>();
exec(
"def indices(n=1):\n"
" \"\"\"Create n distinct indices.\"\"\"\n"
" i = 0\n"
" while i<n:\n"
" yield Index()\n"
" i += 1\n"
, scope().attr("__dict__"));
VECTOR_TO_PY(Index, "IndexVector");
implicitly_convertible<internal::IndexedTensorReadOnly<Tensor>, internal::IndexedTensorMoveable<TensorNetwork>>();
implicitly_convertible<internal::IndexedTensorWritable<Tensor>, internal::IndexedTensorMoveable<TensorNetwork>>();
implicitly_convertible<internal::IndexedTensorMoveable<Tensor>, internal::IndexedTensorMoveable<TensorNetwork>>();
implicitly_convertible<internal::IndexedTensor<Tensor>, internal::IndexedTensorMoveable<TensorNetwork>>();
// NOTE in the following all __mul__ variants are defined for the ReadOnly indexed Tensors, even if they are meant for
// the moveable indexed tensors. boost will take care of the proper matching that way. if IndexedTensorMoveable
// defined an __mul__ function on its own it would overwrite all overloaded variants of the readonly indexed tensors
// and thus loose a lot of functionality.
// ---------------------------------------------- indexedTensor<TN>
using namespace internal;
#define ADD_MOVE_AND_RESULT_PTR(name, op, lhs_type, rhs_type, res_type) \
.def(name, \
+[](lhs_type &_l, rhs_type &_r) -> res_type* { \
LOG(pydebug, "python wrapper: " name);\
return new res_type(std::move(_l) op std::move(_r)); \
}, return_value_policy<manage_new_object>())
class_<internal::IndexedTensorReadOnly<TensorNetwork>, boost::noncopyable>("IndexedTensorNetworkReadOnly", no_init)
ADD_MOVE_AND_RESULT_PTR("__add__", +, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__add__", +, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__sub__", -, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__sub__", -, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorMoveable<TensorNetwork>, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorMoveable<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<TensorNetwork>)
.def("__mul__",
+[](internal::IndexedTensorReadOnly<TensorNetwork> &_l, value_t _r) -> internal::IndexedTensorReadOnly<TensorNetwork>* {
LOG(pydebug, "mul TN ro * scalar");
return new internal::IndexedTensorMoveable<TensorNetwork>(std::move(_l) * _r);
}, return_value_policy<manage_new_object>())
.def("__rmul__",
+[](value_t _r, internal::IndexedTensorReadOnly<TensorNetwork> &_l) -> internal::IndexedTensorReadOnly<TensorNetwork>* {
LOG(pydebug, "mul TN scalar * ro");
return new internal::IndexedTensorMoveable<TensorNetwork>(std::move(_l) * _r);
}, return_value_policy<manage_new_object>())
.def("__div__",
+[](internal::IndexedTensorReadOnly<TensorNetwork> &_l, value_t _r) -> internal::IndexedTensorReadOnly<TensorNetwork>* {
LOG(pydebug, "div TN ro / scalar");
return new internal::IndexedTensorMoveable<TensorNetwork>(std::move(_l) / _r);
}, return_value_policy<manage_new_object>())
.def("frob_norm", static_cast<value_t (*)(const IndexedTensorReadOnly<TensorNetwork> &)>(&frob_norm<TensorNetwork>))
.def(float_(self)) // cast to double
;
class_<internal::IndexedTensorWritable<TensorNetwork>, boost::noncopyable, bases<internal::IndexedTensorReadOnly<TensorNetwork>>>("IndexedTensorNetworkWriteable", no_init)
;
class_<internal::IndexedTensorMoveable<TensorNetwork>, boost::noncopyable, bases<internal::IndexedTensorWritable<TensorNetwork>>>("IndexedTensorNetworkMoveable", no_init)
;
class_<internal::IndexedTensor<TensorNetwork>, boost::noncopyable, bases<internal::IndexedTensorWritable<TensorNetwork>>>("IndexedTensorNetwork", no_init)
.def("__lshift__",
+[](internal::IndexedTensor<TensorNetwork> &_lhs, internal::IndexedTensorReadOnly<Tensor> &_rhs) {
std::move(_lhs) = std::move(_rhs);
})
.def("__lshift__",
+[](internal::IndexedTensor<TensorNetwork> &_lhs, internal::IndexedTensorReadOnly<TensorNetwork> &_rhs) {
std::move(_lhs) = std::move(_rhs);
})
;
// --------------------------------------------- indexedTensor<Tensor>
class_<internal::IndexedTensorReadOnly<Tensor>, boost::noncopyable>("IndexedTensorReadOnly", no_init)
ADD_MOVE_AND_RESULT_PTR("__add__", +, IndexedTensorReadOnly<Tensor>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<Tensor>)
ADD_MOVE_AND_RESULT_PTR("__sub__", -, IndexedTensorReadOnly<Tensor>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<Tensor>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorReadOnly<Tensor>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__mul__", *, IndexedTensorReadOnly<Tensor>, IndexedTensorReadOnly<TensorNetwork>, IndexedTensorMoveable<TensorNetwork>)
ADD_MOVE_AND_RESULT_PTR("__div__", /, IndexedTensorReadOnly<Tensor>, IndexedTensorReadOnly<Tensor>, IndexedTensorMoveable<Tensor>)
.def("__mul__",
+[](internal::IndexedTensorReadOnly<Tensor> &_l, value_t _r) -> internal::IndexedTensorReadOnly<Tensor>* {
LOG(pydebug, "mul ro * scalar");
return new internal::IndexedTensorMoveable<Tensor>(std::move(_l) * _r);
}, return_value_policy<manage_new_object>())
.def("__rmul__",
+[](value_t _r, internal::IndexedTensorReadOnly<Tensor> &_l) -> internal::IndexedTensorReadOnly<Tensor>* {
LOG(pydebug, "mul scalar * ro");
return new internal::IndexedTensorMoveable<Tensor>(std::move(_l) * _r);
}, return_value_policy<manage_new_object>())
.def("__div__",
+[](internal::IndexedTensorReadOnly<Tensor> &_l, value_t _r) -> internal::IndexedTensorReadOnly<Tensor>* {
LOG(pydebug, "div ro / scalar");
return new internal::IndexedTensorMoveable<Tensor>(std::move(_l) / _r);
}, return_value_policy<manage_new_object>())
.def("frob_norm", static_cast<value_t (*)(const IndexedTensorReadOnly<Tensor> &)>(&frob_norm<Tensor>))
.def(float_(self)) // cast to double
;
class_<internal::IndexedTensorWritable<Tensor>, boost::noncopyable, bases<internal::IndexedTensorReadOnly<Tensor>>>("IndexedTensorWriteable", no_init)
;
class_<internal::IndexedTensorMoveable<Tensor>, boost::noncopyable, bases<internal::IndexedTensorWritable<Tensor>>>("IndexedTensorMoveable", no_init)
;
class_<internal::IndexedTensor<Tensor>, boost::noncopyable, bases<internal::IndexedTensorWritable<Tensor>>>("IndexedTensor", no_init)
.def("__lshift__",
+[](internal::IndexedTensor<Tensor> &_lhs, internal::IndexedTensorReadOnly<Tensor> &_rhs) {
std::move(_lhs) = std::move(_rhs);
})
.def("__lshift__",
+[](internal::IndexedTensor<Tensor> &_lhs, internal::IndexedTensorReadOnly<TensorNetwork> &_rhs) {
std::move(_lhs) = std::move(_rhs);
})
;
VECTOR_TO_PY(IndexedTensor<Tensor>*, "IndexedTensorList");
}
// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.
/**
* @file
* @brief Definition of the python bindings of our least squares algorithms.
*/
#include "misc.h"
void expose_leastSquaresAlgorithms() {
VECTOR_TO_PY(PerformanceData::DataPoint, "PerfDataVector");
{ scope perfdata =
class_<PerformanceData>("PerformanceData")
.def_readwrite("printProgress", &PerformanceData::printProgress)
.def_readwrite("startTime", &PerformanceData::startTime)
.def_readwrite("stopTime", &PerformanceData::stopTime)
.def_readwrite("additionalInformation", &PerformanceData::additionalInformation)
.add_property("data", +[](PerformanceData &_this){
return _this.data;
}, +[](PerformanceData &_this, std::vector<PerformanceData::DataPoint> &_newData){
_this.data = _newData;
})
.add_property("errorFunction",
+[](PerformanceData &_this){ return _this.errorFunction; },
+[](PerformanceData &_this, PyObject *_f){
// TODO increase ref count for _f? also decrease it on overwrite?!
_this.errorFunction = [_f](const TTTensor &_x)->double{
return call<double>(_f, _x);
};
})
.def(init<bool>())
.def("start", &PerformanceData::start)
.def("stop_timer", &PerformanceData::stop_timer)
.def("continue_timer", &PerformanceData::continue_timer)
.def("reset", &PerformanceData::reset)
.def("get_elapsed_time", &PerformanceData::get_elapsed_time)
.def("get_runtime", &PerformanceData::get_runtime)
.def("add", +[](PerformanceData &_this, size_t _itr, value_t _res){
_this.add(_itr, _res);
})
.def("add", +[](PerformanceData &_this, size_t _itr, value_t _res, const TTTensor &_x, size_t _flags){
_this.add(_itr, _res, _x, _flags);
}, (arg("iterationCount"), arg("residual"), arg("x"), arg("flags")=0) )
.def("add", +[](PerformanceData &_this, value_t _res, const TTTensor &_x, size_t _flags){
_this.add(_res, _x, _flags);
}, (arg("residual"), arg("x"), arg("flags")=0) )
.def("__nonzero__", +[](PerformanceData &_this){ return bool(_this); })
.def("dump_to_file", &PerformanceData::dump_to_file)
.def("__iadd__", +[](PerformanceData &_this, const std::string &_s){
_this << _s;
})
// TODO histogram
;
class_<PerformanceData::DataPoint>("DataPoint", no_init)
.def_readonly("iterationCount", &PerformanceData::DataPoint::iterationCount)
.def_readonly("elapsedTime", &PerformanceData::DataPoint::elapsedTime)
.def_readonly("residual", &PerformanceData::DataPoint::residual)
.def_readonly("error", &PerformanceData::DataPoint::error)
.def_readonly("ranks", &PerformanceData::DataPoint::ranks)
.def_readonly("flags", &PerformanceData::DataPoint::flags)
;
}
class_<TTRetractionI>("TTRetractionI", init<const TTRetractionI &>());
scope().attr("ALSRetractionI") = object(TTRetractionI(&ALSRetractionI));
scope().attr("SubmanifoldRetractionI") = object(TTRetractionI(&SubmanifoldRetractionI));
scope().attr("HOSVDRetractionI") = object(TTRetractionI(&HOSVDRetractionI));
class_<TTRetractionII>("TTRetractionII", init<const TTRetractionII &>());
scope().attr("ALSRetractionII") = object(TTRetractionII(&ALSRetractionII));
scope().attr("SubmanifoldRetractionII") = object(TTRetractionII(&SubmanifoldRetractionII));
scope().attr("HOSVDRetractionII") = object(TTRetractionII(&HOSVDRetractionII));
class_<TTVectorTransport>("TTVectorTransport", init<const TTVectorTransport &>());
scope().attr("ProjectiveVectorTransport") = object(TTVectorTransport(&ProjectiveVectorTransport));
{ scope als_scope =
class_<ALSVariant>("ALSVariant", init<uint, size_t, ALSVariant::LocalSolver, bool, optional<bool>>())
.def(init<const ALSVariant&>())
.def_readwrite("sites", &ALSVariant::sites)
.def_readwrite("numHalfSweeps", &ALSVariant::numHalfSweeps)
.def_readwrite("convergenceEpsilon", &ALSVariant::convergenceEpsilon)
.def_readwrite("useResidualForEndCriterion", &ALSVariant::useResidualForEndCriterion)
.def_readwrite("preserveCorePosition", &ALSVariant::preserveCorePosition)
.def_readwrite("assumeSPD", &ALSVariant::assumeSPD)
.add_property("localSolver",
+[](ALSVariant &_this){ return _this.localSolver; },
+[](ALSVariant &_this, ALSVariant::LocalSolver _s){ _this.localSolver = _s; })
.def("__call__", +[](ALSVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_A, _x, _b, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](ALSVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_A, _x, _b, _eps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](ALSVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, size_t _numHalfSweeps, PerformanceData &_pd) {
_this(_A, _x, _b, _numHalfSweeps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("numHalfSweeps"), arg("perfData")=NoPerfData) )
.def("__call__", +[](ALSVariant &_this, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_x, _b, _pd);
}, (arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](ALSVariant &_this, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_x, _b, _eps, _pd);
}, (arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](ALSVariant &_this, TTTensor &_x, const TTTensor &_b, size_t _numHalfSweeps, PerformanceData &_pd) {
_this(_x, _b, _numHalfSweeps, _pd);
}, (arg("x"), arg("b"), arg("numHalfSweeps"), arg("perfData")=NoPerfData) )
;
class_<ALSVariant::LocalSolver>("LocalSolver", boost::python::no_init);
als_scope.attr("lapack_solver") = object(ALSVariant::LocalSolver(&ALSVariant::lapack_solver));
als_scope.attr("ASD_solver") = object(ALSVariant::LocalSolver(&ALSVariant::ASD_solver));
}
scope().attr("ALS") = object(ptr(&ALS));
scope().attr("ALS_SPD") = object(ptr(&ALS_SPD));
scope().attr("DMRG") = object(ptr(&DMRG));
scope().attr("DMRG_SPD") = object(ptr(&DMRG_SPD));
scope().attr("ASD") = object(ptr(&ASD));
scope().attr("ASD_SPD") = object(ptr(&ASD_SPD));
def("decomposition_als", &decomposition_als, (arg("x"), arg("b"), arg("epsilon")=EPSILON, arg("maxIterations")=1000));
class_<GeometricCGVariant>("GeometricCGVariant", init<size_t, value_t, bool, TTRetractionI, TTVectorTransport>())
.def(init<const GeometricCGVariant&>())
.def_readwrite("numSteps", &GeometricCGVariant::numSteps)
.def_readwrite("convergenceEpsilon", &GeometricCGVariant::convergenceEpsilon)
.def_readwrite("assumeSymmetricPositiveDefiniteOperator", &GeometricCGVariant::assumeSymmetricPositiveDefiniteOperator)
.add_property("retraction",
+[](GeometricCGVariant &_this){ return _this.retraction; },
+[](GeometricCGVariant &_this, TTRetractionI _r){ _this.retraction = _r; })
.add_property("vectorTransport",
+[](GeometricCGVariant &_this){ return _this.vectorTransport; },
+[](GeometricCGVariant &_this, TTVectorTransport _transp){ _this.vectorTransport = _transp; })
.def("__call__", +[](GeometricCGVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_A, _x, _b, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](GeometricCGVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_A, _x, _b, _eps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](GeometricCGVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, size_t _numSteps, PerformanceData &_pd) {
_this(_A, _x, _b, _numSteps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("numSteps"), arg("perfData")=NoPerfData) )
.def("__call__", +[](GeometricCGVariant &_this, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_x, _b, _pd);
}, (arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](GeometricCGVariant &_this, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_x, _b, _eps, _pd);
}, (arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](GeometricCGVariant &_this, TTTensor &_x, const TTTensor &_b, size_t _numSteps, PerformanceData &_pd) {
_this(_x, _b, _numSteps, _pd);
}, (arg("x"), arg("b"), arg("numSteps"), arg("perfData")=NoPerfData) )
;
scope().attr("GeometricCG") = object(ptr(&GeometricCG));
class_<SteepestDescentVariant>("SteepestDescentVariant", init<size_t, value_t, bool, TTRetractionII>())
.def(init<const SteepestDescentVariant&>())
.def_readwrite("numSteps", &SteepestDescentVariant::numSteps)
.def_readwrite("convergenceEpsilon", &SteepestDescentVariant::convergenceEpsilon)
.def_readwrite("assumeSymmetricPositiveDefiniteOperator", &SteepestDescentVariant::assumeSymmetricPositiveDefiniteOperator)
.add_property("retraction",
+[](SteepestDescentVariant &_this){ return _this.retraction; },
+[](SteepestDescentVariant &_this, TTRetractionII _r){ _this.retraction = _r; })
.def("__call__", +[](SteepestDescentVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_A, _x, _b, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](SteepestDescentVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_A, _x, _b, _eps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](SteepestDescentVariant &_this, const TTOperator &_A, TTTensor &_x, const TTTensor &_b, size_t _numSteps, PerformanceData &_pd) {
_this(_A, _x, _b, _numSteps, _pd);
}, (arg("A"), arg("x"), arg("b"), arg("numSteps"), arg("perfData")=NoPerfData) )
.def("__call__", +[](SteepestDescentVariant &_this, TTTensor &_x, const TTTensor &_b, PerformanceData &_pd) {
_this(_x, _b, _pd);
}, (arg("x"), arg("b"), arg("perfData")=NoPerfData) )
.def("__call__", +[](SteepestDescentVariant &_this, TTTensor &_x, const TTTensor &_b, value_t _eps, PerformanceData &_pd) {
_this(_x, _b, _eps, _pd);
}, (arg("x"), arg("b"), arg("epsilon"), arg("perfData")=NoPerfData) )
.def("__call__", +[](SteepestDescentVariant &_this, TTTensor &_x, const TTTensor &_b, size_t _numSteps, PerformanceData &_pd) {
_this(_x, _b, _numSteps, _pd);
}, (arg("x"), arg("b"), arg("numSteps"), arg("perfData")=NoPerfData) )
;
scope().attr("SteepestDescent") = object(ptr(&SteepestDescent));
}
// Xerus - A General Purpose Tensor Library
// Copyright (C) 2014-2016 Benjamin Huber and Sebastian Wolf.
//
// Xerus is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Xerus 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Xerus. If not, see <http://www.gnu.org/licenses/>.
//
// For further information on Xerus visit https://libXerus.org
// or contact us at contact@libXerus.org.
/**
* @file
* @brief Definition of the python bindings of save and restore, exceptions etc..
*/
#include "misc.h"
void variable_argument_member_to_tuple_wrapper(const std::string &_name, const std::string &_tmpName) {
boost::python::str pyCode;
pyCode += "def patch_call_fn():\n";
pyCode += std::string(" original = ")+_name+"\n";
pyCode += std::string(" def ")+_tmpName+"( this, *args ):\n";
pyCode += " return original( this, args )\n";
pyCode += std::string(" return ")+_tmpName+"\n";
pyCode += _name + " = patch_call_fn()\n";
boost::python::exec(pyCode, scope().attr("__dict__"));
}
using namespace internal;
void expose_misc() {
def("frob_norm", +[](const Tensor& _x){ return _x.frob_norm(); });
def("frob_norm", +[](const TensorNetwork& _x){ return _x.frob_norm(); });
def("frob_norm", static_cast<value_t (*)(const IndexedTensorReadOnly<Tensor>&)>(&frob_norm));
def("frob_norm", static_cast<value_t (*)(const IndexedTensorReadOnly<TensorNetwork>&)>(&frob_norm));
def("approx_equal", static_cast<bool (*)(const TensorNetwork&, const TensorNetwork&, double)>(&approx_equal));
def("approx_equal", static_cast<bool (*)(const Tensor&, const TensorNetwork&, double)>(&approx_equal));
def("approx_equal", static_cast<bool (*)(const TensorNetwork&, const Tensor&, double)>(&approx_equal));
def("approx_equal", static_cast<bool (*)(const Tensor&, const Tensor&, double)>(&approx_equal));
def("approx_equal", +[](const Tensor& _l, const Tensor& _r) {
return approx_equal(_l, _r);
});
def("approx_equal", +[](const Tensor& _l, const TensorNetwork& _r) {
return approx_equal(_l, _r);
});
def("approx_equal", +[](const TensorNetwork& _l, const Tensor& _r) {
return approx_equal(_l, _r);
});
def("approx_equal", +[](const TensorNetwork& _l, const TensorNetwork& _r) {
return approx_equal(_l, _r);
});
def("log", +[](std::string _msg){
LOG_SHORT(info, _msg);
});
enum_<misc::FileFormat>("FileFormat")
.value("BINARY", misc::FileFormat::BINARY)
.value("TSV", misc::FileFormat::TSV)
;
def("save_to_file", +[](const Tensor &_obj, const std::string &_filename, misc::FileFormat _format){
misc::save_to_file(_obj, _filename, _format);
}, (arg("object"), arg("filename"), arg("format")=misc::FileFormat::BINARY) );
def("save_to_file", +[](const TensorNetwork &_obj, const std::string &_filename, misc::FileFormat _format){
misc::save_to_file(_obj, _filename, _format);
}, (arg("object"), arg("filename"), arg("format")=misc::FileFormat::BINARY) );
def("save_to_file", +[](const TTTensor &_obj, const std::string &_filename, misc::FileFormat _format){
misc::save_to_file(_obj, _filename, _format);
}, (arg("object"), arg("filename"), arg("format")=misc::FileFormat::BINARY) );
def("save_to_file", +[](const TTOperator &_obj, const std::string &_filename, misc::FileFormat _format){
misc::save_to_file(_obj, _filename, _format);
}, (arg("object"), arg("filename"), arg("format")=misc::FileFormat::BINARY) );
def("load_from_file", +[](std::string _filename){
// determine type stored in the file
std::ifstream in(_filename);
if (!in) {
return object();
}
std::string classname;
in >> classname; // "Xerus"
in >> classname;
in.close();
if (classname == "xerus::Tensor") {
return object(misc::load_from_file<Tensor>(_filename));
}
if (classname == "xerus::TensorNetwork") {
return object(misc::load_from_file<TensorNetwork>(_filename));
}
if (classname == "xerus::TTNetwork<false>") {
return object(misc::load_from_file<TTTensor>(_filename));
}
if (classname == "xerus::TTNetwork<true>") {
return object(misc::load_from_file<TTOperator>(_filename));
}
LOG_SHORT(warning, "unknown class type '" << classname << "' in file '" << _filename << "'");
return object();
});
// identity returns the cpp name to a python object
// def("identity", identity_);
def("xethrow", +[](){XERUS_THROW(misc::generic_error() << misc::get_call_stack());});
// translate all exceptions thrown inside xerus to own python exception class
static char fully_qualified_gen_error_name[] = "xerus.generic_error";
static PyObject* py_gen_error = PyErr_NewException(fully_qualified_gen_error_name, PyExc_Exception, 0);
py::scope().attr("generic_error") = py::handle<>(py::borrowed(py_gen_error));
register_exception_translator<misc::generic_error>([](const misc::generic_error &_e){
LOG(pydebug, "custom exception handler called with " << _e.what());
PyErr_SetString(py_gen_error, _e.what());
});
}