Wiki
Clone wikiblaze / Vector Types
Dense Vectors
StaticVector
The blaze::StaticVector
class template is the representation of a fixed size vector with statically allocated elements of arbitrary type. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/StaticVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the number of elements, the transpose flag, the alignment, the padding, and the group tag of the vector can be specified via the six template parameters:
namespace blaze {
template< typename Type, size_t N, bool TF, AlignmentFlag AF, PaddingFlag PF, typename Tag >
class StaticVector;
} // namespace blaze
Type
: specifies the type of the vector elements.StaticVector
can be used with any non-cv-qualified element type, including other vector or matrix types.N
: specifies the total number of vector elements. It is expected thatStaticVector
is only used for tiny and small vectors.TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.AF
: specifies whether the first element of the vector is properly aligned with respect to the available instruction set (SSE, AVX, ...). Possible values areblaze::aligned
andblaze::unaligned
. The default value isblaze::defaultAlignmentFlag
.PF
: specifies whether the vector should be padded to maximize the efficiency of vectorized operations. Possible values areblaze::padded
andblaze::unpadded
. The default value isblaze::defaultPaddingFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::StaticVector
is perfectly suited for small to medium vectors whose size is known at compile time:
// Definition of a 3-dimensional integral column vector
blaze::StaticVector<int,3UL> a;
// Definition of a 4-dimensional single precision column vector
blaze::StaticVector<float,4UL,blaze::columnVector> b;
// Definition of an unaligned, unpadded 6-dimensional double precision row vector
blaze::StaticVector<double,6UL,blaze::rowVector,blaze::unaligned,blaze::unpadded> c;
Alignment
In case AF
is set to blaze::aligned
, the elements of a StaticVector
are possibly over-aligned to meet the alignment requirements of the available instruction set (SSE, AVX, AVX-512, ...). The alignment for fundamental types (short
, int
, float
, double
, ...) and complex types (complex<float>
, complex<double>
, ...) is 16 bytes for SSE, 32 bytes for AVX, and 64 bytes for AVX-512. All other types are aligned according to their intrinsic alignment:
struct Int { int i; };
using VT1 = blaze::StaticVector<double,3UL>;
using VT2 = blaze::StaticVector<complex<float>,2UL>;
using VT3 = blaze::StaticVector<Int,5UL>;
alignof( VT1 ); // Evaluates to 16 for SSE, 32 for AVX, and 64 for AVX-512
alignof( VT2 ); // Evaluates to 16 for SSE, 32 for AVX, and 64 for AVX-512
alignof( VT3 ); // Evaluates to 'alignof( Int )'
Note that an aligned StaticVector
instance may be bigger than the sum of its data elements:
sizeof( VT1 ); // Evaluates to 32 for both SSE and AVX
sizeof( VT2 ); // Evaluates to 16 for SSE and 32 for AVX
sizeof( VT3 ); // Evaluates to 20; no special alignment requirements
Please note that for this reason an aligned StaticVector
cannot be used in containers using dynamic memory such as std::vector
without additionally providing an allocator that can provide over-aligned memory:
using Type = blaze::StaticVector<double,3UL>;
using Allocator = blaze::AlignedAllocator<Type>;
std::vector<Type> v1; // Might be misaligned for AVX or AVX-512
std::vector<Type,Allocator> v2; // Properly aligned for AVX or AVX-512
Padding
Adding padding elements to the end of a StaticVector
can have a significant impact on the performance. For instance, assuming that AVX is available, then two padded 3-dimensional vectors of double precision values can be added via a single SIMD addition operation:
using blaze::StaticVector;
using blaze::columnVector;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;
StaticVector<double,3UL,columnVector,aligned,padded> a1, b1, c1;
StaticVector<double,3UL,columnVector,unaligned,unpadded> a2, b2, c2;
// ... Initialization
c1 = a1 + b1; // AVX-based vector addition; maximum performance
c2 = a2 + b2; // Scalar vector addition; limited performance
sizeof( a1 ); // Evaluates to 32 for SSE and AVX, and 64 for AVX-512
sizeof( a2 ); // Evaluates to 24 for SSE, AVX, and AVX-512 (minimum size)
Due to padding, the first addition will run at maximum performance. On the flip side, the size of each vector instance is increased due to the padding elements. The total size of an instance depends on the number of elements and width of the available instruction set (16 bytes for SSE, 32 bytes for AVX, and 64 bytes for AVX-512).
The second addition will be limited in performance since due to the number of elements some of the elements need to be handled in a scalar operation. However, the size of an unaligned
, unpadded
StaticVector
instance is guaranteed to be the sum of its elements.
Please also note that Blaze will zero initialize the padding elements in order to achieve maximum performance!
DynamicVector
The blaze::DynamicVector
class template is the representation of an arbitrarily sized vector with dynamically allocated elements of arbitrary type. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/DynamicVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the transpose flag, the type of the allocator, and the group tag of the vector can be specified via the three template parameters:
namespace blaze {
template< typename Type, bool TF, typename Alloc, typename Tag >
class DynamicVector;
} // namespace blaze
Type
: specifies the type of the vector elements.DynamicVector
can be used with any non-cv-qualified element type, including other vector or matrix types.TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.Alloc
: specifies the type of allocator used to allocate dynamic memory. The default type of allocator isblaze::AlignedAllocator
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::DynamicVector
is the default choice for all kinds of dense vectors and the best choice for medium to large vectors. Its size can be modified at runtime:
// Definition of a 3-dimensional integral column vector
blaze::DynamicVector<int> a( 3UL );
// Definition of a 4-dimensional single precision column vector
blaze::DynamicVector<float,blaze::columnVector> b( 4UL );
// Definition of a double precision row vector with size 0
blaze::DynamicVector<double,blaze::rowVector> c;
Allocators
Via the third template parameter it is possible to customize the memory allocation of a blaze::DynamicVector
. The provided allocator is expected to represent an implementation of the allocator concept of the standard library (see for instance std::vector
and std::allocator
). In addition, the provided allocator is also required to provide properly (over-)aligned memory for fundamental and complex numbers. For instance, in case SSE vectorization is possible, the returned memory must be at least 16-byte aligned. In case AVX is active, the memory must be at least 32-byte aligned, and in case of AVX-512 the memory must be even 64-byte aligned.
HybridVector
The blaze::HybridVector
class template combines the advantages of the blaze::StaticVector
and the blaze::DynamicVector
class templates. It represents a fixed size vector with statically allocated elements, but can still be dynamically resized (within the bounds of the available memory). It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/HybridVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the maximum number of elements, the transpose flag, the alignment, the padding, and the group tag of the vector can be specified via the six template parameters:
namespace blaze {
template< typename Type, size_t N, bool TF, AlignmentFlag AF, PaddingFlag PF, typename Tag >
class HybridVector;
} // namespace blaze
Type
: specifies the type of the vector elements.HybridVector
can be used with any non-cv-qualified element type, including other vector or matrix types.N
: specifies the total number of vector elements. It is expected thatHybridVector
is only used for tiny and small vectors.TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.AF
: specifies whether the first element of the vector is properly aligned with respect to the available instruction set (SSE, AVX, ...). Possible values areblaze::aligned
andblaze::unaligned
. The default value isblaze::defaultAlignmentFlag
.PF
: specifies whether the vector should be padded to maximize the efficiency of vectorized operations. Possible values areblaze::padded
andblaze::unpadded
. The default value isblaze::defaultPaddingFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::HybridVector
is a suitable choice for small to medium vectors, whose size is not known at compile time or not fixed at runtime, but whose maximum size is known at compile time:
// Definition of a 3-dimensional integral column vector with a maximum size of 6
blaze::HybridVector<int,6UL> a( 3UL );
// Definition of a 4-dimensional single precision column vector with a maximum size of 16
blaze::HybridVector<float,16UL,blaze::columnVector> b( 4UL );
// Definition of a unaligned, unpadded double precision row vector with size 0 and a maximum size of 6
blaze::HybridVector<double,6UL,blaze::rowVector,blaze::unaligned,blaze::unpadded> c;
Alignment
In case AF
is set to blaze::aligned
, the elements of a HybridVector
are possibly over-aligned to meet the alignment requirements of the available instruction set (SSE, AVX, AVX-512, ...). The alignment for fundamental types (short
, int
, float
, double
, ...) and complex types (complex<float>
, complex<double>
, ...) is 16 bytes for SSE, 32 bytes for AVX, and 64 bytes for AVX-512. All other types are aligned according to their intrinsic alignment:
struct Int { int i; };
using VT1 = blaze::HybridVector<double,3UL>;
using VT2 = blaze::HybridVector<complex<float>,2UL>;
using VT3 = blaze::HybridVector<Int,5UL>;
alignof( VT1 ); // Evaluates to 16 for SSE, 32 for AVX, and 64 for AVX-512
alignof( VT2 ); // Evaluates to 16 for SSE, 32 for AVX, and 64 for AVX-512
alignof( VT3 ); // Evaluates to 'alignof( Int )'
Note that an aligned HybridVector
instance may be bigger than an according unaligned HybridVector
:
sizeof( VT1 ); // Evaluates to 32 for both SSE and AVX
sizeof( VT2 ); // Evaluates to 16 for SSE and 32 for AVX
sizeof( VT3 ); // Evaluates to 20; no special alignment requirements
Please note that for this reason an aligned HybridVector
cannot be used in containers using dynamic memory such as std::vector
without additionally providing an allocator that can provide over-aligned memory:
using Type = blaze::HybridVector<double,3UL>;
using Allocator = blaze::AlignedAllocator<Type>;
std::vector<Type> v1; // Might be misaligned for AVX or AVX-512
std::vector<Type,Allocator> v2; // Properly aligned for AVX or AVX-512
Padding
Adding padding elements to the end of a HybridVector
can have a significant impact on the performance. For instance, assuming that AVX is available, then two padded 3-dimensional vectors of double precision values can be added via a single SIMD addition operation:
using blaze::HybridVector;
using blaze::columnVector;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;
HybridVector<double,3UL,columnVector,aligned,padded> a1, b1, c1;
HybridVector<double,3UL,columnVector,unaligned,unpadded> a2, b2, c2;
// ... Resizing and initialization
c1 = a1 + b1; // AVX-based vector addition; maximum performance
c2 = a2 + b2; // Scalar vector addition; limited performance
sizeof( a1 ); // Evaluates to 48 for SSE, 64 and AVX, and 128 for AVX-512
sizeof( a2 ); // Evaluates to 32 for SSE, AVX, and AVX-512 (minimum size)
Due to padding, the first addition will run at maximum performance. On the flip side, the size of each vector instance is increased due to the padding elements. The total size of an instance depends on the number of elements and width of the available instruction set (16 bytes for SSE, 32 bytes for AVX, and 64 bytes for AVX-512).
The second addition will be limited in performance since due to the number of elements some of the elements need to be handled in a scalar operation. However, the size of an unaligned
, unpadded
HybridVector
instance is guaranteed to be the sum of its elements plus the necessary data members to store the current size.
Please also note that Blaze will zero initialize the padding elements in order to achieve maximum performance!
CustomVector
The blaze::CustomVector
class template provides the functionality to represent an external array of elements of arbitrary type and a fixed size as a native Blaze dense vector data structure. Thus in contrast to all other dense vector types a custom vector does not perform any kind of memory allocation by itself, but it is provided with an existing array of element during construction. A custom vector can therefore be considered an alias to the existing array. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/CustomVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the properties of the given array of elements, the transpose flag, and the group tag of the vector can be specified via the following five template parameters:
namespace blaze {
template< typename Type, bool AF, bool PF, bool TF, typename Tag >
class CustomVector;
} // namespace blaze
Type
: specifies the type of the vector elements.CustomVector
can be used with any possibly cv-qualified, non-reference, non-pointer element type.AF
: specifies whether the represented, external arrays are properly aligned with respect to the available instruction set (SSE, AVX, ...) or not (blaze::aligned
orblaze::unaligned
).PF
: specified whether the represented, external arrays are properly padded with respect to the available instruction set (SSE, AVX, ...) or not (blaze::padded
orblaze::unpadded
).TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::CustomVector
is the right choice if any external array needs to be represented as a Blaze dense vector data structure:
using blaze::CustomVector;
using blaze::Deallocate;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;
// Definition of an unmanaged custom column vector for unaligned, unpadded integer arrays
using UnalignedUnpadded = CustomVector<int,unaligned,unpadded,columnVector>;
std::vector<int> vec( 7UL );
UnalignedUnpadded a( &vec[0], 7UL );
// Definition of a managed custom column vector for unaligned but padded 'float' arrays
using UnalignedPadded = CustomVector<float,unaligned,padded,columnVector>;
std::unique_ptr<float[]> memory1( new float[16] );
UnalignedPadded b( memory1.get(), 9UL, 16UL );
// Definition of a managed custom row vector for aligned, unpadded 'double' arrays
using AlignedUnpadded = CustomVector<double,aligned,unpadded,rowVector>;
std::unique_ptr<double[],Deallocate> memory2( blaze::allocate<double>( 7UL ) );
AlignedUnpadded c( memory2.get(), 7UL );
// Definition of a managed custom row vector for aligned, padded 'complex<double>' arrays
using cplx = complex<double>;
using AlignedPadded = CustomVector<cplx,aligned,padded,columnVector>;
std::unique_ptr<cplx[],Deallocate> memory3( allocate<cplx>( 8UL ) );
AlignedPadded d( memory3.get(), 5UL, 8UL );
In comparison with the remaining Blaze dense vector types CustomVector
has several special characteristics. All of these result from the fact that a custom vector is not performing any kind of memory allocation, but instead is given an existing array of elements. The following sections discuss all of these characteristics:
Memory Management
The CustomVector
class template acts as an adaptor for an existing array of elements. As such it provides everything that is required to use the array just like a native Blaze dense vector data structure. However, this flexibility comes with the price that the user of a custom vector is responsible for the resource management.
The following examples give an impression of several possible types of custom vectors:
using blaze::CustomVector;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::unaligned;
using blaze::padded;
using blaze::unpadded;
// Definition of a 3-dimensional custom vector with unaligned, unpadded and externally
// managed integer array. Note that the std::vector must be guaranteed to outlive the
// custom vector!
std::vector<int> vec( 3UL );
CustomVector<int,unaligned,unpadded> a( &vec[0], 3UL );
// Definition of a custom vector with size 3 and capacity 16 with aligned, padded and
// externally managed integer array. Note that the std::unique_ptr must be guaranteed
// to outlive the custom vector!
std::unique_ptr<int[],Deallocate> memory( allocate<int>( 16UL ) );
CustomVector<int,aligned,padded> b( memory.get(), 3UL, 16UL );
Copy Operations
As with all dense vectors it is possible to copy construct a custom vector:
using blaze::CustomVector;
using blaze::unaligned;
using blaze::unpadded;
using CustomType = CustomVector<int,unaligned,unpadded>;
std::vector<int> vec( 5UL, 10 ); // Vector of 5 integers of the value 10
CustomType a( &vec[0], 5UL ); // Represent the std::vector as Blaze dense vector
a[1] = 20; // Also modifies the std::vector
CustomType b( a ); // Creating a copy of vector a
b[2] = 20; // Also affects vector a and the std::vector
It is important to note that a custom vector acts as a reference to the specified array. Thus the result of the copy constructor is a new custom vector that is referencing and representing the same array as the original custom vector.
In contrast to copy construction, just as with references, copy assignment does not change which array is referenced by the custom vector, but modifies the values of the array:
std::vector<int> vec2( 5UL, 4 ); // Vector of 5 integers of the value 4
CustomType c( &vec2[0], 5UL ); // Represent the std::vector as Blaze dense vector
a = c; // Copy assignment: Set all values of vector a and b to 4.
Alignment
In case the custom vector is specified as aligned
the passed array must be guaranteed to be aligned according to the requirements of the used instruction set (SSE, AVX, ...). For instance, if AVX is active an array of integers must be 32-bit aligned:
using blaze::CustomVector;
using blaze::Deallocate;
using blaze::aligned;
using blaze::unpadded;
// Allocation of 32-bit aligned memory
std::unique_ptr<int[],Deallocate> memory( allocate<int>( 5UL ) );
CustomVector<int,aligned,unpadded> a( memory.get(), 5UL );
In case the alignment requirements are violated, a std::invalid_argument
exception is thrown.
Padding
Adding padding elements to the end of an array can have a significant impact on performance. For instance, assuming that AVX is available, then two aligned, padded, 3-dimensional vectors of double precision values can be added via a single SIMD addition instruction:
using blaze::CustomVector;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::padded;
using CustomType = CustomVector<double,aligned,padded>;
std::unique_ptr<double[],Deallocate> memory1( allocate<double>( 4UL ) );
std::unique_ptr<double[],Deallocate> memory2( allocate<double>( 4UL ) );
std::unique_ptr<double[],Deallocate> memory3( allocate<double>( 4UL ) );
// Creating padded custom vectors of size 3 and a capacity of 4
CustomType a( memory1.get(), 3UL, 4UL );
CustomType b( memory2.get(), 3UL, 4UL );
CustomType c( memory3.get(), 3UL, 4UL );
// ... Initialization
c = a + b; // AVX-based vector addition
In this example, maximum performance is possible. However, in case no padding elements are inserted, a scalar addition has to be used:
using blaze::CustomVector;
using blaze::Deallocate;
using blaze::allocate;
using blaze::aligned;
using blaze::unpadded;
using CustomType = CustomVector<double,aligned,unpadded>;
std::unique_ptr<double[],Deallocate> memory1( allocate<double>( 3UL ) );
std::unique_ptr<double[],Deallocate> memory2( allocate<double>( 3UL ) );
std::unique_ptr<double[],Deallocate> memory3( allocate<double>( 3UL ) );
// Creating unpadded custom vector of size 3
CustomType a( allocate<double>( 3UL ), 3UL );
CustomType b( allocate<double>( 3UL ), 3UL );
CustomType c( allocate<double>( 3UL ), 3UL );
// ... Initialization
c = a + b; // Scalar vector addition
Note the different number of constructor parameters for unpadded and padded custom vectors: In contrast to unpadded vectors, where during the construction only the size of the array has to be specified, during the construction of a padded custom vector it is additionally necessary to explicitly specify the capacity of the array.
The number of padding elements is required to be sufficient with respect to the available instruction set: In case of an aligned padded custom vector the added padding elements must guarantee that the capacity is greater or equal than the size and a multiple of the SIMD vector width. In case of unaligned padded vectors the number of padding elements can be greater or equal the number of padding elements of an aligned padded custom vector. In case the padding is insufficient with respect to the available instruction set, a std::invalid_argument
exception is thrown.
Please also note that Blaze will zero initialize the padding elements in order to achieve maximum performance!
UniformVector
The blaze::UniformVector
class template is the representation of an arbitrary sized uniform vector with elements of arbitrary type. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/UniformVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the transpose flag, and the group tag of the vector can be specified via the three template parameters:
namespace blaze {
template< typename Type, bool TF, typename Tag >
class UniformVector;
} // namespace blaze
Type
: specifies the type of the vector elements. UniformVector can be used with any non-cv-qualified, non-reference, non-pointer element type.TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::UniformVector
is the best choice for uniform vectors of any size. Its size can be modified at runtime:
// Definition of a 3-dimensional integral column vector
blaze::UniformVector<int> a( 3UL );
// Definition of a 4-dimensional single precision column vector
blaze::UniformVector<float,blaze::columnVector> b( 4UL );
// Definition of a double precision row vector with size 0
blaze::UniformVector<double,blaze::rowVector> c;
Sparse Vectors
CompressedVector
The blaze::CompressedVector
class is the representation of an arbitrarily sized sparse vector, which stores only non-zero elements of arbitrary type. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/CompressedVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the transpose flag, and the group tag of the vector can be specified via the three template parameters:
namespace blaze {
template< typename Type, bool TF, typename Tag >
class CompressedVector;
} // namespace blaze
Type
: specifies the type of the vector elements.CompressedVector
can be used with any non-cv-qualified element type (including other vector or matrix types).TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::CompressedVector
is the right choice for all kinds of sparse vectors:
// Definition of a 3-dimensional integral column vector
blaze::CompressedVector<int> a( 3UL );
// Definition of a 4-dimensional single precision column vector with capacity for 3 non-zero elements
blaze::CompressedVector<float,blaze::columnVector> b( 4UL, 3UL );
// Definition of a double precision row vector with size 0
blaze::CompressedVector<double,blaze::rowVector> c;
ZeroVector
The blaze::ZeroVector
class template is the representation of an immutable, arbitrary sized zero vector with elements of arbitrary type. It can be included via the header files
#include <blaze/Blaze.h>
// or
#include <blaze/Math.h>
// or
#include <blaze/math/ZeroVector.h>
and forward declared via the header file
#include <blaze/Forward.h>
The type of the elements, the transpose flag, and the group tag of the vector can be specified via the three template parameters:
namespace blaze {
template< typename Type, bool TF, typename Tag >
class ZeroVector;
} // namespace blaze
Type
: specifies the type of the vector elements.ZeroVector
can be used with any non-cv-qualified, non-reference, non-pointer element type.TF
: specifies whether the vector is a row vector (blaze::rowVector
) or a column vector (blaze::columnVector
). The default value isblaze::defaultTransposeFlag
.Tag
: optional type parameter to tag the vector. The default type isblaze::Group0
. See Grouping/Tagging for details.
The blaze::ZeroVector
is the perfect choice to represent a zero vector:
// Definition of a 3-dimensional integral zero column vector
blaze::ZeroVector<int> a( 3UL );
// Definition of a 6-dimensional single precision zero column vector
blaze::ZeroVector<float,blaze::columnVector> b( 6UL );
// Definition of a double precision row vector with size 0
blaze::ZeroVector<double,blaze::rowVector> c;
Previous: Vectors ---- Next: Vector Operations
Updated