Different applications need to access vector elements in different ways.
The Extreme Optimization Numerical Libraries for .NET
accommodates these needs by providing four different options.
The VectorT class has an
ItemInt32 property.
Several types can be used as indexes: integers, ranges, masks, and predicates.
Accessing single elements
The index is zero based. If the
index is greater than or equal to the length, an exception of type IndexOutOfRangeException is
thrown.
var v = Vector.Create(1, 2, 4, 8, 16);
Console.WriteLine("v[1] = {0}", v[1]);
v[1] = 7;
Console.WriteLine("v = {0}", v);
Dim v = Vector.Create(1, 2, 4, 8, 16)
Console.WriteLine("v(1) = {0}", v(1))
v(1) = 7
Console.WriteLine("v = {0}", v)
No code example is currently available or this language may not be supported.
let v = Vector.Create(1, 2, 4, 8, 16)
Console.WriteLine("v.[1] = [|0|]", v.[1])
v.[1] <- 7
Console.WriteLine("v = [|0|]", v)
Some vector operations operate on a range of elements of a vector.
The Range structure
A Range structure represents a range of indices. The
following table illustrates the different ways to specify a range:
Expression | Description |
---|
new Range(startIndex, endIndex) |
A range that runs from startIndex up to and including endIndex.
|
new Range(startIndex, endIndex, stride) |
A range that runs from startIndex to endIndex with an increments of
stride.
|
Range.All | A range that spans the entire vector. |
StartIndex,
EndIndex and
Stride are properties of the Range structure
and can be set directly. StartIndex is guaranteed to be the first index in the range. In the second
example, the last index in the range is the largest number of the form StartIndex +
kStride that is less than or equal to EndIndex. The Stride can also
be negative. In this case, the last index in the range is the smallest number of the form StartIndex +
kStride that is greater than or equal to EndIndex.
The special range Range.All can be used to represent a range over an entire row, column, or vector,
without having to specify the EndIndex explicitly.
Using ranges as an index
The indexer property of
VectorT
is overloaded to allow a
Range
structure as an index. When getting this property,
it returns a vector that spans the range specified by the index:
var v = Vector.Create(0, 1, 2, 3, 4, 5, 6);
Console.WriteLine("v[new Range(2, 3)] = {0}", v[new Range(2, 3)]);
Console.WriteLine("v[new Range(2, 5, 2)] = {0}", v[new Range(2, 5, 2)]);
Console.WriteLine("v[Range.All] = {0}", v[Range.All]);
Dim v = Vector.Create(0, 1, 2, 3, 4, 5, 6)
Console.WriteLine("v(new Range(2, 3)) = {0}", v(New Range(2, 3)))
Console.WriteLine("v(new Range(2, 5, 2)) = {0}", v(New Range(2, 5, 2)))
Console.WriteLine("v(Range.All) = {0}", v(Range.All))
No code example is currently available or this language may not be supported.
let v = Vector.Create(0, 1, 2, 3, 4, 5, 6)
Console.WriteLine("v.[Range(2, 3)] = [|0|]", v.[2..3])
Console.WriteLine("v.[Range(2, 5, 2)] = [|0|]", v.[Range(2, 5, 2)])
Console.WriteLine("v.[Range.All] = [|0|]", v.[*])
The first example gets the 3rd and 4th elements of the vector.
(Indexes are 0-based!) The second example gets the elements with index 2 and 4.
The last example gets the entire vector.
When setting this property, the elements in the range are set to
the elements of the right-hand side.
var v = Vector.Create(6);
var w = Vector.Create(1, 2, 3);
v[new Range(2, 4)] = w;
Console.WriteLine("v = {0}", v);
var x = Vector.Create(6);
x[new Range(5, 0, -1)] = v;
Console.WriteLine("x = {0}", x);
Dim v = Vector.Create(6)
Dim w = Vector.Create(1, 2, 3)
v(New Range(2, 4)) = w
Console.WriteLine("v = {0}", v)
Dim x = Vector.Create(6)
x(New Range(5, 0, -1)) = v
Console.WriteLine("x = {0}", x)
No code example is currently available or this language may not be supported.
let v = Vector.Create<float>(6)
let w = Vector.Create(1.0, 2.0, 3.0)
v.[2..4] <- w
Console.WriteLine("v = [|0|]", v)
let x = Vector.Create(6)
x.[Range(5, 0, -1)] <- v
The first example sets the 3rd to 5th elements of a vector to the elements of
w. The second example sets the reverse range of
x equal to v.
This, in effect, sets x equal to the reverse of the vector.
The SetValues(T, Range)
method sets all elements in a range to a single value.
In F#, assignment to the indexer can be used for this purpose.
Boolean masks and predicates
Using a boolean vector as an index selects those elements for which
the corresponding element in the mask is .
The mask must have the same length as the vector it indexes.
Another option is to use a predicate: a delegate that maps a value
to a boolean. In this case, the values for which the predicate returns
are selected.
The SetValues(T, Range)
method sets all elements in a range to a single value.
In F#, assignment to the indexer can be used for this purpose.
In the example below, we first select and negate the larger elements in a vector.
We then set the elements that are less than zero equal to 99:
var v = Vector.Create(1, 5, 2, 6, 3, 7, 4);
var big = Vector.GreaterThan(v, 4);
v[big] = -v[big];
v.SetValues(99, x => x < 0);
Dim v = Vector.Create(1, 5, 2, 6, 3, 7, 4)
Dim big = Vector.GreaterThan(v, 4)
v(big) = -v(big)
v.SetValues(99, Function(x) x < 0)
No code example is currently available or this language may not be supported.
let v = Vector.Create(1, 5, 2, 6, 3, 7, 4)
let big = Vector.GreaterThan(v, 4)
v.[big] <- -v.[big]
v.[v .< 0] <- 99
v.[fun x -> x < 0] <- 99
Although the indexers are very powerful and offer a lot of flexibility,
they are limited in one important way: the mutability is always inherited
from the parent vector.
In situations where more control is needed, one of the overloads of the
GetSlice
method may be used instead. These methods are identical to their indexer counterparts,
but add an optional argument of type
Intent.
var v = Vector.Create(6, i => i, ArrayMutability.Immutable);
var s1 = v.GetSlice(2, 3, Intent.WritableCopy);
s1[0] = 99;
Console.WriteLine("s1 = {0}", s1);
var s2 = v.GetSlice(2, 4, 2);
Console.WriteLine("s2 = {0}", s2);
var s3 = v.GetSlice(6, 0, -1);
var s4 = v.GetSlice(new Range(6, 0, -1));
Dim v = Vector.Create(6, Function(i) i, ArrayMutability.Immutable)
Dim s1 = v.GetSlice(2, 3, Intent.WritableCopy)
s1(0) = 99
Console.WriteLine("s1 = {0}", s1)
Dim s2 = v.GetSlice(2, 4, 2)
Console.WriteLine("s2 = {0}", s2)
Dim s3 = v.GetSlice(6, 0, -1)
Dim s4 = v.GetSlice(New Range(6, 0, -1))
No code example is currently available or this language may not be supported.
let v = Vector.Create(6, (fun i -> i), ArrayMutability.Immutable)
let s1 = v.GetSlice(2, 3, Intent.WritableCopy)
s1.[0] <- 99
let s2 = v.GetSlice(2, 4, 2)
let s3 = v.GetSlice(6, 0, -1)
let s4 = v.GetSlice(Range(6, 0, -1))
The VectorT class
implements the IEnumerableT
interface. This lets you iterate through the elements in a for-each loop:
double ProductOfElements(Vector<double> v)
{
double product = 1.0;
foreach (double element in v)
product *= element;
return product;
}
Function ProductOfElements(v As Vector(Of Double)) As Double
Dim product = 1.0
For Each element In v
product *= element
Next
Return product
End Function
No code example is currently available or this language may not be supported.
let ProductOfElements (v : Vector<double>) =
let mutable product = 1.0
for element in v do
product <- product * element
product