Vectors

Definition

Vectors are instances of the class Vector. Class Vector is a template class: Vector<T, Storage, Allocator>. T is the type of the elements to be stored (e.g. double). Storage defines how the vector is stored. Storage is equal to Vect_Full by default for full vectors, you can set it to Vect_Sparse for sparse vectors. Finally, Allocator defines the way memory is managed. It is close to STL allocators. See the section "Allocators" for further details.

Declaration

There is a default Allocator (see the section "Allocators") and a default Storage (Vect_Full). It means that these two template parameters may be omitted. Then a vector of integers may be declared thanks to the line:

  
Vector<int> V;

This defines a vector of size 0, that is to say an empty vector. To define a vector of length 5, one may write:

  
Vector<int> V(5);

Other declarations may be:

  
Vector<int, Vect_Full> V(10);
Vector<int> U(V); // Copy constructor.
Vector<int, Vect_Full, MallocAlloc<int> > V(10);
Vector<int, Vect_Full, NewAlloc<int> > V(10);

Use of vectors

Access to elements is achieved through the operator(int), and indices start at 0:

  
Vector<int, Vect_Full> V(10);
V(5) = -3;
V(0) = 2 * V(5);

To display vectors, there are two convenient options:

  
V.Print();
std::cout << V << std::endl;

There are lots of methods that are described in the documentation. One may point out:

  • Fill fills with 0, 1, 2, 3, etc. or fills the vector with a given value.

  • GetLength or GetSize return the length of the vector.

  • Reallocate resizes the vector (warning, data may be lost, depending on the allocator).

  • Resize resizes the vector while keeping previous entries.

  • PushBack inserts an element at the end of the vector.

  • Read, ReadText, Write, WriteText are useful methods for input/ouput operations.

A comprehensive test of dense vectors is achieved in file test/program/vector_test.cpp.


Sparse vectors

Declaration

There is a default Allocator (see the section "Allocators"). It means that this template parameter may be omitted. Then a sparse vector of doubles may be declared thanks to the line:

  
Vector<double, Vect_Sparse> V;

This defines a null vector, that is to say that V(i) will return 0 for all i. To define a vector with 5 non-zero entries, one may write:

  
Vector<double, Vect_Sparse> V(5);

Other declarations may be:

  
Vector<double, Vect_Sparse> U(V); // Copy constructor.
Vector<int, Vect_Sparse, MallocAlloc<int> > V(10);
Vector<int, Vect_Sparse, NewAlloc<int> > V(10);

Use of sparse vectors

A good technique consists of modifying those vectors through methods AddInteraction and AddInteractionRow. These methods insert (or add) the elements at the correct position, so that the row numbers are always sorted in ascending order. You can use them as in the following example :

  
Vector<double, Vect_Sparse> V;
cout << "Empty vector V = " << V << endl;
// non-null value of 1.5 at row 2
V.AddInteraction(2, 1.5);
V.AddInteraction(2, 0.8);
// now V(2) should be equal to 1.5+0.8 = 2.3
cout << "After AddInteraction, V = " << V << endl;

// AddInteractionRow for several rows to add
IVect num(2);
Vector<double> val(2);
num(0) = 1; val(0) = -0.4;
num(1) = 4; val(1) = 0.6;
V.AddInteractionRow(num, val);
cout << "After AddInteractionRow, V = " << endl << V << endl;
 

The output of this code would read :

Empty vector V =
After AddInteraction, V = 3 2.3
AfterAddInteractionRow, V =
2 -0.4
3  2.3
5  0.6

You noticed that the row indices are displayed with indices beginning at 1 instead of 0, this is more convenient for debugging, or exporting datas into Matlab for example.

You can also use the operator(int) to modify directly values.

  
Vector<double, Vect_Sparse> V;
V(5) = -3;
V(0) = 2 * V(5);

If the non-zero entry doesn't exist, it is created at the correction position as for AddInteraction.

The methods Reallocate, Index and Value can also be used, but they need to be used carefully and often the method Assemble has to be called in order to sort non-zero entries.

  
// 3 non-zero entries
Vector<double, Vect_Sparse> V;
// creation of 3 non-zero entries
V.Reallocate(3);
// initialization of non-zero entries with Index and Value
V.Index(0) = 1; // row number of first entry
V.Value(0) = 1.3; // value of first entry
V.Index(1) = 3;
V.Value(1) = -0.5;
V.Index(2) = 2;
V.Value(2) = 2.7;
// Here the row numbers are not sorted
// you need to call Assemble
V.Assemble();

In the same way, the method SetData can be used in conjunction with Assemble :

  
Vector<double, Vect_Sparse> V;
IVect row(3);
Vector<double> value(3);
row(0) = 1; // row number of first entry
value(0) = 1.3; // value of first entry
row(1) = 3;
value(1) = -0.5;
row(2) = 2;
value(2) = 2.7;
// feeding V with row and value
V.SetData(value, row);
// Here the row numbers are not sorted
// you need to call Assemble
V.Assemble();

You may notice that the method SetData empties vectors row and value.

There are lots of methods that are described in the documentation. One may point out:

  • Fill give to non-zero entries the value 0, 1, 2, 3, etc. or a given value.

  • GetLength or GetSize return the number of non-zero entries.

  • Read, ReadText, Write, WriteText are useful methods for input/ouput operations.

A comprehensive test of dense vector is achieved in file test/program/sparse_vector_test.cpp.