Skip to content

Commit

Permalink
Adding export_data. Adding tests for export_data. Cleaning up test data.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmdunla committed Jun 27, 2022
1 parent 1cc199f commit cf9598a
Show file tree
Hide file tree
Showing 6 changed files with 222 additions and 78 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ build/
.ipynb_checkpoints
htmlcov
__pycache__
.vs*
.vs*
TestResults
1 change: 1 addition & 0 deletions TensorToolbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from TensorToolbox.cp_als import cp_als

from TensorToolbox.import_data import import_data
from TensorToolbox.export_data import export_data

import warnings
def ignore_warnings(ignore=True):
Expand Down
103 changes: 103 additions & 0 deletions TensorToolbox/export_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Copyright 2022 National Technology & Engineering Solutions of Sandia,
# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the
# U.S. Government retains certain rights in this software.

import numpy as np
import os
import TensorToolbox as ttb

def export_data(data, filename, fmt_data=None, fmt_weights=None):
"""
Export tensor-related data to a file.
"""
# open file
fp = open(filename, 'w')

if isinstance(data, ttb.tensor):
print('tensor', file=fp)
export_size(fp, data.shape)
export_array(fp, data.data, fmt_data)

elif isinstance(data, ttb.sptensor):
print('sptensor', file=fp)
export_sparse_size(fp, data)
export_sparse_array(fp, data, fmt_data)

elif isinstance(data, ttb.ktensor):
print('ktensor', file=fp)
export_size(fp, data.shape)
export_rank(fp, data)
export_weights(fp, data, fmt_weights)
for n in range(data.ndims):
print('matrix', file=fp)
export_size(fp, data.factor_matrices[n].shape)
export_factor(fp, data.factor_matrices[n], fmt_data)
"""
fprintf(fid, 'ktensor\n');
export_size(fid, size(A));
export_rank(fid, A);
export_lambda(fid, A.lambda, fmt_lambda);
for n = 1:length(size(A))
fprintf(fid, 'matrix\n');
export_size(fid, size(A.U{n}));
export_factor(fid, A.U{n}, fmt_data);
end
"""

elif isinstance(data, np.ndarray):
print('matrix', file=fp)
export_size(fp, data.shape)
export_array(fp, data, fmt_data)

else:
assert False, 'Invalid data type for export'

def export_size(fp, shape):
# Export the size of something to a file
print(f'{len(shape)}', file=fp) # # of dimensions on one line
shape_str = ' '.join([str(d) for d in shape])
print(f'{shape_str}', file=fp) # size of each dimensions on the next line

def export_rank(fp, data):
# Export the rank of a ktensor to a file
print(f'{len(data.weights)}', file=fp) # ktensor rank on one line

def export_weights(fp, data, fmt_weights):
# Export dense data that supports numel and linear indexing
if not fmt_weights: fmt_weights = '%.16e'
data.weights.tofile(fp, sep=' ', format=fmt_weights)
print(file=fp)

def export_array(fp, data, fmt_data):
# Export dense data that supports numel and linear indexing
if not fmt_data: fmt_data = '%.16e'
data.tofile(fp, sep='\n', format=fmt_data)
print(file=fp)

def export_factor(fp, data, fmt_data):
# Export dense data that supports numel and linear indexing
if not fmt_data: fmt_data = '%.16e'
for i in range(data.shape[0]):
row = data[i,:]
row.tofile(fp, sep=' ', format=fmt_data)
print(file=fp)

def export_sparse_size(fp, A):
# Export the size of something to a file
print(f'{len(A.shape)}', file=fp) # # of dimensions on one line
shape_str = ' '.join([str(d) for d in A.shape])
print(f'{shape_str}', file=fp) # size of each dimensions on the next line
print(f'{A.nnz}', file=fp) # number of nonzeros

def export_sparse_array(fp, A, fmt_data):
# Export sparse array data in coordinate format
if not fmt_data: fmt_data = '%.16e'
# TODO: looping through all values may take a long time, can this be more efficient?
for i in range(A.nnz):
# 0-based indexing in package, 1-based indexing in file
subs = A.subs[i,:] + 1
subs.tofile(fp, sep=' ', format="%d")
print(end=' ', file=fp)
val = A.vals[i][0]
val.tofile(fp, sep=' ', format=fmt_data)
print(file=fp)
12 changes: 8 additions & 4 deletions tests/data/matrix.tns
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
matrix
2
4 2
1.0000000000000000e+00 5.0000000000000000e+00
2.0000000000000000e+00 6.0000000000000000e+00
3.0000000000000000e+00 7.0000000000000000e+00
4.0000000000000000e+00 8.0000000000000000e+00
1.0000000000000000e+00
5.0000000000000000e+00
2.0000000000000000e+00
6.0000000000000000e+00
3.0000000000000000e+00
7.0000000000000000e+00
4.0000000000000000e+00
8.0000000000000000e+00
22 changes: 0 additions & 22 deletions tests/data/sptensor_zero_based_index.tns

This file was deleted.

159 changes: 108 additions & 51 deletions tests/test_import_export_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,54 @@
import TensorToolbox as ttb

@pytest.fixture()
def sample_tensor_2way():
data = np.array([[1., 2., 3.], [4., 5., 6.]])
shape = (2, 3)
params = {'data':data, 'shape': shape}
tensorInstance = ttb.tensor().from_data(data, shape)
return params, tensorInstance
def sample_tensor():
# truth data
T = ttb.tensor.from_data(np.ones((3,3,3)), (3,3,3))
return T

@pytest.fixture()
def sample_tensor_3way():
data = np.array([1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.])
shape = (2, 3, 2)
params = {'data':np.reshape(data, np.array(shape), order='F'), 'shape': shape}
tensorInstance = ttb.tensor().from_data(data, shape)
return params, tensorInstance
def sample_sptensor():
# truth data
subs = np.array([[0, 0, 0],[0, 2, 2],[1, 1, 1],[1, 2, 0],[1, 2, 1],[1, 2, 2],
[1, 3, 1],[2, 0, 0],[2, 0, 1],[2, 2, 0],[2, 2, 1],[2, 3, 0],
[2, 3, 2],[3, 0, 0],[3, 0, 1],[3, 2, 0],[4, 0, 2],[4, 3, 2]])
vals = np.reshape(np.array(range(1,19)),(18,1))
shape = (5, 4, 3)
S = ttb.sptensor().from_data(subs, vals, shape)
return S

@pytest.fixture()
def sample_tensor_4way():
data = np.arange(1, 82)
shape = (3, 3, 3, 3)
params = {'data':np.reshape(data, np.array(shape), order='F'), 'shape': shape}
tensorInstance = ttb.tensor().from_data(data, shape)
return params, tensorInstance
def sample_ktensor():
# truth data
weights = np.array([3, 2])
fm0 = np.array([[1., 5.], [2., 6.], [3., 7.], [4., 8.]])
fm1 = np.array([[ 2., 7.], [ 3., 8.], [ 4., 9.], [ 5., 10.], [ 6., 11.]])
fm2 = np.array([[3., 6.], [4., 7.], [5., 8.]])
factor_matrices = [fm0, fm1, fm2]
K = ttb.ktensor.from_data(weights, factor_matrices)
return K

@pytest.fixture()
def sample_array():
# truth data
M = np.array([[1., 5.], [2., 6.], [3., 7.], [4., 8.]])
return M

@pytest.mark.indevelopment
def test_import_data_tensor():
def test_import_data_tensor(sample_tensor):
# truth data
T = ttb.tensor.from_data(np.ones((3,3,3)), (3,3,3))
T = sample_tensor

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','tensor.tns')
X = ttb.import_data(data_filename)

assert X.shape == (3, 3, 3)
assert T.isequal(X)

@pytest.mark.indevelopment
def test_import_data_sptensor():
def test_import_data_sptensor(sample_sptensor):
# truth data
subs = np.array([[0, 0, 0],[0, 2, 2],[1, 1, 1],[1, 2, 0],[1, 2, 1],[1, 2, 2],
[1, 3, 1],[2, 0, 0],[2, 0, 1],[2, 2, 0],[2, 2, 1],[2, 3, 0],
[2, 3, 2],[3, 0, 0],[3, 0, 1],[3, 2, 0],[4, 0, 2],[4, 3, 2]])
vals = np.reshape(np.array(range(1,19)),(18,1))
shape = (5, 4, 3)
S = ttb.sptensor().from_data(subs, vals, shape)
S = sample_sptensor

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','sptensor.tns')
Expand All @@ -60,49 +64,102 @@ def test_import_data_sptensor():
assert S.isequal(X)

@pytest.mark.indevelopment
def test_import_data_ktensor():
def test_import_data_ktensor(sample_ktensor):
# truth data
weights = np.array([3, 2])
fm0 = np.array([[1., 5.], [2., 6.], [3., 7.], [4., 8.]])
fm1 = np.array([[ 2., 7.], [ 3., 8.], [ 4., 9.], [ 5., 10.], [ 6., 11.]])
fm2 = np.array([[3., 6.], [4., 7.], [5., 8.]])
factor_matrices = [fm0, fm1, fm2]
K = ttb.ktensor.from_data(weights, factor_matrices)

K = sample_ktensor

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','ktensor.tns')
X = ttb.import_data(data_filename)

assert K.isequal(X)

@pytest.mark.indevelopment
def test_import_data_array():
def test_import_data_array(sample_array):
# truth data
M = np.array([[1., 5.], [2., 6.], [3., 7.], [4., 8.]])
print('\nM')
print(M)

M = sample_array

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','matrix.tns')
X = ttb.import_data(data_filename)
print('\nX')
print(X)

assert (M == X).all()

@pytest.mark.indevelopment
def test_export_data_tensor():
pass
def test_export_data_tensor(sample_tensor):
# truth data
T = sample_tensor

data_filename = os.path.join(os.path.dirname(__file__),'data','tensor.out')
ttb.export_data(T, data_filename)

X = ttb.import_data(data_filename)
assert T.isequal(X)
os.unlink(data_filename)

data_filename = os.path.join(os.path.dirname(__file__),'data','tensor_int.out')
ttb.export_data(T, data_filename, fmt_data='%d')

X = ttb.import_data(data_filename)
assert T.isequal(X)
os.unlink(data_filename)

@pytest.mark.indevelopment
def test_export_data_sptensor():
pass
def test_export_data_sptensor(sample_sptensor):
# truth data
S = sample_sptensor

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','sptensor.out')
ttb.export_data(S, data_filename)

X = ttb.import_data(data_filename)
assert S.isequal(X)
os.unlink(data_filename)

data_filename = os.path.join(os.path.dirname(__file__),'data','sptensor_int.out')
ttb.export_data(S, data_filename, fmt_data='%d')

X = ttb.import_data(data_filename)
assert S.isequal(X)
os.unlink(data_filename)

@pytest.mark.indevelopment
def test_export_data_ktensor():
pass
def test_export_data_ktensor(sample_ktensor):
# truth data
K = sample_ktensor

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','ktensor.out')
ttb.export_data(K, data_filename)

X = ttb.import_data(data_filename)
assert K.isequal(X)
os.unlink(data_filename)

data_filename = os.path.join(os.path.dirname(__file__),'data','ktensor_int.out')
ttb.export_data(K, data_filename, fmt_data='%d', fmt_weights='%d')

X = ttb.import_data(data_filename)
assert K.isequal(X)
os.unlink(data_filename)

@pytest.mark.indevelopment
def test_export_data_array():
pass
def test_export_data_array(sample_array):
# truth data
M = sample_array

# imported data
data_filename = os.path.join(os.path.dirname(__file__),'data','matrix.out')
ttb.export_data(M, data_filename)

X = ttb.import_data(data_filename)
assert (M == X).all()
os.unlink(data_filename)

data_filename = os.path.join(os.path.dirname(__file__),'data','matrix_int.out')
ttb.export_data(M, data_filename, fmt_data='%d')

X = ttb.import_data(data_filename)
assert (M == X).all()
os.unlink(data_filename)

0 comments on commit cf9598a

Please sign in to comment.