#!/usr/bin/env ruby
require("gsl")
require("./gsl_test2.rb")
include GSL::Test

def check(x, actual, eps)
  if x == actual
    return 0
  elsif atcual.zero?
    return x.abs > eps ? 1 : 0
  else
    return ((x - actual).abs/actual.abs > eps) ? 1 : 0
  end
end

def create_hilbert_matrix(size)
  m = Matrix.new(size, size)
  for i in 0...size
    for j in 0...size
      m.set(i, j, 1.0/(i+j+1.0))
    end
  end
  return m
end

def create_general_matrix(size1, size2)
  m = Matrix.new(size1, size2)
  for i in 0...size1
    for j in 0...size2
      m.set(i, j, 1.0/(i+j+1.0))
    end
  end
  return m
end

def create_singular_matrix(size1, size2)
  m = create_general_matrix(size1, size2)
  for j in 0...m.size2
    m.set(0, j, 0.0)
  end
  return m
end

def create_vandermonde_matrix(size)
  m = Matrix.new(size, size)
  for i in 0...size
    for j in 0...size
      m.set(i, j, pow(i + 1.0, size - j - 1.0))
    end
  end
  return m
end

def create_moler_matrix(size)
  m = Matrix.new(size, size)
  for i in 0...size
    for j in 0...size
      m.set(i, j, GSL::MIN(i+1, j+1) - 2.0)
    end
  end
  return m
end

def create_complex_matrix(size)
  m = Matrix::Complex.new(size, size)
  for i in 0...size
    for j in 0...size
      z = GSL::Complex.new(1.0/(i+j+1.0), 1/(i*i+j*j+0.5))
      m.set(i, j, z)
    end
  end
  return m
end

def create_row_matrix(size1, size2)
  m = Matrix.new(size1, size2)
  for i in 0...size1
    m.set(i, 0, 1.0/(i + 1.0))
  end
  return m
end

def create_2x2_matrix(a11, a12, a21, a22)
  return Matrix.new(a11, a12, a21, a22)
end

def create_diagonal_matrix(a, size)
  m = Matrix.new(size, size)
  for i in 0...size
    m.set(i, i, a[i])
  end
  return m
end

inf5_data = Vector.new(1.0, 0.0, -3.0, 0.0, -5.0)
m53_lssolution = Vector.new(52.5992295702070, -337.7263113752073, 351.8823436427604)
hilb2_solution = Vector.new(-8.0, 18.0)
hilb3_solution = Vector.new(27.0, -192.0, 210.0)
hilb4_solution = Vector.new(-64.0, 900.0, -2520.0, 1820.0)
hilb12_solution = Vector.new(-1728.0, 245388.0, -8528520.0, 
                             127026900.0, -1009008000.0, 4768571808.0, 
                             -14202796608.0, 27336497760.0, -33921201600.0,
                             26189163000.0, -11437874448.0, 2157916488.0)

c7_solution = Vector.new(2.40717272023734e+01, -9.84612797621247e+00,
                         -2.69338853034031e+02, 8.75455232472528e+01,
                         2.96661356736296e+03, -1.02624473923993e+03,
                         -1.82073812124749e+04, 5.67384473042410e+03,
                         5.57693879019068e+04, -1.61540963210502e+04,
                         -7.88941207561151e+04, 1.95053812987858e+04,
                         3.95548551241728e+04, -7.76593696255317e+03)

vander2_solution = Vector.new(1.0, 0.0) 
vander3_solution = Vector.new(0.0, 1.0, 0.0) 
vander4_solution = Vector.new(0.0, 0.0, 1.0, 0.0) 
vander12_solution = Vector.new(0.0, 0.0, 0.0, 0.0,
                            0.0, 0.0, 0.0, 0.0, 
                            0.0, 0.0, 1.0, 0.0) 

def test_matmult()
  s = 0
  a = Matrix.new([10.0, 5.0, 1.0, 20.0], 2, 2)
  b = Matrix.new([10.0, 5.0, 2.0, 1.0, 3.0, 2.0], 2, 3)
  c = a**b
  s += ((c[0][0] - 105.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  s += ((c[0][1] -  65.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  s += ((c[0][2] -  30.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  s += ((c[1][0] -  30.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  s += ((c[1][1] -  65.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  s += ((c[1][2] -  42.0).abs > GSL::DBL_EPSILON) ? 1 : 0
  return s
end

def test_bidiag_decomp_dim(m, eps)
  a = m.clone
  tau1, tau2 = a.bidiag_decomp
end

