gonum.org/v1/gonum@v0.14.0/mat/doc.go (about)

     1  // Copyright ©2015 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package mat provides implementations of float64 and complex128 matrix
     6  // structures and linear algebra operations on them.
     7  //
     8  // # Overview
     9  //
    10  // This section provides a quick overview of the mat package. The following
    11  // sections provide more in depth commentary.
    12  //
    13  // mat provides:
    14  //   - Interfaces for Matrix classes (Matrix, Symmetric, Triangular)
    15  //   - Concrete implementations (Dense, SymDense, TriDense, VecDense)
    16  //   - Methods and functions for using matrix data (Add, Trace, SymRankOne)
    17  //   - Types for constructing and using matrix factorizations (QR, LU, etc.)
    18  //   - The complementary types for complex matrices, CMatrix, CSymDense, etc.
    19  //
    20  // In the documentation below, we use "matrix" as a short-hand for all of
    21  // the FooDense types implemented in this package. We use "Matrix" to
    22  // refer to the Matrix interface.
    23  //
    24  // A matrix may be constructed through the corresponding New function. If no
    25  // backing array is provided the matrix will be initialized to all zeros.
    26  //
    27  //	// Allocate a zeroed real matrix of size 3×5
    28  //	zero := mat.NewDense(3, 5, nil)
    29  //
    30  // If a backing data slice is provided, the matrix will have those elements.
    31  // All matrices are stored in row-major format and users should consider
    32  // this when expressing matrix arithmetic to ensure optimal performance.
    33  //
    34  //	// Generate a 6×6 matrix of random values.
    35  //	data := make([]float64, 36)
    36  //	for i := range data {
    37  //		data[i] = rand.NormFloat64()
    38  //	}
    39  //	a := mat.NewDense(6, 6, data)
    40  //
    41  // Operations involving matrix data are implemented as functions when the values
    42  // of the matrix remain unchanged
    43  //
    44  //	tr := mat.Trace(a)
    45  //
    46  // and are implemented as methods when the operation modifies the receiver.
    47  //
    48  //	zero.Copy(a)
    49  //
    50  // Note that the input arguments to most functions and methods are interfaces
    51  // rather than concrete types `func Trace(Matrix)` rather than
    52  // `func Trace(*Dense)` allowing flexible use of internal and external
    53  // Matrix types.
    54  //
    55  // When a matrix is the destination or receiver for a function or method,
    56  // the operation will panic if the matrix is not the correct size.
    57  // An exception to this is when the destination is empty (see below).
    58  //
    59  // # Empty matrix
    60  //
    61  // An empty matrix is one that has zero size. Empty matrices are used to allow
    62  // the destination of a matrix operation to assume the correct size automatically.
    63  // This operation will re-use the backing data, if available, or will allocate
    64  // new data if necessary. The IsEmpty method returns whether the given matrix
    65  // is empty. The zero-value of a matrix is empty, and is useful for easily
    66  // getting the result of matrix operations.
    67  //
    68  //	var c mat.Dense // construct a new zero-value matrix
    69  //	c.Mul(a, a)     // c is automatically adjusted to be the right size
    70  //
    71  // The Reset method can be used to revert a matrix to an empty matrix.
    72  // Reset should not be used when multiple different matrices share the same backing
    73  // data slice. This can cause unexpected data modifications after being resized.
    74  // An empty matrix can not be sliced even if it does have an adequately sized
    75  // backing data slice, but can be expanded using its Grow method if it exists.
    76  //
    77  // # The Matrix Interfaces
    78  //
    79  // The Matrix interface is the common link between the concrete types of real
    80  // matrices. The Matrix interface is defined by three functions: Dims, which
    81  // returns the dimensions of the Matrix, At, which returns the element in the
    82  // specified location, and T for returning a Transpose (discussed later). All of
    83  // the matrix types can perform these behaviors and so implement the interface.
    84  // Methods and functions are designed to use this interface, so in particular the method
    85  //
    86  //	func (m *Dense) Mul(a, b Matrix)
    87  //
    88  // constructs a *Dense from the result of a multiplication with any Matrix types,
    89  // not just *Dense. Where more restrictive requirements must be met, there are also
    90  // additional interfaces like Symmetric and Triangular. For example, in
    91  //
    92  //	func (s *SymDense) AddSym(a, b Symmetric)
    93  //
    94  // the Symmetric interface guarantees a symmetric result.
    95  //
    96  // The CMatrix interface plays the same role for complex matrices. The difference
    97  // is that the CMatrix type has the H method instead T, for returning the conjugate
    98  // transpose.
    99  //
   100  // (Conjugate) Transposes
   101  //
   102  // The T method is used for transposition on real matrices, and H is used for
   103  // conjugate transposition on complex matrices. For example, c.Mul(a.T(), b) computes
   104  // c = aᵀ * b. The mat types implement this method implicitly —
   105  // see the Transpose and Conjugate types for more details. Note that some
   106  // operations have a transpose as part of their definition, as in *SymDense.SymOuterK.
   107  //
   108  // # Matrix Factorization
   109  //
   110  // Matrix factorizations, such as the LU decomposition, typically have their own
   111  // specific data storage, and so are each implemented as a specific type. The
   112  // factorization can be computed through a call to Factorize
   113  //
   114  //	var lu mat.LU
   115  //	lu.Factorize(a)
   116  //
   117  // The elements of the factorization can be extracted through methods on the
   118  // factorized type, for example *LU.UTo. The factorization types can also be used
   119  // directly, as in *Cholesky.SolveTo. Some factorizations can be updated directly,
   120  // without needing to update the original matrix and refactorize, for example with
   121  // *LU.RankOne.
   122  //
   123  // # BLAS and LAPACK
   124  //
   125  // BLAS and LAPACK are the standard APIs for linear algebra routines. Many
   126  // operations in mat are implemented using calls to the wrapper functions
   127  // in gonum/blas/blas64 and gonum/lapack/lapack64 and their complex equivalents.
   128  // By default, blas64 and lapack64 call the native Go implementations of the
   129  // routines. Alternatively, it is possible to use C-based implementations of the
   130  // APIs through the respective cgo packages and the wrapper packages' "Use"
   131  // functions. The Go implementation of LAPACK makes calls through blas64, so if
   132  // a cgo BLAS implementation is registered, the lapack64 calls will be partially
   133  // executed in Go and partially executed in C.
   134  //
   135  // # Type Switching
   136  //
   137  // The Matrix abstraction enables efficiency as well as interoperability. Go's
   138  // type reflection capabilities are used to choose the most efficient routine
   139  // given the specific concrete types. For example, in
   140  //
   141  //	c.Mul(a, b)
   142  //
   143  // if a and b both implement RawMatrixer, that is, they can be represented as a
   144  // blas64.General, blas64.Gemm (general matrix multiplication) is called, while
   145  // instead if b is a RawSymmetricer blas64.Symm is used (general-symmetric
   146  // multiplication), and if b is a *VecDense blas64.Gemv is used.
   147  //
   148  // There are many possible type combinations and special cases. No specific guarantees
   149  // are made about the performance of any method, and in particular, note that an
   150  // abstract matrix type may be copied into a concrete type of the corresponding
   151  // value. If there are specific special cases that are needed, please submit a
   152  // pull-request or file an issue.
   153  //
   154  // # Invariants
   155  //
   156  // Matrix input arguments to package functions are never directly modified. If an
   157  // operation changes Matrix data, the mutated matrix will be the receiver of a
   158  // method, or will be the first, dst, argument to a method named with a To suffix.
   159  //
   160  // For convenience, a matrix may be used as both a receiver and as an input, e.g.
   161  //
   162  //	a.Pow(a, 6)
   163  //	v.SolveVec(a.T(), v)
   164  //
   165  // though in many cases this will cause an allocation (see Element Aliasing).
   166  // An exception to this rule is Copy, which does not allow a.Copy(a.T()).
   167  //
   168  // # Element Aliasing
   169  //
   170  // Most methods in mat modify receiver data. It is forbidden for the modified
   171  // data region of the receiver to overlap the used data area of the input
   172  // arguments. The exception to this rule is when the method receiver is equal to one
   173  // of the input arguments, as in the a.Pow(a, 6) call above, or its implicit transpose.
   174  //
   175  // This prohibition is to help avoid subtle mistakes when the method needs to read
   176  // from and write to the same data region. There are ways to make mistakes using the
   177  // mat API, and mat functions will detect and complain about those.
   178  // There are many ways to make mistakes by excursion from the mat API via
   179  // interaction with raw matrix values.
   180  //
   181  // If you need to read the rest of this section to understand the behavior of
   182  // your program, you are being clever. Don't be clever. If you must be clever,
   183  // blas64 and lapack64 may be used to call the behavior directly.
   184  //
   185  // mat will use the following rules to detect overlap between the receiver and one
   186  // of the inputs:
   187  //   - the input implements one of the Raw methods, and
   188  //   - the address ranges of the backing data slices overlap, and
   189  //   - the strides differ or there is an overlap in the used data elements.
   190  //
   191  // If such an overlap is detected, the method will panic.
   192  //
   193  // The following cases will not panic:
   194  //   - the data slices do not overlap,
   195  //   - there is pointer identity between the receiver and input values after
   196  //     the value has been untransposed if necessary.
   197  //
   198  // mat will not attempt to detect element overlap if the input does not implement a
   199  // Raw method. Method behavior is undefined if there is undetected overlap.
   200  package mat // import "gonum.org/v1/gonum/mat"