nfTlWNl rn7pj-u8gB'֘;e4"oԗ|CA1vx4)xtDL\O%],D,K^v~QͿ:C=^ܘ6X/Qq0D;E|.4L*#@I+7N c\kЂuہ3IFE^'긙m ;S9g9Pb̅V$+n`l_tnAMOJiPl)wD@$Y?,hDZ @7f((ѯ[iie~ <)U9u;F 0/#x3\dO@ #aT"fX'UsNrl*~npi;%Gcv/whBe7x0F ZvY@o?G-i%N\IMQsA ~xђr{h~nqAV 72#x_ Mh&lijuD"0VH#/epufDв0\g-=oϲ><>,?Q8"zF[W K+I lQ*>psq/hVnȐ24 p9G_Yr  { $'Fzp E抩7RI5h ĢQ$3TEVF T "T z`t%IShxJ4-G=T]cۥHX}%},jg#߉} <٬ܦ&  $%W (dnΨ`; 'Fu4$$u<(7ơ0Pue5#A+J#?Cr9m{ς4 MoMG|8Iqģyq; W-<-ؿN4ILpaf=5%_'ٚNX3ʍEAyI $78?|QJiC&4^DN,N˾n1S^ή%}+l\zk&%G $kO={h;CȐPZ72ƾ'ی%#x s#e芽K͓!~{rIf {FEsEU =8ϻ⅀Ϲb`zdZ [i>I]4{H7%^FEFz3@.2k:bR^mv喸Z2xx (dnΨ`; '3;slFLm HXaˋ}*̩rFDj1ppH b/$qzq{ ĢQ$31#$0干/kt$P\ 4k2ӓl)0 ; [,`!/`IZEe*" &瑒E+tKPc2Q?V2.8L80F3 ,:!+lmm&zv#qH\ rE|CR4@Lm7| .awz6V1$ G:R|Z Y\Tb^qk!ֻqG#M_k5Z4@әGUoON{[ |NNTNЫ` C"9,5o 1*gL7UI^2P@Ņ=ސ()U\ʻAJImG.{X_*цH1R=9ra z8$թ q"rI ȏY׾갍^:KCO0lBzٮ8JϝŶj-@OTm@ ĢQ$3,ia_ߍfMs _y,j~{gQO,'@N Qg#ՔHǯ 7J5`; Tҫ1D&3px>N am@liЉ/`<`)GKY(aٳeΏVss ,o0E ZGguC %+9)Ӽq(VitAЦ x6_+nB UA)EuӐ^ܯ37Xfp T9CLߎG4`5cC+.z Y\Tb^q"&.M]@k,mh4^Čɖ'GrgtwQ^DCnUъXvp $˳͜qy݊Ho#Ҳ8=8Z\&4^DN,N˾s'9~D} mtCU1Y+=.)5og&YiSDsY5T쒫c9Grpހ^ ̣#aƣչ'gnV1ep}bE%CI}7(c JA7!;=J 4wƩʂa dDݟt %9)17$ Nni؄kǣ<R^ΑdI8A?Ao8Tì-}0/(ZL6$2;7*CPVMΊal^vy2^i\[pŗܽjZp[.Z msL]`G%׏G4VVr<2UJ3Iz2E;+9r#`GhT+۟Gf _ڲ m *_K|:(8D%vXBbWýӦPVYK6`7"eOgCd! [) v4Zے ԫ@sAq2!qDV[|f^˞n3v0>\#jt^懶0Ikn'*OV!/ꙌR+4T,TxzF[W O%Q;H<x ųt_bKq31#I,7[Hj^W6/K͎_:Nk?A뇤3߈ya~1; Y\Tb^qsRFB{DqG2T V-dA( z&sXؽr  w !鿗it݁3~ېNA(0a" p\qwvfYij*+a ĢQ$3h,:/.CkBR4@Lm1#$0干/h~ (!qbz^P%]L̻hpc XyVhjL ĢQ$3뇤3߈ydLK R4@Lm1#$0干/W s"P8#~^&k1v[8z9.UBX7KH(%QouIDt,H|`rZO67r'/|fyf[rows; ++$i) { $s += $this->qrMatrix[$i][$k] * $this->qrMatrix[$i][$j]; } $s = -$s / $this->qrMatrix[$k][$k]; for ($i = $k; $i < $this->rows; ++$i) { $this->qrMatrix[$i][$j] += $s * $this->qrMatrix[$i][$k]; } } } $this->rDiagonal[$k] = -$norm; } } public function isFullRank(): bool { for ($j = 0; $j < $this->columns; ++$j) { if ($this->rDiagonal[$j] == 0.0) { return false; } } return true; } /** * Least squares solution of A*X = B. * * @param Matrix $B a Matrix with as many rows as A and any number of columns * * @throws Exception * * @return Matrix matrix that minimizes the two norm of Q*R*X-B */ public function solve(Matrix $B): Matrix { if ($B->rows !== $this->rows) { throw new Exception('Matrix row dimensions are not equal'); } if (!$this->isFullRank()) { throw new Exception('Can only perform this operation on a full-rank matrix'); } // Compute Y = transpose(Q)*B $Y = $this->getQ()->transpose() ->multiply($B); // Solve R*X = Y; return $this->getR()->inverse() ->multiply($Y); } }