From 322b5b5874beb93ddeeec19f4e66ea23a667b632 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz>
Date: Sun, 7 Jul 2019 22:11:31 +0200
Subject: [PATCH] Reordering and optimizing tests in VectorTest to improve the
 compilation time

---
 src/UnitTests/Containers/VectorTest-1.h | 264 ++++++++++---
 src/UnitTests/Containers/VectorTest-2.h | 358 +++++++++++++-----
 src/UnitTests/Containers/VectorTest-3.h | 163 +++-----
 src/UnitTests/Containers/VectorTest-4.h | 474 +++++++-----------------
 src/UnitTests/Containers/VectorTest-5.h | 204 +++-------
 src/UnitTests/Containers/VectorTest-6.h | 399 +++-----------------
 src/UnitTests/Containers/VectorTest-7.h | 427 +++++++++++++++++----
 7 files changed, 1114 insertions(+), 1175 deletions(-)

diff --git a/src/UnitTests/Containers/VectorTest-1.h b/src/UnitTests/Containers/VectorTest-1.h
index 6ebb6eb212..c1a29f7895 100644
--- a/src/UnitTests/Containers/VectorTest-1.h
+++ b/src/UnitTests/Containers/VectorTest-1.h
@@ -13,23 +13,9 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
-// should be small enough to have fast tests, but larger than minGPUReductionDataSize
-// and large enough to require multiple CUDA blocks for reduction
-constexpr int VECTOR_TEST_SIZE = 5000;
+constexpr int VECTOR_TEST_SIZE = 100;
 
 TYPED_TEST( VectorTest, constructors )
 {
@@ -91,72 +77,231 @@ TYPED_TEST( VectorTest, constructors )
    EXPECT_EQ( a3.getElement( 2 ), 9 );
 }
 
-TYPED_TEST( VectorTest, max )
+TEST( VectorSpecialCasesTest, defaultConstructors )
+{
+   using ArrayType = Containers::Array< int, Devices::Host >;
+   using VectorViewType = VectorView< int, Devices::Host >;
+   using ArrayViewType = ArrayView< int, Devices::Host >;
+
+   ArrayType a( 100 );
+   a.setValue( 0 );
+
+   ArrayViewType a_view;
+   a_view.bind( a );
+
+   VectorViewType v_view;
+   v_view.bind( a );
+   EXPECT_EQ( v_view.getData(), a_view.getData() );
+}
+
+TEST( VectorSpecialCasesTest, assignmentThroughView )
+{
+   using VectorType = Containers::Vector< int, Devices::Host >;
+   using ViewType = VectorView< int, Devices::Host >;
+
+   static_assert( Algorithms::Details::HasSubscriptOperator< VectorType >::value, "Subscript operator detection by SFINAE does not work for Vector." );
+   static_assert( Algorithms::Details::HasSubscriptOperator< ViewType >::value, "Subscript operator detection by SFINAE does not work for VectorView." );
+
+   VectorType u( 100 ), v( 100 );
+   ViewType u_view( u ), v_view( v );
+
+   u.setValue( 42 );
+   v.setValue( 0 );
+   v_view = u_view;
+   EXPECT_EQ( u_view.getData(), u.getData() );
+   EXPECT_EQ( v_view.getData(), v.getData() );
+   for( int i = 0; i < 100; i++ )
+      EXPECT_EQ( v_view[ i ], 42 );
+
+   u.setValue( 42 );
+   v.setValue( 0 );
+   v_view = u;
+   EXPECT_EQ( u_view.getData(), u.getData() );
+   EXPECT_EQ( v_view.getData(), v.getData() );
+   for( int i = 0; i < 100; i++ )
+      EXPECT_EQ( v_view[ i ], 42 );
+}
+
+TEST( VectorSpecialCasesTest, operationsOnConstView )
+{
+   using VectorType = Containers::Vector< int, Devices::Host >;
+   using ViewType = VectorView< const int, Devices::Host >;
+
+   VectorType u( 100 ), v( 100 );
+   ViewType u_view( u ), v_view( v );
+
+   u.setValue( 1 );
+   v.setValue( 1 );
+
+   EXPECT_EQ( u_view.max(), 1 );
+   EXPECT_EQ( u_view.min(), 1 );
+   EXPECT_EQ( u_view.absMax(), 1 );
+   EXPECT_EQ( u_view.absMin(), 1 );
+   EXPECT_EQ( u_view.lpNorm( 1 ), 100 );
+   EXPECT_EQ( u_view.differenceMax( v_view ), 0 );
+   EXPECT_EQ( u_view.differenceMin( v_view ), 0 );
+   EXPECT_EQ( u_view.differenceAbsMax( v_view ), 0 );
+   EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 );
+   EXPECT_EQ( u_view.differenceLpNorm( v_view, 1 ), 0 );
+   EXPECT_EQ( u_view.differenceSum( v_view ), 0 );
+   EXPECT_EQ( u_view.scalarProduct( v_view ), 100 );
+}
+
+TEST( VectorSpecialCasesTest, initializationOfVectorViewByArrayView )
+{
+   using ArrayType = Containers::Array< int, Devices::Host >;
+   using VectorViewType = VectorView< const int, Devices::Host >;
+   using ArrayViewType = ArrayView< int, Devices::Host >;
+
+   ArrayType a( 100 );
+   a.setValue( 0 );
+   ArrayViewType a_view( a );
+
+   VectorViewType v_view( a_view );
+   EXPECT_EQ( v_view.getData(), a_view.getData() );
+   EXPECT_EQ( v_view.sum(), 0 );
+}
+
+TYPED_TEST( VectorTest, scalarMultiplication )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType v;
-   v.setSize( size );
-   ViewType v_view( v );
-   setLinearSequence( v );
+   VectorType u( size );
+   ViewType u_view( u );
+
+   typename VectorType::HostType expected;
+   expected.setSize( size );
+   for( int i = 0; i < size; i++ )
+      expected[ i ] = 2.0 * i;
+
+   setLinearSequence( u );
+   VectorOperations::vectorScalarMultiplication( u, 2.0 );
+   EXPECT_EQ( u, expected );
+
+   setLinearSequence( u );
+   u.scalarMultiplication( 2.0 );
+   EXPECT_EQ( u, expected );
+
+   setLinearSequence( u );
+   u_view.scalarMultiplication( 2.0 );
+   EXPECT_EQ( u, expected );
 
-   EXPECT_EQ( v.max(), size - 1 );
-   EXPECT_EQ( v_view.max(), size - 1 );
-   EXPECT_EQ( VectorOperations::getVectorMax( v ), size - 1 );
+   setLinearSequence( u );
+   u *= 2.0;
+   EXPECT_EQ( u, expected );
+
+   setLinearSequence( u );
+   u_view *= 2.0;
+   EXPECT_EQ( u, expected );
 }
 
-TYPED_TEST( VectorTest, min )
+TYPED_TEST( VectorTest, addVector )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType v;
-   v.setSize( size );
-   ViewType v_view( v );
-   setLinearSequence( v );
+   VectorType x, y;
+   x.setSize( size );
+   y.setSize( size );
+   ViewType x_view( x ), y_view( y );
+
+   typename VectorType::HostType expected1, expected2;
+   expected1.setSize( size );
+   expected2.setSize( size );
+   for( int i = 0; i < size; i++ ) {
+      expected1[ i ] = 2.0 + 3.0 * i;
+      expected2[ i ] = 1.0 + 3.0 * i;
+   }
 
-   EXPECT_EQ( v.min(), 0 );
-   EXPECT_EQ( v_view.min(), 0 );
-   EXPECT_EQ( VectorOperations::getVectorMin( v ), 0 );
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   VectorOperations::addVector( x, y, 3.0, 2.0 );
+   EXPECT_EQ( x, expected1 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   x.addVector( y, 3.0, 1.0 );
+   EXPECT_EQ( x, expected2 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   x_view.addVector( y_view, 3.0, 1.0 );
+   EXPECT_EQ( x, expected2 );
+
+   // multiplication by floating-point scalars which produces integer values
+   setConstantSequence( x, 2 );
+   setConstantSequence( y, 4 );
+   x.addVector( y, 2.5, -1.5 );
+   EXPECT_EQ( x.min(), 7 );
+   EXPECT_EQ( x.max(), 7 );
 }
 
-TYPED_TEST( VectorTest, absMax )
+TYPED_TEST( VectorTest, addVectors )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType v;
-   v.setSize( size );
-   ViewType v_view( v );
-   setNegativeLinearSequence( v );
+   VectorType x, y, z;
+   x.setSize( size );
+   y.setSize( size );
+   z.setSize( size );
+   ViewType x_view( x ), y_view( y ), z_view( z );
+
+   typename VectorType::HostType expected1, expected2;
+   expected1.setSize( size );
+   expected2.setSize( size );
+   for( int i = 0; i < size; i++ ) {
+      expected1[ i ] = 1.0 + 3.0 * i + 2.0;
+      expected2[ i ] = 2.0 + 3.0 * i + 2.0;
+   }
 
-   EXPECT_EQ( v.absMax(), size - 1 );
-   EXPECT_EQ( v_view.absMax(), size - 1 );
-   EXPECT_EQ( VectorOperations::getVectorAbsMax( v ), size - 1 );
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   setConstantSequence( z, 2 );
+   VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 );
+   EXPECT_EQ( x, expected1 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   setConstantSequence( z, 2 );
+   x.addVectors( y, 3.0, z, 1.0, 2.0 );
+   EXPECT_EQ( x, expected2 );
+
+   setConstantSequence( x, 1 );
+   setLinearSequence( y );
+   setConstantSequence( z, 2 );
+   x_view.addVectors( y_view, 3.0, z_view, 1.0, 2.0 );
+   EXPECT_EQ( x, expected2 );
+
+   // multiplication by floating-point scalars which produces integer values
+   setConstantSequence( x, 2 );
+   setConstantSequence( y, 4 );
+   setConstantSequence( z, 6 );
+   x.addVectors( y, 2.5, z, -1.5, -1.5 );
+   EXPECT_EQ( x.min(), -2 );
+   EXPECT_EQ( x.max(), -2 );
 }
 
-TYPED_TEST( VectorTest, absMin )
+TYPED_TEST( VectorTest, abs )
 {
    using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType v;
-   v.setSize( size );
-   ViewType v_view( v );
-   setNegativeLinearSequence( v );
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+      u.setElement( i, i );
 
-   EXPECT_EQ( v.absMin(), 0 );
-   EXPECT_EQ( v_view.absMin(), 0 );
-   EXPECT_EQ( VectorOperations::getVectorAbsMin( v ), 0 );
+   v = -u;
+   EXPECT_TRUE( abs( v ) == u );
 }
 
 TYPED_TEST( VectorTest, comparison )
@@ -176,7 +321,28 @@ TYPED_TEST( VectorTest, comparison )
    EXPECT_TRUE( w + 1.0 < v + 4.0 );
 }
 
+TYPED_TEST( VectorTest, horizontalOperations )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   using IndexType = typename VectorType::IndexType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size ), _w( size );
+   ViewType u( _u ), v( _v ), w( _w );
+   EXPECT_EQ( u.getSize(), size );
+   u = 0;
+   v = 1;
+   w = 2;
+
+   u = u + 4 * TNL::max( v, 0 );
+   EXPECT_TRUE( u.containsOnlyValue( 4.0 ) );
+
+   u = u + 3 * w + 4 * TNL::max( v, 0 );
+   EXPECT_TRUE( u.containsOnlyValue( 14.0 ) );
+}
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
diff --git a/src/UnitTests/Containers/VectorTest-2.h b/src/UnitTests/Containers/VectorTest-2.h
index bf60389f60..93a15168f5 100644
--- a/src/UnitTests/Containers/VectorTest-2.h
+++ b/src/UnitTests/Containers/VectorTest-2.h
@@ -13,141 +13,315 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction
-constexpr int VECTOR_TEST_SIZE = 5000;
+constexpr int VECTOR_TEST_SIZE = 10000;
 
-TYPED_TEST( VectorTest, lpNorm )
+TYPED_TEST( VectorTest, prefixSum )
 {
    using VectorType = typename TestFixture::VectorType;
-   using RealType = typename VectorType::RealType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   using DeviceType = typename VectorType::DeviceType;
+   using IndexType = typename VectorType::IndexType;
    const int size = VECTOR_TEST_SIZE;
-   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
 
-   VectorType v;
-   v.setSize( size );
+   if( std::is_same< RealType, float >::value ||
+       std::is_same< IndexType, short >::value )
+   return;
+
+   VectorType v( size );
    ViewType v_view( v );
+   typename VectorType::HostType v_host( size );
+
+   v = 0;
+   v_host = -1;
+   v.prefixSum();
+   v_host = v;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], 0 );
+
+   setLinearSequence( v );
+   v_host = -1;
+   v.prefixSum();
+   v_host = v;
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i );
+
    setConstantSequence( v, 1 );
+   v_host = -1;
+   v_view.prefixSum();
+   v_host = v_view;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], i + 1 );
+
+   v = 0;
+   v_host = -1;
+   v_view.prefixSum();
+   v_host = v_view;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], 0 );
+
+   setLinearSequence( v );
+   v_host = -1;
+   v_view.prefixSum();
+   v_host = v_view;
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i );
+
+   ////
+   // With CUDA, perform tests with multiple CUDA grids.
+   if( std::is_same< DeviceType, Devices::Cuda >::value )
+   {
+#ifdef HAVE_CUDA
+      Algorithms::CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::setMaxGridSize( 3 );
+      v = 0;
+      v_host = -1;
+      v.prefixSum();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], 0 );
+
+      setLinearSequence( v );
+      v_host = -1;
+      v.prefixSum();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v;
+      for( int i = 1; i < size; i++ )
+         EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i );
+
+      setConstantSequence( v, 1 );
+      v_host = -1;
+      v_view.prefixSum();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], i + 1 );
 
-   const RealType expectedL1norm = size;
-   const RealType expectedL2norm = std::sqrt( size );
-   const RealType expectedL3norm = std::cbrt( size );
-   EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm );
-   EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm );
-   EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon );
-   EXPECT_EQ( v_view.lpNorm( 1.0 ), expectedL1norm );
-   EXPECT_EQ( v_view.lpNorm( 2.0 ), expectedL2norm );
-   EXPECT_NEAR( v_view.lpNorm( 3.0 ), expectedL3norm, epsilon );
-   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 1.0 ), expectedL1norm );
-   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 2.0 ), expectedL2norm );
-   EXPECT_NEAR( VectorOperations::getVectorLpNorm( v, 3.0 ), expectedL3norm, epsilon );
+      v = 0;
+      v_host = -1;
+      v_view.prefixSum();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], 0 );
+
+      setLinearSequence( v );
+      v_host = -1;
+      v_view.prefixSum();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 1; i < size; i++ )
+         EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i );
+      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::resetMaxGridSize();
+#endif
+   }
 }
 
-TYPED_TEST( VectorTest, sum )
+TYPED_TEST( VectorTest, exclusivePrefixSum )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   // this test expect an even size
-   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
+   using RealType = typename VectorType::RealType;
+   using DeviceType = typename VectorType::DeviceType;
+   using IndexType = typename VectorType::IndexType;
+   const int size = VECTOR_TEST_SIZE;
+
+   if( std::is_same< RealType, float >::value ||
+       std::is_same< IndexType, short >::value )
+      return;
 
    VectorType v;
    v.setSize( size );
    ViewType v_view( v );
+   typename VectorType::HostType v_host( size );
 
    setConstantSequence( v, 1 );
-   EXPECT_EQ( v.sum(), size );
-   EXPECT_EQ( v_view.sum(), size );
-   EXPECT_EQ( VectorOperations::getVectorSum( v ), size );
+   v_host = -1;
+   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], i );
+
+   v.setValue( 0 );
+   v_host = -1;
+   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], 0 );
+
+   setLinearSequence( v );
+   v_host = -1;
+   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v;
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 );
+
+   setConstantSequence( v, 1 );
+   v_host = -1;
+   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v_view;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], i );
+
+   v.setValue( 0 );
+   v_host = -1;
+   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v_view;
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_host[ i ], 0 );
 
    setLinearSequence( v );
-   EXPECT_EQ( v.sum(), 0.5 * size * ( size - 1 ) );
-   EXPECT_EQ( v_view.sum(), 0.5 * size * ( size - 1 ) );
-   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0.5 * size * ( size - 1 ) );
-
-   setNegativeLinearSequence( v );
-   EXPECT_EQ( v.sum(), - 0.5 * size * ( size - 1 ) );
-   EXPECT_EQ( v_view.sum(), - 0.5 * size * ( size - 1 ) );
-   EXPECT_EQ( VectorOperations::getVectorSum( v ), - 0.5 * size * ( size - 1 ) );
-
-   setOscilatingSequence( v, 1.0 );
-   EXPECT_EQ( v.sum(), 0 );
-   EXPECT_EQ( v_view.sum(), 0 );
-   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0 );
+   v_host = -1;
+   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+   v_host = v_view;
+   for( int i = 1; i < size; i++ )
+      EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 );
+
+   ////
+   // With CUDA, perform tests with multiple CUDA grids.
+   if( std::is_same< DeviceType, Devices::Cuda >::value )
+   {
+#ifdef HAVE_CUDA
+      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::setMaxGridSize( 3 );
+
+      setConstantSequence( v, 1 );
+      v_host = -1;
+      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], i );
+
+      v.setValue( 0 );
+      v_host = -1;
+      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], 0 );
+
+      setLinearSequence( v );
+      v_host = -1;
+      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v;
+      for( int i = 1; i < size; i++ )
+         EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 );
+
+      setConstantSequence( v, 1 );
+      v_host = -1;
+      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], i );
+
+      v.setValue( 0 );
+      v_host = -1;
+      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_host[ i ], 0 );
+
+      setLinearSequence( v );
+      v_host = -1;
+      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
+      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
+      v_host = v_view;
+      for( int i = 1; i < size; i++ )
+         EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 );
+      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::resetMaxGridSize();
+#endif
+   }
 }
 
-TYPED_TEST( VectorTest, differenceMax )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
-   using ViewType = typename TestFixture::ViewType;
-   const int size = VECTOR_TEST_SIZE;
+// TODO: test prefix sum with custom begin and end parameters
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   setLinearSequence( u );
-   setConstantSequence( v, size / 2 );
 
-   EXPECT_EQ( u.differenceMax( v ), size - 1 - size / 2 );
-   EXPECT_EQ( u_view.differenceMax( v_view ), size - 1 - size / 2 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceMax( u, v ), size - 1 - size / 2 );
+template< typename FlagsView >
+void setupFlags( FlagsView& f )
+{
+   auto f1 = [] __cuda_callable__ ( typename FlagsView::IndexType i ) { return ( i % 5 ) == 0; };
+   f.evaluate( f1 );
 }
 
-TYPED_TEST( VectorTest, differenceMin )
+/*
+TYPED_TEST( VectorTest, segmentedPrefixSum )
 {
    using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   using DeviceType = typename VectorType::DeviceType;
+   using IndexType = typename VectorType::IndexType;
+   using FlagsArrayType = Array< bool, DeviceType, IndexType >;
+   using FlagsViewType = ArrayView< bool, DeviceType, IndexType >;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   setLinearSequence( u );
-   setConstantSequence( v, size / 2 );
-
-   EXPECT_EQ( u.differenceMin( v ), - size / 2 );
-   EXPECT_EQ( u_view.differenceMin( v_view ), - size / 2 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( u, v ), - size / 2 );
-   EXPECT_EQ( v.differenceMin( u ), size / 2 - size + 1 );
-   EXPECT_EQ( v_view.differenceMin( u_view ), size / 2 - size + 1 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( v, u ), size / 2 - size + 1 );
-}
+   VectorType v( size );
+   ViewType v_view( v );
 
-TYPED_TEST( VectorTest, differenceAbsMax )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
-   using ViewType = typename TestFixture::ViewType;
-   // this test expects an odd size
-   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
+   FlagsArrayType flags( size ), flags_copy( size );
+   FlagsViewType flags_view( flags );
+   //auto f1 = [] __cuda_callable__ ( IndexType i ) { return ( i % 5 ) == 0; };
+   //flags_view.evaluate( f1 );
+   setupFlags( flags_view );
+   flags_copy = flags_view;
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   setNegativeLinearSequence( u );
-   setConstantSequence( v, - size / 2 );
+   v = 0;
+   v.computeSegmentedPrefixSum( flags_view );
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v.getElement( i ), 0 );
+   flags_view = flags_copy;
 
-   EXPECT_EQ( u.differenceAbsMax( v ), size - 1 - size / 2 );
-   EXPECT_EQ( u_view.differenceAbsMax( v_view ), size - 1 - size / 2 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMax( u, v ), size - 1 - size / 2 );
-}
+   v = 1;
+   v.computeSegmentedPrefixSum( flags_view );
+   for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v.getElement( i ), ( i % 5 ) + 1 );
+   flags_view = flags_copy;
+
+   setLinearSequence( v );
+   v.computeSegmentedPrefixSum( flags_view );
+   for( int i = 1; i < size; i++ )
+   {
+      if( flags.getElement( i ) )
+         EXPECT_EQ( v.getElement( i ), i );
+      else
+         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
+   }
+   flags_view = flags_copy;
+
+   v_view = 0;
+   v_view.computeSegmentedPrefixSum( flags_view );
+   for( int i = 0; i < size; i++ )
+      EXPECT_EQ( v_view.getElement( i ), 0 );
+   flags_view = flags_copy;
 
+   v_view = 1;
+   v_view.computeSegmentedPrefixSum( flags_view );
+   for( int i = 0; i < size; i++ )
+         EXPECT_EQ( v_view.getElement( i ), ( i % 5 ) + 1 );
+   flags_view = flags_copy;
+
+   //v_view.evaluate( [] __cuda_callable__ ( IndexType i ) { return i; } );
+   setLinearSequence( v );
+   v_view.computeSegmentedPrefixSum( flags_view );
+   for( int i = 1; i < size; i++ )
+   {
+      if( flags.getElement( i ) )
+         EXPECT_EQ( v_view.getElement( i ), i );
+      else
+         EXPECT_EQ( v_view.getElement( i ) - v_view.getElement( i - 1 ), i );
+   }
+}
+*/
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
diff --git a/src/UnitTests/Containers/VectorTest-3.h b/src/UnitTests/Containers/VectorTest-3.h
index 6eae23b844..c857c9edd5 100644
--- a/src/UnitTests/Containers/VectorTest-3.h
+++ b/src/UnitTests/Containers/VectorTest-3.h
@@ -13,157 +13,106 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction
 constexpr int VECTOR_TEST_SIZE = 5000;
 
-TYPED_TEST( VectorTest, differenceAbsMin )
+TYPED_TEST( VectorTest, max )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   setNegativeLinearSequence( u );
-   setConstantSequence( v, - size / 2 );
-
-   EXPECT_EQ( u.differenceAbsMin( v ), 0 );
-   EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( u, v ), 0 );
-   EXPECT_EQ( v.differenceAbsMin( u ), 0 );
-   EXPECT_EQ( v_view.differenceAbsMin( u_view ), 0 );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( v, u ), 0 );
+   VectorType v;
+   v.setSize( size );
+   ViewType v_view( v );
+   setLinearSequence( v );
+
+   EXPECT_EQ( v.max(), size - 1 );
+   EXPECT_EQ( v_view.max(), size - 1 );
+   EXPECT_EQ( VectorOperations::getVectorMax( v ), size - 1 );
 }
 
-TYPED_TEST( VectorTest, differenceLpNorm )
+TYPED_TEST( VectorTest, min )
 {
    using VectorType = typename TestFixture::VectorType;
-   using RealType = typename VectorType::RealType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
-   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   u.setValue( 3.0 );
-   v.setValue( 1.0 );
-
-   const RealType expectedL1norm = 2.0 * size;
-   const RealType expectedL2norm = std::sqrt( 4.0 * size );
-   const RealType expectedL3norm = std::cbrt( 8.0 * size );
-   EXPECT_EQ( u.differenceLpNorm( v, 1.0 ), expectedL1norm );
-   EXPECT_EQ( u.differenceLpNorm( v, 2.0 ), expectedL2norm );
-   EXPECT_NEAR( u.differenceLpNorm( v, 3.0 ), expectedL3norm, epsilon );
-   EXPECT_EQ( u_view.differenceLpNorm( v_view, 1.0 ), expectedL1norm );
-   EXPECT_EQ( u_view.differenceLpNorm( v_view, 2.0 ), expectedL2norm );
-   EXPECT_NEAR( u_view.differenceLpNorm( v_view, 3.0 ), expectedL3norm, epsilon );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 1.0 ), expectedL1norm );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 2.0 ), expectedL2norm );
-   EXPECT_NEAR( VectorOperations::getVectorDifferenceLpNorm( u, v, 3.0 ), expectedL3norm, epsilon );
+   VectorType v;
+   v.setSize( size );
+   ViewType v_view( v );
+   setLinearSequence( v );
+
+   EXPECT_EQ( v.min(), 0 );
+   EXPECT_EQ( v_view.min(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorMin( v ), 0 );
 }
 
-TYPED_TEST( VectorTest, differenceSum )
+TYPED_TEST( VectorTest, absMax )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   // this test expect an even size
-   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
-
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   v.setValue( 1.0 );
-
-   setConstantSequence( u, 2 );
-   EXPECT_EQ( u.differenceSum( v ), size );
-   EXPECT_EQ( u_view.differenceSum( v_view ), size );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), size );
-
-   setLinearSequence( u );
-   EXPECT_EQ( u.differenceSum( v ), 0.5 * size * ( size - 1 ) - size );
-   EXPECT_EQ( u_view.differenceSum( v_view ), 0.5 * size * ( size - 1 ) - size );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), 0.5 * size * ( size - 1 ) - size );
-
-   setNegativeLinearSequence( u );
-   EXPECT_EQ( u.differenceSum( v ), - 0.5 * size * ( size - 1 ) - size );
-   EXPECT_EQ( u_view.differenceSum( v_view ), - 0.5 * size * ( size - 1 ) - size );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - 0.5 * size * ( size - 1 ) - size );
-
-   setOscilatingSequence( u, 1.0 );
-   EXPECT_EQ( u.differenceSum( v ), - size );
-   EXPECT_EQ( u_view.differenceSum( v_view ), - size );
-   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - size );
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType v;
+   v.setSize( size );
+   ViewType v_view( v );
+   setNegativeLinearSequence( v );
+
+   EXPECT_EQ( v.absMax(), size - 1 );
+   EXPECT_EQ( v_view.absMax(), size - 1 );
+   EXPECT_EQ( VectorOperations::getVectorAbsMax( v ), size - 1 );
 }
 
-TYPED_TEST( VectorTest, scalarMultiplication )
+TYPED_TEST( VectorTest, absMin )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType u( size );
-   ViewType u_view( u );
-
-   typename VectorType::HostType expected;
-   expected.setSize( size );
-   for( int i = 0; i < size; i++ )
-      expected[ i ] = 2.0 * i;
-
-   setLinearSequence( u );
-   VectorOperations::vectorScalarMultiplication( u, 2.0 );
-   EXPECT_EQ( u, expected );
-
-   setLinearSequence( u );
-   u.scalarMultiplication( 2.0 );
-   EXPECT_EQ( u, expected );
-
-   setLinearSequence( u );
-   u_view.scalarMultiplication( 2.0 );
-   EXPECT_EQ( u, expected );
+   VectorType v;
+   v.setSize( size );
+   ViewType v_view( v );
+   setNegativeLinearSequence( v );
 
-   setLinearSequence( u );
-   u *= 2.0;
-   EXPECT_EQ( u, expected );
-
-   setLinearSequence( u );
-   u_view *= 2.0;
-   EXPECT_EQ( u, expected );
+   EXPECT_EQ( v.absMin(), 0 );
+   EXPECT_EQ( v_view.absMin(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorAbsMin( v ), 0 );
 }
 
-TYPED_TEST( VectorTest, scalarProduct )
+TYPED_TEST( VectorTest, lpNorm )
 {
    using VectorType = typename TestFixture::VectorType;
+   using RealType = typename VectorType::RealType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   // this test expects an odd size
-   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
+   const int size = VECTOR_TEST_SIZE;
+   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
 
-   VectorType u( size ), v( size );
-   ViewType u_view( u ), v_view( v );
-   setOscilatingSequence( u, 1.0 );
+   VectorType v;
+   v.setSize( size );
+   ViewType v_view( v );
    setConstantSequence( v, 1 );
 
-   EXPECT_EQ( u.scalarProduct( v ), 1.0 );
-   EXPECT_EQ( u_view.scalarProduct( v_view ), 1.0 );
-   EXPECT_EQ( VectorOperations::getScalarProduct( u, v ), 1.0 );
+   const RealType expectedL1norm = size;
+   const RealType expectedL2norm = std::sqrt( size );
+   const RealType expectedL3norm = std::cbrt( size );
+   EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm );
+   EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm );
+   EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( v_view.lpNorm( 1.0 ), expectedL1norm );
+   EXPECT_EQ( v_view.lpNorm( 2.0 ), expectedL2norm );
+   EXPECT_NEAR( v_view.lpNorm( 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( VectorOperations::getVectorLpNorm( v, 3.0 ), expectedL3norm, epsilon );
 }
 
 #endif // HAVE_GTEST
diff --git a/src/UnitTests/Containers/VectorTest-4.h b/src/UnitTests/Containers/VectorTest-4.h
index 20650272e3..950d46ef6a 100644
--- a/src/UnitTests/Containers/VectorTest-4.h
+++ b/src/UnitTests/Containers/VectorTest-4.h
@@ -13,385 +13,175 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // Should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction.
-constexpr int VECTOR_TEST_SIZE = 10000;
-
-TYPED_TEST( VectorTest, addVector )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
-   using ViewType = typename TestFixture::ViewType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType x, y;
-   x.setSize( size );
-   y.setSize( size );
-   ViewType x_view( x ), y_view( y );
-
-   typename VectorType::HostType expected1, expected2;
-   expected1.setSize( size );
-   expected2.setSize( size );
-   for( int i = 0; i < size; i++ ) {
-      expected1[ i ] = 2.0 + 3.0 * i;
-      expected2[ i ] = 1.0 + 3.0 * i;
-   }
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   VectorOperations::addVector( x, y, 3.0, 2.0 );
-   EXPECT_EQ( x, expected1 );
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   x.addVector( y, 3.0, 1.0 );
-   EXPECT_EQ( x, expected2 );
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   x_view.addVector( y_view, 3.0, 1.0 );
-   EXPECT_EQ( x, expected2 );
-
-   // multiplication by floating-point scalars which produces integer values
-   setConstantSequence( x, 2 );
-   setConstantSequence( y, 4 );
-   x.addVector( y, 2.5, -1.5 );
-   EXPECT_EQ( x.min(), 7 );
-   EXPECT_EQ( x.max(), 7 );
-}
-
-TYPED_TEST( VectorTest, addVectors )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using VectorOperations = typename TestFixture::VectorOperations;
-   using ViewType = typename TestFixture::ViewType;
-   const int size = VECTOR_TEST_SIZE;
+constexpr int VECTOR_TEST_SIZE = 5000;
 
-   VectorType x, y, z;
-   x.setSize( size );
-   y.setSize( size );
-   z.setSize( size );
-   ViewType x_view( x ), y_view( y ), z_view( z );
-
-   typename VectorType::HostType expected1, expected2;
-   expected1.setSize( size );
-   expected2.setSize( size );
-   for( int i = 0; i < size; i++ ) {
-      expected1[ i ] = 1.0 + 3.0 * i + 2.0;
-      expected2[ i ] = 2.0 + 3.0 * i + 2.0;
-   }
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   setConstantSequence( z, 2 );
-   VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 );
-   EXPECT_EQ( x, expected1 );
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   setConstantSequence( z, 2 );
-   x.addVectors( y, 3.0, z, 1.0, 2.0 );
-   EXPECT_EQ( x, expected2 );
-
-   setConstantSequence( x, 1 );
-   setLinearSequence( y );
-   setConstantSequence( z, 2 );
-   x_view.addVectors( y_view, 3.0, z_view, 1.0, 2.0 );
-   EXPECT_EQ( x, expected2 );
-
-   // multiplication by floating-point scalars which produces integer values
-   setConstantSequence( x, 2 );
-   setConstantSequence( y, 4 );
-   setConstantSequence( z, 6 );
-   x.addVectors( y, 2.5, z, -1.5, -1.5 );
-   EXPECT_EQ( x.min(), -2 );
-   EXPECT_EQ( x.max(), -2 );
-}
-
-TYPED_TEST( VectorTest, prefixSum )
+TYPED_TEST( VectorTest, sum )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   using DeviceType = typename VectorType::DeviceType;
-   using IndexType = typename VectorType::IndexType;
-   const int size = VECTOR_TEST_SIZE;
+   // this test expect an even size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
 
-   if( std::is_same< RealType, float >::value ||
-       std::is_same< IndexType, short >::value )
-   return;
-
-   VectorType v( size );
+   VectorType v;
+   v.setSize( size );
    ViewType v_view( v );
 
-   v = 0;
-   v.prefixSum();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), 0 );
-
-   setLinearSequence( v );
-   v.prefixSum();
-   for( int i = 1; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
-
    setConstantSequence( v, 1 );
-   v_view.prefixSum();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), i + 1 );
-
-   v = 0;
-   v_view.prefixSum();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), 0 );
+   EXPECT_EQ( v.sum(), size );
+   EXPECT_EQ( v_view.sum(), size );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), size );
 
    setLinearSequence( v );
-   v_view.prefixSum();
-   for( int i = 1; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
-
-   ////
-   // With CUDA, perform tests with multiple CUDA grids.
-   if( std::is_same< DeviceType, Devices::Cuda >::value )
-   {
-#ifdef HAVE_CUDA
-      Algorithms::CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::setMaxGridSize( 3 );
-      v = 0;
-      v.prefixSum();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), 0 );
-
-      setLinearSequence( v );
-      v.prefixSum();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 1; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
-
-      setConstantSequence( v, 1 );
-      v_view.prefixSum();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), i + 1 );
-
-      v = 0;
-      v_view.prefixSum();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), 0 );
+   EXPECT_EQ( v.sum(), 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( v_view.sum(), 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0.5 * size * ( size - 1 ) );
+
+   setNegativeLinearSequence( v );
+   EXPECT_EQ( v.sum(), - 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( v_view.sum(), - 0.5 * size * ( size - 1 ) );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), - 0.5 * size * ( size - 1 ) );
+
+   setOscilatingSequence( v, 1.0 );
+   EXPECT_EQ( v.sum(), 0 );
+   EXPECT_EQ( v_view.sum(), 0 );
+   EXPECT_EQ( VectorOperations::getVectorSum( v ), 0 );
+}
 
-      setLinearSequence( v );
-      v_view.prefixSum();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 1; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
-      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::resetMaxGridSize();
-#endif
-   }
+TEST( VectorSpecialCasesTest, sumOfBoolVector )
+{
+   using VectorType = Containers::Vector< bool, Devices::Host >;
+   using ViewType = VectorView< bool, Devices::Host >;
+   const float epsilon = 64 * std::numeric_limits< float >::epsilon();
+
+   VectorType v( 512 ), w( 512 );
+   ViewType v_view( v ), w_view( w );
+   v.setValue( true );
+   w.setValue( false );
+
+   const int sum = v.sum< int >();
+   const int l1norm = v.lpNorm< int >( 1.0 );
+   const float l2norm = v.lpNorm< float >( 2.0 );
+   const float l3norm = v.lpNorm< float >( 3.0 );
+   EXPECT_EQ( sum, 512 );
+   EXPECT_EQ( l1norm, 512 );
+   EXPECT_NEAR( l2norm, std::sqrt( 512 ), epsilon );
+   EXPECT_NEAR( l3norm, std::cbrt( 512 ), epsilon );
+
+   const int diff_sum = v.differenceSum< int >( w );
+   const int diff_l1norm = v.differenceLpNorm< int >( w, 1.0 );
+   const float diff_l2norm = v.differenceLpNorm< float >( w, 2.0 );
+   const float diff_l3norm = v.differenceLpNorm< float >( w, 3.0 );
+   EXPECT_EQ( diff_sum, 512 );
+   EXPECT_EQ( diff_l1norm, 512 );
+   EXPECT_NEAR( diff_l2norm, std::sqrt( 512 ), epsilon );
+   EXPECT_NEAR( diff_l3norm, std::cbrt( 512 ), epsilon );
+
+   // test views
+   const int sum_view = v_view.sum< int >();
+   const int l1norm_view = v_view.lpNorm< int >( 1.0 );
+   const float l2norm_view = v_view.lpNorm< float >( 2.0 );
+   const float l3norm_view = v_view.lpNorm< float >( 3.0 );
+   EXPECT_EQ( sum_view, 512 );
+   EXPECT_EQ( l1norm_view, 512 );
+   EXPECT_NEAR( l2norm_view, std::sqrt( 512 ), epsilon );
+   EXPECT_NEAR( l3norm_view, std::cbrt( 512 ), epsilon );
+
+   const int diff_sum_view = v_view.differenceSum< int >( w_view );
+   const int diff_l1norm_view = v_view.differenceLpNorm< int >( w_view, 1.0 );
+   const float diff_l2norm_view = v_view.differenceLpNorm< float >( w_view, 2.0 );
+   const float diff_l3norm_view = v_view.differenceLpNorm< float >( w_view, 3.0 );
+   EXPECT_EQ( diff_sum_view, 512 );
+   EXPECT_EQ( diff_l1norm_view, 512 );
+   EXPECT_NEAR( diff_l2norm_view, std::sqrt( 512 ), epsilon );
+   EXPECT_NEAR( diff_l3norm_view, std::cbrt( 512 ), epsilon );
 }
 
-TYPED_TEST( VectorTest, exclusivePrefixSum )
+TYPED_TEST( VectorTest, scalarProduct )
 {
    using VectorType = typename TestFixture::VectorType;
    using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   using DeviceType = typename VectorType::DeviceType;
-   using IndexType = typename VectorType::IndexType;
-   const int size = VECTOR_TEST_SIZE;
-
-   if( std::is_same< RealType, float >::value ||
-       std::is_same< IndexType, short >::value )
-      return;
-
-   VectorType v;
-   v.setSize( size );
-   ViewType v_view( v );
-
-   setConstantSequence( v, 1 );
-   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), i );
-
-   v.setValue( 0 );
-   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), 0 );
-
-   setLinearSequence( v );
-   v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 1; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
+   // this test expects an odd size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
 
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   setOscilatingSequence( u, 1.0 );
    setConstantSequence( v, 1 );
-   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), i );
-
-   v.setValue( 0 );
-   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), 0 );
-
-   setLinearSequence( v );
-   v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-   for( int i = 1; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
-
-   ////
-   // With CUDA, perform tests with multiple CUDA grids.
-   if( std::is_same< DeviceType, Devices::Cuda >::value )
-   {
-#ifdef HAVE_CUDA
-      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::setMaxGridSize( 3 );
-
-      setConstantSequence( v, 1 );
-      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), i );
 
-      v.setValue( 0 );
-      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), 0 );
-
-      setLinearSequence( v );
-      v.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 1; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
-
-      setConstantSequence( v, 1 );
-      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), i );
-
-      v.setValue( 0 );
-      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), 0 );
-
-      setLinearSequence( v );
-      v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >();
-      EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1  );
-      for( int i = 1; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 );
-      CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::resetMaxGridSize();
-#endif
-   }
+   EXPECT_EQ( u.scalarProduct( v ), 1.0 );
+   EXPECT_EQ( u_view.scalarProduct( v_view ), 1.0 );
+   EXPECT_EQ( VectorOperations::getScalarProduct( u, v ), 1.0 );
+   EXPECT_EQ( (u, v), 1.0 );
+   EXPECT_EQ( (u_view, v_view), 1.0 );
 }
 
-
-template< typename FlagsView >
-void setupFlags( FlagsView& f )
-{
-   auto f1 = [] __cuda_callable__ ( typename FlagsView::IndexType i ) { return ( i % 5 ) == 0; };
-   f.evaluate( f1 );
-}
-
-/*
-TYPED_TEST( VectorTest, segmentedPrefixSum )
+TYPED_TEST( VectorTest, differenceLpNorm )
 {
    using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
    using RealType = typename VectorType::RealType;
-   using DeviceType = typename VectorType::DeviceType;
-   using IndexType = typename VectorType::IndexType;
-   using FlagsArrayType = Array< bool, DeviceType, IndexType >;
-   using FlagsViewType = ArrayView< bool, DeviceType, IndexType >;
+   using VectorOperations = typename TestFixture::VectorOperations;
+   using ViewType = typename TestFixture::ViewType;
    const int size = VECTOR_TEST_SIZE;
-
-   VectorType v( size );
-   ViewType v_view( v );
-
-   FlagsArrayType flags( size ), flags_copy( size );
-   FlagsViewType flags_view( flags );
-   //auto f1 = [] __cuda_callable__ ( IndexType i ) { return ( i % 5 ) == 0; };
-   //flags_view.evaluate( f1 );
-   setupFlags( flags_view );
-   flags_copy = flags_view;
-
-   v = 0;
-   v.computeSegmentedPrefixSum( flags_view );
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v.getElement( i ), 0 );
-   flags_view = flags_copy;
-
-   v = 1;
-   v.computeSegmentedPrefixSum( flags_view );
-   for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v.getElement( i ), ( i % 5 ) + 1 );
-   flags_view = flags_copy;
-
-   setLinearSequence( v );
-   v.computeSegmentedPrefixSum( flags_view );
-   for( int i = 1; i < size; i++ )
-   {
-      if( flags.getElement( i ) )
-         EXPECT_EQ( v.getElement( i ), i );
-      else
-         EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i );
-   }
-   flags_view = flags_copy;
-
-   v_view = 0;
-   v_view.computeSegmentedPrefixSum( flags_view );
-   for( int i = 0; i < size; i++ )
-      EXPECT_EQ( v_view.getElement( i ), 0 );
-   flags_view = flags_copy;
-
-   v_view = 1;
-   v_view.computeSegmentedPrefixSum( flags_view );
-   for( int i = 0; i < size; i++ )
-         EXPECT_EQ( v_view.getElement( i ), ( i % 5 ) + 1 );
-   flags_view = flags_copy;
-
-   //v_view.evaluate( [] __cuda_callable__ ( IndexType i ) { return i; } );
-   setLinearSequence( v );
-   v_view.computeSegmentedPrefixSum( flags_view );
-   for( int i = 1; i < size; i++ )
-   {
-      if( flags.getElement( i ) )
-         EXPECT_EQ( v_view.getElement( i ), i );
-      else
-         EXPECT_EQ( v_view.getElement( i ) - v_view.getElement( i - 1 ), i );
-   }
+   const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon();
+
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   u.setValue( 3.0 );
+   v.setValue( 1.0 );
+
+   const RealType expectedL1norm = 2.0 * size;
+   const RealType expectedL2norm = std::sqrt( 4.0 * size );
+   const RealType expectedL3norm = std::cbrt( 8.0 * size );
+   EXPECT_EQ( u.differenceLpNorm( v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( u.differenceLpNorm( v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( u.differenceLpNorm( v, 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( u_view.differenceLpNorm( v_view, 1.0 ), expectedL1norm );
+   EXPECT_EQ( u_view.differenceLpNorm( v_view, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( u_view.differenceLpNorm( v_view, 3.0 ), expectedL3norm, epsilon );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 1.0 ), expectedL1norm );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 2.0 ), expectedL2norm );
+   EXPECT_NEAR( VectorOperations::getVectorDifferenceLpNorm( u, v, 3.0 ), expectedL3norm, epsilon );
 }
-*/
 
-TYPED_TEST( VectorTest, abs )
+TYPED_TEST( VectorTest, differenceSum )
 {
    using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-      u.setElement( i, i );
-
-   v = -u;
-   EXPECT_TRUE( abs( v ) == u );
+   // this test expect an even size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE;
+
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   v.setValue( 1.0 );
+
+   setConstantSequence( u, 2 );
+   EXPECT_EQ( u.differenceSum( v ), size );
+   EXPECT_EQ( u_view.differenceSum( v_view ), size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), size );
+
+   setLinearSequence( u );
+   EXPECT_EQ( u.differenceSum( v ), 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( u_view.differenceSum( v_view ), 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), 0.5 * size * ( size - 1 ) - size );
+
+   setNegativeLinearSequence( u );
+   EXPECT_EQ( u.differenceSum( v ), - 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( u_view.differenceSum( v_view ), - 0.5 * size * ( size - 1 ) - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - 0.5 * size * ( size - 1 ) - size );
+
+   setOscilatingSequence( u, 1.0 );
+   EXPECT_EQ( u.differenceSum( v ), - size );
+   EXPECT_EQ( u_view.differenceSum( v_view ), - size );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - size );
 }
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
diff --git a/src/UnitTests/Containers/VectorTest-5.h b/src/UnitTests/Containers/VectorTest-5.h
index bff4c117bb..f2a53df10e 100644
--- a/src/UnitTests/Containers/VectorTest-5.h
+++ b/src/UnitTests/Containers/VectorTest-5.h
@@ -13,197 +13,87 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction
 constexpr int VECTOR_TEST_SIZE = 5000;
 
-TYPED_TEST( VectorTest, sin )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::sin( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( sin( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( sin( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, cos )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::cos( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( cos( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( cos( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, tan )
+TYPED_TEST( VectorTest, differenceMax )
 {
    using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
    const int size = VECTOR_TEST_SIZE;
-   const double h = 10.0 / size;
 
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      const RealType x = -5.0 + i * h;
-      u.setElement( i, x );
-      v.setElement( i, TNL::tan( x ) );
-   }
-
-   //EXPECT_EQ( tan( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( tan( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   setLinearSequence( u );
+   setConstantSequence( v, size / 2 );
 
+   EXPECT_EQ( u.differenceMax( v ), size - 1 - size / 2 );
+   EXPECT_EQ( u_view.differenceMax( v_view ), size - 1 - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMax( u, v ), size - 1 - size / 2 );
 }
 
-TYPED_TEST( VectorTest, sqrt )
+TYPED_TEST( VectorTest, differenceMin )
 {
    using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i );
-      v.setElement( i, TNL::sqrt( ( RealType ) i ) );
-   }
-
-   //EXPECT_EQ( sqrt( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( sqrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   setLinearSequence( u );
+   setConstantSequence( v, size / 2 );
+
+   EXPECT_EQ( u.differenceMin( v ), - size / 2 );
+   EXPECT_EQ( u_view.differenceMin( v_view ), - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( u, v ), - size / 2 );
+   EXPECT_EQ( v.differenceMin( u ), size / 2 - size + 1 );
+   EXPECT_EQ( v_view.differenceMin( u_view ), size / 2 - size + 1 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceMin( v, u ), size / 2 - size + 1 );
 }
 
-TYPED_TEST( VectorTest, cbrt )
+TYPED_TEST( VectorTest, differenceAbsMax )
 {
    using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i );
-      v.setElement( i, TNL::cbrt( ( RealType ) i ) );
-   }
+   // this test expects an odd size
+   const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1;
 
-   //EXPECT_EQ( cbrt( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( cbrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   setNegativeLinearSequence( u );
+   setConstantSequence( v, - size / 2 );
 
+   EXPECT_EQ( u.differenceAbsMax( v ), size - 1 - size / 2 );
+   EXPECT_EQ( u_view.differenceAbsMax( v_view ), size - 1 - size / 2 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMax( u, v ), size - 1 - size / 2 );
 }
 
-TYPED_TEST( VectorTest, pow )
+TYPED_TEST( VectorTest, differenceAbsMin )
 {
    using VectorType = typename TestFixture::VectorType;
+   using VectorOperations = typename TestFixture::VectorOperations;
    using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType _u( size ), _v( size ), _w( size );
-   ViewType u( _u ), v( _v ), w( _w );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 2.0 ) );
-      w.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 3.0 ) );
-   }
-
-   //EXPECT_EQ( pow( u, 2.0 ), v );
-   //EXPECT_EQ( pow( u, 3.0 ), w );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( pow( u, 2.0 ).getElement( i ), v.getElement( i ), 1.0e-6 );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( pow( u, 3.0 ).getElement( i ), w.getElement( i ), 1.0e-6 );
-
-
-}
-
-TYPED_TEST( VectorTest, floor )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::floor( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( floor( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( floor( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-
-}
-
-TYPED_TEST( VectorTest, ceil )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::ceil( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( ceil( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( ceil( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-
+   VectorType u( size ), v( size );
+   ViewType u_view( u ), v_view( v );
+   setNegativeLinearSequence( u );
+   setConstantSequence( v, - size / 2 );
+
+   EXPECT_EQ( u.differenceAbsMin( v ), 0 );
+   EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( u, v ), 0 );
+   EXPECT_EQ( v.differenceAbsMin( u ), 0 );
+   EXPECT_EQ( v_view.differenceAbsMin( u_view ), 0 );
+   EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( v, u ), 0 );
 }
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
diff --git a/src/UnitTests/Containers/VectorTest-6.h b/src/UnitTests/Containers/VectorTest-6.h
index c8e9d3d35e..6b04d4083f 100644
--- a/src/UnitTests/Containers/VectorTest-6.h
+++ b/src/UnitTests/Containers/VectorTest-6.h
@@ -13,367 +13,74 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction
-constexpr int VECTOR_TEST_SIZE = 5000;
-
-TYPED_TEST( VectorTest, acos )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType )( i - size / 2 ) / ( RealType ) size );
-      v.setElement( i, TNL::acos( ( RealType )( i - size / 2 ) / ( RealType ) size ) );
-   }
-
-   //EXPECT_EQ( acos( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( acos( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, asin )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) ( i - size / 2 ) / ( RealType ) size );
-      v.setElement( i, TNL::asin( ( RealType )( i - size / 2 ) / ( RealType ) size ) );
-   }
+constexpr int VECTOR_TEST_SIZE = 500;
 
-   //EXPECT_EQ( asin( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( asin( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, atan )
+TYPED_TEST( VectorTest, verticalOperations )
 {
    using VectorType = typename TestFixture::VectorType;
    using ViewType = typename TestFixture::ViewType;
    using RealType = typename VectorType::RealType;
+   using IndexType = typename VectorType::IndexType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
+   VectorType _u( size ), _v( size ), _w( size );
+   ViewType u( _u ), v( _v ), w( _w );
+   RealType sum_( 0.0 ), absSum( 0.0 ), diffSum( 0.0 ), diffAbsSum( 0.0 ),
+   absMin( size + 10.0 ), absMax( -size - 10.0 ),
+   diffMin( 2 * size + 10.0 ), diffMax( - 2.0 * size - 10.0 ),
+   l2Norm( 0.0 ), l2NormDiff( 0.0 ), argMinValue( size * size ), argMaxValue( -size * size );
+   IndexType argMin( 0 ), argMax( 0 );
    for( int i = 0; i < size; i++ )
    {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::atan( ( RealType ) i - ( RealType ) size / 2 ) );
+      const RealType aux = ( RealType )( i - size / 2 ) / ( RealType ) size;
+      const RealType w_value = aux * aux - 5.0;
+      u.setElement( i, aux );
+      v.setElement( i, -aux );
+      w.setElement( i, w_value );
+      absMin = TNL::min( absMin, TNL::abs( aux ) );
+      absMax = TNL::max( absMax, TNL::abs( aux ) );
+      diffMin = TNL::min( diffMin, 2 * aux );
+      diffMax = TNL::max( diffMax, 2 * aux );
+      sum_ += aux;
+      absSum += TNL::abs( aux );
+      diffSum += 2.0 * aux;
+      diffAbsSum += TNL::abs( 2.0* aux );
+      l2Norm += aux * aux;
+      l2NormDiff += 4.0 * aux * aux;
+      if( w_value < argMinValue ) {
+         argMinValue = w_value;
+         argMin = i;
+      }
+      if( w_value > argMaxValue ) {
+         argMaxValue = w_value;
+         argMax = i;
+      }
    }
-
-   //EXPECT_EQ( atan( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( atan( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, cosh )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   RealType h = 2.0 / ( RealType ) size;
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, i * h - ( RealType ) 1.0 );
-      v.setElement( i, TNL::cosh( i * h - ( RealType ) 1.0 ) );
-   }
-
-   // EXPECT_EQ( cosh( u ), v ) does not work here for float, maybe because
-   // of some fast-math optimization
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( cosh( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, tanh )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::tanh( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( tanh( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( tanh( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, log )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i + 1 );
-      v.setElement( i, TNL::log( ( RealType ) i + 1 ) );
-   }
-
-   //EXPECT_EQ( log( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( log( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-
-}
-
-TYPED_TEST( VectorTest, log10 )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i + 1 );
-      v.setElement( i, TNL::log10( ( RealType ) i + 1 ) );
-   }
-
-   // EXPECT_EQ( log10( u ), v ) does not work here for float, maybe because
-   // of some fast-math optimization
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( log10( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, log2 )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i + 1 );
-      v.setElement( i, TNL::log2( ( RealType ) i + 1 ) );
-   }
-
-   //EXPECT_EQ( log2( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( log2( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-
-}
-
-TYPED_TEST( VectorTest, exp )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-   const double h = 10.0 / size;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      const RealType x = -5.0 + i * h;
-      u.setElement( i, x  );
-      v.setElement( i, TNL::exp( x ) );
-   }
-
-   //EXPECT_EQ( exp( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( exp( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-TYPED_TEST( VectorTest, sign )
-{
-   using VectorType = typename TestFixture::VectorType;
-   using ViewType = typename TestFixture::ViewType;
-   using RealType = typename VectorType::RealType;
-   const int size = VECTOR_TEST_SIZE;
-
-   VectorType _u( size ), _v( size );
-   ViewType u( _u ), v( _v );
-   for( int i = 0; i < size; i++ )
-   {
-      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
-      v.setElement( i, TNL::sign( ( RealType ) i - ( RealType ) size / 2 ) );
-   }
-
-   //EXPECT_EQ( sign( u ), v );
-   for( int i = 0; i < size; i++ )
-      EXPECT_NEAR( sign( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
-}
-
-// TODO: test prefix sum with custom begin and end parameters
-
-TEST( VectorSpecialCasesTest, sumOfBoolVector )
-{
-   using VectorType = Containers::Vector< bool, Devices::Host >;
-   using ViewType = VectorView< bool, Devices::Host >;
-   const float epsilon = 64 * std::numeric_limits< float >::epsilon();
-
-   VectorType v( 512 ), w( 512 );
-   ViewType v_view( v ), w_view( w );
-   v.setValue( true );
-   w.setValue( false );
-
-   const int sum = v.sum< int >();
-   const int l1norm = v.lpNorm< int >( 1.0 );
-   const float l2norm = v.lpNorm< float >( 2.0 );
-   const float l3norm = v.lpNorm< float >( 3.0 );
-   EXPECT_EQ( sum, 512 );
-   EXPECT_EQ( l1norm, 512 );
-   EXPECT_NEAR( l2norm, std::sqrt( 512 ), epsilon );
-   EXPECT_NEAR( l3norm, std::cbrt( 512 ), epsilon );
-
-   const int diff_sum = v.differenceSum< int >( w );
-   const int diff_l1norm = v.differenceLpNorm< int >( w, 1.0 );
-   const float diff_l2norm = v.differenceLpNorm< float >( w, 2.0 );
-   const float diff_l3norm = v.differenceLpNorm< float >( w, 3.0 );
-   EXPECT_EQ( diff_sum, 512 );
-   EXPECT_EQ( diff_l1norm, 512 );
-   EXPECT_NEAR( diff_l2norm, std::sqrt( 512 ), epsilon );
-   EXPECT_NEAR( diff_l3norm, std::cbrt( 512 ), epsilon );
-
-   // test views
-   const int sum_view = v_view.sum< int >();
-   const int l1norm_view = v_view.lpNorm< int >( 1.0 );
-   const float l2norm_view = v_view.lpNorm< float >( 2.0 );
-   const float l3norm_view = v_view.lpNorm< float >( 3.0 );
-   EXPECT_EQ( sum_view, 512 );
-   EXPECT_EQ( l1norm_view, 512 );
-   EXPECT_NEAR( l2norm_view, std::sqrt( 512 ), epsilon );
-   EXPECT_NEAR( l3norm_view, std::cbrt( 512 ), epsilon );
-
-   const int diff_sum_view = v_view.differenceSum< int >( w_view );
-   const int diff_l1norm_view = v_view.differenceLpNorm< int >( w_view, 1.0 );
-   const float diff_l2norm_view = v_view.differenceLpNorm< float >( w_view, 2.0 );
-   const float diff_l3norm_view = v_view.differenceLpNorm< float >( w_view, 3.0 );
-   EXPECT_EQ( diff_sum_view, 512 );
-   EXPECT_EQ( diff_l1norm_view, 512 );
-   EXPECT_NEAR( diff_l2norm_view, std::sqrt( 512 ), epsilon );
-   EXPECT_NEAR( diff_l3norm_view, std::cbrt( 512 ), epsilon );
-}
-
-TEST( VectorSpecialCasesTest, assignmentThroughView )
-{
-   using VectorType = Containers::Vector< int, Devices::Host >;
-   using ViewType = VectorView< int, Devices::Host >;
-
-   static_assert( Algorithms::Details::HasSubscriptOperator< VectorType >::value, "Subscript operator detection by SFINAE does not work for Vector." );
-   static_assert( Algorithms::Details::HasSubscriptOperator< ViewType >::value, "Subscript operator detection by SFINAE does not work for VectorView." );
-
-   VectorType u( 100 ), v( 100 );
-   ViewType u_view( u ), v_view( v );
-
-   u.setValue( 42 );
-   v.setValue( 0 );
-   v_view = u_view;
-   EXPECT_EQ( u_view.getData(), u.getData() );
-   EXPECT_EQ( v_view.getData(), v.getData() );
-   for( int i = 0; i < 100; i++ )
-      EXPECT_EQ( v_view[ i ], 42 );
-
-   u.setValue( 42 );
-   v.setValue( 0 );
-   v_view = u;
-   EXPECT_EQ( u_view.getData(), u.getData() );
-   EXPECT_EQ( v_view.getData(), v.getData() );
-   for( int i = 0; i < 100; i++ )
-      EXPECT_EQ( v_view[ i ], 42 );
-}
-
-TEST( VectorSpecialCasesTest, operationsOnConstView )
-{
-   using VectorType = Containers::Vector< int, Devices::Host >;
-   using ViewType = VectorView< const int, Devices::Host >;
-
-   VectorType u( 100 ), v( 100 );
-   ViewType u_view( u ), v_view( v );
-
-   u.setValue( 1 );
-   v.setValue( 1 );
-
-   EXPECT_EQ( u_view.max(), 1 );
-   EXPECT_EQ( u_view.min(), 1 );
-   EXPECT_EQ( u_view.absMax(), 1 );
-   EXPECT_EQ( u_view.absMin(), 1 );
-   EXPECT_EQ( u_view.lpNorm( 1 ), 100 );
-   EXPECT_EQ( u_view.differenceMax( v_view ), 0 );
-   EXPECT_EQ( u_view.differenceMin( v_view ), 0 );
-   EXPECT_EQ( u_view.differenceAbsMax( v_view ), 0 );
-   EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 );
-   EXPECT_EQ( u_view.differenceLpNorm( v_view, 1 ), 0 );
-   EXPECT_EQ( u_view.differenceSum( v_view ), 0 );
-   EXPECT_EQ( u_view.scalarProduct( v_view ), 100 );
-}
-
-TEST( VectorSpecialCasesTest, initializationOfVectorViewByArrayView )
-{
-   using ArrayType = Containers::Array< int, Devices::Host >;
-   using VectorViewType = VectorView< const int, Devices::Host >;
-   using ArrayViewType = ArrayView< int, Devices::Host >;
-
-   ArrayType a( 100 );
-   a.setValue( 0 );
-   ArrayViewType a_view( a );
-
-   VectorViewType v_view( a_view );
-   EXPECT_EQ( v_view.getData(), a_view.getData() );
-   EXPECT_EQ( v_view.sum(), 0 );
-}
-
-TEST( VectorSpecialCasesTest, defaultConstructors )
-{
-   using ArrayType = Containers::Array< int, Devices::Host >;
-   using VectorViewType = VectorView< int, Devices::Host >;
-   using ArrayViewType = ArrayView< int, Devices::Host >;
-
-   ArrayType a( 100 );
-   a.setValue( 0 );
-
-   ArrayViewType a_view;
-   a_view.bind( a );
-
-   VectorViewType v_view;
-   v_view.bind( a );
-   EXPECT_EQ( v_view.getData(), a_view.getData() );
+   l2Norm = TNL::sqrt( l2Norm );
+   l2NormDiff = TNL::sqrt( l2NormDiff );
+
+   EXPECT_EQ( min( u ), u.getElement( 0 ) );
+   EXPECT_EQ( max( u ), u.getElement( size - 1 ) );
+   EXPECT_NEAR( sum( u ), sum_, 2.0e-5 );
+   EXPECT_EQ( min( abs( u ) ), absMin );
+   EXPECT_EQ( max( abs( u ) ), absMax );
+   EXPECT_EQ( min( u - v ), diffMin );
+   EXPECT_EQ( max( u - v ), diffMax );
+   EXPECT_NEAR( sum( u - v ), diffSum, 2.0e-5 );
+   EXPECT_NEAR( sum( abs( u - v ) ), diffAbsSum, 2.0e-5 );
+   EXPECT_NEAR( lpNorm( u, 2.0 ), l2Norm, 2.0e-5 );
+   EXPECT_NEAR( lpNorm( u - v, 2.0 ), l2NormDiff, 2.0e-5 );
+   IndexType wArgMin, wArgMax;
+   EXPECT_NEAR( TNL::argMin( w, wArgMin ), argMinValue, 2.0e-5 );
+   EXPECT_EQ( argMin, wArgMin );
+   EXPECT_NEAR( TNL::argMax( w, wArgMax ), argMaxValue, 2.0e-5 );
+   EXPECT_EQ( argMax, wArgMax );
 }
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
diff --git a/src/UnitTests/Containers/VectorTest-7.h b/src/UnitTests/Containers/VectorTest-7.h
index a8a6c145de..ecf6fabbf6 100644
--- a/src/UnitTests/Containers/VectorTest-7.h
+++ b/src/UnitTests/Containers/VectorTest-7.h
@@ -13,109 +13,144 @@
 #pragma once
 
 #ifdef HAVE_GTEST
-#include <limits>
-
-#include <TNL/Experimental/Arithmetics/Quad.h>
-#include <TNL/Containers/Vector.h>
-#include <TNL/Containers/VectorView.h>
 #include "VectorTestSetup.h"
 
-#include "gtest/gtest.h"
-
-using namespace TNL;
-using namespace TNL::Containers;
-using namespace TNL::Containers::Algorithms;
-using namespace TNL::Arithmetics;
-
 // should be small enough to have fast tests, but larger than minGPUReductionDataSize
 // and large enough to require multiple CUDA blocks for reduction
-constexpr int VECTOR_TEST_SIZE = 500;
+constexpr int VECTOR_TEST_SIZE = 100;
 
-TYPED_TEST( VectorTest, horizontalOperations )
+TYPED_TEST( VectorTest, sin )
 {
    using VectorType = typename TestFixture::VectorType;
    using ViewType = typename TestFixture::ViewType;
    using RealType = typename VectorType::RealType;
-   using IndexType = typename VectorType::IndexType;
    const int size = VECTOR_TEST_SIZE;
 
-   VectorType _u( size ), _v( size ), _w( size );
-   ViewType u( _u ), v( _v ), w( _w );
-   EXPECT_EQ( u.getSize(), size );
-   u = 0;
-   v = 1;
-   w = 2;
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::sin( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
+
+   //EXPECT_EQ( sin( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( sin( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, cos )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
 
-   u = u + 4 * TNL::max( v, 0 );
-   EXPECT_TRUE( u.containsOnlyValue( 4.0 ) );
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::cos( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
 
-   u = u + 3 * w + 4 * TNL::max( v, 0 );
-   EXPECT_TRUE( u.containsOnlyValue( 14.0 ) );
+   //EXPECT_EQ( cos( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( cos( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
 }
 
-TYPED_TEST( VectorTest, verticalOperations )
+TYPED_TEST( VectorTest, tan )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+   const double h = 10.0 / size;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      const RealType x = -5.0 + i * h;
+      u.setElement( i, x );
+      v.setElement( i, TNL::tan( x ) );
+   }
+
+   //EXPECT_EQ( tan( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( tan( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, sqrt )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i );
+      v.setElement( i, TNL::sqrt( ( RealType ) i ) );
+   }
+
+   //EXPECT_EQ( sqrt( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( sqrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, cbrt )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i );
+      v.setElement( i, TNL::cbrt( ( RealType ) i ) );
+   }
+
+   //EXPECT_EQ( cbrt( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( cbrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, pow )
 {
    using VectorType = typename TestFixture::VectorType;
    using ViewType = typename TestFixture::ViewType;
    using RealType = typename VectorType::RealType;
-   using IndexType = typename VectorType::IndexType;
    const int size = VECTOR_TEST_SIZE;
 
    VectorType _u( size ), _v( size ), _w( size );
    ViewType u( _u ), v( _v ), w( _w );
-   RealType sum_( 0.0 ), absSum( 0.0 ), diffSum( 0.0 ), diffAbsSum( 0.0 ),
-   absMin( size + 10.0 ), absMax( -size - 10.0 ),
-   diffMin( 2 * size + 10.0 ), diffMax( - 2.0 * size - 10.0 ),
-   l2Norm( 0.0 ), l2NormDiff( 0.0 ), argMinValue( size * size ), argMaxValue( -size * size );
-   IndexType argMin( 0 ), argMax( 0 );
    for( int i = 0; i < size; i++ )
    {
-      const RealType aux = ( RealType )( i - size / 2 ) / ( RealType ) size;
-      const RealType w_value = aux * aux - 5.0;
-      u.setElement( i, aux );
-      v.setElement( i, -aux );
-      w.setElement( i, w_value );
-      absMin = TNL::min( absMin, TNL::abs( aux ) );
-      absMax = TNL::max( absMax, TNL::abs( aux ) );
-      diffMin = TNL::min( diffMin, 2 * aux );
-      diffMax = TNL::max( diffMax, 2 * aux );
-      sum_ += aux;
-      absSum += TNL::abs( aux );
-      diffSum += 2.0 * aux;
-      diffAbsSum += TNL::abs( 2.0* aux );
-      l2Norm += aux * aux;
-      l2NormDiff += 4.0 * aux * aux;
-      if( w_value < argMinValue ) {
-         argMinValue = w_value;
-         argMin = i;
-      }
-      if( w_value > argMaxValue ) {
-         argMaxValue = w_value;
-         argMax = i;
-      }
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 2.0 ) );
+      w.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 3.0 ) );
    }
-   l2Norm = TNL::sqrt( l2Norm );
-   l2NormDiff = TNL::sqrt( l2NormDiff );
 
-   EXPECT_EQ( min( u ), u.getElement( 0 ) );
-   EXPECT_EQ( max( u ), u.getElement( size - 1 ) );
-   EXPECT_NEAR( sum( u ), sum_, 2.0e-5 );
-   EXPECT_EQ( min( abs( u ) ), absMin );
-   EXPECT_EQ( max( abs( u ) ), absMax );
-   EXPECT_EQ( min( u - v ), diffMin );
-   EXPECT_EQ( max( u - v ), diffMax );
-   EXPECT_NEAR( sum( u - v ), diffSum, 2.0e-5 );
-   EXPECT_NEAR( sum( abs( u - v ) ), diffAbsSum, 2.0e-5 );
-   EXPECT_NEAR( lpNorm( u, 2.0 ), l2Norm, 2.0e-5 );
-   EXPECT_NEAR( lpNorm( u - v, 2.0 ), l2NormDiff, 2.0e-5 );
-   IndexType wArgMin, wArgMax;
-   EXPECT_NEAR( TNL::argMin( w, wArgMin ), argMinValue, 2.0e-5 );
-   EXPECT_EQ( argMin, wArgMin );
-   EXPECT_NEAR( TNL::argMax( w, wArgMax ), argMaxValue, 2.0e-5 );
-   EXPECT_EQ( argMax, wArgMax );
+   //EXPECT_EQ( pow( u, 2.0 ), v );
+   //EXPECT_EQ( pow( u, 3.0 ), w );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( pow( u, 2.0 ).getElement( i ), v.getElement( i ), 1.0e-6 );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( pow( u, 3.0 ).getElement( i ), w.getElement( i ), 1.0e-6 );
+
+
 }
 
-TYPED_TEST( VectorTest, scalarProduct )
+TYPED_TEST( VectorTest, floor )
 {
    using VectorType = typename TestFixture::VectorType;
    using ViewType = typename TestFixture::ViewType;
@@ -124,18 +159,246 @@ TYPED_TEST( VectorTest, scalarProduct )
 
    VectorType _u( size ), _v( size );
    ViewType u( _u ), v( _v );
-   RealType aux( 0.0 );
    for( int i = 0; i < size; i++ )
    {
-      const RealType x = i;
-      const RealType y = size / 2 - i;
-      u.setElement( i, x );
-      v.setElement( i, y );
-      aux += x * y;
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::floor( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
+
+   //EXPECT_EQ( floor( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( floor( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, ceil )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::ceil( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
+
+   //EXPECT_EQ( ceil( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( ceil( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, acos )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType )( i - size / 2 ) / ( RealType ) size );
+      v.setElement( i, TNL::acos( ( RealType )( i - size / 2 ) / ( RealType ) size ) );
+   }
+
+   //EXPECT_EQ( acos( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( acos( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, asin )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) ( i - size / 2 ) / ( RealType ) size );
+      v.setElement( i, TNL::asin( ( RealType )( i - size / 2 ) / ( RealType ) size ) );
+   }
+
+   //EXPECT_EQ( asin( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( asin( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, atan )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::atan( ( RealType ) i - ( RealType ) size / 2 ) );
    }
-   EXPECT_NEAR( ( u, v ), aux, 1.0e-5 );
+
+   //EXPECT_EQ( atan( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( atan( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, cosh )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   RealType h = 2.0 / ( RealType ) size;
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, i * h - ( RealType ) 1.0 );
+      v.setElement( i, TNL::cosh( i * h - ( RealType ) 1.0 ) );
+   }
+
+   // EXPECT_EQ( cosh( u ), v ) does not work here for float, maybe because
+   // of some fast-math optimization
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( cosh( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, tanh )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::tanh( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
+
+   //EXPECT_EQ( tanh( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( tanh( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, log )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i + 1 );
+      v.setElement( i, TNL::log( ( RealType ) i + 1 ) );
+   }
+
+   //EXPECT_EQ( log( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( log( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, log10 )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i + 1 );
+      v.setElement( i, TNL::log10( ( RealType ) i + 1 ) );
+   }
+
+   // EXPECT_EQ( log10( u ), v ) does not work here for float, maybe because
+   // of some fast-math optimization
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( log10( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, log2 )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i + 1 );
+      v.setElement( i, TNL::log2( ( RealType ) i + 1 ) );
+   }
+
+   //EXPECT_EQ( log2( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( log2( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+
+}
+
+TYPED_TEST( VectorTest, exp )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+   const double h = 10.0 / size;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      const RealType x = -5.0 + i * h;
+      u.setElement( i, x  );
+      v.setElement( i, TNL::exp( x ) );
+   }
+
+   //EXPECT_EQ( exp( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( exp( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
+}
+
+TYPED_TEST( VectorTest, sign )
+{
+   using VectorType = typename TestFixture::VectorType;
+   using ViewType = typename TestFixture::ViewType;
+   using RealType = typename VectorType::RealType;
+   const int size = VECTOR_TEST_SIZE;
+
+   VectorType _u( size ), _v( size );
+   ViewType u( _u ), v( _v );
+   for( int i = 0; i < size; i++ )
+   {
+      u.setElement( i, ( RealType ) i - ( RealType ) size / 2 );
+      v.setElement( i, TNL::sign( ( RealType ) i - ( RealType ) size / 2 ) );
+   }
+
+   //EXPECT_EQ( sign( u ), v );
+   for( int i = 0; i < size; i++ )
+      EXPECT_NEAR( sign( u ).getElement( i ), v.getElement( i ), 1.0e-6 );
 }
 
 #endif // HAVE_GTEST
 
-#include "../main.h"
\ No newline at end of file
+#include "../main.h"
-- 
GitLab