Coder Social home page Coder Social logo

boostorg / ublas Goto Github PK

View Code? Open in Web Editor NEW
104.0 16.0 156.0 47.96 MB

Boost.uBlas

Home Page: https://www.boost.org/doc/libs/release/libs/numeric/ublas

QMake 0.59% C++ 99.02% HTML 0.03% Python 0.24% Shell 0.10% CMake 0.03%
boost ublas tensor matrix linear-algebra vector

ublas's Introduction

Boost Linear and Multilinear Algebra Library

Language License Documentation Wiki Mailing List Discussions Gitter Contributor Covenant

Windows Linux Apple MacOS Clang Sanitizer Clang Tidy Codecov

Boost.uBlas is a header-only library and part of the Boost C++ libraries. It provides a set of basic linear and multilinear algebra operations with tensors, matrices and vectors. uBLAS is documented at boost.org or in docs. Simple examples of the tensor extension is provided by the wiki page.

Simple Example

#include <boost/numeric/ublas/tensor.hpp> 
#include <iostream>

int main()
{
  using namespace boost::numeric::ublas::index;
  using tensor  = boost::numeric::ublas::tensor_dynamic<float>;
  auto ones     = boost::numeric::ublas::ones<float>{};

  tensor A = ones(3,4,5);
  tensor B = ones(4,6,3,2);

  tensor C = 2*ones(5,6,2) + A(_i,_j,_k)*B(_j,_l,_i,_m) + 5;
  
  // Matlab Compatible Formatted Output
  std::cout << "C=" << C << ";" << std::endl;
}

Requirements

  • Boost.uBlas requires a C++20 compatible compiler
    • gcc version >= 10.x.x
    • clang version >= 10.x.x
    • msvc version >= 14.28
  • Unit-tests require Boost.Test

Discussions and Questions

Contribution

Directories

Name Purpose
doc documentation
examples example files
include headers
test unit tests
benchmarks timing and benchmarking

ublas's People

Contributors

awulkiew avatar bassoy avatar beman avatar chriskohlhoff avatar coder3101 avatar danieljames avatar douggregor avatar goerch avatar grafikrobot avatar guwi17 avatar hkaiser avatar imikejackson avatar jdurancomas avatar jensmaurer avatar jewillco avatar jhunold avatar jzmaddock avatar mclow avatar nasosi avatar pdimov avatar rasky avatar sithhell avatar stefanseefeld avatar stevensmi avatar straszheim avatar swatanabe avatar timblechmann avatar toonknapen avatar vprus avatar yimyom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ublas's Issues

OpenCL tests failing on travis

All the unit tests requiring OpenCL are failing on Travis as a result the builds are failing. The following information may help fix the problem.

  • Reason for failure : No OpenCL Device Found
  • Build Environment : trusty 14.04 LTS
  • Extra : In recent blog post of Travis, they mentioned that they are migrating to Xenial 16.04 as trusty's support ended on April 30.

boost::compute is used by uBLAS for OpenCL based computation. The possible reason for failure could be change in build environment by Travis or Invalid installation of OpenCL. All the branches are affected by this, master branch is also likely to fall.

Exception Raised for Static Rank Tensor inside the Tensor Times Tensor Product

This exception is raised because the static rank extents for result type are not filled with one but instead default initialized to zero, making the extents invalid.

auto A = tensor_static_rank<float,2>(4,3);
auto B = tensor_static_rank<float,3>(3,4,2);
auto AB = A(_d,_f) * B(_f,_d,_); // Throws the exception

Exception raised on the construction of the tensor from the `tensor_expression`

When constructing expression such as A + 3 * B and constructing a tensor out of the expression, the exception is raised, which should not happen.

    using tensor_t = tensor_dynamic<float>;
    auto const e = extents<>{3,2};

    auto const a = tensor_t(e, 1.f);

    auto const three = 3.f;
    auto const expr = a + three * a;
    auto const t = tensor_t(expr); // exception

Use of Template Type in the Wrong Place

The template type, which is used for the type of extents harder coded to std::size_t instead of using the template type provided by the user. The user-provided type is misused to define the size of the static rank extents.

Link to the bug.

Fix:

template <integral T, T N>
class extents_core<T,N> {
public:  
       using base_type       = std::array<T,N>;
....
}

Incorrect parameter ordering in element_sub

The parameter ordering of a call to element_wise within one of the element_sub overloads is incorrect.

Since the function signature of element_wise is:

void element_wise(ublas::matrix<T, L1, opencl::storage> const &a,
	ublas::matrix<T, L2, opencl::storage> const &b,
	ublas::matrix<T, L3, opencl::storage> &result,
	O op, compute::command_queue& queue)

The call in the first element_sub overload should be changed to:
element_wise(a, b, result, compute::minus<T>(), queue);
as opposed to
element_wise(a, b, compute::minus<T>(), result, queue);

warning: unused parameter size_i and size_j

This program:

#include <boost/numeric/ublas/functional.hpp>
int main() {
  return 0;
}

when compiled on linux x86_64 with clang++ 5.0.2 and boost 1.68.0 beta1 with the following command:
clang++ -o ublas.o -c -DNDEBUG -Wall -Wextra -std=c++14 -I/softs/lin64-clang-5.0.2/release/boost/include ublas.cpp
gives the following warnings:

In file included from ublas.cpp:1:
/softs/lin64-clang-5.0.2/release/boost/include/boost/numeric/ublas/functional.hpp:1673:57: warning: unused parameter 'size_i' [-Wunused-parameter]
        size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
                                                        ^
/softs/lin64-clang-5.0.2/release/boost/include/boost/numeric/ublas/functional.hpp:1673:88: warning: unused parameter 'size_j' [-Wunused-parameter]
        size_type upper_element (size_type i, size_type size_i, size_type j, size_type size_j) {
                                                                                       ^
2 warnings generated.

Matrix/Tensor Factorization

Operations such as matrix multiplication are BLAS level 3 operations, while matrix addition is level 1. Suppose we have the following computation of 4 matrices:

A * C + B * D;

Suppose A = B, but the user of the library may or may not know this. Would it be a good idea to find a way to compute this instead:

A (C+ D)

I think this is a rather trivial topic, but I thought it might be cool for uBLAS to have this

custom type support

matrix template has incomplete support for custom types or it was broken.

can try it with this https://github.com/ohhmm/openmind/blob/master/omnn/extrapolator/Number.h

the error message:
[ 4%] Built target omnn
[ 8%] Built target ct
[ 12%] Built target TrainedUnit
[ 16%] Built target MathTool
[ 20%] Built target Mnist
[ 24%] Built target opengl_rt_laby
[ 26%] Building CXX object omnn/extrapolator/CMakeFiles/extrapolator.dir/Extrapolator.cpp.o
[ 28%] Building CXX object omnn/extrapolator/CMakeFiles/extrapolator.dir/System.cpp.o
[ 68%] Built target OpenMind
[ 72%] Built target IdleTimeWorker
[ 78%] Built target chatbot
[ 90%] Built target arithm
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/System.cpp:5:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/System.h:11:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:13:
In file included from /usr/local/include/boost/numeric/ublas/matrix.hpp:20:
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:33:35: error: invalid operands to binary expression ('typename matrix_scalar_unary_traits<matrix_binary<matrix_matrix_binary<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, matrix_matrix_prod<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> >, matrix_norm_inf<matrix_binary<matrix_matrix_binary<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, matrix_matrix_prod<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> > > >::result_type' (aka 'matrix_scalar_unary<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix_norm_inf<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> > > >') and 'omnn::extrapolator::Number')
return norm_inf (e1 - e2) < epsilon *
~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:42:16: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::equals<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, omnn::extrapolator::Number>' requested here
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
^
/usr/local/include/boost/numeric/ublas/lu.hpp:166:36: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::expression_type_check<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > > >' requested here
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
^
/Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:26:30: note: in instantiation of function template specialization 'boost::numeric::ublas::lu_factorize<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::permutation_matrix<unsigned long, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator > > >' requested here
auto isSingular = ublas::lu_factorize(matrix, pivots);
^
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.cpp:5:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:13:
In file included from /usr/local/include/boost/numeric/ublas/matrix.hpp:20:
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:33:35: error: invalid operands to binary expression ('typename matrix_scalar_unary_traits<matrix_binary<matrix_matrix_binary<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, matrix_matrix_prod<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> >, matrix_norm_inf<matrix_binary<matrix_matrix_binary<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, matrix_matrix_prod<triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_unit_lower >, triangular_adaptor<matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> > > >::result_type' (aka 'matrix_scalar_unary<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix_norm_inf<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> > > >') and 'omnn::extrapolator::Number')
return norm_inf (e1 - e2) < epsilon *
~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:42:16: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::equals<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, omnn::extrapolator::Number>' requested here
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
^
/usr/local/include/boost/numeric/ublas/lu.hpp:166:36: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::expression_type_check<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > > >' requested here
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
^
/Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:26:30: note: in instantiation of function template specialization 'boost::numeric::ublas::lu_factorize<boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::permutation_matrix<unsigned long, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator > > >' requested here
auto isSingular = ublas::lu_factorize(matrix, pivots);
^
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/System.cpp:5:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/System.h:11:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:13:
In file included from /usr/local/include/boost/numeric/ublas/matrix.hpp:20:
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:33:35: error: invalid operands to binary expression ('typename matrix_scalar_unary_traits<matrix_binary<matrix_matrix_binary<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, matrix_matrix_prod<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> >, matrix_norm_inf<matrix_binary<matrix_matrix_binary<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, matrix_matrix_prod<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> > > >::result_type' (aka 'matrix_scalar_unary<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix_norm_inf<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> > > >') and 'omnn::extrapolator::Number')
return norm_inf (e1 - e2) < epsilon *
~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:42:16: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::equals<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, omnn::extrapolator::Number>' requested here
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
^
/usr/local/include/boost/numeric/ublas/lu.hpp:166:36: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::expression_type_check<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > > >' requested here
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
^
/Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:87:34: note: in instantiation of function template specialization 'boost::numeric::ublas::lu_factorize<omnn::extrapolator::Extrapolator, boost::numeric::ublas::permutation_matrix<unsigned long, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator > > >' requested here
auto isSingular = ublas::lu_factorize(mLu, pivots);
^
/usr/local/include/boost/array.hpp:346:10: note: candidate template ignored: could not match 'array' against 'matrix_scalar_unary'
bool operator< (const array<T,N>& x, const array<T,N>& y) {
^
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.cpp:5:
In file included from /Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:13:
In file included from /usr/local/include/boost/numeric/ublas/matrix.hpp:20:
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:33:35: error: invalid operands to binary expression ('typename matrix_scalar_unary_traits<matrix_binary<matrix_matrix_binary<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, matrix_matrix_prod<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> >, matrix_norm_inf<matrix_binary<matrix_matrix_binary<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, matrix_matrix_prod<triangular_adaptor<Extrapolator, basic_unit_lower >, triangular_adaptor<Extrapolator, basic_upper >, Number> >, matrix<Number, basic_row_major<unsigned long, long>, unbounded_array<Number, allocator > >, scalar_minus<Number, Number> > > >::result_type' (aka 'matrix_scalar_unary<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix_norm_inf<boost::numeric::ublas::matrix_binary<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, boost::numeric::ublas::scalar_minus<omnn::extrapolator::Number, omnn::extrapolator::Number> > > >') and 'omnn::extrapolator::Number')
return norm_inf (e1 - e2) < epsilon *
~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
/usr/local/include/boost/numeric/ublas/detail/matrix_assign.hpp:42:16: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::equals<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > >, omnn::extrapolator::Number>' requested here
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
^
/usr/local/include/boost/numeric/ublas/lu.hpp:166:36: note: in instantiation of function template specialization 'boost::numeric::ublas::detail::expression_type_check<boost::numeric::ublas::matrix_matrix_binary<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, boost::numeric::ublas::matrix_matrix_prod<boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_unit_lower >, boost::numeric::ublas::triangular_adaptor<omnn::extrapolator::Extrapolator, boost::numeric::ublas::basic_upper >, omnn::extrapolator::Number> >, boost::numeric::ublas::matrix<omnn::extrapolator::Number, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<omnn::extrapolator::Number, std::__1::allocatoromnn::extrapolator::Number > > >' requested here
detail::expression_type_check (prod (triangular_adaptor<matrix_type, unit_lower> (m),
^
/Users/sergejkrivonos/Projects/openmind/omnn/extrapolator/Extrapolator.h:87:34: note: in instantiation of function template specialization 'boost::numeric::ublas::lu_factorize<omnn::extrapolator::Extrapolator, boost::numeric::ublas::permutation_matrix<unsigned long, boost::numeric::ublas::unbounded_array<unsigned long, std::__1::allocator > > >' requested here
auto isSingular = ublas::lu_factorize(mLu, pivots);
^
/usr/local/include/boost/array.hpp:346:10: note: candidate template ignored: could not match 'array' against 'matrix_scalar_unary'
bool operator< (const array<T,N>& x, const array<T,N>& y) {
^
2 errors generated.
2 errors generated.
gmake[2]: *** [omnn/extrapolator/CMakeFiles/extrapolator.dir/build.make:87: omnn/extrapolator/CMakeFiles/extrapolator.dir/System.cpp.o] Error 1
gmake[2]: *** Waiting for unfinished jobs....
gmake[2]: *** [omnn/extrapolator/CMakeFiles/extrapolator.dir/build.make:63: omnn/extrapolator/CMakeFiles/extrapolator.dir/Extrapolator.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:222: omnn/extrapolator/CMakeFiles/extrapolator.dir/all] Error 2
gmake: *** [Makefile:95: all] Error 2

Undefined return value on GCC/MSVC with -O2 using "auto"

Dear everyone,
I hope you are doing well. I stumbled across an oddity using ublas::vector which I am not able to explain. Any information as to why this happens and how it can be prevented would be very appreciated. I have reproduced the issue in Compiler-Explorer:

https://godbolt.org/z/pknvaB

Description [Boost 1.73]:
Doing simple vector arithmetic on a fixed sized vec3, I get different (wrong) results using the "auto" keyword once any optimizations (anything other than -O0) are in place on GCC and MSVC. Clang does not have this problem. I attached the code used in Compiler-Explorer to this E-Mail.

Defining BOOST_UBLAS_SIMPLE_ET_DEBUG seems to also resolve the issue?

Is this the right spot to ask this question or should I post this to the Mailing List aswell?

Best,
Faaux

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>

 namespace ublas = boost::numeric::ublas;
 class vec3 : public ublas::vector<double, ublas::bounded_array<double,3> >
 {
    typedef ublas::vector<double, ublas::bounded_array<double,3> > Base_vector;
 public:
    // Default construction
    vec3 () : Base_vector(3)
    {}
    // Construction and assignment from a uBLAS vector expression or copy assignment
    template <class R> vec3 (const ublas::vector_expression<R>& r) : Base_vector(r)
    {}
    template <class R> void operator=(const ublas::vector_expression<R>& r)
    {
        Base_vector::operator=(r);
    }
    template <class R> void operator=(const Base_vector& r)
    {
        Base_vector::operator=(r);
    }
 };

int main () {
    vec3 v;
    v (0) = -0.5;
    v (1) = -0.5;
    v (2) = -0.5;

    vec3 b;
    b (0) = 0.5;
    b (1) = 0.5;
    b (2) = 0.5;

    auto impl = (b-v)*0.5;
    vec3 expl = (b-v)*0.5;
    std::cout << "AutoType     : " << impl << std::endl; // Returns (1.4822e-323,1.4822e-323,1.4822e-323) (GCC 10.1 -O2)
    std::cout << "Immediate    : " << (b-v)*0.5 << std::endl; // Returns (0.5,0.5,0.5) (GCC 10.1 -O2)
    std::cout << "Explicit vec3: " << expl << std::endl; // Returns (0.5,0.5,0.5) (GCC 10.1 -O2)
}

Compiler cannot perform small-object and other optimizations in algorithms.cpp

We are currently using std::function to recurse. It can be avoided by simply providing the trailing return type and passing the lambda through one of its arguments.
There is are two main disadvantages of using std::function:

  • Uses heap allocation if the compiler does not implement Small-Object Optimization ( May vary from compiler to compiler ).
  • It invokes the function through a function pointer that could hinder possible optimizations by the compiler.

Current implementation

ValueType accumulate(SizeType const p, SizeType const*const n,
           PointerIn a, SizeType const*const w,
           ValueType k)
{
...
  std::function<ValueType(SizeType r, PointerIn a, ValueType k)> lambda;

  lambda = [&lambda, n, w](SizeType r, PointerIn a, ValueType k)
  {
    if(r > 0u)
      for(auto d = 0u; d < n[r]; a += w[r], ++d)
        k = lambda(r-1, a, k);
    else
      for(auto d = 0u; d < n[0]; a += w[0], ++d)
        k += *a;
    return k;
  };

  return lambda( p-1, a,  k );
}

Improved implementation

ValueType accumulate(SizeType const p, SizeType const*const n,
           PointerIn a, SizeType const*const w,
           ValueType k)
{
...
  auto lambda = [n, w](auto const& self, SizeType r, PointerIn a, ValueType k)
    -> ValueType
  {
    if(r > 0u)
      for(auto d = 0u; d < n[r]; a += w[r], ++d)
        k = self(self,r-1, a, k);
    else
      for(auto d = 0u; d < n[0]; a += w[0], ++d)
        k += *a;
    return k;
  };

  return lambda(lambda, p-1, a,  k );
}

Add out of range exception to the static tensor

The static tensor does not check for out of range error, which makes the read and writes of invalid memory or segmentation fault easier.

auto t = tensor_static<float,extents<1,2,3>>{4.f};
t.at(1,2,3) = 10.f; // no exception triggered.

Crash in MSVC Debug mode caused by disabling of iterator debugging in vector_sparse.hpp

This was a tricky issue to find (from where I started)!

At the following line in code:

// https://msdn.microsoft.com/en-us/library/hh697468.aspx
the MSVC iterator debugging is temporarily switched off because it was causing issues when the sparse matrix was comparing iterators. The iterators are from different containers and the iterator debugging complains about this.

However this method of fixing causes real problems for the following reason.
_ITERATOR_DEBUG_LEVEL 2 results in a different definition of the std iterator classes (with extra members to enable debugging when it is temporarily disabled in this file we end up with two incompatible definitions and the potential (a reality in my case) for unexplained crashes in code very far from this library.

I have an alternative fix which uses the _Unwrapped() function (see https://devblogs.microsoft.com/cppblog/stl-features-and-fixes-in-vs-2017-15-8/) which allows access to an unchecked version of the iterators. I think this is the basis for a solution, but so far I have only fixed instances that were causing assertions in the unit tests (see below) and I don't know the code well enough to determine whether there are other cases (it looks like there could very well be). Also, I don't know coding guidelines well enough to know whether this should be refactored to avoid many #ifs in the code.

Review of this and a proper fix, very much appreciated :-)

Here is the basis of the suggested fix:

in vector_sparse.hpp remove the following preprocessor code:

#ifdef BOOST_MSVC
#define _BACKUP_ITERATOR_DEBUG_LEVEL _ITERATOR_DEBUG_LEVEL
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL 0
#endif

... and at end of the file, remove:

#ifdef BOOST_MSVC
#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL _BACKUP_ITERATOR_DEBUG_LEVEL
#undef _BACKUP_ITERATOR_DEBUG_LEVEL
#endif

in matrix_sparse.hpp make the following change to operator == () functions, as required (lines 2118, 2305 & 2517 fix the unit tests) :

#if defined BOOST_MSVC &&  defined _ITERATOR_DEBUG_LEVEL && _ITERATOR_DEBUG_LEVEL >= 2
                  return it_._Unwrapped() == it.it_._Unwrapped();
#else
                  return it_ == it.it_;
#endif

Include some Clang-Tidy checks

The configuration file excludes clang-tidy checks

google-readability-braces-around-statements
google-explicit-constructor
hicpp-vararg
cppcoreguidelines-pro-type-vararg

We should include them.

  • google-readability-braces-around-statements requires simple refactoring
  • google-explicit-constructor needs significant rework also in the test files and results in API change
  • hicpp-vararg needs usage of the boost lightweight unit test instead of the boost-test

Tests do not pass with current master branch in C++03 and C++14

The current master branch is what is being released in Boost 1.75 but these failures were also present in the Boost 1.74 release it seems.

C++20 was also failing but it passes now that I cherry-picked the allocator related fixes from develop to master. C++11 and C++17 pass.

Tensor examples in the documentation are not correct.

https://boostorg.github.io/ublas/
I checked this documentation link to try out some code examples and under this section https://boostorg.github.io/ublas/#tensor_idealogy
The code example given gives a build error on my system saying 'shape' is not defined. I have tried other examples and everything under vector and matrix works fine but everything under tensor gives an error. How can I fix this?

Originally posted by @harjot20022001 in #133 (reply in thread)

Error in Github Actions due to incorrect msvc toolset version

Github Actions reports an error due to incorrect msvc toolset version:

Run ilammy/msvc-dev-cmd@v1
  with:
    toolset: 14.28
    arch: x64
Found with vswhere: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat
Error: Could not setup Developer Command Prompt: invalid parameters
[ERROR:vcvars.bat] Toolset directory for version '14.28' was not found.

C++20: ‘class std::allocator’ has no member named ‘construct’

Taken from the -developers mailing list.

Problem description:
When compiling the following example:

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

int main () {
using namespace boost::numeric::ublas;
matrix m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
  for (unsigned j = 0; j < m.size2 (); ++ j)
    m (i, j) = 3 * i + j;
std::cout << m << std::endl;
}

with gcc-10 with -std=gnu++2a flag, compilation breaks
Running the same compilation line with -std=gnu++17 passes

boost build command lines:
./bootstrap.sh --prefix="${PWD}/../boost-bin"
./b2
./b2 install

Compiled on ubuntu 18.04, added gcc-10:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt install gcc-10 g++-10

Compilation error:
test_boost.cpp:9:27: required from here
/home/ubuntu/repos/cv-engine/externals/boost-bin/include/boost/numeric/ublas/storage.hpp:79:30: error: ‘class std::allocator’ has no member named ‘construct’
79 | alloc_.construct(d, value_type());

Initializer list constructor for vector

Initializer list constructors are not supported for ublas vector (error message from g++ 8):

 error: no matching function for call to 'boost::numeric::ublas::vector<double>::vector(<brace-enclosed initializer list>)'
     boost::numeric::ublas::vector<double> w{1,2,3,4,5,6,7};

It would be a convenient enhancement, and presumably easy to implement.

Deprecated copy constructor in C++17

In boost/libs/math/test/univariate_statistics_test.cpp, we see the following warning using g++-9:

../../../boost/numeric/ublas/detail/iterator.hpp:268:27: warning: implicitly-declared ‘constexpr boost::numeric::ublas::vector<int, boost::numeric::ublas::unbounded_array<int, std::allocator<int> > >::iterator::iterator(const boost::numeric::ublas::vector<int, boost::numeric::ublas::unbounded_array<int, std::allocator<int> > >::iterator&)’ is deprecated [-Wdeprecated-copy]
  268 |             return tmp -= n;

Test test3_mvov failed when running in clang and clang-cl on Windows

Hi,
I found that Test test3_mvov failed for map/set iterators incompatible in clang and clang-cl on Windows.
Below are the commands that I used.

clang test3.cpp -o test3.obj -std=c++17 -D_CRT_USE_BUILTIN_OFFSETOF -c -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -DUSE_DOUBLE -DUSE_FLOAT -DUSE_MAPPED_VECTOR_OF_MAPPED_VECTOR -DUSE_STD_COMPLEX -DUSE_STD_MAP -I"..\..\..\.."
clang test31.cpp -o test31.obj -std=c++17 -D_CRT_USE_BUILTIN_OFFSETOF -c -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -DUSE_DOUBLE -DUSE_FLOAT -DUSE_MAPPED_VECTOR_OF_MAPPED_VECTOR -DUSE_STD_COMPLEX -DUSE_STD_MAP -I"..\..\..\.."
clang test32.cpp -o test32.obj -std=c++17 -D_CRT_USE_BUILTIN_OFFSETOF -c -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -DUSE_DOUBLE -DUSE_FLOAT -DUSE_MAPPED_VECTOR_OF_MAPPED_VECTOR -DUSE_STD_COMPLEX -DUSE_STD_MAP -I"..\..\..\.."
clang test33.cpp -o test33.obj -std=c++17 -D_CRT_USE_BUILTIN_OFFSETOF -c -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -DUSE_DOUBLE -DUSE_FLOAT -DUSE_MAPPED_VECTOR_OF_MAPPED_VECTOR -DUSE_STD_COMPLEX -DUSE_STD_MAP -I"..\..\..\.."
clang -o test3 test3.obj test31.obj test32.obj test33.obj
./test3

I got lots of warnings when compiling test32.cpp and test33.cpp, which look like this.

In file included from test33.cpp:13:
In file included from ./test3.hpp:18:
In file included from ..\..\..\..\boost/numeric/ublas/vector.hpp:21:
In file included from ..\..\..\..\boost/numeric/ublas/storage.hpp:26:
In file included from ..\..\..\..\boost/numeric/ublas/traits.hpp:21:
..\..\..\..\boost/numeric/ublas/detail/iterator.hpp:149:21: warning: 'iterator<boost::numeric::ublas::sparse_bidirectional_iterator_tag, std::complex<double>, long long, std::complex<double> *, std::complex<double> &>' is deprecated: warning STL4015: The std::iterator
      class template (used as a base class to provide typedefs) is deprecated in C++17. (The <iterator> header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from
      std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define
      _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning. [-Wdeprecated-declarations]
        public std::iterator<IC, T> {
                    ^

And I also got the following output and a window which showed me the debug assertion failing message when running the exeutable file test3.

test_vector
test_matrix_vector
float mapped_vector_of_mapped_vector
row (m, 0) = [3](1,2,3)

As the warnings tell us, should the source code be modified to fix this issue?
Thanks!

Changing strides APIs to support custom order

Introducing new order custom_order which allows the user to add any type of strides other than column_major or row_major which makes the tensor more modular and gives a new customization point. To incorporate there needs to be a few changes in strides classes.

boost 1.73.0 - boost::numeric::ublas::matrix compilation issues with gcc-10 with c++20 support

Problem description:
When compiling the following example:
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

int main () {
using namespace boost::numeric::ublas;
matrix m (3, 3);
for (unsigned i = 0; i < m.size1 (); ++ i)
for (unsigned j = 0; j < m.size2 (); ++ j)
m (i, j) = 3 * i + j;
std::cout << m << std::endl;
}

with gcc-10 with -std=gnu++2a flag, compilation breaks
Running the same compilation line with -std=gnu++17 passes

boost build command lines:
./bootstrap.sh --prefix="${PWD}/../boost-bin"
./b2
./b2 install

Compiled on ubuntu 18.04, added gcc-10:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt install gcc-10 g++-10

Compilation error:
test_boost.cpp:9:27: required from here
boost-bin/include/boost/numeric/ublas/storage.hpp:79:30: error: ‘class std::allocator’ has no member named ‘construct’
79 | alloc_.construct(d, value_type());

Extension of lifetime within tensor expression templates for prvalues not guaranteed.

The current expression template implementation binds rvalue expressions to const references.
In such cases the lifetime of designated temporary objects are automatically extended due to prvalue to xvalue expression conversion, see also temporary materialization and value categorization.

In case of prvalue expressions such as 42 or 42+13, it seems that such a lifetime extension dos not work such that tensor expressions are not correctly evaluated although tensor expression objects are never copied. We suspect that this bug results from the mandatory copy elision rules as the prvalue is passed without materialization.

Possible fixes are

Invalid strides type for static extents of rank one

Right now, the static tensor gets confused about which strides type it should use for rank one extents because of the ambiguity between the extents_static_rank<4> and extents_static<4>. This ambiguity occurs because, behind the scene, they both are the specialization of the extents_core<...>.

When we create a static tensor of rank one, instead of choosing the strides from the extents_static, it chooses the strides from the extents_static_rank.

auto t = tensor_static<float, extents<2>>(); // error: no viable conversion from 'const array<[...], 1>' to 'const array<[...], 2UL aka 2>'

GCC ≥ 4.8 warns about unused local typedefs

Using gcc ≥ 4.8 causes a lot of warnings about unused local typedefs to be emitted, eg. (there may be more):

include/boost/numeric/ublas/triangular.hpp:1862:46: warning: typedef ‘difference_type’ locally defined but not used [-Wunused-local-typedefs]
include/boost/numeric/ublas/detail/matrix_assign.hpp:969:40: warning: typedef ‘value_type’ locally defined but not used [-Wunused-local-typedefs]
include/boost/numeric/ublas/detail/matrix_assign.hpp:1280:39: warning: typedef ‘size_type’ locally defined but not used [-Wunused-local-typedefs]

..and so on. This causes a lot of noise in compiler output

C++17 deprecates std::iterator

Compiling with Visual Studio 2017 with c++17 language flag set:

warning C4996: 'std::iterator<IC,T,ptrdiff_t,_Ty *,_Ty &>::iterator_category': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17.
Results from using one of the iterator base classes, e.g. random_access_iterator_base.

Not urgent as it is easy enough to suppress the warning, but I thought I'd note the issue since I don't see it here already.

Error when I run examples/tensor/simple_expressions.cpp

I am getting the following error when I run examples/tensor/simple_expressions.cpp

In file included from simple_expressions.cpp:13:
In file included from /usr/include/boost/numeric/ublas/tensor.hpp:18:
In file included from /usr/include/boost/numeric/ublas/tensor/functions.hpp:25:
/usr/include/boost/numeric/ublas/tensor/expression.hpp:148:20: error: no member named 'l' in '(lambda at
      /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:122:80)'
          : e(l.e), op(op.l) {}
                       ~~ ^
/usr/include/boost/numeric/ublas/tensor/expression.hpp:161:9: note: in instantiation of member function
      'boost::numeric::ublas::detail::unary_tensor_expression<boost::numeric::ublas::tensor<float, boost::numeric::ublas::basic_column_major<unsigned long, long>,
      std::vector<float, std::allocator<float> > >, boost::numeric::ublas::tensor<float, boost::numeric::ublas::basic_column_major<unsigned long, long>,
      std::vector<float, std::allocator<float> > >, (lambda at /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:122:80)>::unary_tensor_expression'
      requested here
        return unary_tensor_expression<T,E,OP>( e() , op);
               ^
/usr/include/boost/numeric/ublas/tensor/expression.hpp:148:20: error: no member named 'l' in '(lambda at
      /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:112:80)'
          : e(l.e), op(op.l) {}
                       ~~ ^
/usr/include/boost/numeric/ublas/tensor/expression.hpp:161:9: note: in instantiation of member function
      'boost::numeric::ublas::detail::unary_tensor_expression<boost::numeric::ublas::tensor<float, boost::numeric::ublas::basic_column_major<unsigned long, long>,
      std::vector<float, std::allocator<float> > >, boost::numeric::ublas::tensor<float, boost::numeric::ublas::basic_column_major<unsigned long, long>,
      std::vector<float, std::allocator<float> > >, (lambda at /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:112:80)>::unary_tensor_expression'
      requested here
        return unary_tensor_expression<T,E,OP>( e() , op);
               ^
/usr/include/boost/numeric/ublas/tensor/expression.hpp:148:20: error: no member named 'l' in '(lambda at
      /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:126:80)'
          : e(l.e), op(op.l) {}
                       ~~ ^
/usr/include/boost/numeric/ublas/tensor/expression.hpp:161:9: note: in instantiation of member function
      'boost::numeric::ublas::detail::unary_tensor_expression<boost::numeric::ublas::tensor<float, boost::numeric::ublas::basic_column_major<unsigned long, long>,
      std::vector<float, std::allocator<float> > >, boost::numeric::ublas::detail::unary_tensor_expression<boost::numeric::ublas::tensor<float,
      boost::numeric::ublas::basic_column_major<unsigned long, long>, std::vector<float, std::allocator<float> > >, boost::numeric::ublas::tensor<float,
      boost::numeric::ublas::basic_column_major<unsigned long, long>, std::vector<float, std::allocator<float> > >, (lambda at
      /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:112:80)>, (lambda at
      /usr/include/boost/numeric/ublas/tensor/operators_arithmetic.hpp:126:80)>::unary_tensor_expression' requested here
        return unary_tensor_expression<T,E,OP>( e() , op);
               ^
3 errors generated.

Use function call operator for indexing instead of at

Discussed in #141

Originally posted by bassoy October 21, 2021
Right now index accessing is performed using the at member function in tensor e.g. in tensor_dynamic, see also in example.

for(auto i = 0u; i < B.size(0); ++i)
  for(auto j = 0u; j < B.size(1); ++j)
        C.at(i,j) = std::conj(B.at(i,j));

Is it possible to overload operator() for this purpose? Note that operator() will also be used for creating subtensors.

for(auto i = 0u; i < B.size(0); ++i)
  for(auto j = 0u; j < B.size(1); ++j)
        C(i,j) = std::conj(B(i,j));

We could also use operator[] for accessing single indices and multi-indices.

for(auto i = 0u; i < B.size(0); ++i)
  for(auto j = 0u; j < B.size(1); ++j)
        C[i,j] = std::conj(B[i,j]);

This will be again closer to a Matlab or Octave or R notation.

uBLAS FAQ

I see the following question in the boost ublas link https://www.boost.org/doc/libs/1_76_0/libs/numeric/ublas/doc/index.html.
Down the page FAQ - 1
"Should I use uBLAS for new projects?
A: At the time of writing (09/2012) there are a lot of good matrix libraries available, e.g., MTL4, armadillo, eigen. uBLAS offers a stable, well tested set of vector and matrix classes, the typical operations for linear algebra and solvers for triangular systems of equations. uBLAS offers dense, structured and sparse matrices - all using similar interfaces. And finally uBLAS offers good (but not outstanding) performance. On the other side, the last major improvement of uBLAS was in 2008 and no significant change was committed since 2009. So one should ask himself some questions to aid the decision: Availability? uBLAS is part of boost and thus available in many environments. Easy to use? uBLAS is easy to use for simple things, but needs decent C++ knowledge when you leave the path. Performance? There are faster alternatives. Cutting edge? uBLAS is more than 10 years old and missed all new stuff from C++11."
Is there any effort being made to develop it further ?

Error when compiling tensor with NDEBUG

I'm compiling a simple program which includes the tensor.hpp header:

#include <boost/numeric/ublas/tensor.hpp>
#include <ostream>

int main()
{
    auto A = boost::numeric::ublas::tensor<float>{3,4,2};
    std::cout << "A=" << A << std::endl;
    return 0;
}

This works fine if I don't define NDEBUG. However, in release mode with (-DNDEBUG argument to the compiler), this fails:

In file included from /celibs/boost_1_72_0/boost/numeric/ublas/tensor.hpp:22,
                 from <source>:1:
/celibs/boost_1_72_0/boost/numeric/ublas/tensor/strides.hpp:215:9: error: expected unqualified-id before '<' token
  215 | template<class size_type, class layout_type>
      |         ^
/celibs/boost_1_72_0/boost/numeric/ublas/tensor/strides.hpp:223:2: error: expected ';' before 'inline'
  223 | }
      |  ^
      |  ;
In file included from /celibs/boost_1_72_0/boost/numeric/ublas/tensor.hpp:24,
                 from <source>:1:
/celibs/boost_1_72_0/boost/numeric/ublas/tensor/tensor.hpp:333:2: error: expected unqualified-id before 'template'
  333 |  template<class other_layout>
      |  ^~~~~~~~
/celibs/boost_1_72_0/boost/numeric/ublas/tensor/tensor.hpp:355:2: error: expected unqualified-id before 'template'
  355 |  template<class derived_type>
      |  ^~~~~~~~

...

As you can see in compiler explorer, this happens both on gcc 9.3 and clang 10.0.0 with these command-line options: -DNDEBUG -std=c++17

I also found that adding #define BOOST_UBLAS_INLINE before including tensor.hpp solves the compilation problem (but, of course, cancels inlining which probably hurts performance).

Am I using the wrong compilation options? ublas' documentation says I should define NDEBUG preprocessor symbol to get proper performance (release mode). I assume tensor was tested with -DNDEBUG and -O3 etc. BTW I think that the error reported in #79 might also be related to -DNDEBUG.

Modular Boost C++ Libraries Request

We are in the process of making B2 build changes to all of the B2 build files
to support "modular" consumption of the Boost Libraries by users. See this list
post for some details: https://lists.boost.org/Archives/boost/2024/01/255704.php

The process requires making a variety of changes to make each Boost library
independent of the super-project structure. But the changes do not remove the
super-project structure or the comprehensive Boost release. The changes make
solely make it possible, optionally, for users, like package manages, to easily
consume libraries individually.

Generally the changes include:

  • Adding a libroot/build.jam.
  • Porting any functionality from libroot/jamfile to libroot/build.jam.
  • Moving boost-install declaration from libroot/build/jamfile is applicable.
  • Adjusting other B2 build files in the library, like test/jamfile, as needed.
  • Possible changes to C++ source files to remove includes relative to the
    super-project boostroot location.

Some examples of such changes:

We are asking how you would like us to handle the changes. We would prefer if
you allow the owners of the Boost.org GitHub project to make changes to B2
build files, as needed, to accomplish the changes. But understand
that you may want to manage the proposed changes yourself.

We previously sent emails to all known maintainers to fill out a form with their
preference. We are contacting you in this issue as we have not gotten a response
to that email. You can see the ongoing responses for that form and the responses
to these issues here https://github.com/users/grafikrobot/projects/1/views/6

We are now asking if you can reply directly to this issue to indicate your
preference of handling the changes. Please supply a response to this question
and close the issue (so that we can verify you are a maintainer).

How would you like the build changes to be processed?

  1. Pull request, reviewed and merged by a BOOSTORG OWNER.
  2. Pull request, reviewed and merged by YOU.
  3. Other. (please specify details in the reply)

Also please indicate any special instructions you want us to consider. Or other
information you want us to be aware of.

Thanks you, René

Wrong implementation of copy constructor for the different type of layout

The dynamic and static rank tensors have a constructor, which takes the tensor of different layouts, implemented incorrectly with an unknown or unimplemented member function. To fix the issue, we have to use the copy algorithm, but instead, we are just copying the whole container, without considering the layout. Furthermore, we are not asserting or checking the type of the tensor if it matches the current tensor.

Current Implementation

  template<typename OTE>
  explicit inline tensor_core (const tensor_core<OTE> &other)
    : tensor_expression_type<self_type>{}
    , _extents  (ublas::begin(other.extents  ()), ublas::end (other.extents  ()))
    , _strides  (ublas::begin(other.extents  ()), ublas::end (other.extents  ()))
    , _container(  std::begin(other.container()),   std::end (other.container()))
  {
  }

To fix:

  • use the method tensor::base instead of unknown method tensor::container
  • use the copy algorithm from the boost/numeric/ublas/tensor/algorithm.hpp
  • static assert to check if the types are the same or not.

After the fix, enable the test that tests the construction of the other layout.

Adding different tensor tags

Tags

  • dynamic_shape
  • dynamic_layout
  • dynamic_storage
  • static_shape<Extents...>
  • static_layout<Layouts...>
  • static_storage
  • fixed_shape
  • fixed_layout

These tags will be used for custom tensor types

using my_tensor = tensor< tag::dynamic_shape, tag::static_layout<1,2,3>, tag::dynamic_storage>;

Transpose for Rank One Tensors

As of now, the rank one tensor does not allow to be transposed.

auto const n = extents<>{3};
auto a = tensor_dynamic{n, 1.f};
auto c = tensor_dynamic{n};
std::vector<std::size_t> pi{3};
ublas::trans( 1ul, n.data(), pi.data(), c.data(), c.strides().data(),    a.data(), res.strides().data() ); // c = [0,0,0]

Test placement_new.cpp failed in clang on Windows

Hi,
I found that test placement_new.cpp failed in clang on Windows.
I got 253 as the return value of the exetuable file after running following compiling command.

ksh-3.2$ clang placement_new.cpp -o placement_new.exe -std=c++17 -D_CRT_USE_BUILTIN_OFFSETOF -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -I"..\..\..\.."
ksh-3.2$ ./placement_new.exe
0,0
ksh-3.2$ echo $?
253

We can know that this is because macro BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW is not defined, but the value of array_new_offset is 0.
In addition, this test also failed in clang-cl like below but passed in cl on Windows.
So, is this an issue in the boost code or an bug in the clang compiler?

ksh-3.2$ cl placement_new.cpp -o placement_new.exe /std:c++17 -D_CRT_USE_BUILTIN_OFFSETOF -DBOOST_ALL_NO_LIB=1 -DBOOST_UBLAS_NO_EXCEPTIONS -I"..\..\..\.."
Microsoft (R) C/C++ Optimizing Compiler Version 19.22.27905 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release
placement_new.cpp
placement_new.cpp: warning C4117: macro name '_CRT_USE_BUILTIN_OFFSETOF' is reserved, '#define' ignored
c:/Program files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.22.27905/include\ostream(257): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
c:/Program files (x86)/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/14.22.27905/include\ostream(248): note: while compiling class template member function 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)'
placement_new.cpp(43): note: see reference to function template instantiation 'std::basic_ostream<char,std::char_traits<char>> &std::basic_ostream<char,std::char_traits<char>>::operator <<(int)' being compiled
placement_new.cpp(43): note: see reference to class template instantiation 'std::basic_ostream<char,std::char_traits<char>>' being compiled
Microsoft (R) Incremental Linker Version 14.22.27905.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:placement_new.exe
/out:placement_new.exe
placement_new.obj
ksh-3.2$ ./placement_new.exe
0,8
ksh-3.2$ echo $?
0

ublas::unbounded_array doesn't work with C++11 allocators

This produces a screenful of errors because you're not using std::allocator_traits to access members of the allocator, as required since C++11:

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <memory>

template <class Tp>
  struct SimpleAllocator
  {
    typedef Tp value_type;

    SimpleAllocator() noexcept { }

    template <class T>
      SimpleAllocator(const SimpleAllocator<T>&) { }

    Tp *allocate(std::size_t n)
    { return std::allocator<Tp>().allocate(n); }

    void deallocate(Tp *p, std::size_t n)
    { std::allocator<Tp>().deallocate(p, n); }
  };

template <class T, class U>
  bool operator==(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
  { return true; }
#if __cpp_impl_three_way_comparison < 201907L
template <class T, class U>
  bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
  { return false; }
#endif

int main ()
{
  using namespace boost::numeric::ublas;
  matrix<int, row_major, unbounded_array<int, SimpleAllocator<int>>> m (3, 3);
  for (unsigned i = 0; i < m.size1 (); ++ i)
  for (unsigned j = 0; j < m.size2 (); ++ j)
    m (i, j) = 3 * i + j;
  std::cout << m << std::endl;
}

See also #96 where the problem occurs even for std::allocator, and my comments on #100.

Wrong `to_strides_v` computation

The strides giving wrong strides for static extents, which is not consistent with the other extents types.

    namespace ublas = boost::numeric::ublas;
    using e_t = ublas::extents<2,2>;
    auto s = to_strides_v<e_t, ublas::layout::first_order>; // [1,2], but the right strides should be [1,1]

call to make_array() broke with boost update 1.63 -> 1.64

It seems that my viennacl build broke with boost version update 1.63 -> 1.64:

 In file included from /usr/include/boost/numeric/ublas/vector.hpp:21:0,
                  from /usr/include/boost/numeric/ublas/matrix.hpp:18,
                  from /usr/include/boost/numeric/ublas/triangular.hpp:16,
                  from /build/viennacl-dev-release-1.7.1/examples/tutorial/iterative-ublas.cpp:41:
 /usr/include/boost/numeric/ublas/storage.hpp: In member function 'void boost::numeric::ublas::unbounded_array<T, ALLOC>::serialize(Archive&, unsigned int)':
 /usr/include/boost/numeric/ublas/storage.hpp:299:18: error: 'make_array' is not a member of 'boost::serialization'
              ar & serialization::make_array(data_, s);
                   ^~~~~~~~~~~~~

Boost\libs\numeric\ublas failed to build due to error C2059, C2065, C2923, C2976, C2447 .... on MSVC

Issue Description:
Boost\libs\numeric\ublas failed to build due to error C2059, C2065, C2923, C2976, C2447 .... on MSVC. Could you please take a look? The master branch commit we used is a1552ab. Thanks.

Build Steps:

  1. git clone -c core.autocrlf=true --recursive ​https://github.com/boostorg/boost.git boost
  2. open a VS 2019 x86 command prompt and browse to boost
  3. .\bootstrap
  4. .\b2 headers variant=release --build-dir=..\out\x86rel address-model=32
  5. .\b2 variant=release --build-dir=..\out\x86rel address-model=32
  6. .\b2 -j16 variant=release --build-dir=..\out\x86rel libs\numeric\ublas\test

Error Info:
test_tensor.cpp
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(215): error C2059: syntax error: ''template<''
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2065: 'size_type': undeclared identifier
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2923: 'std::vector': 'size_type' is not a valid template type argument for parameter '_Ty'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): note: see declaration of 'size_type'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2976: 'std::vector': too few template arguments
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\vector(496): note: see declaration of 'std::vector'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2065: 'size_type': undeclared identifier
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2065: 'layout_type': undeclared identifier
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2923: 'boost::numeric::ublas::basic_strides': 'size_type' is not a valid template type argument for parameter '__int_type'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): note: see declaration of 'size_type'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): error C2923: 'boost::numeric::ublas::basic_strides': 'layout_type' is not a valid template type argument for parameter '__layout'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(216): note: see declaration of 'layout_type'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(217): error C2143: syntax error: missing ';' before '{'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(217): error C2447: '{': missing function header (old-style formal list?)
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(235): error C2059: syntax error: ''template<''
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(235): error C2059: syntax error: '...'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(236): error C2065: 'layout_type': undeclared identifier
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(236): error C2923: 'boost::numeric::ublas::basic_strides': 'layout_type' is not a valid template type argument for parameter '__layout'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(236): note: see declaration of 'layout_type'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(237): error C2143: syntax error: missing ';' before '{'
F:\gitP\boostorg\boost\boost\numeric\ublas\tensor\strides.hpp(237): error C2447: '{': missing function header (old-style formal list?)
.\boost/numeric/ublas/tensor/tensor.hpp(333): error C2059: syntax error: ''template<''
.\boost/numeric/ublas/tensor/tensor.hpp(726): note: see reference to class template instantiation 'boost::numeric::ublas::tensor<T,F,A>' being compiled
.\boost/numeric/ublas/tensor/tensor.hpp(334): error C2065: 'other_layout': undeclared identifier
.\boost/numeric/ublas/tensor/tensor.hpp(334): error C2923: 'boost::numeric::ublas::tensor': 'other_layout' is not a valid template type argument for parameter 'F'
.\boost/numeric/ublas/tensor/tensor.hpp(334): note: see declaration of 'other_layout'
.\boost/numeric/ublas/tensor/tensor.hpp(334): error C2976: 'boost::numeric::ublas::tensor': too few template arguments
.\boost/numeric/ublas/tensor/tensor.hpp(79): note: see declaration of 'boost::numeric::ublas::tensor'
.\boost/numeric/ublas/tensor/tensor.hpp(335): error C2334: unexpected token(s) preceding ':'; skipping apparent function body
.\boost/numeric/ublas/tensor/tensor.hpp(30): fatal error C1075: '{': no matching token found

Detailed log file:
test.log.8.log

Deprecated Inheritance From std::iterator Didn't Make It To Release

An UBLAS patch called: "Remove deprecated inheritance from std::iterator #97" didn't make it into the released version of Boost.

"std::iterator was deprecated in C++17 and removed in C++20. I replaced the inheritance with the 5 equivalent typedefs, even though they're not all used by ublas, for compatibility in case clients depend on them."

If I copy the file latest development version of the boost/numeric/ublas/detail/iterator.hpp into my boost directory it fixes the issue when building with VS 2019 C++20.

The fix was over 2 years ago and should have made it into Boost 1_75.

-Kurt

g++ 6.1 misleading indentation warning

This looks like a real error. The brace at the end of line 2227 of matrix_expression.hpp looks like it should properly be at line 2224.

/dev/boost/1_57_0/include/boost/numeric/ublas/matrix_expression.hpp: In member function ‘void boost::numeric::ublas::matrix_binary<E1, E2, F>::const_iterator1::increment(boost::numeric::ublas::sparse_bidirectional_iterator_tag)’:
/home/cmm/dev/boost/1_57_0/include/boost/numeric/ublas/matrix_expression.hpp:2224:17: error: this ‘if’ clause does not guard... [-Werror=misleading-indentation]
if (it2_ != it2_end_)
^~

ublas::matrix broken with compiler error with build 1.80 but not 1.63

Was trying to compile the following code and received the following error information.

Code:

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

int main()
{
    boost::numeric::ublas::matrix<double> u;

    u = u / norm_frobenius(u);  // u /= norm_frobenius(u) works

    return 0;
}

Error:

In file included from /opt/boost/boost/typeof/typeof.hpp:216,
                 from /opt/boost/boost/numeric/ublas/traits.hpp:29,
                 from /opt/boost/boost/numeric/ublas/storage.hpp:27,
                 from /opt/boost/boost/numeric/ublas/vector.hpp:21,
                 from /opt/boost/boost/numeric/ublas/matrix.hpp:18,
                 from example.cpp:1:
/opt/boost/boost/numeric/ublas/traits.hpp: In instantiation of ‘struct boost::numeric::ublas::promote_traits<double, boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > > >’:
/opt/boost/boost/numeric/ublas/functional.hpp:126:63:   required from ‘struct boost::numeric::ublas::scalar_binary_functor<double, boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > > >’
/opt/boost/boost/numeric/ublas/functional.hpp:166:12:   required from ‘struct boost::numeric::ublas::scalar_divides<double, boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > > >’
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:3491:34:   required from ‘class boost::numeric::ublas::matrix_binary_scalar2<boost::numeric::ublas::matrix<double>, const boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >, boost::numeric::ublas::scalar_divides<double, boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > > > >’
example.cpp:7:29:   required from here
/opt/boost/boost/numeric/ublas/traits.hpp:154:40: error: no matching function for call to ‘boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >::matrix_scalar_unary()’
  154 |         typedef BOOST_TYPEOF_TPL(X() + Y()) promote_type;
      |                                        ^~~
/opt/boost/boost/typeof/decltype.hpp:17:69: note: in definition of macro ‘BOOST_TYPEOF’
   17 | #define BOOST_TYPEOF(expr) boost::type_of::remove_cv_ref_t<decltype(expr)>
      |                                                                     ^~~~
/opt/boost/boost/numeric/ublas/traits.hpp:154:17: note: in expansion of macro ‘BOOST_TYPEOF_TPL’
  154 |         typedef BOOST_TYPEOF_TPL(X() + Y()) promote_type;
      |                 ^~~~~~~~~~~~~~~~
In file included from /opt/boost/boost/numeric/ublas/matrix.hpp:19,
                 from example.cpp:1:
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5637:11: note: candidate: ‘boost::numeric::ublas::matrix_scalar_unary<E, F>::matrix_scalar_unary(const expression_type&) [with E = boost::numeric::ublas::matrix<double>; F = boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> >; boost::numeric::ublas::matrix_scalar_unary<E, F>::expression_type = boost::numeric::ublas::matrix<double>]’
 5637 |  explicit matrix_scalar_unary (const expression_type &e):
      |           ^~~~~~~~~~~~~~~~~~~
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5637:11: note:   candidate expects 1 argument, 0 provided
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5627:7: note: candidate: ‘constexpr boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >::matrix_scalar_unary(const boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >&)’
 5627 | class matrix_scalar_unary:
      |       ^~~~~~~~~~~~~~~~~~~
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5627:7: note:   candidate expects 1 argument, 0 provided
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5627:7: note: candidate: ‘constexpr boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >::matrix_scalar_unary(boost::numeric::ublas::matrix_scalar_unary<boost::numeric::ublas::matrix<double>, boost::numeric::ublas::matrix_norm_frobenius<boost::numeric::ublas::matrix<double> > >&&)’
/opt/boost/boost/numeric/ublas/matrix_expression.hpp:5627:7: note:   candidate expects 1 argument, 0 provided

Fixing iteration-type of for-loop.

The current loops rely on auto deduction or integer suffix for the type that may not be a correct iteration type and may produce conversion warnings all over places. Therefore, I propose to remove auto from the loops and use appropriate and explicit types or use explicit types to initialize the variable. In a long run, it would produce a bug-free code, and it would remove all warnings produced by compilers.

From

for(auto d = 0u; d < t.size(); ++d)
{
...
}

To

for(auto d = size_type{0}; d < t.size(); ++d)
{
...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.