Skip to content

Commit

Permalink
Fixed a bug in SVD
Browse files Browse the repository at this point in the history
Added coverage tests for decomposition module

Signed-off-by: Timothy Click <tcthepoet@yahoo.com>
  • Loading branch information
Timothy Click committed Jan 9, 2019
1 parent 95be2b1 commit 8271650
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/fluctmatch/decomposition/svd.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,10 +343,10 @@ def _fit_truncated(self, X, n_components, svd_solver):
U, S, V = randomized_svd(X, n_components=n_components,
n_iter=self.iterated_power,
flip_sign=True, random_state=random_state)
U = U[:, :self.n_components_]
U = U[:, :n_components]

# X_new = X * V = U * S * V^T * V = U * S
U *= S[:self.n_components_]
U *= S[:n_components]

components_: np.ndarray = V

Expand Down
52 changes: 52 additions & 0 deletions tests/decomposition/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding: utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# pysca --- https://github.com/tclick/python-pysca
# Copyright (c) 2015-2017 The pySCA Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the New BSD license.
#
# Please cite your use of fluctmatch in published work:
#
# Timothy H. Click, Nixon Raj, and Jhih-Wei Chu.
# Calculation of Enzyme Fluctuograms from All-Atom Molecular Dynamics
# Simulation. Meth Enzymology. 578 (2016), 327-342,
# doi:10.1016/bs.mie.2016.05.024.
#
from __future__ import (
absolute_import,
division,
print_function,
unicode_literals,
)

from future.utils import (
native_str,
raise_from,
with_metaclass,
)
from future.builtins import (
ascii,
bytes,
chr,
dict,
filter,
hex,
input,
map,
next,
oct,
open,
pow,
range,
round,
str,
super,
zip,
)

import numpy as np
import pandas as pd


41 changes: 41 additions & 0 deletions tests/decomposition/test_eigh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding: utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# fluctmatch --- https://github.com/tclick/python-fluctmatch
# Copyright (c) 2015-2017 The fluctmatch Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the New BSD license.
#
# Please cite your use of fluctmatch in published work:
#
# Timothy H. Click, Nixon Raj, and Jhih-Wei Chu.
# Calculation of Enzyme Fluctuograms from All-Atom Molecular Dynamics
# Simulation. Meth Enzymology. 578 (2016), 327-342,
# doi:10.1016/bs.mie.2016.05.024.
#

import numpy as np
from numpy import testing
from sklearn.utils.extmath import svd_flip

from fluctmatch.decomposition.eigh import Eigh

# Constants
X: np.ndarray = np.array([
[1, 2, 0],
[2, 4, 0],
[0, 0, 3]
])
L: np.ndarray = np.array([5., 3., 0.])
V: np.ndarray = np.array([
[np.sqrt(0.2), 0, np.sqrt(0.8)],
[np.sqrt(0.8), 0, -np.sqrt(0.2)],
[0, 1, 0]
])

def test_eigh():
eigh = Eigh()
Vtest = eigh.fit_transform(X)
testing.assert_almost_equal(Vtest, V, decimal=6)
testing.assert_almost_equal(eigh.eigenvalues_, L, decimal=6)
76 changes: 76 additions & 0 deletions tests/decomposition/test_svd.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding: utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# fluctmatch --- https://github.com/tclick/python-fluctmatch
# Copyright (c) 2015-2017 The fluctmatch Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the New BSD license.
#
# Please cite your use of fluctmatch in published work:
#
# Timothy H. Click, Nixon Raj, and Jhih-Wei Chu.
# Calculation of Enzyme Fluctuograms from All-Atom Molecular Dynamics
# Simulation. Meth Enzymology. 578 (2016), 327-342,
# doi:10.1016/bs.mie.2016.05.024.
#
import numpy as np
from numpy import testing
from sklearn.utils.extmath import svd_flip
from fluctmatch.decomposition.svd import SVD

# Constants
X: np.ndarray = np.array([
[1, 0, 0, 0, 2],
[0, 0, 3, 0, 0],
[0, 0, 0, 0, 0],
[0, 2, 0, 0, 0]
])
U: np.ndarray = np.array([
[0, 1, 0, 0],
[1, 0, 0, 0],
[0, 0, 0, -1],
[0, 0, 1, 0]
])
S: np.ndarray = np.array([3, np.sqrt(5), 2, 0])
VT: np.ndarray = np.array([
[0, 0, 1, 0, 0],
[np.sqrt(0.2), 0, 0, 0, np.sqrt(0.8)],
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0]
])
U, VT = svd_flip(U, VT)
US: np.ndarray = U * S
N_COMPONENTS_ = 3


def test_full():
svd = SVD(svd_solver="full")
Utest = svd.fit_transform(X)
testing.assert_array_almost_equal(Utest, US, decimal=6)
testing.assert_array_almost_equal(svd.singular_values_, S, decimal=6)
testing.assert_array_almost_equal(svd.components_, VT, decimal=6)


def test_randomized():
svd = SVD(svd_solver="randomized")
Utest = svd.fit_transform(X)
testing.assert_array_almost_equal(Utest, US, decimal=6)
testing.assert_array_almost_equal(svd.singular_values_, S, decimal=6)
testing.assert_array_almost_equal(svd.components_, VT, decimal=6)


def test_trunc_randomized():
svd = SVD(n_components=N_COMPONENTS_, svd_solver="randomized")
Utest = svd.fit_transform(X)
testing.assert_array_almost_equal(Utest, US[:, :N_COMPONENTS_], decimal=6)
testing.assert_array_almost_equal(svd.singular_values_, S[:N_COMPONENTS_], decimal=6)
testing.assert_array_almost_equal(svd.components_, VT[:N_COMPONENTS_], decimal=6)


def test_trunc_arpack():
svd = SVD(n_components=N_COMPONENTS_, svd_solver="arpack")
Utest = svd.fit_transform(X)
testing.assert_array_almost_equal(Utest, US[:, :N_COMPONENTS_], decimal=6)
testing.assert_array_almost_equal(svd.singular_values_, S[:N_COMPONENTS_], decimal=6)
testing.assert_array_almost_equal(svd.components_, VT[:N_COMPONENTS_], decimal=6)

0 comments on commit 8271650

Please sign in to comment.