Skip to content

Commit 89b2043

Browse files
authored
Merge pull request #347 from cako/patch-dimsd
Implement `dimsd` for all operators with `dims`
2 parents dce8534 + 4cbaf41 commit 89b2043

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+307
-204
lines changed

MIGRATION_V1_V2.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ should be used as a checklist when converting a piece of code using PyLops from
1212
- `utils.dottest`: Change `tol` into `rtol`. Absolute tolerance is now also supported via the keyword `atol`.
1313
When calling it with purely positional arguments, note that after `rtol` comes now first `atol` before `complexflag`.
1414
When using `raiseerror=True` it now emits an `AttributeError` instead of a `ValueError`.
15+
- `dims_fft` in the FFT operators is deprecated in favor of `dimsd`.
16+
- `dims_d` in `Sum` is deprecated in favor or `dimsd`

examples/plot_matrixmult.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,11 @@
196196
#
197197
# and apply it using the same implementation of the
198198
# :py:class:`pylops.MatrixMult` operator by simply telling the operator how we
199-
# want the model to be organized through the ``dims`` input parameter.
199+
# want the model to be organized through the ``otherdims`` input parameter.
200200
A = np.array([[1.0, 2.0], [4.0, 5.0]])
201201
x = np.array([[1.0, 1.0], [2.0, 2.0], [3.0, 3.0]])
202202

203-
Aop = pylops.MatrixMult(A, dims=(3,), dtype="float64")
203+
Aop = pylops.MatrixMult(A, otherdims=(3,), dtype="float64")
204204
y = Aop * x.ravel()
205205

206206
xest, istop, itn, r1norm, r2norm = lsqr(Aop, y, damp=1e-10, iter_lim=10, show=0)[0:5]

pylops/avo/poststack.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def _PoststackLinearModelling(
8787
M = ncp.dot(C, D)
8888
if sparse:
8989
M = get_csc_matrix(wav)(M)
90-
Pop = _MatrixMult(M, dims=spatdims, dtype=dtype, **args_MatrixMult)
90+
Pop = _MatrixMult(M, otherdims=spatdims, dtype=dtype, **args_MatrixMult)
9191
else:
9292
# Create wavelet operator
9393
if len(wav.shape) == 1:
@@ -102,7 +102,7 @@ def _PoststackLinearModelling(
102102
else:
103103
Cop = _MatrixMult(
104104
nonstationary_convmtx(wav, nt0, hc=wav.shape[1] // 2, pad=(nt0, nt0)),
105-
dims=spatdims,
105+
otherdims=spatdims,
106106
dtype=dtype,
107107
**args_MatrixMult
108108
)
@@ -350,7 +350,7 @@ def PoststackInversion(
350350
minv = get_lstsq(data)(PP, datarn, **kwargs_solver)[0]
351351
else:
352352
# solve regularized normal equations simultaneously
353-
PPop_reg = MatrixMult(PP, dims=nspatprod)
353+
PPop_reg = MatrixMult(PP, otherdims=nspatprod)
354354
if ncp == np:
355355
minv = lsqr(PPop_reg, datar.ravel(), **kwargs_solver)[0]
356356
else:
@@ -364,7 +364,7 @@ def PoststackInversion(
364364
# create regularized normal eqs. and solve them simultaneously
365365
PP = ncp.dot(PPop.A.T, PPop.A) + epsI * ncp.eye(nt0, dtype=PPop.A.dtype)
366366
datarn = PPop.A.T * datar.reshape(nt0, nspatprod)
367-
PPop_reg = MatrixMult(PP, dims=nspatprod)
367+
PPop_reg = MatrixMult(PP, otherdims=nspatprod)
368368
minv = get_lstsq(data)(PPop_reg.A, datarn.ravel(), **kwargs_solver)[0]
369369
else:
370370
# solve unregularized normal equations simultaneously with lop

pylops/avo/prestack.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def PrestackLinearModelling(
182182

183183
# Combine operators
184184
M = ncp.dot(C, ncp.dot(G, D))
185-
Preop = MatrixMult(M, dims=spatdims, dtype=dtype)
185+
Preop = MatrixMult(M, otherdims=spatdims, dtype=dtype)
186186

187187
else:
188188
# Create wavelet operator
@@ -504,7 +504,7 @@ def PrestackInversion(
504504
]
505505
if explicit:
506506
PPop = MatrixMult(
507-
np.vstack([Op.A for Op in PPop]), dims=nspat, dtype=PPop[0].A.dtype
507+
np.vstack([Op.A for Op in PPop]), otherdims=nspat, dtype=PPop[0].A.dtype
508508
)
509509
else:
510510
PPop = VStack(PPop)
@@ -560,7 +560,7 @@ def PrestackInversion(
560560
minv = get_lstsq(data)(PP, datarn, **kwargs_solver)[0]
561561
else:
562562
# solve regularized normal equations simultaneously
563-
PPop_reg = MatrixMult(PP, dims=nspatprod)
563+
PPop_reg = MatrixMult(PP, otherdims=nspatprod)
564564
if ncp == np:
565565
minv = lsqr(PPop_reg, datarn.ravel(), **kwargs_solver)[0]
566566
else:
@@ -574,7 +574,7 @@ def PrestackInversion(
574574
# # create regularized normal eqs. and solve them simultaneously
575575
# PP = np.dot(PPop.A.T, PPop.A) + epsI * np.eye(nt0*nm)
576576
# datarn = PPop.A.T * datar.reshape(nt0*ntheta, nspatprod)
577-
# PPop_reg = MatrixMult(PP, dims=ntheta*nspatprod)
577+
# PPop_reg = MatrixMult(PP, otherdims=ntheta*nspatprod)
578578
# minv = lstsq(PPop_reg, datarn.ravel(), **kwargs_solver)[0]
579579
else:
580580
# solve unregularized normal equations simultaneously with lop

pylops/basicoperators/CausalIntegration.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy as np
44

55
from pylops import LinearOperator
6-
from pylops.utils._internal import _value_or_list_like_to_array
6+
from pylops.utils._internal import _value_or_list_like_to_tuple
77

88

99
class CausalIntegration(LinearOperator):
@@ -97,16 +97,18 @@ def __init__(
9797
kind="full",
9898
removefirst=False,
9999
):
100-
self.dims = _value_or_list_like_to_array(dims)
100+
self.dims = _value_or_list_like_to_tuple(dims)
101101
self.axis = axis
102102
self.sampling = sampling
103103
self.kind = kind
104104
if kind == "full" and halfcurrent: # ensure backcompatibility
105105
self.kind = "half"
106106
self.removefirst = removefirst
107-
self.dimsd = self.dims.copy()
107+
dimsd = list(self.dims)
108108
if self.removefirst:
109-
self.dimsd[self.axis] -= 1
109+
dimsd[self.axis] -= 1
110+
self.dimsd = tuple(dimsd)
111+
110112
self.shape = (np.prod(self.dimsd), np.prod(self.dims))
111113
self.dtype = np.dtype(dtype)
112114
self.explicit = False

pylops/basicoperators/Conj.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22

33
from pylops import LinearOperator
4+
from pylops.utils._internal import _value_or_list_like_to_tuple
45
from pylops.utils.backend import get_array_module
56

67

@@ -41,7 +42,9 @@ class Conj(LinearOperator):
4142
"""
4243

4344
def __init__(self, dims, dtype="complex128"):
44-
self.shape = (np.prod(np.array(dims)), np.prod(np.array(dims)))
45+
self.dims = self.dimsd = _value_or_list_like_to_tuple(dims)
46+
47+
self.shape = (np.prod(self.dimsd), np.prod(self.dims))
4548
self.dtype = np.dtype(dtype)
4649
self.explicit = False
4750
self.clinear = False

pylops/basicoperators/Diagonal.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import numpy as np
44

55
from pylops import LinearOperator
6+
from pylops.utils._internal import _value_or_list_like_to_tuple
67
from pylops.utils.backend import get_array_module, to_cupy_conditional
78

89

@@ -64,28 +65,26 @@ def __init__(self, diag, dims=None, axis=-1, dtype="float64"):
6465
self.diag = diag.ravel()
6566
self.complex = True if ncp.iscomplexobj(self.diag) else False
6667

67-
if dims is None:
68-
self.shape = (len(self.diag), len(self.diag))
69-
self.dims = None
70-
self.reshape = False
71-
else:
72-
diagdims = [1] * len(dims)
73-
diagdims[axis] = dims[axis]
74-
self.diag = self.diag.reshape(diagdims)
75-
self.shape = (np.prod(dims), np.prod(dims))
76-
self.dims = dims
77-
self.reshape = True
68+
ncp = get_array_module(diag)
69+
self.diag = diag.ravel()
70+
self.complex = True if ncp.iscomplexobj(self.diag) else False
71+
self.dims = self.dimsd = (
72+
(len(self.diag),) if dims is None else _value_or_list_like_to_tuple(dims)
73+
)
74+
75+
diagdims = np.ones_like(self.dims)
76+
diagdims[axis] = self.dims[axis]
77+
self.diag = self.diag.reshape(diagdims)
78+
79+
self.shape = (np.prod(self.dimsd), np.prod(self.dims))
7880
self.dtype = np.dtype(dtype)
7981
self.explicit = False
8082

8183
def _matvec(self, x):
8284
if type(self.diag) != type(x):
8385
self.diag = to_cupy_conditional(x, self.diag)
84-
if not self.reshape:
85-
y = self.diag * x.ravel()
86-
else:
87-
x = x.reshape(self.dims)
88-
y = self.diag * x
86+
x = x.reshape(self.dims)
87+
y = self.diag * x
8988
return y.ravel()
9089

9190
def _rmatvec(self, x):
@@ -95,11 +94,8 @@ def _rmatvec(self, x):
9594
diagadj = self.diag.conj()
9695
else:
9796
diagadj = self.diag
98-
if not self.reshape:
99-
y = diagadj * x.ravel()
100-
else:
101-
x = x.reshape(self.dims)
102-
y = diagadj * x
97+
x = x.reshape(self.dims)
98+
y = diagadj * x
10399
return y.ravel()
104100

105101
def matrix(self):

pylops/basicoperators/DirectionalDerivative.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ def FirstDirectionalDerivative(
1414
.. note:: At least 2 dimensions are required, consider using
1515
:py:func:`pylops.FirstDerivative` for 1d arrays.
1616
17-
1817
Parameters
1918
----------
2019
dims : :obj:`tuple`
@@ -67,8 +66,10 @@ def FirstDirectionalDerivative(
6766
else:
6867
Dop = Diagonal(v.ravel(), dtype=dtype)
6968
Sop = Sum(dims=[len(dims)] + list(dims), axis=0, dtype=dtype)
70-
ddop = Sop * Dop * Gop
71-
return LinearOperator(ddop)
69+
ddop = LinearOperator(Sop * Dop * Gop)
70+
ddop.dims = ddop.dimsd = dims
71+
ddop.sampling = sampling
72+
return ddop
7273

7374

7475
def SecondDirectionalDerivative(dims, v, sampling=1, edge=False, dtype="float64"):
@@ -118,5 +119,7 @@ def SecondDirectionalDerivative(dims, v, sampling=1, edge=False, dtype="float64"
118119
in the literature.
119120
"""
120121
Dop = FirstDirectionalDerivative(dims, v, sampling=sampling, edge=edge, dtype=dtype)
121-
ddop = -Dop.H * Dop
122-
return LinearOperator(ddop)
122+
ddop = LinearOperator(-Dop.H * Dop)
123+
ddop.dims = ddop.dimsd = dims
124+
ddop.sampling = sampling
125+
return ddop

pylops/basicoperators/FirstDerivative.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from numpy.core.multiarray import normalize_axis_index
55

66
from pylops import LinearOperator
7-
from pylops.utils._internal import _value_or_list_like_to_array
7+
from pylops.utils._internal import _value_or_list_like_to_tuple
88
from pylops.utils.backend import get_array_module
99

1010

@@ -73,13 +73,13 @@ def __init__(
7373
dtype="float64",
7474
kind="centered",
7575
):
76-
self.dims = _value_or_list_like_to_array(dims)
76+
self.dims = self.dimsd = _value_or_list_like_to_tuple(dims)
7777
self.axis = normalize_axis_index(axis, len(self.dims))
7878
self.sampling = sampling
7979
self.edge = edge
8080
self.kind = kind
81-
N = np.prod(self.dims)
82-
self.shape = (N, N)
81+
82+
self.shape = (np.prod(self.dimsd), np.prod(self.dims))
8383
self.dtype = np.dtype(dtype)
8484
self.explicit = False
8585

pylops/basicoperators/Flip.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy as np
44

55
from pylops import LinearOperator
6-
from pylops.utils._internal import _value_or_list_like_to_array
6+
from pylops.utils._internal import _value_or_list_like_to_tuple
77

88

99
class Flip(LinearOperator):
@@ -46,10 +46,10 @@ class Flip(LinearOperator):
4646
"""
4747

4848
def __init__(self, dims, axis=-1, dtype="float64"):
49-
self.dims = _value_or_list_like_to_array(dims)
49+
self.dims = self.dimsd = _value_or_list_like_to_tuple(dims)
5050
self.axis = axis
51-
N = np.prod(self.dims)
52-
self.shape = (N, N)
51+
52+
self.shape = (np.prod(self.dimsd), np.prod(self.dims))
5353
self.dtype = np.dtype(dtype)
5454
self.explicit = False
5555

0 commit comments

Comments
 (0)