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 .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ jobs:
python-version: ['3.12']
include:
- BACKEND: 'numpy'
python-version: '3.9'
python-version: '3.10'
- BACKEND: 'numpy'
python-version: '3.11'
python-version: '3.13'
TENSORLY_TENALG_BACKEND: ['einsum']
- BACKEND: 'jax'
python-version: '3.13'
TENSORLY_TENALG_BACKEND: ['einsum']
- BACKEND: 'tensorflow'
python-version: '3.12'
python-version: '3.13'
TENSORLY_TENALG_BACKEND: ['einsum']

steps:
Expand Down
1 change: 0 additions & 1 deletion examples/applications/plot_image_compression.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from scipy.ndimage import zoom
from tensorly.decomposition import parafac
from tensorly.decomposition import tucker
from math import ceil


random_state = 12345
Expand Down
1 change: 0 additions & 1 deletion examples/decomposition/plot_permute_factors.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# The permuted tensor (or list of tensors) and list of permutation for each permuted tensors are returned.
# Tensorly CPTensor should be used as an input to permute their factors and weights simultaneously.

import tensorly as tl
from tensorly.random import random_cp
from tensorly.cp_tensor import cp_permute_factors
import matplotlib.pyplot as plt
Expand Down
2 changes: 0 additions & 2 deletions tensorly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
pad_tt_rank,
)
from .tt_matrix import (
tt_matrix_to_tensor,
tt_matrix_to_tensor,
validate_tt_matrix_rank,
tt_matrix_to_unfolded,
Expand Down Expand Up @@ -72,7 +71,6 @@
where,
conj,
index,
index_update,
clip,
max,
min,
Expand Down
11 changes: 5 additions & 6 deletions tensorly/backend/core.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import inspect
import importlib
import os
import sys
import threading
import types
import warnings
import math

Expand Down Expand Up @@ -304,6 +298,11 @@ def to_numpy(tensor):
def copy(tensor):
"""Return a copy of the given tensor"""
raise NotImplementedError

@staticmethod
def ndim(tensor):
"""Return the number of dimensions of a tensor"""
return tensor.ndim

@staticmethod
def concatenate(tensors, axis=0):
Expand Down
5 changes: 0 additions & 5 deletions tensorly/backend/cupy_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
)
raise ImportError(message) from error

import warnings

from .core import (
Backend,
Expand Down Expand Up @@ -39,10 +38,6 @@ def to_numpy(tensor):
return cp.asnumpy(tensor)
return tensor

@staticmethod
def ndim(tensor):
return tensor.ndim

@staticmethod
def clip(tensor, a_min=None, a_max=None):
return cp.clip(tensor, a_min, a_max)
Expand Down
4 changes: 0 additions & 4 deletions tensorly/backend/jax_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ def copy(self, tensor):
return self.tensor(tensor.copy(), **self.context(tensor))
# return copy.copy(tensor)

@staticmethod
def ndim(tensor):
return tensor.ndim

@staticmethod
def lstsq(a, b, rcond=None):
return np.linalg.lstsq(a, b, rcond=rcond, numpy_resid=True)
Expand Down
4 changes: 0 additions & 4 deletions tensorly/backend/numpy_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ def is_tensor(tensor):
def to_numpy(tensor):
return np.copy(tensor)

@staticmethod
def ndim(tensor):
return tensor.ndim

@staticmethod
def clip(tensor, a_min=None, a_max=None):
return np.clip(tensor, a_min, a_max)
Expand Down
8 changes: 2 additions & 6 deletions tensorly/backend/paddle_backend.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from __future__ import annotations
from typing import Sequence
from collections.abc import Sequence

from packaging.version import Version
import warnings
Expand Down Expand Up @@ -158,10 +158,6 @@ def to_numpy(tensor: paddle.Tensor):
def shape(tensor: paddle.Tensor):
return tuple(tensor.shape)

@staticmethod
def ndim(tensor: paddle.Tensor):
return tensor.ndim

@staticmethod
def clip(tensor: paddle.Tensor, a_min=None, a_max=None, inplace=False):
if inplace:
Expand All @@ -176,7 +172,7 @@ def all(tensor: paddle.Tensor):

def transpose(self, tensor: paddle.Tensor, axes: int | Sequence[int] | None = None):
axes = axes or list(range(self.ndim(tensor)))[::-1]
if not isinstance(axes, (tuple, list)):
if not isinstance(axes, tuple | list):
axes = list(axes)
return tensor.transpose(axes)

Expand Down
4 changes: 0 additions & 4 deletions tensorly/backend/pytorch_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ def to_numpy(tensor):
def shape(tensor):
return tuple(tensor.shape)

@staticmethod
def ndim(tensor):
return tensor.dim()

@staticmethod
def arange(start, stop=None, step=1.0, *args, **kwargs):
if stop is None:
Expand Down
1 change: 0 additions & 1 deletion tensorly/backend/tensorflow_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ def logsumexp(tensor, axis=0):
"mean",
"sum",
"moveaxis",
"ndim",
"arange",
"sort",
"argsort",
Expand Down
1 change: 0 additions & 1 deletion tensorly/contrib/sparse/tests/test_decomposition.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from ..decomposition import parafac
from ..tenalg import multi_mode_dot
from ..cp_tensor import cp_to_tensor
from .... import backend as tl

Expand Down
2 changes: 1 addition & 1 deletion tensorly/cp_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def _validate_cp_tensor(cp_tensor):
if isinstance(cp_tensor, CPTensor):
# it's already been validated at creation
return cp_tensor.shape, cp_tensor.rank
elif isinstance(cp_tensor, (float, int)): # 0-order tensor
elif isinstance(cp_tensor, float | int): # 0-order tensor
return 0, 0

weights, factors = cp_tensor
Expand Down
4 changes: 0 additions & 4 deletions tensorly/datasets/data_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@

from os.path import dirname
import numpy as np
from urllib.request import urlopen
import scipy.io
from zipfile import ZipFile
from io import BytesIO
import tensorly as tl


Expand Down
1 change: 0 additions & 1 deletion tensorly/datasets/tests/test_imports.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import pytest

from ..data_imports import (
load_IL2data,
Expand Down
2 changes: 1 addition & 1 deletion tensorly/decomposition/_constrained_cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def initialize_constrained_parafac(

factors.append(U[:, :rank])

elif isinstance(init, (tuple, list, CPTensor)):
elif isinstance(init, tuple | list | CPTensor):
try:
weights, factors = CPTensor(init)

Expand Down
2 changes: 1 addition & 1 deletion tensorly/decomposition/_cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def initialize_cp(

kt = CPTensor((None, factors))

elif isinstance(init, (tuple, list, CPTensor)):
elif isinstance(init, tuple | list | CPTensor):
# TODO: Test this
try:
if normalize_factors is True:
Expand Down
9 changes: 5 additions & 4 deletions tensorly/decomposition/_parafac2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from warnings import warn
from typing import Iterable, Optional, Sequence, Literal, Union
from typing import Literal
from collections.abc import Iterable, Sequence

import tensorly as tl
from ._base_decomposition import DecompositionMixin
Expand Down Expand Up @@ -140,7 +141,7 @@ def initialize_decomposition(
projections = _compute_projections(tensor_slices, (A, B, C), svd)
return Parafac2Tensor((None, [A, B, C], projections))

elif isinstance(init, (tuple, list, Parafac2Tensor, CPTensor)):
elif isinstance(init, tuple | list | Parafac2Tensor | CPTensor):
try:
decomposition = Parafac2Tensor.from_CPTensor(init, parafac2_tensor_ok=True)
except ValueError:
Expand Down Expand Up @@ -404,9 +405,9 @@ def parafac2(
svd: SVD_TYPES = "truncated_svd",
normalize_factors: bool = False,
tol: float = 1.0e-8,
nn_modes: Optional[Union[Sequence[int], Literal["all"]]] = None,
nn_modes: Sequence[int] | Literal["all"] | None = None,
random_state=None,
verbose: Union[bool, int] = False,
verbose: bool | int = False,
return_errors: bool = False,
n_iter_parafac: int = 5,
linesearch: bool = True,
Expand Down
2 changes: 1 addition & 1 deletion tensorly/decomposition/_tt.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import tensorly as tl
from ._base_decomposition import DecompositionMixin
from ..tt_tensor import validate_tt_rank, TTTensor
from ..tt_matrix import validate_tt_matrix_rank, TTMatrix
from ..tt_matrix import TTMatrix
from ..tenalg.svd import svd_interface


Expand Down
3 changes: 0 additions & 3 deletions tensorly/decomposition/_tucker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
validate_tucker_rank,
tucker_normalize,
)
from ..solvers.penalizations import (
process_regularization_weights,
)
from ..solvers.nnls import hals_nnls, fista, active_set_nnls
from math import sqrt
import warnings
Expand Down
1 change: 0 additions & 1 deletion tensorly/decomposition/tests/test_constrained_parafac.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
assert_array_almost_equal,
assert_class_wrapper_correctly_passes_arguments,
)
from ...random import random_cp


def test_constrained_parafac_nonnegative(monkeypatch):
Expand Down
1 change: 0 additions & 1 deletion tensorly/decomposition/tests/test_cp.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
CP_NN_HALS,
)
from ...cp_tensor import cp_to_tensor
from ...cp_tensor import cp_to_tensor
from ...random import random_cp
from ...tenalg import khatri_rao
from ... import backend as T
Expand Down
5 changes: 1 addition & 4 deletions tensorly/decomposition/tests/test_tr_svd.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import pytest
import tensorly as tl

from .._tr_svd import tensor_ring, TensorRing
from .._tr_svd import tensor_ring
from ...random import random_tr
from ...testing import (
assert_,
assert_array_almost_equal,
assert_raises,
assert_class_wrapper_correctly_passes_arguments,
)


Expand Down
1 change: 0 additions & 1 deletion tensorly/random/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import numpy as np
from ..cp_tensor import cp_to_tensor, CPTensor, cp_normalize, validate_cp_rank
from ..tucker_tensor import tucker_to_tensor, TuckerTensor, validate_tucker_rank
from ..tt_tensor import tt_to_tensor, TTTensor, validate_tt_rank
Expand Down
7 changes: 2 additions & 5 deletions tensorly/solvers/penalizations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import tensorly as tl
import numpy as np
import copy
import warnings


Expand All @@ -24,10 +21,10 @@ def process_regularization_weights(ridge_coefficients, sparsity_coefficients, n_
list of floats
sparsity coefficients, processed
"""
if ridge_coefficients is None or isinstance(ridge_coefficients, (int, float)):
if ridge_coefficients is None or isinstance(ridge_coefficients, int | float):
# Populate None or the input float in a list for all modes
ridge_coefficients = [ridge_coefficients] * n_modes
if sparsity_coefficients is None or isinstance(sparsity_coefficients, (int, float)):
if sparsity_coefficients is None or isinstance(sparsity_coefficients, int | float):
# Populate None or the input float in a list for all modes
sparsity_coefficients = [sparsity_coefficients] * n_modes
# Convert None to 0
Expand Down
5 changes: 2 additions & 3 deletions tensorly/solvers/tests/test_admm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
import tensorly as tl

from tensorly.solvers.admm import admm
from tensorly.testing import assert_, assert_array_equal, assert_array_almost_equal
from tensorly import tensor_to_vec, truncated_svd
from tensorly.testing import assert_array_almost_equal
import pytest

# Author: Jean Kossaifi
skip_tensorflow = pytest.mark.skipif(
(tl.get_backend() == "tensorflow"),
reason=f"Indexing with list not supported in TensorFlow",
reason="Indexing with list not supported in TensorFlow",
)


Expand Down
6 changes: 3 additions & 3 deletions tensorly/solvers/tests/test_nnls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
fista,
active_set_nnls,
)
from tensorly.testing import assert_, assert_array_equal, assert_array_almost_equal
from tensorly import tensor_to_vec, truncated_svd
from tensorly.testing import assert_array_almost_equal
from tensorly import tensor_to_vec
import pytest

# Author: Jean Kossaifi
skip_tensorflow = pytest.mark.skipif(
(tl.get_backend() == "tensorflow"),
reason=f"Indexing with list not supported in TensorFlow",
reason="Indexing with list not supported in TensorFlow",
)


Expand Down
1 change: 0 additions & 1 deletion tensorly/solvers/tests/test_penalizations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import numpy as np
import tensorly as tl

from tensorly.solvers.penalizations import process_regularization_weights
Expand Down
1 change: 0 additions & 1 deletion tensorly/tenalg/einsum_tenalg/generalised_inner_product.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from ... import backend as T
import numpy as np

# Author: Jean Kossaifi
# License: BSD 3 clause
Expand Down
4 changes: 2 additions & 2 deletions tensorly/tenalg/proximal.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,8 @@ def unimodality_prox(tensor):
)
# Next line finds mutual peak points
values = tl.tensor(
tl.to_numpy((tensor - monotone_decreasing >= 0))
* tl.to_numpy((tensor - monotone_increasing >= 0)),
tl.to_numpy(tensor - monotone_decreasing >= 0)
* tl.to_numpy(tensor - monotone_increasing >= 0),
**tl.context(tensor)
)

Expand Down
2 changes: 1 addition & 1 deletion tensorly/tenalg/tenalg_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _validate_contraction_modes(shape1, shape2, modes, batched_modes=False):

if len(modes1) != len(modes2):
if batched_modes:
message = f"Both tensors must have the same number of batched modes"
message = "Both tensors must have the same number of batched modes"
else:
message = (
"Both tensors must have the same number of modes to contract along. "
Expand Down
1 change: 0 additions & 1 deletion tensorly/tenalg/tests/test_batched_tensordot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from ...testing import assert_array_almost_equal, assert_raises, assert_
from ... import random
from .. import tensordot
import pytest


def test_batched_tensordot():
Expand Down
1 change: 0 additions & 1 deletion tensorly/tenalg/tests/test_outer_product.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import tensorly as tl
from tensorly import testing
from tensorly import random
from tensorly import tenalg

from .. import outer, batched_outer
Expand Down
Loading
Loading