3
0
mirror of https://github.com/triqs/dft_tools synced 2024-10-31 11:13:46 +01:00

gf: add a few functions in C++

This commit is contained in:
Olivier Parcollet 2014-05-10 21:39:11 +02:00
parent 376056f7bd
commit 3a9f986461
3 changed files with 118 additions and 18 deletions

View File

@ -106,7 +106,10 @@ namespace triqs { namespace arrays { namespace numpy_interface {
// do several checks
if (!numpy_obj) {// The convertion of X to a numpy has failed !
if (PyErr_Occurred()) {PyErr_Print();PyErr_Clear();}
if (PyErr_Occurred()) {
//PyErr_Print();
PyErr_Clear();
}
TRIQS_RUNTIME_ERROR<<"numpy interface : the python object is not convertible to a numpy. ";
}
assert (PyArray_Check(numpy_obj)); assert((numpy_obj->ob_refcnt==1) || ((numpy_obj ==X)));

View File

@ -28,11 +28,16 @@
#include <vector>
#include "./tools.hpp"
#include "./data_proxies.hpp"
#include "./local/tail.hpp"
namespace triqs {
namespace gfs {
using utility::factory;
using arrays::make_shape;
using arrays::array;
using arrays::array_view;
using arrays::matrix;
using arrays::matrix_view;
using triqs::make_clone;
// the gf mesh
@ -424,8 +429,8 @@ namespace gfs {
using target_shape_t = typename factory::target_shape_t;
gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{}, typename B::indices_t const &ind = typename B::indices_t{})
: B(std::move(m), factory::make_data(m, shape), factory::make_singularity(m, shape), typename B::symmetry_t{}, ind, {}, // clean unncessary types
gf(typename B::mesh_t m, target_shape_t shape = target_shape_t{}, typename B::indices_t const &ind = typename B::indices_t{}, std::string name = "")
: B(std::move(m), factory::make_data(m, shape), factory::make_singularity(m, shape), typename B::symmetry_t{}, ind, name, // clean unncessary types
typename B::evaluator_t{}) {}
friend void swap(gf &a, gf &b) noexcept { a.swap_impl(b); }
@ -647,6 +652,91 @@ namespace gfs {
g.singularity(), g.symmetry());
}*/
// ---------------------------------- some functions : invert, conjugate, transpose, ... ------------------------------------
// ---- inversion
// auxiliary function : invert the data : one function for all matrix valued gf (save code).
template <typename A3> void _gf_invert_data_in_place(A3 && a) {
for (int i = 0; i < first_dim(a); ++i) {// Rely on the ordering
auto v = a(i, arrays::range(), arrays::range());
v = inverse(v);
}
}
template <typename Variable, typename Opt>
void invert_in_place(gf_view<Variable, matrix_valued, Opt> g) {
_gf_invert_data_in_place(g.data());
g.singularity() = inverse(g.singularity());
}
template <typename Variable, typename Opt> gf<Variable, matrix_valued, Opt> inverse(gf_view<Variable, matrix_valued, Opt> g) {
auto res = gf<Variable, matrix_valued, Opt>(g);
invert_in_place(res);
return res;
}
// ---- transpose : a new view
/*
template <typename Variable, typename Opt>
gf_view<Variable, matrix_valued, Opt> invert_in_place(gf_view<Variable, matrix_valued, Opt> g) {
return { g.mesh(), transpose( g.data(), xxxx), transpose(g.singularity()), g.symmetry(), g.indices() XXX, g.name};
}
*/
// ---- conjugate : always a new function -> changelog
template <typename Variable, typename Opt> gf<Variable, matrix_valued, Opt> conj(gf_view<Variable, matrix_valued, Opt> g) {
return {g.mesh(), conj(g.data()), conj(g.singularity()), g.symmetry(), g.indices(), g.name};
}
// ---- matrix mult R and L
template <typename A3, typename T> void _gf_data_mul_R(A3 &&a, matrix<T> const &r) {
for (int i = 0; i < first_dim(a); ++i) { // Rely on the ordering
matrix_view<T> v = a(i, arrays::range(), arrays::range());
v = v * r;
}
}
template <typename A3, typename T> void _gf_data_mul_L(matrix<T> const &l, A3 &&a) {
for (int i = 0; i < first_dim(a); ++i) { // Rely on the ordering
matrix_view<T> v = a(i, arrays::range(), arrays::range());
v = l * v;
}
}
template <typename A3, typename T> typename A3::regular_type _gf_data_mul_LR(matrix<T> const &l, A3 &a, matrix<T> const &r) {
auto res = typename A3::regular_type(first_dim(a), first_dim(l), second_dim(r));
for (int i = 0; i < first_dim(a); ++i) { // Rely on the ordering
auto _ = arrays::range{};
res(i, _, _) = l * make_matrix_view(a(i, _, _))* r;
}
return res;
}
template <typename Variable, typename Opt, typename T>
gf<Variable, matrix_valued, Opt> operator*(gf<Variable, matrix_valued, Opt> g, matrix<T> r) {
_gf_data_mul_R(g.data(), r);
g.singularity() = g.singularity() * r;
return g;
}
template <typename Variable, typename Opt, typename T>
gf<Variable, matrix_valued, Opt> operator*(matrix<T> l, gf<Variable, matrix_valued, Opt> g) {
_gf_data_mul_L(l, g.data());
g.singularity() = l * g.singularity();
return g;
}
template <typename Variable, typename Opt, typename T>
gf<Variable, matrix_valued, Opt> L_G_R(matrix<T> l, gf<Variable, matrix_valued, Opt> g, matrix<T> r) {
auto res = gf<Variable, matrix_valued, Opt>{g.mesh(), {first_dim(l), second_dim(r)}};
res.data() = _gf_data_mul_LR(l, g.data(), r);
res.singularity() = l * g.singularity() * r;
return res;
}
namespace gfs_implementation { // implement some default traits
// ------------------------- default factories ---------------------

View File

@ -31,7 +31,9 @@ namespace triqs { namespace gfs { namespace local {
static constexpr double small = 1.e-10;
}
namespace tqa= triqs::arrays; namespace tql= triqs::clef; namespace mpl= boost::mpl;
using arrays::matrix_view;
using arrays::matrix;
namespace tqa= triqs::arrays; //namespace tql= triqs::clef; namespace mpl= boost::mpl;
typedef std::complex<double> dcomplex;
class tail; // the value class
@ -40,7 +42,6 @@ namespace triqs { namespace gfs { namespace local {
template<typename G> struct LocalTail : mpl::false_{}; // a boolean trait to identify the objects modelling the concept LocalTail
template<> struct LocalTail<tail > : mpl::true_{};
template<> struct LocalTail<tail_view >: mpl::true_{};
template<> struct LocalTail<python_tools::cython_proxy<tail_view>>: mpl::true_{};
// a trait to find the scalar of the algebra i.e. the true scalar and the matrix ...
template <typename T> struct is_scalar_or_element : mpl::or_< tqa::ImmutableMatrix<T>, utility::is_in_ZRC<T> > {};
@ -80,8 +81,6 @@ namespace triqs { namespace gfs { namespace local {
typedef tqa::mini_vector<size_t,2> shape_type;
shape_type shape() const { return shape_type(_data.shape()[1], _data.shape()[2]);}
size_t shape(int i) const { return _data.shape()[i];}
bool is_decreasing_at_infinity() const { return (smallest_nonzero() >=1);}
protected:
@ -231,6 +230,7 @@ namespace triqs { namespace gfs { namespace local {
typedef tqa::mini_vector<size_t,2> shape_type;
tail(size_t N1, size_t N2, size_t size_=10, long order_min=-1): B(N1,N2,size_,order_min) {}
tail(shape_type const & sh, size_t size_=10, long order_min=-1): B(sh[0],sh[1],size_,order_min) {}
tail(B::data_type const &d, B::mask_type const &m, long order_min): B(d, m, order_min) {}
tail(tail const & g): B(g) {}
tail(tail_view const & g): B(g) {}
tail(tail &&) = default;
@ -279,6 +279,8 @@ namespace triqs { namespace gfs { namespace local {
return *this;
}
inline tail conj(tail_view t) { return {conj(t.data()), t.mask_view(),t.order_min()};}
/// Slice in orbital space
//template<bool V> tail_view slice_target(tail_impl<V> const & t, tqa::range R1, tqa::range R2) {
inline tail_view slice_target(tail_view t, tqa::range R1, tqa::range R2) {
@ -326,19 +328,24 @@ namespace triqs { namespace gfs { namespace local {
return res;
}
template<typename T1, typename T2>
TYPE_ENABLE_IF(tail,mpl::and_<LocalTail<T1>, LocalTail<T2>>)
operator* (T1 const & a, T2 const & b) { return mult_impl(a,b); }
template <typename T1, typename T2>
TYPE_ENABLE_IF(tail, mpl::and_<LocalTail<T1>, LocalTail<T2>>) operator*(T1 const &a, T2 const &b) {
return mult_impl(a, b);
}
template<typename T1, typename T2> TYPE_ENABLE_IF(tail,mpl::and_<tqa::ImmutableMatrix<T1>, LocalTail<T2>>)
operator* (T1 const & a, T2 const & b) {
tail res(b); for (long n=res.order_min(); n<=res.order_max(); ++n) res(n)=a*res(n); return res;
}
template <typename T1, typename T2>
TYPE_ENABLE_IF(tail, mpl::and_<tqa::ImmutableMatrix<T1>, LocalTail<T2>>) operator*(T1 const &a, T2 const &b) {
auto res = tail{first_dim(a), b.shape()[1], b.size(), b.order_min()};
for (int n = res.order_min(); n <= res.order_max(); ++n) res(n) = a * b(n);
return res;
}
template<typename T1, typename T2> TYPE_ENABLE_IF(tail,mpl::and_<LocalTail<T1>, tqa::ImmutableMatrix<T2>>)
operator* (T1 const & a, T2 const & b) {
tail res(a); for (long n=res.order_min(); n<=res.order_max(); ++n) res(n)=res(n)*b; return res;
}
template <typename T1, typename T2>
TYPE_ENABLE_IF(tail, mpl::and_<LocalTail<T1>, tqa::ImmutableMatrix<T2>>) operator*(T1 const &a, T2 const &b) {
auto res = tail{a.shape()[0], second_dim(b), a.size(), a.order_min()};
for (int n = res.order_min(); n <= res.order_max(); ++n) res(n) = a(n) * b;
return res;
}
inline tail operator * (dcomplex a, tail_view const & r) { tail res(r); res.data()*=a; return res;}
inline tail operator * (tail_view const & r, dcomplex a) { return a*r; }