**18.7****
****Generic Functions** (.NET, C#, CSharp, VB, Visual Basic, F#)

**NMath **provides convenience
methods for applying unary and binary functions to elements of a general
matrix. The Apply() method returns a new
matrix whose contents are the result of applying a given function delegate
to each element of the matrix. The Transform()
method modifies a matrix object by applying the given function to each
of its elements.

**NMath**,
however, does not generally support applying arbitrary functions to structured
sparse matrix types. As described in Section 18.6,
such functions may change unstored zero values to non-zero values, thus
changing a structured sparse matrix type into a general matrix. Again,
the exception is the symmetric matrices which are in a different category
than the other sparse matrix types, because unstored values are not constrained
to be zero. Therefore, **NMath**
provides Apply() and Transform()
methods on these types. For example:

Code Example – C# matrix

int order = 9;

DoubleVector data =

new DoubleVector(( order * ( order + 1 )) / 2,

new RandGenMTwist() );

data -= 0.5;

var A = new DoubleSymmetricMatrix( order, data );

DoubleSymmetricMatrix B = A.Apply( NMathFunctions.SinFunc );

A.Transform( NMathFunctions.CosFunc );

Code Example – VB matrix

Dim Order As Integer = 9

Dim Data As New DoubleVector((Order * (Order + 1)) / 2,

New RandGenMTwist())

Data -= 0.5

Dim A As New DoubleSymmetricMatrix(Order, Data)

Dim B As DoubleSymmetricMatrix = A.Apply(NMathFunctions.SinFunc)

A.Transform(NMathFunctions.CosFunc)

The code above creates a 9 x 9 symmetric matrix filled with random values between 0 and 1, then applies the sine function to create a new symmetric matrix containing the sines of the original values. Finally, the original matrix is transformed using the cosine function.

For structured sparse matrix types other than symmetric, there are two ways to apply an arbitrary function: convert the matrix to a general matrix and apply the function, or retrieve the underlying data vector and apply the function. The difference is whether the function is applied to all elements of the matrix, including unstored zero values, or just to the stored values.

For instance, this code converts an upper triangular matrix to a general matrix, then applies the cosine function to all elements of general matrix, including the zero values in the lower triangular region:

Code Example – C# matrix

var data = new DoubleVector( 10, 0, Math.PI/4 );

var A = new DoubleUpperTriMatrix( data, 4 );

DoubleMatrix genMat = A.ToGeneralMatrix();

genMat.Transform( NMathFunctions.CosFunc );

Code Example – VB matrix

Dim Data As New DoubleVector(10, 0.0, Math.PI / 4.0)

Dim A As New DoubleUpperTriMatrix(Data, 4)

Dim GenMat As DoubleMatrix = A.ToGeneralMatrix()

GenMat.Transform(NMathFunctions.CosFunc)

**NOTE—****Data
is copied when converting a structured sparse matrix to a general matrix.**

In contrast, this code retrieves the underlying data vector from the upper triangular matrix, and transforms it using the cosine function, then creates a new upper triangular matrix using the new data:

Code Example – C# matrix

var data = new DoubleVector( 10, 0, Math.PI/4 );

var A = new DoubleUpperTriMatrix( data, 4 );

A.DataVector.Transform( NMathFunctions.CosFunc );

Code Example – VB matrix

Dim Data As New DoubleVector(10, 0.0, Math.PI / 4.0)

Dim A As New DoubleUpperTriMatrix(Data, 4)

A.DataVector.Transform(NMathFunctions.CosFunc)

In this case, the zeros in the lower triangular region have not been transformed, and the matrix remains an upper triangular matrix. No data was copied.