Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions IDEs/qtcreator/include/include.pro
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ TARGET = ublas
CONFIG += staticlib depend_includepath
CONFIG -= qt
CONFIG += c++20

INCLUDE_DIR=../../../include

include(detail/detail.pri)
Expand Down
60 changes: 5 additions & 55 deletions IDEs/qtcreator/include/tensor/tensor.pri
Original file line number Diff line number Diff line change
@@ -1,55 +1,5 @@
HEADERS += \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/algorithms.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/expression_evaluation.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/functions.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/index.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/index_functions.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/layout.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/multi_index_utility.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/multiplication.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_arithmetic.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/operators_comparison.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/ostream.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tags.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/concepts.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/type_traits.hpp


HEADERS += \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/traits/basic_type_traits.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/traits/storage_traits.hpp

HEADERS += \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_dynamic_size.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_static_size.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_static_functions.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_static.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_base.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/extents_functions.hpp


HEADERS += \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/tensor_core.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/tensor_engine.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/tensor_static.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/tensor_static_rank.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/tensor_dynamic.hpp


HEADERS += \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/inner_prod.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/init.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/outer_prod.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/trans.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/norm.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/imag.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/real.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/conj.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/tensor_times_vector.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/tensor_times_matrix.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/tensor_times_tensor.hpp \
$${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/reshape.hpp
HEADERS += $${INCLUDE_DIR}/boost/numeric/ublas/tensor/*.hpp
HEADERS += $${INCLUDE_DIR}/boost/numeric/ublas/tensor/traits/*.hpp
HEADERS += $${INCLUDE_DIR}/boost/numeric/ublas/tensor/extents/*.hpp
HEADERS += $${INCLUDE_DIR}/boost/numeric/ublas/tensor/tensor/*.hpp
HEADERS += $${INCLUDE_DIR}/boost/numeric/ublas/tensor/function/*.hpp
52 changes: 8 additions & 44 deletions IDEs/qtcreator/test/test_tensor.pro
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ CONFIG += c++20
QMAKE_CXXFLAGS =-std=c++20
QMAKE_CXXFLAGS +=-Wall -Wpedantic -Wextra
QMAKE_CXXFLAGS +=-Wno-unknown-pragmas
QMAKE_CXXFLAGS +=-Wno-unused-but-set-variable
#QMAKE_CXXFLAGS +=-Wno-unused-but-set-variable


gcc:QMAKE_CXXFLAGS_RELEASE =-O3 -march=native -fopenmp
Expand All @@ -18,18 +18,10 @@ clang: QMAKE_CXXFLAGS_RELEASE =-O3 -march=native -fopenmp=libiomp5
gcc:QMAKE_CXXFLAGS_DEBUG = -g
clang: QMAKE_CXXFLAGS_DEBUG =-g


#QMAKE_CXXFLAGS += --coverage

BOOST_ROOT=../../../../../..

#exists( $$BOOST_ROOT/boost-build.jam ) {
# message("Boost installed.")
# INCLUDEPATH += $${BOOST_ROOT}/libs/numeric/ublas/include
# LIBS += -L$${BOOST_ROOT}/stage/lib -lgomp
# QMAKE_RPATHDIR += $${BOOST_ROOT}/stage/lib
#}

QMAKE_RPATHDIR += $${BOOST_ROOT}/stage/lib
INCLUDEPATH+=$$BOOST_ROOT/libs/numeric/ublas/include
LIBS+=-L$${BOOST_ROOT}/stage/lib -lboost_unit_test_framework -lgomp
Expand All @@ -41,39 +33,11 @@ TEST_DIR = ../../../test/tensor

include(../include/tensor/tensor.pri)

HEADERS += \
$${TEST_DIR}/utility.hpp
HEADERS += $${TEST_DIR}/utility.hpp

SOURCES += \
$${TEST_DIR}/test_algorithms.cpp \
$${TEST_DIR}/test_einstein_notation.cpp \
$${TEST_DIR}/test_expression.cpp \
$${TEST_DIR}/test_expression_evaluation.cpp \
$${TEST_DIR}/test_extents_dynamic.cpp \
$${TEST_DIR}/test_extents_dynamic_rank_static.cpp \
$${TEST_DIR}/test_fixed_rank_expression_evaluation.cpp \
$${TEST_DIR}/test_fixed_rank_extents.cpp \
$${TEST_DIR}/test_fixed_rank_functions.cpp \
$${TEST_DIR}/test_fixed_rank_operators_arithmetic.cpp \
$${TEST_DIR}/test_fixed_rank_operators_comparison.cpp \
$${TEST_DIR}/test_fixed_rank_strides.cpp \
$${TEST_DIR}/test_fixed_rank_tensor.cpp \
$${TEST_DIR}/test_fixed_rank_tensor_matrix_vector.cpp \
$${TEST_DIR}/test_functions.cpp \
$${TEST_DIR}/test_multi_index.cpp \
$${TEST_DIR}/test_multi_index_utility.cpp \
$${TEST_DIR}/test_multiplication.cpp \
$${TEST_DIR}/test_operators_arithmetic.cpp \
$${TEST_DIR}/test_operators_comparison.cpp \
$${TEST_DIR}/test_static_expression_evaluation.cpp \
$${TEST_DIR}/test_static_extents.cpp \
# $${TEST_DIR}/test_static_functions.cpp \
$${TEST_DIR}/test_static_operators_arithmetic.cpp \
$${TEST_DIR}/test_static_operators_comparison.cpp \
$${TEST_DIR}/test_static_strides.cpp \
$${TEST_DIR}/test_static_tensor.cpp \
$${TEST_DIR}/test_static_tensor_matrix_vector.cpp \
$${TEST_DIR}/test_strides.cpp \
$${TEST_DIR}/test_tensor.cpp \
$${TEST_DIR}/test_tensor_matrix_vector.cpp \
$${TEST_DIR}/test_extents_functions.cpp
SOURCES += $${TEST_DIR}/algorithm/test_*.cpp
SOURCES += $${TEST_DIR}/extents/test_*.cpp
SOURCES += $${TEST_DIR}/functions/test_*.cpp
SOURCES += $${TEST_DIR}/multiplication/test_*.cpp
SOURCES += $${TEST_DIR}/tensor/test_*.cpp
SOURCES += $${TEST_DIR}/test_*.cpp
2 changes: 1 addition & 1 deletion IDEs/qtcreator/tests.pri
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ SUBDIRS += \
# test_triangular \
# triangular_access \
# triangular_layout \
# test_tensor
# test_tensor

#begin_end.file = test/begin_end.pro
#comp_mat_erase.file = test/comp_mat_erase.pro
Expand Down
2 changes: 2 additions & 0 deletions IDEs/qtcreator/ublas_develop.pro
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ CONFIG += ordered
SUBDIRS = include # examples # benchmarks
OTHER_FILES += ../../changelog.txt

CONFIG += c++17
QMAKE_CXXFLAGS += -std=c++17

#include (tests.pri)

Expand Down
197 changes: 197 additions & 0 deletions include/boost/numeric/ublas/tensor/access.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
//
// Copyright (c) 2020, Cem Bassoy, [email protected]
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// The authors gratefully acknowledge the support of
// Fraunhofer IOSB, Ettlingen, Germany
//


#ifndef BOOST_UBLAS_TENSOR_ACCESS_HPP
#define BOOST_UBLAS_TENSOR_ACCESS_HPP


#include <algorithm>
#include <numeric>
#include <functional>

#include <boost/numeric/ublas/functional.hpp>


namespace boost::numeric::ublas {

using first_order = column_major;
using last_order = row_major;

} // namespace boost::numeric::ublas

namespace boost::numeric::ublas::detail{


/** \brief Computes a single index from multi-index of a tensor or subtensor
*
* \param i iterator to a multi-index vector of length std::distance(begin,end)
* \param ip iterator to a multi-index vector of length std::distance(begin,end)
* \param w iterator to a stride vector of length std::distance(begin,end) or greater
*/
template<typename InputIt1, typename InputIt2>
constexpr inline auto compute_single_index(InputIt1 i, InputIt1 ip, InputIt2 w)
{
return std::inner_product(i,ip,w,0ul,std::plus<>{},std::multiplies<>{});
}


/** \brief Computes a single index from a multi-index of a tensor or subtensor
*
* \param i iterator to a multi-index vector of length std::distance(begin,end)
* \param ip iterator to a multi-index vector of length std::distance(begin,end)
* \param w iterator to a stride vector of length std::distance(begin,end) or greater
*/
template<unsigned p, typename InputIt1, typename InputIt2>
constexpr inline auto compute_single_index(InputIt1 i, InputIt1 /*ip*/, InputIt2 w)
{
if constexpr(p==0u) return 0ul;
else if constexpr(p >1u) return compute_single_index<p-1>(i,i,w)+i[p-1]*w[p-1];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

different indentation for if and corresponding else [readability-misleading-indentation]

else if constexpr(p >1u) return compute_single_index<p-1>(i,i,w)+i[p-1]*w[p-1];
  ^

Reported as warning by clang-tidy.

else return i[p-1]*w[p-1];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

different indentation for if and corresponding else [readability-misleading-indentation]

else                     return i[p-1]*w[p-1];
  ^

Reported as warning by clang-tidy.

}

/** @brief Computes a multi-index from single index of a tensor or subtensor
*
* j = compute_single_index (i, ip, w)
* compute_multi_index (j, w, wp, k) with k == i
*
* @param w begin input iterator to a container with tensor or subtensor strides of length std::distance(begin,end)
* @param wp end input iterator to a container with tensor or subtensor strides of length std::distance(begin,end)
* @param i begin output iterator to a container with tensor or subtensor indices length std::distance(begin,end) or greater
*/
template<typename InputIt1, typename OutputIt, typename LayoutType>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 wp, OutputIt i, LayoutType /*unused*/);
//{
// if(w == wp)
// return;

// auto wr = std::make_reverse_iterator( w );
// auto wrp = std::make_reverse_iterator( wp );
// auto ir = std::make_reverse_iterator( i+std::distance(w,wp) );

// std::transform(wrp,wr,ir, [&j](auto v) { auto k=j/v; j-=v*k; return k; } );
//}


template<typename InputIt1, typename OutputIt>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 wp, OutputIt i, first_order /*unused*/)
{
if(w == wp)
return;

auto wr = std::make_reverse_iterator( w );
auto wrp = std::make_reverse_iterator( wp );
auto ir = std::make_reverse_iterator( i+std::distance(w,wp) );

std::transform(wrp,wr,ir, [&j](auto v) { auto k=j/v; j-=v*k; return k; } );
}

template<typename InputIt1, typename OutputIt>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 wp, OutputIt i, last_order /*unused*/)
{
if(w == wp)
return;

std::transform(w,wp,i, [&j](auto v) { auto k=j/v; j-=v*k; return k; } );
}




//template<typename InputIt1, typename OutputIt>
//constexpr inline void compute_multi_index_last(std::size_t j, InputIt1 w, InputIt1 wp, OutputIt i)
//{
// if(w == wp)
// return;
//// for(unsigned r = 0ul; r < p; ++r) {
//// i[r] = kq/w[r];
//// kq -= w[r]*i[r];
//// }
// std::transform(w,wp,i, [&j](auto v) { auto k=j/v; j-=v*k; return k; } );
//}

//template<typename InputIt1, typename OutputIt>
//constexpr inline void compute_multi_index_first(std::size_t j, InputIt1 w, InputIt1 wp, OutputIt i)
//{
// if(w == wp)
// return;

//// for(int r = p-1; r >= 0; --r) {
//// i[r] = kq/w[r];
//// kq -= w[r]*i[r];
//// }

// auto wr = std::make_reverse_iterator( w );
// auto wrp = std::make_reverse_iterator( wp );
// auto ir = std::make_reverse_iterator( i+std::distance(w,wp) );

// std::transform(wrp,wr,ir, [&j](auto v) { auto k=j/v; j-=v*k; return k; } );
//}


/** @brief Computes a single index from a multi-index of a dense tensor or subtensor
*
* @param j single index that is transformed into a multi-index
* @param w begin input iterator to a container with strides of length p
* @param i begin input iterator to a container with indices of length p or greater
*/
template<unsigned p, typename InputIt1, typename OutputIt, typename LayoutType>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 /*wp*/, OutputIt i, LayoutType);


template<unsigned p, typename InputIt1, typename OutputIt>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 /*wp*/, OutputIt i, first_order o)
{
if constexpr (p==0u) return;
else if constexpr (p >1u) {i[p-1]=j/w[p-1]; compute_multi_index<p-1>(j-w[p-1]*i[p-1],w,w,i,o); }
else {i[p-1]=j/w[p-1]; }
}



template<unsigned p, unsigned k = 0, typename InputIt1, typename OutputIt>
constexpr inline void compute_multi_index(std::size_t j, InputIt1 w, InputIt1 /*wp*/, OutputIt i, last_order o)
{
if constexpr (p == 0u ) { return; }
else if constexpr (k+1 == p) {i[k]=j/w[k]; }
else {i[k]=j/w[k]; compute_multi_index<p,k+1>(j-w[k]*i[k],w,w,i,o); }
}



//template<unsigned p, typename InputIt1, typename OutputIt, unsigned k = 0>
//constexpr inline void compute_multi_index_last(std::size_t j, InputIt1 w, InputIt1 /*wp*/, OutputIt i)
//{
// if constexpr (p == 0u ) return;
// else if constexpr (k+1 == p) {i[k]=j/w[k]; }
// else {i[k]=j/w[k]; compute_multi_index_last<p,k+1>(j-w[k]*i[k],w,w,i); }
//}


/** @brief Computes a single (relative memory) index of a dense tensor from a single index of one of its subtensor
*
* @param jv single index of a subtensor that is transformed into a single index of a dense tensor
* @param w begin input iterator of a container with tensor strides of length std::distance(w,wp)
* @param wp end input iterator of a container with tensor strides of length std::distance(w,wp)
* @param v begin input iterator of a container with subtensor strides of length std::distance(w,wp) or greater
*/
template<typename InputIt1, typename InputIt2>
constexpr inline auto compute_single_index(std::size_t jv, InputIt1 w, InputIt1 wp, InputIt2 v)
{
return std::inner_product(w,wp,v,0ul,
std::plus<>{},
[&jv](auto ww, auto vv) { auto k=jv/vv; jv-=vv*k; return ww*k; }
);
}

} // namespace boost::numeric::ublas::detail

#endif
1 change: 1 addition & 0 deletions include/boost/numeric/ublas/tensor/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <type_traits>


namespace boost::numeric::ublas{

template<typename T>
Expand Down
Loading