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"