pyxu-org / pyxu

Modular and scalable computational imaging in Python with GPU/out-of-core computing.
https://pyxu-org.github.io/
MIT License
117 stars 17 forks source link

[BugFix][ChainRule][estimate_lipschitz] Small bugfix #50

Closed AdriaJ closed 1 year ago

AdriaJ commented 1 year ago

Motivation: if one of the operator has a 0-valued Lipschitz constant and the other is set to infinity (either it is actually infinity or it has not been computed yet), then the machine tries to multiply 0 and inf and raises a warning.

Solution: If one of the operators has a 0-valued Lipschitz constant, then it s possible to determine the value of the Lipschitz of the composed operators. Indeed, a 0-valued Lipschitz implies that the operator is itself constant, thus the composition of the operators is also constant, so that the output Lipschitz value is still 0. This commit implements this small change.

SepandKashani commented 1 year ago

I was not able to induce a warning/error by trying the snippet below.

import pyxu.operator as pxo

A = pxo.NullOp((5,5))
B = pxo.IdentityOp(5)
B.lipschitz = np.inf
C, D = A * B, B * A

print(C.lipschitz, D.lipschitz)  # -> (inf, inf)
print(C.estimate_lipschitz(), D.estimate_lipschitz())  # -> (0.0, 0.0)

Could you provide an example where you encountered this problem?

AdriaJ commented 1 year ago

Sure, here is the situation where I faced this problem:

import pyxu.operator as pxop

A = pxop.NullOp((1000, 10))
B = pxop.SquaredL2Norm(dim=1000)

C = B * A

print(A.lipschitz, B.lipschitz)
print(C.lipschitz)
print(C.estimate_lipschitz())
SepandKashani commented 1 year ago

Thanks; I now understand why my previous example did not trigger any warning. (A subtle bug in Operator.asop() which was introduced with the new Lipschitz API.

Your PR is accepted, albeit I will reformulate the fix to be safer.