# Constructing Vectors

The Vector<T> class is an abstract base class and cannot be instantiated directly. Instead, create instances of one of its derived classes by calling one of the Vector class' factory methods.

## Dense vectors

A DenseVector<T> represents a vector with arbitrary elements. Dense vectors are constructed with the Create method. This method has many overloads. All overloads take a generic type argument that specifies the element type. In most cases, type inference eliminates the need to specify the element type explicitly.

Passing a single integer to the method creates a dense vector of the specified length
with all its elements zero. The element type *must* be
specified as the generic type parameter.
The example below creates a vector of length 5:

```
var v1 = Vector.Create<double>(5);
// v1 -> [ 0.0, 0.0, 0.0, 0.0, 0.0 ]
```

A second overload takes a variable number of arguments, all of the same type, that will serve as the elements of the new vector. The values are copied into the vector's private data storage.

```
var v2 = Vector.Create(1.0, 2.0, 3.0, 4.0, 5.0);
// v2 -> [ 1.0, 2.0, 3.0, 4.0, 5.0 ]
```

The third overload takes a parameter array of values.
No copy is made of this array. If you pass in an array directly,
any change in that array will be reflected in the vector.
The fourth overload takes an array containing the elements.
A second boolean parameter, *reuseComponentArray*,
may be provided. This specifies whether to use the element array directly
for data storage (reuseComponentArray = true),
or to copy the data to a private storage (reuseComponentArray = false).
In the example below, the second
vector is changed when an element of its storage array is changed.

```
double[] elements = { 1.0, 2.0, 3.0, 4.0, 5.0 };
var v3 = Vector.Create(elements);
// v3 -> [ 1.0, 2.0, 3.0, 4.0, 5.0 ]
var v4 = Vector.Create(elements, true);
elements[3] = 99.0;
// v4 -> [ 1.0, 2.0, 3.0, 99.0, 5.0 ]
```

The next overload takes 4 arguments and offers the most options when creating a vector from a part of an array. The first argument is the length of the vector. The second argument is the storage array. The third and fourth arguments are the offset of the first element of the vector in the array, and the stride between vector elements in the array. The storage array is used for the vector's storage.

```
elements = new[] { 0.0, 1.0, 0.0, 2.0, 0.0, 3.0 };
var v5 = Vector.Create(3, elements, 1, 2, ArrayMutability.MutableValues);
// v5 -> [ 1.0, 2.0, 3.0 ]
```

A sixth overload takes a delegate that is used to initialize the elements of the vector. The delegate maps the index of the element to its value:

```
var v6 = Vector.Create(5, i => 1.0 + i * i);
// v6 -> [ 1.0, 2.0, 5.0, 10.0, 17.0 ]
```

Some other methods also create dense vectors:

The CreateRange method constructs a vector with linearly spaced elements. It takes up to 3 arguments. When one argument is provided, it returns a vector with integers from 0 up to the argument value. When two arguments are provided, it returns a vector with values from the first argument value up to the second argument value with unit increments. When three arguments are provided, it returns a vector with values from the first argument value up to the second argument value where the third argument specifies the total number of steps.

```
var v7 = Vector.CreateRange(10);
// v7 -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
var v8 = Vector.CreateRange(5.0, 10.0);
// v8 -> [ 5.0, 6.0, 7.0, 8.0, 9.0 ]
var v9 = Vector.CreateRange(5.0, 10.0, 5);
// v9 -> [ 5.0, 6.25, 7.5, 8.75, 10.0 ]
```

The CreateRandom method constructs a vector with random elements. The first argument is the length of the vector. The second argument is the random number generator to use. This argument is optional.

```
var v10 = Vector.CreateRandom(10, ArrayMutability.Immutable);
// v10 -> [ <10 random values between 0 and 1> ]
var v11 = Vector.CreateRandom(10, new MersenneTwister(17));
// v11 -> [ ]
```

## Constant vectors

A constant vector is a vector whose elements all have the same, constant value. Once created, none of the elements can be changed. They are used mainly to represent unit diagonals (all 1's) or sub- or superdiagonals (all 0's) of triangular matrices.

Constant vectors are implemented by the ConstantVector<T> class and have only one overload with two parameters. The first parameter specifies the length of the vector. The second argumentspecifies the constant value. The following constructs a ConstantVector that represents the vector [2 2 2 2]:

`Vector v1 = Vector.CreateConstant(4, 2.0);`

As mentioned earlier, constant vectors are also returned as diagonals of triangular matrices.

## Band vectors

Band vectors are vectors whose elements are zero outside a contiguous range of elements. The presence of the zero elements makes it possible to optimize many calculations. They get their name from the fact that the rows and columns of a band matrix are of this format. Band vectors are implemented by the BlockVector<T> class.

The range of non-zero elements must be specified at the time of creation. Only elements within this range can be modified. Any attempt to set an element outside this range results in a ComponentReadOnlyException.

The simplest overload takes three integer parameters. The first argument is the length of the vector. The second and third parameters specify the index of the first and last non-zero element of the vector. This example creates a vector of the form [0 x x x 0 0]:

`BandVector v1 = Vector.CreateBanded(6, 1, 3);`

All elements are initially set to zero, but only the elements within the specified range can be modified.

A second overload takes a Double array as its fourth parameter. This array specifies the non-zero elements of the band vector. The second argument is the length of the new vector. The index of the first and last element are the 3rd and 4th parameters. The elements are copied from the element array starting with the first element. The following constructs a band vector with value [0 1 2 3 0 0]:

```
double[] components = {1, 2, 3};
BandVector v2 = Vector.CreateBanded(6, 1, 3, components);
```

Notice that the elements array does not contain any zero elements.

A third overload has an additional Boolean parameter, reuseComponentArray, that specifies whether to use the element array directly for data storage (reuseComponentArray = true), or to copy the data to a private storage (reuseComponentArray = false). In the former case, any changes to the original array cause the elements of the vector to change as well. The following example illustrates what happens:

```
BandVector v3 = Vector.CreateBanded(6, 1, 3, components, true);
Console.WriteLine("v3 = {0}", v3);
components[1] = 1;
Console.WriteLine("v3 = {0}", v3);
```

Changing the value of the second element of Components changes the second non-zero element of v3, which is the third element overall.

Band vectors are created as the rows or columns of triangular matrices. Details can be found in the section on triangular matrices.