# Path: msaf/pymf/vol.py
# def cmdet(d):
# 	# compute the CMD determinant of the euclidean distance matrix d
# 	# -> d should not be squared!
# 	D = np.ones((d.shape[0]+1,d.shape[0]+1))
# 	D[0,0] = 0.0
# 	D[1:,1:] = d**2
# 	j = np.float32(D.shape[0]-2)
# 	f1 = (-1.0)**(j+1) / ( (2**j) * ((factorial(j))**2))
# 	cmd = f1 * np.linalg.det(D)
# 	# sometimes, for very small values "cmd" might be negative ...
# 	return np.sqrt(np.abs(cmd))


import logging
import numpy as np
    import doctest
from .dist import *
from .vol import cmdet
from .sivm import SIVM
    >>> data = np.array([[1.5, 1.3], [1.2, 0.3]])
    >>> W = np.array([[1.0, 0.0], [0.0, 1.0]])
    >>> sivm_mdl = SIVM_GSAT(data, num_bases=2)
    >>> sivm_mdl.W = W
    >>> sivm_mdl.factorize(compute_w=False)

    The result is a set of coefficients sivm_mdl.H, s.t. data = W * sivm_mdl.H.
    """

    def init_w(self):
        self.select = range(self._num_bases)
        self.W = self.data[:, self.select]

    def online_update_w(self, vec):
        # update D if it does not exist
        k = self._num_bases
        if not hasattr(self, 'D'):
            self.D = np.zeros((k + 1, k + 1))
            self.D[:k, :k] = pdist(self.W, self.W)
            self.V = cmdet(self.D[:k, :k])

        tmp_d = self._distfunc(self.W, vec.reshape((-1,1)))
        self.D[k, :-1] = tmp_d
        self.D[:-1, k] = tmp_d

        v = np.zeros((self._num_bases + 1))

        for i in range(self._num_bases):
                # compute volume for each combination...
                s = np.setdiff1d(range(self._num_bases + 1), [i])

# Path: msaf/pymf/vol.py
# def cmdet(d):
# 	# compute the CMD determinant of the euclidean distance matrix d
# 	# -> d should not be squared!
# 	D = np.ones((d.shape[0]+1,d.shape[0]+1))
# 	D[0,0] = 0.0
# 	D[1:,1:] = d**2
# 	j = np.float32(D.shape[0]-2)
# 	f1 = (-1.0)**(j+1) / ( (2**j) * ((factorial(j))**2))
# 	cmd = f1 * np.linalg.det(D)
# 	# sometimes, for very small values "cmd" might be negative ...
# 	return np.sqrt(np.abs(cmd))


# Path: msaf/pymf/sivm_gsat.py
import logging
import numpy as np
    import doctest
from .dist import *
from .vol import cmdet
from .sivm import SIVM

    >>> data = np.array([[1.5, 1.3], [1.2, 0.3]])
    >>> W = np.array([[1.0, 0.0], [0.0, 1.0]])
    >>> sivm_mdl = SIVM_GSAT(data, num_bases=2)
    >>> sivm_mdl.W = W
    >>> sivm_mdl.factorize(compute_w=False)

    The result is a set of coefficients sivm_mdl.H, s.t. data = W * sivm_mdl.H.
    """

    def init_w(self):
        self.select = range(self._num_bases)
        self.W = self.data[:, self.select]

    def online_update_w(self, vec):
        # update D if it does not exist
        k = self._num_bases
        if not hasattr(self, 'D'):
            self.D = np.zeros((k + 1, k + 1))
            self.D[:k, :k] = pdist(self.W, self.W)
            self.V = cmdet(self.D[:k, :k])

        tmp_d = self._distfunc(self.W, vec.reshape((-1,1)))
        self.D[k, :-1] = tmp_d
        self.D[:-1, k] = tmp_d

        v = np.zeros((self._num_bases + 1))

        for i in range(self._num_bases):
                # compute volume for each combination...
                s = np.setdiff1d(range(self._num_bases + 1), [i])

                v[i] = cmdet((self.D[s,:])[:,s])