-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong results when cascading biquads in sosfilter_c #24
Comments
You should recheck your code (there is a wrong usage of the function) and
read the documentation.
ZR Han ***@***.***> schrieb am Fr., 6. Jan. 2023, 10:16:
… sosfilter_c gives wrong results when cascading multiple biquads. Some
simple code to show:
import numpy as npfrom pyfilterbank.sosfiltering import sosfilter_cfrom scipy.signal import sosfilt
sos0 = np.array([
[0.9994671940803528, -1.980954885482788, 0.9816480278968811, 1.0, -1.9809452295303345, 0.981124997138977],
[0.9940603375434875, -1.8794806003570557, 0.89670330286026, 1.0, -1.8794806003570557, 0.8907635807991028]
])sos1 = sos0.flatten()
x = np.random.random((16,))z0 = np.zeros((sos0.shape[0], 2))y0, z0 = sosfilt(sos0, x, zi=z0)
y1, z1 = sosfilter_c(x, sos1)
y2, _ = sosfilter_c(x, sos0[0])y2, _ = sosfilter_c(y2, sos0[1])
y0 and y1 are identical except the numerical precision but y1 is
incorrect.
—
Reply to this email directly, view it on GitHub
<#24>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAXQ6H7VV6QZFFIXDU5UVV3WQ7PIJANCNFSM6AAAAAATS37RWA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
@SiggiGue Thank you for response. Could you please specify where the wrong usage is? I've read the documentation and the syntax of the function is
In my code By the way, I think there's something wrong in your unit test code: pyfilterbank/pyfilterbank/tests/test_sosfiltering.py Lines 10 to 18 in 5d74af8
In the test code |
You can check this out by replacing
and you will see the unit test failed:
|
If you cascade sos, you need too feed the intermediate states into the
function as well to get the expected results for your comparison.
ZR Han ***@***.***> schrieb am Do., 12. Jan. 2023, 03:40:
… You can check this out by replacing sf.sosfilter_double_c with
sf.sosfilter_c in the ut
https://github.com/SiggiGue/pyfilterbank/blob/87b9bb52cb6ecdbcbc0385f1c10ed040b22b49d1/pyfilterbank/tests/test_sosfiltering.py#L23
and you will see the unit test failed:
Traceback (most recent call last):
File "~/ut.py", line 41, in test_implementation
self.assertAlmostEqual(sop, soc, places=6)
AssertionError: 1119.841385113597 != 1121.028 within 6 places (1.1865689879655292 difference)
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAXQ6H4657QOED2Z6MT4BWTWR5VIRANCNFSM6AAAAAATS37RWA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
This doesn't make sense to me. The documentation states that initial state can be y1, z1 = sosfilter_c(x, sos1) to y1, z1 = sosfilter_c(x, sos1, states=np.zeros((2 * 2, ))) the result is still incorrect. If you meant that y2, _ = sosfilter_c(x, sos0[0])
y2, _ = sosfilter_c(y2, sos0[1]) should be
I don't think this is true. Cascaded biquads don't share internal states. |
Have a look at this code: import numpy as np
from pyfilterbank.sosfiltering import sosfilter_c, sosfilter_double_c
from scipy.signal import sosfilt
sos = np.array([
[0.9994671940803528, -1.980954885482788, 0.9816480278968811, 1.0, -1.9809452295303345, 0.981124997138977],
[0.9940603375434875, -1.8794806003570557, 0.89670330286026, 1.0, -1.8794806003570557, 0.8907635807991028]
], dtype=np.float32)
x = np.random.random((16,)).astype(np.float32)
y0, z0 = sosfilt(sos, x, zi=np.zeros((sos.shape[0], 2)))
y1, z1 = sosfilter_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))
y2, z2 = sosfilter_double_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))
print(np.mean((y0 - y1)**2))
print(np.mean((y0 - y2)**2)) The only difference between
|
Sorry, you are totally right with the states, I was a bit short in time,
answering to your issue.
Maybe you can find out, what the problem is? Because I have no spare time
for this repo at the moment.
The plan is to remove the c part totally since scipy has a sosfilt function
by this time.
Best regards and thank you for reporting.
ZR Han ***@***.***> schrieb am Do., 12. Jan. 2023, 08:56:
… Have a look at this code:
import numpy as npfrom pyfilterbank.sosfiltering import sosfilter_c, sosfilter_double_cfrom scipy.signal import sosfilt
sos = np.array([
[0.9994671940803528, -1.980954885482788, 0.9816480278968811, 1.0, -1.9809452295303345, 0.981124997138977],
[0.9940603375434875, -1.8794806003570557, 0.89670330286026, 1.0, -1.8794806003570557, 0.8907635807991028]
], dtype=np.float32)
x = np.random.random((16,)).astype(np.float32)
y0, z0 = sosfilt(sos, x, zi=np.zeros((sos.shape[0], 2)))y1, z1 = sosfilter_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))y2, z2 = sosfilter_double_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))
print(np.mean((y0 - y1)**2))print(np.mean((y0 - y2)**2))
The only difference between y1 and y2 is sosfilter_c and
sosfilter_double_c, and the output is quite different.
0.0013462692831356475
3.282670120428347e-29
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAXQ6HYSD2ZKMQQFXUKNSG3WR62LXANCNFSM6AAAAAATS37RWA>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Have you tried what happens if you feed the scipy sosfilt function with
float32 data cascaded inside and outside?
Maybe this is just a numerical issue.
Siegfried Gündert ***@***.***> schrieb am Do., 12.
Jan. 2023, 09:45:
… Sorry, you are totally right with the states, I was a bit short in time,
answering to your issue.
Maybe you can find out, what the problem is? Because I have no spare time
for this repo at the moment.
The plan is to remove the c part totally since scipy has a sosfilt
function by this time.
Best regards and thank you for reporting.
ZR Han ***@***.***> schrieb am Do., 12. Jan. 2023, 08:56:
> Have a look at this code:
>
> import numpy as npfrom pyfilterbank.sosfiltering import sosfilter_c, sosfilter_double_cfrom scipy.signal import sosfilt
> sos = np.array([
> [0.9994671940803528, -1.980954885482788, 0.9816480278968811, 1.0, -1.9809452295303345, 0.981124997138977],
> [0.9940603375434875, -1.8794806003570557, 0.89670330286026, 1.0, -1.8794806003570557, 0.8907635807991028]
> ], dtype=np.float32)
> x = np.random.random((16,)).astype(np.float32)
> y0, z0 = sosfilt(sos, x, zi=np.zeros((sos.shape[0], 2)))y1, z1 = sosfilter_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))y2, z2 = sosfilter_double_c(x, sos.flatten(), states=np.zeros((sos.shape[0] * 2, )))
> print(np.mean((y0 - y1)**2))print(np.mean((y0 - y2)**2))
>
> The only difference between y1 and y2 is sosfilter_c and
> sosfilter_double_c, and the output is quite different.
>
> 0.0013462692831356475
> 3.282670120428347e-29
>
> —
> Reply to this email directly, view it on GitHub
> <#24 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAXQ6HYSD2ZKMQQFXUKNSG3WR62LXANCNFSM6AAAAAATS37RWA>
> .
> You are receiving this because you were mentioned.Message ID:
> ***@***.***>
>
|
As you can see the output is so different that we can't say it's related to the numeric issue. The states of the first stage of sos is correct but the second one is not. I've checked the source code and all I found is pyfilterbank/pyfilterbank/sosfiltering.py Lines 109 to 110 in 87b9bb5
can be changed to if isinstance(states, type(None)):
states = np.zeros(ksos*2).astype(np.float32) but this doesn't help because you convert it to pyfilterbank/pyfilterbank/sosfiltering.py Lines 112 to 113 in 87b9bb5
C code seems correct too. I can't tell what's going wrong. |
Thank you for having a look into that.
Line 111 is a bit misleading withe the double cast and I should have
changed it to float32 but as you said, this won't make a difference.
I would be very interested in the reson of this issue.
Anyway, applying the YAGNI principle will remove the sosfilt.c stuff from
this repo, as mentioned above.
ZR Han ***@***.***> schrieb am Do., 12. Jan. 2023, 10:30:
… [image: image]
<https://user-images.githubusercontent.com/21305646/212028051-2830982d-3e86-40b0-b4cf-fb5efa33b988.png>
As you can see the output is so different that we can't say it's related
to the numeric issue. The states of the first stage of sos is correct but
the second one is not. I've checked the source code and all I found is
https://github.com/SiggiGue/pyfilterbank/blob/87b9bb52cb6ecdbcbc0385f1c10ed040b22b49d1/pyfilterbank/sosfiltering.py#L109-L110
can be changed to
if isinstance(states, type(None)):
states = np.zeros(ksos*2).astype(np.float32)
but this doesn't help because you convert it to np.float32 in the
following lines
https://github.com/SiggiGue/pyfilterbank/blob/87b9bb52cb6ecdbcbc0385f1c10ed040b22b49d1/pyfilterbank/sosfiltering.py#L112-L113
C code seems correct too. I can't tell what's going wrong.
—
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAXQ6H6H5CR6HNIKY7GDIHLWR7FKDANCNFSM6AAAAAATS37RWA>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
sosfilter_c
gives wrong results when cascading multiple biquads. Some simple code to show:y0
andy2
are identical except the numerical precision buty1
is incorrect.The text was updated successfully, but these errors were encountered: