Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/source/gcp/fg.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.fg
====================
pyttb.decompositions.cp.gcp.fg
==============================

.. automodule:: pyttb.gcp.fg
.. automodule:: pyttb.decompositions.cp.gcp.fg
:members:
:undoc-members:
:show-inheritance:
6 changes: 3 additions & 3 deletions docs/source/gcp/fg_est.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.fg_est
====================
pyttb.decompositions.cp.gcp.fg_est
==================================

.. automodule:: pyttb.gcp.fg_est
.. automodule:: pyttb.decompositions.cp.gcp.fg_est
:members:
:undoc-members:
:show-inheritance:
6 changes: 3 additions & 3 deletions docs/source/gcp/fg_setup.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.fg_setup
====================
pyttb.decompositions.cp.gcp.fg_setup
====================================

.. automodule:: pyttb.gcp.fg_setup
.. automodule:: pyttb.decompositions.cp.gcp.fg_setup
:members:
:undoc-members:
:show-inheritance:
6 changes: 3 additions & 3 deletions docs/source/gcp/handles.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.handles
====================
pyttb.decompositions.cp.gcp.handles
===================================

.. automodule:: pyttb.gcp.handles
.. automodule:: pyttb.decompositions.cp.gcp.handles
:members:
:undoc-members:
:show-inheritance:
6 changes: 3 additions & 3 deletions docs/source/gcp/optimizers.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.optimizers
====================
pyttb.decompositions.cp.gcp.optimizers
======================================

.. automodule:: pyttb.gcp.optimizers
.. automodule:: pyttb.decompositions.cp.gcp.optimizers
:members:
:undoc-members:
:special-members: __init__
Expand Down
6 changes: 3 additions & 3 deletions docs/source/gcp/samplers.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pyttb.gcp.samplers
====================
pyttb.decompositions.cp.gcp.samplers
====================================

.. automodule:: pyttb.gcp.samplers
.. automodule:: pyttb.decompositions.cp.gcp.samplers
:members:
:undoc-members:
:special-members: __init__
Expand Down
8 changes: 4 additions & 4 deletions docs/source/tutorial/algorithm_gcp_opt.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@
"import numpy as np\n",
"\n",
"import pyttb as ttb\n",
"from pyttb.gcp.fg_setup import function_type, setup\n",
"from pyttb.gcp.handles import Objectives\n",
"from pyttb.gcp.optimizers import LBFGSB, SGD, Adagrad, Adam\n",
"from pyttb.gcp.samplers import GCPSampler"
"from pyttb.decompositions.cp.gcp.fg_setup import function_type, setup\n",
"from pyttb.decompositions.cp.gcp.handles import Objectives\n",
"from pyttb.decompositions.cp.gcp.optimizers import LBFGSB, SGD, Adagrad, Adam\n",
"from pyttb.decompositions.cp.gcp.samplers import GCPSampler"
]
},
{
Expand Down
25 changes: 13 additions & 12 deletions pyttb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@

import warnings

from pyttb.cp_als import cp_als
from pyttb.cp_apr import cp_apr
from pyttb.decompositions.cp import cp_als, cp_apr, gcp_opt
from pyttb.decompositions.tucker import hosvd, tucker_als
from pyttb.export_data import export_data
from pyttb.gcp_opt import gcp_opt
from pyttb.hosvd import hosvd
from pyttb.import_data import import_data
from pyttb.khatrirao import khatrirao
from pyttb.ktensor import ktensor
from pyttb.matlab import matlab_support
from pyttb.sptenmat import sptenmat
from pyttb.sptensor import sptendiag, sptenrand, sptensor
from pyttb.sumtensor import sumtensor
from pyttb.tenmat import tenmat
from pyttb.tensor import tendiag, teneye, tenones, tenrand, tensor, tenzeros
from pyttb.ttensor import ttensor
from pyttb.tucker_als import tucker_als
from pyttb.tensors import (
ktensor,
sptenmat,
sptensor,
sumtensor,
tenmat,
tensor,
ttensor,
)
from pyttb.tensors.dense import tendiag, teneye, tenones, tenrand, tenzeros
from pyttb.tensors.sparse import sptendiag, sptenrand


def ignore_warnings(ignore=True):
Expand Down
1 change: 1 addition & 0 deletions pyttb/decompositions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tensor Decompositions."""
13 changes: 13 additions & 0 deletions pyttb/decompositions/cp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""CP Decompositions."""

from __future__ import annotations

from .als import cp_als
from .apr import cp_apr
from .general import gcp_opt

__all__ = [
"cp_als",
"cp_apr",
"gcp_opt",
]
15 changes: 8 additions & 7 deletions pyttb/cp_als.py → pyttb/decompositions/cp/als.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@

import pyttb as ttb
from pyttb.pyttb_utils import OneDArray, parse_one_d
from pyttb.tensors import ktensor, sptensor, tensor, ttensor


def cp_als( # noqa: PLR0912,PLR0913,PLR0915
input_tensor: ttb.tensor | ttb.sptensor | ttb.ttensor | ttb.sumtensor,
input_tensor: tensor | sptensor | ttensor | ttb.sumtensor,
rank: int,
stoptol: float = 1e-4,
maxiters: int = 1000,
dimorder: OneDArray | None = None,
optdims: OneDArray | None = None,
init: Literal["random"] | Literal["nvecs"] | ttb.ktensor = "random",
init: Literal["random"] | Literal["nvecs"] | ktensor = "random",
printitn: int = 1,
fixsigns: bool = True,
) -> tuple[ttb.ktensor, ttb.ktensor, dict]:
) -> tuple[ktensor, ktensor, dict]:
"""Compute CP decomposition with alternating least squares.

Parameters
Expand Down Expand Up @@ -150,7 +151,7 @@ def cp_als( # noqa: PLR0912,PLR0913,PLR0915
assert rank > 0, "Number of components requested must be positive"

# Set up and error checking on initial guess
if isinstance(init, ttb.ktensor):
if isinstance(init, ktensor):
# User provided an initial ktensor; validate it
assert init.ndims == N, f"Initial guess does not have {N} modes"
assert init.ncomponents == rank, (
Expand All @@ -165,15 +166,15 @@ def cp_als( # noqa: PLR0912,PLR0913,PLR0915
factor_matrices.append(
np.random.uniform(0, 1, (input_tensor.shape[n], rank))
)
init = ttb.ktensor(factor_matrices)
init = ktensor(factor_matrices)
elif isinstance(init, str) and init.lower() == "nvecs":
assert not isinstance(input_tensor, ttb.sumtensor), (
"Sumtensor doesn't support nvecs"
)
factor_matrices = []
for n in range(N):
factor_matrices.append(input_tensor.nvecs(n, rank))
init = ttb.ktensor(factor_matrices)
init = ktensor(factor_matrices)
else:
assert False, "The selected initialization method is not supported"

Expand Down Expand Up @@ -234,7 +235,7 @@ def cp_als( # noqa: PLR0912,PLR0913,PLR0915
U[n] = Unew
UtU[:, :, n] = U[n].T @ U[n]

M = ttb.ktensor(U, weights)
M = ktensor(U, weights)

# This is equivalent to innerprod(X,P).
iprod = np.sum(
Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pyttb/gcp/fg.py → pyttb/decompositions/cp/gcp/fg.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import pyttb as ttb

if TYPE_CHECKING:
from pyttb.gcp.fg_setup import function_type
from pyttb.decompositions.cp.gcp.fg_setup import function_type


@overload
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

if TYPE_CHECKING:
import pyttb as ttb
from pyttb.gcp.fg_setup import function_type
from pyttb.decompositions.cp.gcp.fg_setup import function_type


@overload
Expand Down
25 changes: 14 additions & 11 deletions pyttb/gcp/fg_setup.py → pyttb/decompositions/cp/gcp/fg_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@
from __future__ import annotations

from functools import partial
from typing import Callable
from typing import TYPE_CHECKING, Callable

import numpy as np

import pyttb as ttb
from pyttb.gcp import handles
from pyttb.gcp.handles import Objectives
from pyttb.decompositions.cp.gcp import handles
from pyttb.decompositions.cp.gcp.handles import Objectives
from pyttb.tensors.sparse import sptensor

if TYPE_CHECKING:
from pyttb.tensors.dense import tensor

function_type = Callable[[np.ndarray, np.ndarray], np.ndarray]
fg_return = tuple[function_type, function_type, float]


def setup( # noqa: PLR0912,PLR0915
objective: Objectives,
data: ttb.tensor | ttb.sptensor | None = None,
data: tensor | sptensor | None = None,
additional_parameter: float | None = None,
) -> fg_return:
"""Collect the function and gradient handles for GCP.
Expand Down Expand Up @@ -121,23 +124,23 @@ def setup( # noqa: PLR0912,PLR0915
return function_handle, gradient_handle, lower_bound


def valid_nonneg(data: ttb.tensor | ttb.sptensor) -> bool:
def valid_nonneg(data: tensor | sptensor) -> bool:
"""Check if provided data is valid non-negative tensor."""
if isinstance(data, ttb.sptensor):
if isinstance(data, sptensor):
return bool(np.all(data.vals > 0))
return bool(np.all(data.data > 0))


def valid_binary(data: ttb.tensor | ttb.sptensor) -> bool:
def valid_binary(data: tensor | sptensor) -> bool:
"""Check if provided data is valid binary tensor."""
if isinstance(data, ttb.sptensor):
if isinstance(data, sptensor):
return bool(np.all(data.vals == 1))
return bool(np.all(np.isin(np.unique(data.data), [0, 1])))


def valid_natural(data: ttb.tensor | ttb.sptensor) -> bool:
def valid_natural(data: tensor | sptensor) -> bool:
"""Check if provided data is valid natural number tensor."""
if isinstance(data, ttb.sptensor):
if isinstance(data, sptensor):
vals = data.vals
else:
vals = data.data
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
from scipy.optimize import fmin_l_bfgs_b

import pyttb as ttb
from pyttb.gcp.fg import evaluate
from pyttb.gcp.fg_est import estimate
from pyttb.gcp.samplers import GCPSampler
from pyttb.decompositions.cp.gcp.fg import evaluate
from pyttb.decompositions.cp.gcp.fg_est import estimate
from pyttb.decompositions.cp.gcp.samplers import GCPSampler

if TYPE_CHECKING:
from pyttb.gcp.fg_setup import function_type
from pyttb.decompositions.cp.gcp.fg_setup import function_type


class StochasticSolver(ABC):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

import pyttb as ttb
from pyttb.pyttb_utils import tt_sub2ind
from pyttb.sptensor import sptensor
from pyttb.tensor import tensor
from pyttb.tensors.dense import tensor
from pyttb.tensors.sparse import sptensor

sample_type = tuple[np.ndarray, np.ndarray, np.ndarray]
sampler_type = Callable[[Union[tensor, sptensor]], sample_type]
Expand Down
8 changes: 4 additions & 4 deletions pyttb/gcp_opt.py → pyttb/decompositions/cp/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import numpy as np

import pyttb as ttb
from pyttb.gcp.fg_setup import function_type, setup
from pyttb.gcp.handles import Objectives
from pyttb.gcp.optimizers import LBFGSB, StochasticSolver
from pyttb.decompositions.cp.gcp.fg_setup import function_type, setup
from pyttb.decompositions.cp.gcp.handles import Objectives
from pyttb.decompositions.cp.gcp.optimizers import LBFGSB, StochasticSolver

if TYPE_CHECKING:
from pyttb.gcp.samplers import GCPSampler
from pyttb.decompositions.cp.gcp.samplers import GCPSampler


def gcp_opt( # noqa: PLR0912,PLR0913
Expand Down
11 changes: 11 additions & 0 deletions pyttb/decompositions/tucker/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Tucker Decompositions."""

from __future__ import annotations

from .als import tucker_als
from .svd import hosvd

__all__ = [
"hosvd",
"tucker_als",
]
2 changes: 1 addition & 1 deletion pyttb/tucker_als.py → pyttb/decompositions/tucker/als.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import numpy as np

from pyttb.pyttb_utils import OneDArray, parse_one_d
from pyttb.ttensor import ttensor
from pyttb.tensors.tucker import ttensor

if TYPE_CHECKING:
import pyttb as ttb
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion pyttb/matlab/matlab_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import numpy as np

from pyttb.tensor import tensor
from pyttb.tensors.dense import tensor

from .matlab_utilities import _matlab_array_str

Expand Down
21 changes: 21 additions & 0 deletions pyttb/tensors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Tensor Classes."""

from __future__ import annotations

from .dense import tensor
from .kruskal import ktensor
from .matricized import tenmat
from .sparse import sptensor
from .sparse_matricized import sptenmat
from .sum import sumtensor
from .tucker import ttensor

__all__ = [
"ktensor",
"sptenmat",
"sptensor",
"sumtensor",
"tenmat",
"tensor",
"ttensor",
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions tests/gcp/test_fg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import pytest

import pyttb as ttb
from pyttb.gcp import fg_setup
from pyttb.gcp.fg import evaluate
from pyttb.gcp.handles import Objectives
from pyttb.decompositions.cp.gcp import fg_setup
from pyttb.decompositions.cp.gcp.fg import evaluate
from pyttb.decompositions.cp.gcp.handles import Objectives


def test_evaluate():
Expand Down
2 changes: 1 addition & 1 deletion tests/gcp/test_fg_est.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pytest

import pyttb as ttb
from pyttb.gcp.fg_est import estimate, estimate_helper
from pyttb.decompositions.cp.gcp.fg_est import estimate, estimate_helper


def test_estimate_helper():
Expand Down
Loading
Loading