#!/usr/bin/env ruby
# NOTE: gsl_tensor is not included in GSL:
# It is distributed separately as an add-on package for GSL.
# See http://sources.redhat.com/ml/gsl-discuss/2004-q4/msg00053.html.
#
require("gsl")
require("./gsl_test2.rb")
include GSL::Test
RANK = 3
DIMENSION = 5
t = Tensor.alloc(RANK, DIMENSION)
Test::test2(t.rank == RANK, "#{t.class}.alloc returns valid rank")
Test::test2(t.dimension == DIMENSION, "#{t.class}_alloc returns valid dimension")
counter = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
t.set(i, j, k, counter)
# t[i, j, k] = counter
end
end
end
status = 0
counter = 0
data = t.data # GSL::Vector::View
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
if data[DIMENSION*DIMENSION*i + DIMENSION*j + k] != counter
status += 1
end
end
end
end
Test::test(status, "#{t.class}#set writes into array")
status = 0
counter = 0
data = t.data
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
# if t.get(i, j, k) != counter
if t[i, j, k] != counter
status += 1
end
end
end
end
Test::test(status, "#{t.class}#get reads from array")
t = Tensor.calloc(RANK, DIMENSION)
counter = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
t.set(i, j, k, counter)
end
end
end
exp_max = t[0, 0, 0]
exp_min = t[0, 0, 0]
exp_imax = exp_jmax = exp_kmax = 0
exp_imin = exp_jmin = exp_kmin = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
value = t[i, j, k]
if value > exp_max
exp_max = value
exp_imax = i; exp_jmax = j; exp_kmax = k
end
if value < exp_min
exp_min = t[i, j, k]
exp_imin = i; exp_jmin = j; exp_kmin = k
end
end
end
end
max = t.max
Test::test2(max == exp_max, "#{t.class}#max returns correct maximum value")
min = t.min
Test::test2(min == exp_min, "#{t.class}#min returns correct minimum value")
min, max = t.minmax
Test::test2(max == exp_max, "#{t.class}#minmax returns correct maximum value")
Test::test2(min == exp_min, "#{t.class}#minmax returns correct minimum value")
imax = t.max_index
status = 0
if imax[0] != exp_imax; status += 1; end
if imax[1] != exp_jmax; status += 1; end
if imax[2] != exp_kmax; status += 1; end
Test::test(status, "#{t.class}#max_index returns correct maximum indices")
imin = t.min_index
status = 0
if imin[0] != exp_imin; status += 1; end
if imin[1] != exp_jmin; status += 1; end
if imin[2] != exp_kmin; status += 1; end
Test::test(status, "#{t.class}#min_index returns correct minimum indices")
imin, imax = t.minmax_index
status = 0
if imin[0] != exp_imin; status += 1; end
if imin[1] != exp_jmin; status += 1; end
if imin[2] != exp_kmin; status += 1; end
if imax[0] != exp_imax; status += 1; end
if imax[1] != exp_jmax; status += 1; end
if imax[2] != exp_kmax; status += 1; end
Test::test(status, "#{t.class}#minmax_index returns correct indices")
##### Operations
a = Tensor.new(RANK, DIMENSION)
b = Tensor.new(RANK, DIMENSION)
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
a[i, j, k] = 3 + i + 5 * j + 2 * k
b[i, j, k] = 3 + 2 * i + 4 * j + k
end
end
end
# Addition
c = a + b
#c = a.add(b)
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
r = c[i, j, k]
x = a[i, j, k]
y = b[i, j, k]
z = x + y
status += 1 if r != z
end
end
end
Test::test(status, "#{t.class}#add tensor addition")
# Subtraction
c = a - b
# c = a.sub(b)
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
r = c[i, j, k]
x = a[i, j, k]
y = b[i, j, k]
z = x - y
status += 1 if r != z
end
end
end
Test::test(status, "#{t.class}#sub tensor subtraction")
# Element multiplication
c = a.mul_elements(b)
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
r = c[i, j, k]
x = a[i, j, k]
y = b[i, j, k]
z = x * y
status += 1 if r != z
end
end
end
Test::test(status, "#{t.class}#mul_elements element multiplication")
# Element division
c = a.div_elements(b)
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
r = c[i, j, k]
x = a[i, j, k]
y = b[i, j, k]
z = x / y
if (r-z).abs > 2*GSL::FLT_EPSILON*z.abs; status += 1; end
end
end
end
Test::test(status, "#{t.class}#div_elements element division")
### Tensor product
c = a*b
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
for l in 0...DIMENSION do
for m in 0...DIMENSION do
for n in 0...DIMENSION do
r = c[i, j, k, l, m, n]
x = a[i, j, k]
y = b[l, m, n]
z = x*y
if r != z; status += 1; end
end
end
end
end
end
end
Test::test(status, "#{t.class}#product tensorial product")
### Index contraction
tt = a.contract(0, 1)
Test::test2(tt.rank == RANK-2, "#{t.class}.contract returns valid rank")
Test::test2(tt.dimension == DIMENSION, "#{t.class}_contract returns valid dimension")
### Swap indices
a_102 = a.swap_indices(0, 1)
a_210 = a.swap_indices(0, 2)
a_021 = a.swap_indices(1, 2)
status = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
x = a[i, j, k]
x_102 = a_102[j, i, k]
x_210 = a_210[k, j, i]
x_021 = a_021[i, k, j]
if x != x_102 or x != x_210 or x != x_021; status += 1; end
end
end
end
Test::test(status, "#{t.class}#swap_indices swap indices")
### Test text IO
file = "tensor_test.txt"
t = Tensor.alloc(RANK, DIMENSION)
counter = 0
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
t[i, j, k] = counter
end
end
end
t.fprintf(file, "%g")
tt = Tensor.alloc(RANK, DIMENSION)
status = 0
tt.fscanf(file)
counter = 0
data = tt.data
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
if data[DIMENSION*DIMENSION*i + DIMENSION*j + k] != counter
status += 1
end
end
end
end
Test::test(status, "#{t.class}#fprintf and fscanf")
File.delete(file)
### Test binary IO
file = "tensor_test.dat"
t.fwrite(file)
tt = Tensor.alloc(RANK, DIMENSION)
status = 0
tt.fread(file)
counter = 0
data = tt.data
for i in 0...DIMENSION do
for j in 0...DIMENSION do
for k in 0...DIMENSION do
counter += 1
if data[DIMENSION*DIMENSION*i + DIMENSION*j + k] != counter
status += 1
end
end
end
end
Test::test(status, "#{t.class}#fwrite and fread")
File.delete(file)
### Trap
i = j = k = 0
t = Tensor.calloc(RANK, DIMENSION)
begin
t[DIMENSION+1, 0, 0] = 1.2
rescue
# if an exception occurred
puts("PASS: #{t.class}#set traps 1st index above upper bound")
end
begin
t[0, DIMENSION+1, 0] = 1.2
rescue
puts("PASS: #{t.class}#set traps 2nd index above upper bound")
end
begin
t[0, 0, DIMENSION+1] = 1.2
rescue
puts("PASS: #{t.class}#set traps 3rd index above upper bound")
end
begin
t[0, DIMENSION, 0] = 1.2
rescue
puts("PASS: #{t.class}#set traps 2nd index at upper bound")
end
begin
t[0, i-1, 0] = 1.2
rescue
puts("PASS: #{t.class}#set traps 2nd index below lower bound")
end
begin
x = t[DIMENSION+1, 0, 0]
rescue
puts("PASS: #{t.class}#get traps 1st index above upper bound")
end
begin
x = t[0, DIMENSION+1, 0]
rescue
puts("PASS: #{t.class}#get traps 2nd index above upper bound")
end
begin
x = t[0, 0, DIMENSION+1]
rescue
puts("PASS: #{t.class}#get traps 3rd index above upper bound")
end
begin
x = t[0, DIMENSION, 0]
rescue
puts("PASS: #{t.class}#get traps 2nd index at upper bound")
end
begin
x = t[0, i-1, 0]
rescue
puts("PASS: #{t.class}#get traps 2nd index below lower bound")
end
#####
# Vector and Tensor, subtensors
v = GSL::Vector.new(0...125)
t = v.to_tensor(3, 5)
Test::test2(t.rank == RANK, "#{v.class}.to_tensor(#{RANK}, #{DIMENSION}) returns valid rank")
Test::test2(t.dimension == DIMENSION, "#{v.class}.to_tensor(#{RANK}, #{DIMENSION}) returns valid dimension")
m0_exp = Matrix[0...25, 5, 5]
m1_exp = Matrix[25...50, 5, 5]
m2_exp = Matrix[50...75, 5, 5]
m3_exp = Matrix[75...100, 5, 5]
m4_exp = Matrix[100...125, 5, 5]
# Create tensors of rank 2
t0 = t.subtensor(0)
t1 = t[1]
t2 = t.subtensor(2)
t3 = t[3]
t4 = t.subtensor(4)
# 2-tensors can be compared directly with matrices
Test::test2(t0 == m0_exp, "#{t.class}#subtensor(0) returns valid tensor")
Test::test2(t1 == m1_exp, "#{t.class}#subtensor(1) returns valid tensor")
Test::test2(t2 == m2_exp, "#{t.class}#subtensor(2) returns valid tensor")
Test::test2(t3 == m3_exp, "#{t.class}#subtensor(3) returns valid tensor")
Test::test2(t4 == m4_exp, "#{t.class}#subtensor(4) returns valid tensor")
v0_exp = Vector[100...105]
v1_exp = Vector[105...110]
v2_exp = Vector[110...115]
v3_exp = Vector[115...120]
v4_exp = Vector[120...125]
# Create tensors of rank1
v0 = t[4, 0]
v1 = t[4][1]
v2 = t.subtensor(4, 2)
v3 = t4[3]
v4 = t4.subtensor(4)
# 1-tensors can be compared directly with vectors
Test::test2(v0 == v0_exp, "#{t.class}#subtensor(4,0) returns valid tensor")
Test::test2(v1 == v1_exp, "#{t.class}#subtensor(4,1) returns valid tensor")
Test::test2(v2 == v2_exp, "#{t.class}#subtensor(4,2) returns valid tensor")
Test::test2(v3 == v3_exp, "#{t.class}#subtensor(4,3) returns valid tensor")
Test::test2(v4 == v4_exp, "#{t.class}#subtensor(4,4) returns valid tensor")
syntax highlighted by Code2HTML, v. 0.9.1