[ ruby-Bugs-9360 ] Matrix inverse problem

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

rubyforgee$B%P%0%l%]!<%H$K0J2<$N$h$&$J%l%]!<%H$,Mh$F$^$9$,!";de(B
e$B$K$OH=CG$G$-$^$;$s!#$I$&$G$7$g$&!#@PDM$5$s!)e(B

e$B%3%a%s%H$OJT=8$7$F$"$j$^$9!#%Q%C%A$Oe(B(3e$B$D$"$ke(B)e$B:G=*HG$N$b$Ne(B

e$B$G$9!#e(B


There is a problem with the Matrix.inverse method.
Given the following matrix

m = Matrix[[0.417787968829298, 0.542037605627772, 

0.729142268138943],
[0.0, 6.12303176911189e-17, 1.0],
[-0.542037605627772, 0.417787968829298, -2.55812900589452e-17]]

the result of

m.inverse * m

is

[[1.0, 0.0, 0.650423523448542],
[5.55111512312578e-17, 1.0, 0.84385869292008],
[0.0, 9.24446373305873e-33, 1.0]]

but it should be

[[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0]]

or close to this!


The patch below should “fix” the inverse method. It adds partial
pivoting to the Gauss-Jordan algorithm, making it stable. (I used Ruby
1.8.5 (2006-08-22).)

I don’t think there is an error in the algorithm, and the matrix is not
ill-conditioned (a condition number of about 2.5 isn’t so bad).

Looks to me like BigDecimal uses Gaussian elimination with partial
pivoting too, or at least that’s what the comments say. It includes some
additional scaling, but this may be specific to BigDecimal (precision
works differently for BigDecimals and floats).

Peter

— lib/matrix.rb.old 2007-03-19 01:46:44.000000000 +0100
+++ lib/matrix.rb 2007-03-19 03:26:38.000000000 +0100
@@ -590,15 +590,21 @@
a = src.to_a

 for k in 0..size
  •  if (akk = a[k][k]) == 0
    
  •    i = k
    
  •    begin
    
  •      Matrix.Raise ErrNotRegular if (i += 1) > size
    
  •    end while a[i][k] == 0
    
  •  i = k
    
  •  akk = a[k][k].abs
    
  •  for j in (k+1)..size
    
  •    v = a[j][k].abs
    
  •    if v > akk
    
  •      i = j
    
  •      akk = v
    
  •    end
    
  •  end
    
  •  Matrix.Raise ErrNotRegular if akk == 0
    
  •  if i != k
       a[i], a[k] = a[k], a[i]
       @rows[i], @rows[k] = @rows[k], @rows[i]
    
  •    akk = a[k][k]
     end
    
  •  akk = a[k][k]
    
     for i in 0 .. size
       next if i == k

e$B$1$$$8$e!w$$$7$D$+$G$9e(B.

In [ruby-dev:30627] the message: “[ruby-dev:30627] [ ruby-Bugs-9360 ]
Matrix inverse problem”, on Mar/19 13:08(JST) Yukihiro M.
writes:

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

rubyforgee$B%P%0%l%]!<%H$K0J2<$N$h$&$J%l%]!<%H$,Mh$F$^$9$,!";de(B
e$B$K$OH=CG$G$-$^$;$s!#$I$&$G$7$g$&!#@PDM$5$s!)e(B

e$B5W$7$V$j$K?tCM2r@O$NK$rD4$Y$^$7$?e(B.
e$B$3$N$h$&$J=hM}$O>o<1$N$h$&$G$9e(B(e$BItJ,E*%T%%C%F%#%s%0$H8@$&$i$7$$e(B).

e$B7W;;%3%9%H$bL5;k$G$-$k$0$i$$7ZHy$H$J$C$F$$$k$N$Ge(B,
e$B$3$A$i$KJQ$($FNI$$$He(B
e$B;W$$$^$9e(B.

cie$B$O>>K$5$s$NJ}$G$7$^$9e(B?

__
---------------------------------------------------->> e$B@PDMe(B
e$B7=<ye(B <<—
---------------------------------->> e-mail: [email protected] <<—

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:30632] Re: [ ruby-Bugs-9360 ] Matrix inverse
problem”
on Mon, 19 Mar 2007 13:54:43 +0900, [email protected]
(e$B@PDM7=<ye(B) writes:

|e$B5W$7$V$j$K?tCM2r@O$NK$rD4$Y$^$7$?e(B.
|e$B$3$N$h$&$J=hM}$O>o<1$N$h$&$G$9e(B(e$BItJ,E*%T%%C%F%#%s%0$H8@$&$i$7$$e(B).
|
|e$B7W;;%3%9%H$bL5;k$G$-$k$0$i$$7ZHy$H$J$C$F$$$k$N$Ge(B, e$B$3$A$i$KJQ$($FNI$$$He(B
|e$B;W$$$^$9e(B.

e$BN;2r$7$^$7$?!#e(B

|cie$B$O>>K$5$s$NJ}$G$7$^$9e(B?

trunke$B$O;d$G$d$j$^$9!#e(B1.8e$B$Oe(Bknue$B$5$s$K$*G$$;$7$^$9!#e(B

At Mon, 19 Mar 2007 14:11:28 +0900,
matz wrote:

|ciは松本さんの方でします?

trunkは私でやります。1.8はknuさんにお任せします。

ã€€å¾Œã»ã©å–ã‚Šè¾¼ã¿ã¾ã™ã€‚ãƒ†ã‚¹ãƒˆã‚±ãƒ¼ã‚¹ã‚‚è¿½åŠ ã—ãŸã„ã§ã™ã­ã€‚


/
/__ __ Akinori.org / MUSHA.org
/ ) ) ) ) / FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp

“Different eyes see different things,
Different hearts beat on different strings –
But there are times for you and me when all such things agree”