1<?php 2 3namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig; 4 5use Matrix\Builder; 6use Matrix\Exception as MatrixException; 7use Matrix\Matrix; 8use PhpOffice\PhpSpreadsheet\Calculation\Exception; 9use PhpOffice\PhpSpreadsheet\Calculation\Functions; 10 11class MatrixFunctions 12{ 13 /** 14 * Convert parameter to matrix. 15 * 16 * @param mixed $matrixValues A matrix of values 17 */ 18 private static function getMatrix($matrixValues): Matrix 19 { 20 $matrixData = []; 21 if (!is_array($matrixValues)) { 22 $matrixValues = [[$matrixValues]]; 23 } 24 25 $row = 0; 26 foreach ($matrixValues as $matrixRow) { 27 if (!is_array($matrixRow)) { 28 $matrixRow = [$matrixRow]; 29 } 30 $column = 0; 31 foreach ($matrixRow as $matrixCell) { 32 if ((is_string($matrixCell)) || ($matrixCell === null)) { 33 throw new Exception(Functions::VALUE()); 34 } 35 $matrixData[$row][$column] = $matrixCell; 36 ++$column; 37 } 38 ++$row; 39 } 40 41 return new Matrix($matrixData); 42 } 43 44 /** 45 * MDETERM. 46 * 47 * Returns the matrix determinant of an array. 48 * 49 * Excel Function: 50 * MDETERM(array) 51 * 52 * @param mixed $matrixValues A matrix of values 53 * 54 * @return float|string The result, or a string containing an error 55 */ 56 public static function determinant($matrixValues) 57 { 58 try { 59 $matrix = self::getMatrix($matrixValues); 60 61 return $matrix->determinant(); 62 } catch (MatrixException $ex) { 63 return Functions::VALUE(); 64 } catch (Exception $e) { 65 return $e->getMessage(); 66 } 67 } 68 69 /** 70 * MINVERSE. 71 * 72 * Returns the inverse matrix for the matrix stored in an array. 73 * 74 * Excel Function: 75 * MINVERSE(array) 76 * 77 * @param mixed $matrixValues A matrix of values 78 * 79 * @return array|string The result, or a string containing an error 80 */ 81 public static function inverse($matrixValues) 82 { 83 try { 84 $matrix = self::getMatrix($matrixValues); 85 86 return $matrix->inverse()->toArray(); 87 } catch (MatrixException $e) { 88 return (strpos($e->getMessage(), 'determinant') === false) ? Functions::VALUE() : Functions::NAN(); 89 } catch (Exception $e) { 90 return $e->getMessage(); 91 } 92 } 93 94 /** 95 * MMULT. 96 * 97 * @param mixed $matrixData1 A matrix of values 98 * @param mixed $matrixData2 A matrix of values 99 * 100 * @return array|string The result, or a string containing an error 101 */ 102 public static function multiply($matrixData1, $matrixData2) 103 { 104 try { 105 $matrixA = self::getMatrix($matrixData1); 106 $matrixB = self::getMatrix($matrixData2); 107 108 return $matrixA->multiply($matrixB)->toArray(); 109 } catch (MatrixException $ex) { 110 return Functions::VALUE(); 111 } catch (Exception $e) { 112 return $e->getMessage(); 113 } 114 } 115 116 /** 117 * MUnit. 118 * 119 * @param mixed $dimension Number of rows and columns 120 * 121 * @return array|string The result, or a string containing an error 122 */ 123 public static function identity($dimension) 124 { 125 try { 126 $dimension = (int) Helpers::validateNumericNullBool($dimension); 127 Helpers::validatePositive($dimension, Functions::VALUE()); 128 $matrix = Builder::createFilledMatrix(0, $dimension)->toArray(); 129 for ($x = 0; $x < $dimension; ++$x) { 130 $matrix[$x][$x] = 1; 131 } 132 133 return $matrix; 134 } catch (Exception $e) { 135 return $e->getMessage(); 136 } 137 } 138} 139