matlab
1%%テストデータの読み込み 2[x2,fs]=audioread('sound.wav'); 3 4d=zeros(length(x2),1); %d:エコー信号 5x=zeros(length(x2),1) %x:参照信号 6e=zeros(length(x2),1); %誤差信号 7%wave信号を参照信号とエコー信号に分ける 8x(:)=x2(:,1); 9d(:)=x2(:,2); 10myu=0.5; %ステップサイズパラメータ 11filter_length=400; 12w=zeros(filter_length,1);%フィルタ係数初期化 13N=length(x2)-filter_length; 14 15for i=1:N; 16 xx=x(i:i+filter_length-1); 17 y(i)=w.'.*xx; 18 e(i)=d(i)-y(i); 19 w=w+(myu.*((e(i).*x)./(x.'.*x))); 20end 21figure(1) 22plot(flipud(w)) 23 24
音源x2(2,80000)の中身のwavファイルでサンプリング周波数は8000Hzに設定しています.
学習同定法を用いてインパルス応答を推定するプログラムをリンク内容を参考にして作成しています.
x2の長さの80000までwを計算し,最後にwをプロットすることで音源のインパルス応答が取得できます.
for文のところを作成してみたのですが,
左辺と右辺の要素数が異なるため、代入を実行できません。
matlab
1左辺と右辺の要素数が異なるため、代入を実行できません。 2 3エラー: (行 16) 4 y(i)=w.'.*xx; 5 6>>
このようなエラーが出ます.
matlab
1 2>> size(y) 3 4ans = 5 6 80000 400 7 8>> size(w.'.*x) 9 10ans = 11 12 80000 400 13 14>>
と確認しましたが,sizeは合っているように見えます.
w,xxは400×1の行列です.
matlab
1>> size(y(1)) 2 3ans = 4 5 1 1
matlab
1 2y=w.'.*x; 3e=d-y; 4w=w+(myu.*((e.*x)/(x.'.*x))); 5
またfor文をこのように直すと以下のようなエラーが出ます.
matlab
1要求された 80000x80000 (47.7GB) 配列は、最大配列サイズの基本設定 (8.0GB) を超 2えています。これにより、MATLAB は反応しなくなる可能性があります。 3 4エラー: (行 17) 5w=w+(myu.*((e.*x)/(x.'.*x))); 6
質問のコードでは、yはforループ内の
y(i)=w.'.*xx;
でいきなり出てきてますけど、
> size(y)
ans = 80000 400
ということは、実際はそれよりも前に
y=zeros(length(x2),filter_length)
みたいにして、形状を定義してるのでしょうか?
> w,xxは400×1の行列です.
の場合、
size(w.'.*xx)
ans = 400 400
なので、
y(i)=w.'.*xx;
とするには、y(1), y(2)...それぞれが400x400のサイズで、それがN個あるのがyとなり、yは80000x400x400という、かなりサイズがでかい3次元配列になるはずで、
> size(y)
ans = 80000 400
とは矛盾します
y(i, :)=(w.*xx)';
ならば、式の右辺のサイズは
size((w.*xx)')
ans = 1 400
と1x400になるので、yはNx400の2次元配列になりますけど
あと
> w=w+(myu.*((e(i).*x)./(x.'.*x)));
の「(x.'.*x)」は、80000x80000というサイズの配列なので、サイズがでかすぎて領域確保できないと思う
そこを「(x.*x)」に変えたら80000x1のサイズになるけど、
size(myu.*((e(i).*x)./(x.*x)))
ans = 80000 1
と
size(w)
ans = 400 1
が違うので、結局
w=w+(...
の計算はできない