lib/opr-calc/matrix.rb in opr-calc-0.1.2 vs lib/opr-calc/matrix.rb in opr-calc-1.0.0

- old
+ new

@@ -14,47 +14,54 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. =end -require "matrix" +require 'matrix' # Props to http://rosettacode.org/wiki/Cholesky_decomposition#Ruby :L class Matrix # Returns whether or not the Matrix is symmetric (http://en.wikipedia.org/wiki/Symmetric_matrix). def symmetric? # Matrices can't be symmetric if they're not square. return false unless square? (0...row_size).each do |i| (0..i).each do |j| + return false if self[i,j] != self[j,i] + end end true end # Determines the [L] matrix through Cholesky decomposition. # To obtain [L]*, just transpose the matrix, it should work. def cholesky_factor # We need a symmetric matrix for Cholesky decomposition. - raise ArgumentError, "must provide a symmetric matrix" unless symmetric? + raise ArgumentError, 'must provide a symmetric matrix' unless symmetric? # Make a new matrix to return. l = Array.new(row_size) { Array.new(row_size, 0) } (0...row_size).each do |k| (0...row_size).each do |i| + if i == k + sum = (0..k-1).inject(0.0) { |sum, j| sum + l[k][j] ** 2 } val = Math.sqrt(self[k,k] - sum) l[k][k] = val + elsif i > k + sum = (0..k-1).inject(0.0) { |sum, j| sum + l[i][j] * l[k][j] } val = (self[k,i] - sum) / l[k][k] l[i][k] = val + end end end Matrix[*l] @@ -62,13 +69,15 @@ # A helpful debug function for Matrices. def output (0..self.row_size - 1).each do |row_number| (0..self.column_size - 1).each do |column_number| - printf("%8.4f ", self[row_number, column_number]) + + printf('%8.4f ', self[row_number, column_number]) + end - printf("\n") + printf('\n') end self end end