Differences Between: [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
1 <?php 2 3 namespace Matrix; 4 5 class Functions 6 { 7 /** 8 * Calculate the adjoint of the matrix 9 * 10 * @param Matrix $matrix The matrix whose adjoint we wish to calculate 11 * @return Matrix 12 * 13 * @throws Exception 14 */ 15 private static function getAdjoint(Matrix $matrix) 16 { 17 return self::transpose( 18 self::getCofactors($matrix) 19 ); 20 } 21 22 /** 23 * Return the adjoint of this matrix 24 * The adjugate, classical adjoint, or adjunct of a square matrix is the transpose of its cofactor matrix. 25 * The adjugate has sometimes been called the "adjoint", but today the "adjoint" of a matrix normally refers 26 * to its corresponding adjoint operator, which is its conjugate transpose. 27 * 28 * @param Matrix $matrix The matrix whose adjoint we wish to calculate 29 * @return Matrix 30 * @throws Exception 31 **/ 32 public static function adjoint(Matrix $matrix) 33 { 34 if (!$matrix->isSquare()) { 35 throw new Exception('Adjoint can only be calculated for a square matrix'); 36 } 37 38 return self::getAdjoint($matrix); 39 } 40 41 /** 42 * Calculate the cofactors of the matrix 43 * 44 * @param Matrix $matrix The matrix whose cofactors we wish to calculate 45 * @return Matrix 46 * 47 * @throws Exception 48 */ 49 private static function getCofactors(Matrix $matrix) 50 { 51 $cofactors = self::getMinors($matrix); 52 $dimensions = $matrix->rows; 53 54 $cof = 1; 55 for ($i = 0; $i < $dimensions; ++$i) { 56 $cofs = $cof; 57 for ($j = 0; $j < $dimensions; ++$j) { 58 $cofactors[$i][$j] *= $cofs; 59 $cofs = -$cofs; 60 } 61 $cof = -$cof; 62 } 63 64 return new Matrix($cofactors); 65 } 66 67 /** 68 * Return the cofactors of this matrix 69 * 70 * @param Matrix $matrix The matrix whose cofactors we wish to calculate 71 * @return Matrix 72 * 73 * @throws Exception 74 */ 75 public static function cofactors(Matrix $matrix) 76 { 77 if (!$matrix->isSquare()) { 78 throw new Exception('Cofactors can only be calculated for a square matrix'); 79 } 80 81 return self::getCofactors($matrix); 82 } 83 84 /** 85 * @param Matrix $matrix 86 * @param int $row 87 * @param int $column 88 * @return float 89 * @throws Exception 90 */ 91 private static function getDeterminantSegment(Matrix $matrix, $row, $column) 92 { 93 $tmpMatrix = $matrix->toArray(); 94 unset($tmpMatrix[$row]); 95 array_walk( 96 $tmpMatrix, 97 function (&$row) use ($column) { 98 unset($row[$column]); 99 } 100 ); 101 102 return self::getDeterminant(new Matrix($tmpMatrix)); 103 } 104 105 /** 106 * Calculate the determinant of the matrix 107 * 108 * @param Matrix $matrix The matrix whose determinant we wish to calculate 109 * @return float 110 * 111 * @throws Exception 112 */ 113 private static function getDeterminant(Matrix $matrix) 114 { 115 $dimensions = $matrix->rows; 116 $determinant = 0; 117 118 switch ($dimensions) { 119 case 1: 120 $determinant = $matrix->getValue(1, 1); 121 break; 122 case 2: 123 $determinant = $matrix->getValue(1, 1) * $matrix->getValue(2, 2) - 124 $matrix->getValue(1, 2) * $matrix->getValue(2, 1); 125 break; 126 default: 127 for ($i = 1; $i <= $dimensions; ++$i) { 128 $det = $matrix->getValue(1, $i) * self::getDeterminantSegment($matrix, 0, $i - 1); 129 if (($i % 2) == 0) { 130 $determinant -= $det; 131 } else { 132 $determinant += $det; 133 } 134 } 135 break; 136 } 137 138 return $determinant; 139 } 140 141 /** 142 * Return the determinant of this matrix 143 * 144 * @param Matrix $matrix The matrix whose determinant we wish to calculate 145 * @return float 146 * @throws Exception 147 **/ 148 public static function determinant(Matrix $matrix) 149 { 150 if (!$matrix->isSquare()) { 151 throw new Exception('Determinant can only be calculated for a square matrix'); 152 } 153 154 return self::getDeterminant($matrix); 155 } 156 157 /** 158 * Return the diagonal of this matrix 159 * 160 * @param Matrix $matrix The matrix whose diagonal we wish to calculate 161 * @return Matrix 162 * @throws Exception 163 **/ 164 public static function diagonal(Matrix $matrix) 165 { 166 if (!$matrix->isSquare()) { 167 throw new Exception('Diagonal can only be extracted from a square matrix'); 168 } 169 170 $dimensions = $matrix->rows; 171 $grid = Builder::createFilledMatrix(0, $dimensions, $dimensions) 172 ->toArray(); 173 174 for ($i = 0; $i < $dimensions; ++$i) { 175 $grid[$i][$i] = $matrix->getValue($i + 1, $i + 1); 176 } 177 178 return new Matrix($grid); 179 } 180 181 /** 182 * Return the antidiagonal of this matrix 183 * 184 * @param Matrix $matrix The matrix whose antidiagonal we wish to calculate 185 * @return Matrix 186 * @throws Exception 187 **/ 188 public static function antidiagonal(Matrix $matrix) 189 { 190 if (!$matrix->isSquare()) { 191 throw new Exception('Anti-Diagonal can only be extracted from a square matrix'); 192 } 193 194 $dimensions = $matrix->rows; 195 $grid = Builder::createFilledMatrix(0, $dimensions, $dimensions) 196 ->toArray(); 197 198 for ($i = 0; $i < $dimensions; ++$i) { 199 $grid[$i][$dimensions - $i - 1] = $matrix->getValue($i + 1, $dimensions - $i); 200 } 201 202 return new Matrix($grid); 203 } 204 205 /** 206 * Return the identity matrix 207 * The identity matrix, or sometimes ambiguously called a unit matrix, of size n is the n × n square matrix 208 * with ones on the main diagonal and zeros elsewhere 209 * 210 * @param Matrix $matrix The matrix whose identity we wish to calculate 211 * @return Matrix 212 * @throws Exception 213 **/ 214 public static function identity(Matrix $matrix) 215 { 216 if (!$matrix->isSquare()) { 217 throw new Exception('Identity can only be created for a square matrix'); 218 } 219 220 $dimensions = $matrix->rows; 221 222 return Builder::createIdentityMatrix($dimensions); 223 } 224 225 /** 226 * Return the inverse of this matrix 227 * 228 * @param Matrix $matrix The matrix whose inverse we wish to calculate 229 * @return Matrix 230 * @throws Exception 231 **/ 232 public static function inverse(Matrix $matrix) 233 { 234 if (!$matrix->isSquare()) { 235 throw new Exception('Inverse can only be calculated for a square matrix'); 236 } 237 238 $determinant = self::getDeterminant($matrix); 239 if ($determinant == 0.0) { 240 throw new Exception('Inverse can only be calculated for a matrix with a non-zero determinant'); 241 } 242 243 if ($matrix->rows == 1) { 244 return new Matrix([[1 / $matrix->getValue(1, 1)]]); 245 } 246 247 return self::getAdjoint($matrix) 248 ->multiply(1 / $determinant); 249 } 250 251 /** 252 * Calculate the minors of the matrix 253 * 254 * @param Matrix $matrix The matrix whose minors we wish to calculate 255 * @return array[] 256 * 257 * @throws Exception 258 */ 259 protected static function getMinors(Matrix $matrix) 260 { 261 $minors = $matrix->toArray(); 262 $dimensions = $matrix->rows; 263 if ($dimensions == 1) { 264 return $minors; 265 } 266 267 for ($i = 0; $i < $dimensions; ++$i) { 268 for ($j = 0; $j < $dimensions; ++$j) { 269 $minors[$i][$j] = self::getDeterminantSegment($matrix, $i, $j); 270 } 271 } 272 273 return $minors; 274 } 275 276 /** 277 * Return the minors of the matrix 278 * The minor of a matrix A is the determinant of some smaller square matrix, cut down from A by removing one or 279 * more of its rows or columns. 280 * Minors obtained by removing just one row and one column from square matrices (first minors) are required for 281 * calculating matrix cofactors, which in turn are useful for computing both the determinant and inverse of 282 * square matrices. 283 * 284 * @param Matrix $matrix The matrix whose minors we wish to calculate 285 * @return Matrix 286 * @throws Exception 287 **/ 288 public static function minors(Matrix $matrix) 289 { 290 if (!$matrix->isSquare()) { 291 throw new Exception('Minors can only be calculated for a square matrix'); 292 } 293 294 return new Matrix(self::getMinors($matrix)); 295 } 296 297 /** 298 * Return the trace of this matrix 299 * The trace is defined as the sum of the elements on the main diagonal (the diagonal from the upper left to the lower right) 300 * of the matrix 301 * 302 * @param Matrix $matrix The matrix whose trace we wish to calculate 303 * @return float 304 * @throws Exception 305 **/ 306 public static function trace(Matrix $matrix) 307 { 308 if (!$matrix->isSquare()) { 309 throw new Exception('Trace can only be extracted from a square matrix'); 310 } 311 312 $dimensions = $matrix->rows; 313 $result = 0; 314 for ($i = 1; $i <= $dimensions; ++$i) { 315 $result += $matrix->getValue($i, $i); 316 } 317 318 return $result; 319 } 320 321 /** 322 * Return the transpose of this matrix 323 * 324 * @param Matrix $matrix The matrix whose transpose we wish to calculate 325 * @return Matrix 326 **/ 327 public static function transpose(Matrix $matrix) 328 { 329 $array = array_values(array_merge([null], $matrix->toArray())); 330 $grid = call_user_func_array( 331 'array_map', 332 $array 333 ); 334 335 return new Matrix($grid); 336 } 337 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body