# Symmetrical Matrices

A SymmetricMatrix<T> represents a matrix whose elements are symmetrical about the main diagonal. A symmetric matrix is equal to its transpose.

## How symmetrical matrices are stored

Symmetrical matrices are stored in the upper or lower triangular part of a rectangular array. The MatrixTriangle property indicates how elements are stored. It is of type MatrixTriangle and can have values Upper and Lower. The element order is always column major order. Row major storage in the upper triangle is exactly equivalent to column major storage in the lower triangle.

## Constructing symmetrical matrices

Constructing symmetrical matrices is analogous to triangular matrices, by calling the Matrix.CreateSymmetric method. The fact that symmetrical matrices are always square means only one dimension needs to be passed to the method. The method has several overloads.

The simplest overload has just one argument. It constructs a symmetrical matrix with the specified number of rows and columns. All elements are initially set to zero. The element type must be specified as a generic type argument. For example, for a 5x5 symmetrical matrix, we have:

C#
``var s1 = Matrix.CreateSymmetric<double>(5);``

The two remaining overloads allow you to initialize the elements of the matrix. The first argument once again specifies the number of rows and columns. The second argument is an array containing the elements of the new matrix. The third argument is of type MatrixTriangle, and indicates whether the elements are taken from the upper or lower triangular part of the element array. The fourth argument is of type MatrixElementOrder, and indicates whether the elements in the array are stored in column-major or row-major order.

C#
``````double[] elements = { 1, 0, 0, 2, 3, 0, 4, 5, 6 };
var s2 = Matrix.CreateSymmetric(3, elements,
MatrixTriangle.Upper, MatrixElementOrder.ColumnMajor);
var s3 = Matrix.CreateSymmetric(3, elements,
MatrixTriangle.Lower, MatrixElementOrder.RowMajor);``````

The last overload adds one Boolean argument that lets you specify whether the element array should be reused or copied. If the element array is reused, any changes to its elements will result in changes to the corresponding elements of the matrix.

C#
``````var s4 = Matrix.CreateSymmetric(3, elements,
MatrixTriangle.Upper, MatrixElementOrder.ColumnMajor, true);``````

## Methods specific to symmetrical matrices

The static FromOuterProduct methods return a symmetric matrix that is the product of a matrix with its transpose. An optional second argument of type MatrixOperationSide specifies which of the two operands should be transposed. The default is MatrixOperationSide.Left The following example creates a 2x2 symmetrical matrix that is the product of a 2x3 matrix with its transpose.

C#
``````var a = Matrix.Create(3, 2, new [] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 },
MatrixElementOrder.ColumnMajor);
var s = Extreme.Mathematics.LinearAlgebra.SymmetricMatrix<double>.FromOuterProduct(a);``````

The SymmetricMatrix<T> class has two specific instance methods. The AddOuterProduct method adds the outer product of a vector or a matrix with its transpose to a SymmetricMatrix<T>. You may supply a scale factor for the outer product, as in the following example:

C#
``````var A = Matrix.CreateSymmetric<double>(4);
var v = Vector.Create(1.0, 2.0, 3.0, 4.0);
var w = Vector.Create(1.0, 2.0, 3.0, 4.0);
``````var S = Matrix.CreateSymmetric(2, new[] { 1.0, 0.0, 3.0, 4.0 },