From 785d943542fffb99e8a0e7b77d7a2014efb5f8a9 Mon Sep 17 00:00:00 2001 From: francof2a Date: Thu, 8 Feb 2024 10:48:37 -0300 Subject: [PATCH 1/6] 0.4.10-dev.0 --- fxpmath/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fxpmath/__init__.py b/fxpmath/__init__.py index 34872e7..bb8b575 100644 --- a/fxpmath/__init__.py +++ b/fxpmath/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.4.9' +__version__ = '0.4.10-dev.0' import sys import os From 85d731cc6e883a36edab891c1391ee3280aca13b Mon Sep 17 00:00:00 2001 From: francof2a Date: Sat, 10 Feb 2024 13:18:46 -0300 Subject: [PATCH 2/6] fix numpy int size for windows OS. This fix #73 #76 and #85 in windows OS using numpy 32 bit integer type --- fxpmath/functions.py | 4 ++-- fxpmath/objects.py | 5 ++++- tests/test_issues.py | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/fxpmath/functions.py b/fxpmath/functions.py index 3fd98d4..4b5c198 100644 --- a/fxpmath/functions.py +++ b/fxpmath/functions.py @@ -568,7 +568,7 @@ def cumsum(x, axis=None, out=None, out_like=None, sizing='optimal', method='raw' """ def _cumsum_raw(x, n_frac, **kwargs): precision_cast = (lambda m: np.array(m, dtype=object)) if n_frac >= _n_word_max else (lambda m: m) - return np.cumsum(x.val, **kwargs) * precision_cast(2**(n_frac - x.n_frac)) + return np.cumsum(precision_cast(x.val), **kwargs) * precision_cast(2**(n_frac - x.n_frac)) if not isinstance(x, Fxp): x = Fxp(x) @@ -591,7 +591,7 @@ def _cumprod_raw(x, n_frac, **kwargs): precision_cast = (lambda m: np.array(m, dtype=object)) if n_frac >= _n_word_max else (lambda m: m) pow_vals = n_frac - np.cumsum(np.ones_like(np.array(x)), axis=axis).astype(int) * x.n_frac conv_factors = utils.int_array([2**pow_val for pow_val in precision_cast(pow_vals)]) - return np.cumprod(x.val, **kwargs) * conv_factors + return np.cumprod(precision_cast(x.val), **kwargs) * precision_cast(conv_factors) if not isinstance(x, Fxp): x = Fxp(x) diff --git a/fxpmath/objects.py b/fxpmath/objects.py index e560a29..e66df05 100644 --- a/fxpmath/objects.py +++ b/fxpmath/objects.py @@ -849,7 +849,10 @@ def set_val(self, val, raw=False, vdtype=None, index=None): val = val.astype(object) else: val = val.astype(original_vdtype) - val_dtype = np.int64 if self.signed else np.uint64 + if _n_word_max_ <= 32: + val_dtype = np.int32 if self.signed else np.uint32 + else: + val_dtype = np.int64 if self.signed else np.uint64 # rounding and overflowing new_val = self._round(val * conv_factor , method=self.config.rounding) diff --git a/tests/test_issues.py b/tests/test_issues.py index cbfce6a..c74437d 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -422,6 +422,11 @@ def test_issue_76_v0_4_8(): y = np.cumsum(w) assert np.all(y() == np.array([1, 2, 3, 4])) + # Increase word size to 96 bits + w = Fxp([1, 1, 1, 1], dtype='fxp-s96/0') + y = np.cumsum(w) + assert np.all(y() == np.array([1, 2, 3, 4])) + def test_issue_77_v0_4_8(): # Precision error when numpy.reshape From 1c8bb97cd1c683fa63faf8d5c690bde0d7dfb905 Mon Sep 17 00:00:00 2001 From: francof2a Date: Sat, 10 Feb 2024 13:59:57 -0300 Subject: [PATCH 3/6] modify github workflows to run in every push over every branch --- .github/workflows/python-app.yml | 6 ++++-- .github/workflows/python-os.yml | 6 ++++-- .github/workflows/python-package.yml | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 8f75a06..7f2e38b 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -5,9 +5,11 @@ name: Python package on: push: - branches: [ master ] + branches: + - '*' pull_request: - branches: [ master ] + branches: + - '*' jobs: build: diff --git a/.github/workflows/python-os.yml b/.github/workflows/python-os.yml index ededfd0..cfd3b10 100644 --- a/.github/workflows/python-os.yml +++ b/.github/workflows/python-os.yml @@ -5,9 +5,11 @@ name: Python package on: push: - branches: [ master ] + branches: + - '*' pull_request: - branches: [ master ] + branches: + - '*' jobs: build: diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index e17275f..f268696 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,9 +5,11 @@ name: Python package on: push: - branches: [ master ] + branches: + - '*' pull_request: - branches: [ master ] + branches: + - '*' jobs: build: From 2bb9e93d4a3a5df6702b85a04fe9c73ea80cda00 Mon Sep 17 00:00:00 2001 From: francof2a Date: Sat, 10 Feb 2024 14:01:38 -0300 Subject: [PATCH 4/6] fix workflow names --- .github/workflows/python-app.yml | 2 +- .github/workflows/python-os.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 7f2e38b..c205fa4 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -1,7 +1,7 @@ # This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: Python package +name: Python App on: push: diff --git a/.github/workflows/python-os.yml b/.github/workflows/python-os.yml index cfd3b10..01e4018 100644 --- a/.github/workflows/python-os.yml +++ b/.github/workflows/python-os.yml @@ -1,7 +1,7 @@ # This workflow will install Python dependencies, run tests and lint with a single version of Python # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions -name: Python package +name: Python OS on: push: From bf94a97a820cb024bbc9c539014dc0e63ae3a1da Mon Sep 17 00:00:00 2001 From: francof2a Date: Sat, 10 Feb 2024 15:25:46 -0300 Subject: [PATCH 5/6] modify `reshape` method behavior to match numpy behavior. Now, this method not modify self object, only returned a reshaped Fxp. Fix issue #90 --- fxpmath/objects.py | 5 +++-- tests/test_issues.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/fxpmath/objects.py b/fxpmath/objects.py index e66df05..4789fe4 100644 --- a/fxpmath/objects.py +++ b/fxpmath/objects.py @@ -619,8 +619,9 @@ def reshape(self, shape, order='C'): """ - self.val = self.val.reshape(shape=shape, order=order) - return self + x = self.copy() + x.val = x.val.reshape(shape, order=order) + return x def flatten(self, order='C'): """ diff --git a/tests/test_issues.py b/tests/test_issues.py index c74437d..c68d041 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -471,3 +471,21 @@ def test_issue_85_v0_4_8(): x = Fxp(0.0, dtype=dt, overflow='wrap') # EXCEPTION assert x() == 0.0 + +def test_issue_90_v0_4_9(): + # Built-in Fxp.reshape() method passes the wrong number of arguments to underlying numpy reshape() function + x = Fxp([1,2,3,4], False, 8, 0) + y = x.reshape((2,2)) + + assert np.all(x.val.shape == np.array((4,))) + assert np.all(y.val.shape == np.array((2,2))) + + z = np.reshape(x, (2,2)) + + assert np.all(x.val.shape == np.array((4,))) + assert np.all(z.val.shape == np.array((2,2))) + + zz = fxp.reshape(x, (2,2)) + + assert np.all(x.val.shape == np.array((4,))) + assert np.all(zz.val.shape == np.array((2,2))) From a8e4b011cbcb9a97135264a7768ce51bf244ea3c Mon Sep 17 00:00:00 2001 From: francof2a Date: Sat, 10 Feb 2024 16:22:11 -0300 Subject: [PATCH 6/6] fix sizing at mul, truediv and floordiv when operands are complex. Fix issue # 91 --- fxpmath/functions.py | 16 ++++++++++------ tests/test_issues.py | 13 +++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/fxpmath/functions.py b/fxpmath/functions.py index 4b5c198..fc7ed7a 100644 --- a/fxpmath/functions.py +++ b/fxpmath/functions.py @@ -366,9 +366,11 @@ def _mul_raw(x, y, n_frac): if not isinstance(y, Fxp): y = Fxp(y) + is_complex = x.vdtype == complex or y.vdtype == complex + signed = x.signed or y.signed n_frac = x.n_frac + y.n_frac - n_word = x.n_word + y.n_word + n_word = x.n_word + y.n_word + int(is_complex) n_int = n_word - int(signed) - n_frac optimal_size = (signed, n_word, n_int, n_frac) @@ -405,12 +407,13 @@ def _floordiv_raw_complex(x, y, n_frac): if not isinstance(y, Fxp): y = Fxp(y) - if x.vdtype == complex or y.vdtype == complex: + is_complex = x.vdtype == complex or y.vdtype == complex + if is_complex: _floordiv_repr = _floordiv_repr_complex _floordiv_raw = _floordiv_raw_complex signed = x.signed or y.signed - n_int = x.n_int + y.n_frac + signed + n_int = x.n_int + y.n_frac + int(signed) + int(is_complex) n_frac = 0 n_word = int(signed) + n_int + n_frac optimal_size = (signed, n_word, n_int, n_frac) @@ -444,12 +447,13 @@ def _truediv_raw_complex(x, y, n_frac): if not isinstance(y, Fxp): y = Fxp(y) - if x.vdtype == complex or y.vdtype == complex: + is_complex = x.vdtype == complex or y.vdtype == complex + if is_complex: _truediv_raw = _truediv_raw_complex signed = x.signed or y.signed - n_int = x.n_int + y.n_frac + signed - n_frac = x.n_frac + y.n_int + n_int = x.n_int + y.n_frac + int(signed) + int(is_complex) + n_frac = x.n_frac + y.n_int + int(is_complex) n_word = int(signed) + n_int + n_frac optimal_size = (signed, n_word, n_int, n_frac) diff --git a/tests/test_issues.py b/tests/test_issues.py index c68d041..b4b637a 100644 --- a/tests/test_issues.py +++ b/tests/test_issues.py @@ -489,3 +489,16 @@ def test_issue_90_v0_4_9(): assert np.all(x.val.shape == np.array((4,))) assert np.all(zz.val.shape == np.array((2,2))) + + +def test_issue_91_v0_4_10(): + # Inaccuracy for certain complex multiplications + + x = Fxp(-1-1j) + xa = np.array(-1-1j) + + y = x * x + ya = xa * xa + + assert np.all(y() == ya) + \ No newline at end of file