uncertainties icon indicating copy to clipboard operation
uncertainties copied to clipboard

Strange behavior on copying

Open jagerber48 opened this issue 1 year ago • 0 comments

AffineScalarFunc/UFloat has very strange behavior on copying. We discovered this in one of the issues about hash. @newville provided this example clearly showing some of the strange behavior.

>>> from uncertainties import ufloat
>>> import copy
>>> a = ufloat(1, 0.1)
>>> a == a*1.0
True
>>> a == copy.copy(a)
False
>>> a*1.0 == copy.copy(a*1.0)
True
>>> a == copy.copy(a*1.0)
True
>>> a*1.0 == copy.copy(a)
False

This behavior is very confusing to a user, but, looking at the test_copy test, it looks like some of this behavior is desired. There is similar behavior for pickling.

https://github.com/lmfit/uncertainties/blob/f097015634e4a6ec8c1bea77e9743533f88a38d9/tests/test_uncertainties.py#L177-L225

It seems like the targeted behavior involves copies creating new, independent AffineScalarFunc instances but somehow retaining the correlations of the original. It just seems strange.

I would suggest that copies should be equal to the originals and have the exact same correlations as the original. Copies are correlated with originals, copies are correlated with copies etc. This is realized without any extra handling on my rewrite branch which uses immutable UAtoms and UCombos to represent the uncertainty of UFloats. This allows the following diff on test_copy and changes newville's test to

>>> from uncertainties.new import ufloat
>>> import copy
>>> a = ufloat(1, 0.1)
>>> a == a*1.0
True
>>> a == copy.copy(a)
True
>>> a*1.0 == copy.copy(a*1.0)
True
>>> a == copy.copy(a*1.0)
True
>>> a*1.0 == copy.copy(a)
True

Regardless of how the fix is implemented, I think this behavior should be modified to be more intuitive.

jagerber48 avatar Jul 28 '24 18:07 jagerber48