Skip to content
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

Inverting signal with division operator throws error when using fft normalization #587

Open
tjueterb opened this issue Apr 12, 2024 · 2 comments · May be fixed by #593
Open

Inverting signal with division operator throws error when using fft normalization #587

tjueterb opened this issue Apr 12, 2024 · 2 comments · May be fixed by #593

Comments

@tjueterb
Copy link
Contributor

General

  • pyfar version: 0.6.5
  • Python version: 3.11.2
  • Operating System: macOS
  • Did you install pyfar via pip: yes

Description

Hi,

When using an fft normalization other than none, inverting the signal with the division operator 1 / signal throws the error:

ValueError: Either fft_norm_2 (denominator) has to be 'none' or both fft_norms must be the same, but they are none and rms.

Inverting with signal**-1 works fine.

What I Did

import pyfar as pf
signal = pf.signals.exponential_sweep_time(44100, (50, 2e4))
signal.fft_norm = 'rms'
1 / signal
{
	"name": "ValueError",
	"message": "Either fft_norm_2 (denominator) has to be 'none' or both fft_norms must be the same, but they are none and rms.",
	"stack": "---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[4], line 4
      2 signal = pf.signals.exponential_sweep_time(44100, (50, 2e4))
      3 signal.fft_norm = 'rms'
----> 4 1 / signal

File ~/anaconda3/envs/electroacoustics/lib/python3.11/site-packages/pyfar/classes/audio.py:519, in FrequencyData.__rtruediv__(self, data)
    518 def __rtruediv__(self, data):
--> 519     return divide((data, self), 'freq')

File ~/anaconda3/envs/electroacoustics/lib/python3.11/site-packages/pyfar/classes/audio.py:1049, in divide(data, domain)
   1008 def divide(data: tuple, domain='freq'):
   1009     \"\"\"Divide pyfar audio objects, array likes, and scalars.
   1010 
   1011     Pyfar audio objects are: :py:func:`Signal`, :py:func:`TimeData`, and
   (...)
   1047     * Other combinations raise an error.
   1048    \"\"\"
-> 1049     return _arithmetic(data, domain, _divide)

File ~/anaconda3/envs/electroacoustics/lib/python3.11/site-packages/pyfar/classes/audio.py:1271, in _arithmetic(data, domain, operation, **kwargs)
   1267 division = True if operation == _divide else False
   1268 matmul = True if operation == _matrix_multiplication else False
   1269 sampling_rate, n_samples, fft_norm, times, frequencies, audio_type, \\
   1270     cshape = \\
-> 1271     _assert_match_for_arithmetic(data, domain, division, matmul)
   1273 # apply arithmetic operation
   1274 result = _get_arithmetic_data(data[0], domain, cshape, matmul, audio_type)

File ~/anaconda3/envs/electroacoustics/lib/python3.11/site-packages/pyfar/classes/audio.py:1370, in _assert_match_for_arithmetic(data, domain, division, matmul)
   1365     n_samples = d.n_samples
   1366     # if a signal comes first (n==0) its fft_norm is taken
   1367     # directly. If a signal does not come first, (n>0, e.g.
   1368     # 1/signal), the fft norm is matched
   1369     fft_norm = d.fft_norm if n == 0 else \\
-> 1370         _match_fft_norm(fft_norm, d.fft_norm, division)
   1371 elif isinstance(d, TimeData):
   1372     if domain != \"time\":

File ~/anaconda3/envs/electroacoustics/lib/python3.11/site-packages/pyfar/classes/audio.py:1579, in _match_fft_norm(fft_norm_1, fft_norm_2, division)
   1576         fft_norm_result = 'none'
   1578     else:
-> 1579         raise ValueError((\"Either fft_norm_2 (denominator) has to be \"
   1580                           \"'none' or both fft_norms must be the same, but \"
   1581                           f\"they are {fft_norm_1} and {fft_norm_2}.\"))
   1583 return fft_norm_result

ValueError: Either fft_norm_2 (denominator) has to be 'none' or both fft_norms must be the same, but they are none and rms."
}
@mberz
Copy link
Member

mberz commented Apr 19, 2024

That's an interesting issue. Seems like it is due to the fact that internally 1 is "cast" to a Signal with "none" normalisation.

In any case I'd recommend using the regularised spectrum inversion for the example you provided (if the example you provided is not an irrelevant toy example)

@tjueterb
Copy link
Contributor Author

The example was just for demonstration purposes, of course I always use regularized inversion 😇

robogeisha added a commit to robogeisha/pyfar that referenced this issue Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants