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

fftpack → fft #381

Closed
wants to merge 10 commits into from
71 changes: 43 additions & 28 deletions mir_eval/separation.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"""

import numpy as np
import scipy.fftpack
import scipy.fft
from scipy.linalg import toeplitz
from scipy.signal import fftconvolve
import collections
Expand Down Expand Up @@ -692,17 +692,17 @@ def _project(reference_sources, estimated_source, flen):

# computing coefficients of least squares problem via FFT ##
# zero padding and FFT of input data
reference_sources = np.hstack((reference_sources, np.zeros((nsrc, flen - 1))))
estimated_source = np.hstack((estimated_source, np.zeros(flen - 1)))
n_fft = int(2 ** np.ceil(np.log2(nsampl + flen - 1.0)))
sf = scipy.fftpack.fft(reference_sources, n=n_fft, axis=1)
sef = scipy.fftpack.fft(estimated_source, n=n_fft)
# reference_sources = np.hstack((reference_sources, np.zeros((nsrc, flen - 1))))
# estimated_source = np.hstack((estimated_source, np.zeros(flen - 1)))
n_fft = scipy.fft.next_fast_len(nsampl + flen - 1, True)
sf = scipy.fft.rfft(reference_sources, n=n_fft, axis=1)
sef = scipy.fft.rfft(estimated_source, n=n_fft)
# inner products between delayed versions of reference_sources
G = np.zeros((nsrc * flen, nsrc * flen))
for i in range(nsrc):
for j in range(nsrc):
ssf = sf[i] * np.conj(sf[j])
ssf = np.real(scipy.fftpack.ifft(ssf))
ssf = scipy.fft.irfft(ssf, n=n_fft)
ss = toeplitz(np.hstack((ssf[0], ssf[-1:-flen:-1])), r=ssf[:flen])
G[i * flen : (i + 1) * flen, j * flen : (j + 1) * flen] = ss
G[j * flen : (j + 1) * flen, i * flen : (i + 1) * flen] = ss.T
Expand All @@ -711,15 +711,21 @@ def _project(reference_sources, estimated_source, flen):
D = np.zeros(nsrc * flen)
for i in range(nsrc):
ssef = sf[i] * np.conj(sef)
ssef = np.real(scipy.fftpack.ifft(ssef))
ssef = scipy.fft.irfft(ssef, n=n_fft)
D[i * flen : (i + 1) * flen] = np.hstack((ssef[0], ssef[-1:-flen:-1]))

# Computing projection
# Distortion filters
try:
C = np.linalg.solve(G, D).reshape(flen, nsrc, order="F")
except np.linalg.linalg.LinAlgError:
C = np.linalg.lstsq(G, D)[0].reshape(flen, nsrc, order="F")
with warnings.catch_warnings():
warnings.filterwarnings("error", category=scipy.linalg.LinAlgWarning)
try:
C = scipy.linalg.solve(G, D).reshape(flen, nsrc, order="F")
except (
np.linalg.linalg.LinAlgError,
scipy.linalg.LinAlgError,
scipy.linalg.LinAlgWarning,
):
C = scipy.linalg.lstsq(G, D, cond=None)[0].reshape(flen, nsrc, order="F")
# Filtering
sproj = np.zeros(nsampl + flen - 1)
for i in range(nsrc):
Expand All @@ -743,15 +749,15 @@ def _project_images(reference_sources, estimated_source, flen, G=None):

# computing coefficients of least squares problem via FFT ##
# zero padding and FFT of input data
reference_sources = np.hstack(
(reference_sources, np.zeros((nchan * nsrc, flen - 1)))
)
estimated_source = np.hstack(
(estimated_source.transpose(), np.zeros((nchan, flen - 1)))
)
n_fft = int(2 ** np.ceil(np.log2(nsampl + flen - 1.0)))
sf = scipy.fftpack.fft(reference_sources, n=n_fft, axis=1)
sef = scipy.fftpack.fft(estimated_source, n=n_fft)
# reference_sources = np.hstack(
# (reference_sources, np.zeros((nchan * nsrc, flen - 1)))
# )
# estimated_source = np.hstack(
# (estimated_source.transpose(), np.zeros((nchan, flen - 1)))
# )
n_fft = scipy.fft.next_fast_len(nsampl + flen - 1, True)
sf = scipy.fft.rfft(reference_sources, n=n_fft, axis=1)
sef = scipy.fft.rfft(estimated_source.T, n=n_fft)

# inner products between delayed versions of reference_sources
if G is None:
Expand All @@ -760,7 +766,7 @@ def _project_images(reference_sources, estimated_source, flen, G=None):
for i in range(nchan * nsrc):
for j in range(i + 1):
ssf = sf[i] * np.conj(sf[j])
ssf = np.real(scipy.fftpack.ifft(ssf))
ssf = scipy.fft.irfft(ssf, n=n_fft)
ss = toeplitz(np.hstack((ssf[0], ssf[-1:-flen:-1])), r=ssf[:flen])
G[i * flen : (i + 1) * flen, j * flen : (j + 1) * flen] = ss
G[j * flen : (j + 1) * flen, i * flen : (i + 1) * flen] = ss.T
Expand All @@ -771,7 +777,7 @@ def _project_images(reference_sources, estimated_source, flen, G=None):
for i in range(nchan * nsrc):
for j in range(i + 1):
ssf = sf[i] * np.conj(sf[j])
ssf = np.real(scipy.fftpack.ifft(ssf))
ssf = scipy.fft.irfft(ssf, n=n_fft)
ss = toeplitz(np.hstack((ssf[0], ssf[-1:-flen:-1])), r=ssf[:flen])
G[i * flen : (i + 1) * flen, j * flen : (j + 1) * flen] = ss
G[j * flen : (j + 1) * flen, i * flen : (i + 1) * flen] = ss.T
Expand All @@ -782,17 +788,26 @@ def _project_images(reference_sources, estimated_source, flen, G=None):
for k in range(nchan * nsrc):
for i in range(nchan):
ssef = sf[k] * np.conj(sef[i])
ssef = np.real(scipy.fftpack.ifft(ssef))
ssef = scipy.fft.irfft(ssef, n=n_fft)
D[k * flen : (k + 1) * flen, i] = np.hstack(
(ssef[0], ssef[-1:-flen:-1])
).transpose()

# Computing projection
# Distortion filters
try:
C = np.linalg.solve(G, D).reshape(flen, nchan * nsrc, nchan, order="F")
except np.linalg.linalg.LinAlgError:
C = np.linalg.lstsq(G, D)[0].reshape(flen, nchan * nsrc, nchan, order="F")
with warnings.catch_warnings():
warnings.filterwarnings("error", category=scipy.linalg.LinAlgWarning)

try:
C = scipy.linalg.solve(G, D).reshape(flen, nchan * nsrc, nchan, order="F")
except (
np.linalg.linalg.LinAlgError,
scipy.linalg.LinAlgError,
scipy.linalg.LinAlgWarning,
):
C = scipy.linalg.lstsq(G, D, cond=None)[0].reshape(
flen, nchan * nsrc, nchan, order="F"
)
# Filtering
sproj = np.zeros((nchan, nsampl + flen - 1))
for k in range(nchan * nsrc):
Expand Down
5 changes: 5 additions & 0 deletions tests/test_separation.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ def test_separation_images_framewise(separation_data):
imageframe_scores[key],
expected_image_frames[test_data_name],
atol=A_TOL,
), np.max(
np.abs(
np.array(imageframe_scores[key])
- np.array(expected_image_frames[test_data_name])
)
)

# Catch a few exceptions in the evaluate function
Expand Down
Loading