質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Q&A

解決済

1回答

1177閲覧

max関数でのエラー

kaeruuuun

総合スコア19

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

0グッド

0クリップ

投稿2021/06/07 00:14

編集2021/06/07 00:31

j=1からj=200まで自己相関関数r(j)を求めてそのうちのr(80)からr(200)での最大値を求めてその最大値の位置を返すと言うプログラムを実現したいと考えています.
r(1)からr(200)には自己相関関数が求まっているとして最大値の位置を求めます.max関数の第二引数が最大値のインデックスを返すので,

scilab

1 max=0; 2 for j=80:200 3 4 [z,argmax]=max(r(j)); 5 6 end

のようにしてみたのですが,

scilab

1実行されたファイルの 103 行目 2/Users/ 3Wrong number of output arguments. 4

このようなエラーが出ます.この103行目はmax=0のところなのですが,初期値としてmaxに0を入れると言うのは無理なのでしょうか.この場合,z=0とすれば,初期値に0が入っていることになりますか?

追記

z=0で実行してみるとargmaxには1が一つ入っているだけでグラフとしてもずっと0のグラフが表示されます.

最終的には求めた最大値の位置argmaxから基本周波数f0を推定し,f0をプロットします.

scilab

1 period = argmax/16; 2 f0(n) = 1000/period; 3 4

そもそもこれはmax関数を使う方法であっていますか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/06/07 00:43 編集

max=0; も for j=80:200 も(endも)無しで、 [z,argmax]=max(r(80:200)); だけで、できませんか? https://teratail.com/questions/341675 で、yuki23さんも回答の最後にfor要らないって書いてますよね
jbpb0

2021/06/07 00:47

> 初期値としてmaxに0を入れると言うのは無理なのでしょうか なぜ初期値が要るのでしょうか?
kaeruuuun

2021/06/07 00:57

>[z,argmax]=max(r(80:200)); やってみたのですが,最大値が一つだけ表示されてargmaxも1つしか値が入っていません.私はこの操作を音声の終端に達するまで行いたいのですが,forを取ると一回だけしかmax関数が行われないことになりませんか? >なぜ初期値が要るのでしょうか? sumなどをするときは初期値がいるので,その感覚でした.
kaeruuuun

2021/06/07 01:17 編集

thlogpwr=-25; for n=1:n_frame // n_frameは分析フレーム数 if logpwr(n) < thlogpwr then f0(n)=0; else st=1+(n-1)*sfreq*fshift; // 現フレームの開始サンプル番号 j=1; for l=0:order // 自己相関関数r(j), j=1,...,order を計算する end max=0; for j=80:200 // r(j), j=80,...,200の最大値の位置(argmax)を求める end period = argmax/16; f0(n) = 1000/period; end end subplot(3,1,3); xlabel("Time [ms]"); ylabel("Fundamental Frequency [Hz]"); plot2d(tp,f0); このようにある程度雛形があるプログラムだったので,このように定義していたわけです. nが分析フレームなので,そのフレームでf0の最大値を求めてまたnが動いてその部分でf0の最大値を求めたいと言う感じでした.
jbpb0

2021/06/07 01:11 編集

> forを取ると一回だけしかmax関数が行われないことになりませんか? 「そのr(80:200)」に対して、1回だけ計算されます 「そのr(80:200)」に付いては、最大値は一つだけだし、最大値の場所も一つだけだから、1回だけしか計算する必要はありません > 音声の終端に達するまで行いたい その場合は、音声のいろんな場所毎に「別のr(80:200)」があるのですよね?? (音声のいろんな場所に対応した)「たくさんのr(80:200)」があって、それぞれに対してmax()を計算するのなら、ループの中で、 ・「たくさんのr(80:200)」から「一つのr(80:200)」を取り出す ・取り出した「一つのr(80:200)」でmax()計算する ・max()の結果は、上書きされて消えないように、配列に入れる みたいなことをします 質問のどこにも「たくさんのr(80:200)」があって、それらに個別にmax()計算したい、とは書かれてないので、そんなこと他人には分かりません > sumなどをするときは初期値がいる 要りません rsum=sum(r(80:200)); で、r(80:200)の合計が計算できます
kaeruuuun

2021/06/07 01:12

>質問のどこにも「たくさんのr(80:200)」があって、それらに個別にmax()計算したい、とは書かれてないので、そんなこと他人には分かりません 申し訳ございません.この質問には書き忘れていました.
jbpb0

2021/06/07 01:28

> nが分析フレームなので,そのフレームでf0の最大値を求めてまたnが動いてその部分でf0の最大値を求めたい の上のコードを読んでも、意味が分かりません nが変わろうと、nに連動してstが変わろうと、それに連動してrが変わっているわけではないので、for n...のループを何回回そうと、同じrから計算した最大値は常に同じです 「たくさんのr(80:200)」から「一つのr(80:200)」を取り出す、が無い それは意図通りですか?
kaeruuuun

2021/06/07 01:28

>要りません rsum=sum(r(80:200)); で、r(80:200)の合計が計算できます もしかしたらCと混乱しているかもしれません.ありがとうございます.
jbpb0

2021/06/07 06:10 編集

> Cと混乱している そうなんでしょうね たとえば、max()を使わずに maxval=-1000000000; maxpos=0; for j=80:200 if r(j)>maxval then maxval=r(j); maxpos=j; end end みたいなことをやるのなら、ループの前に初期値を入れます max()を使えば、上記のようなことをやらなくても [maxval, maxpos]=max(r(80:200)); だけで済みます sum()も同様 他の配列を処理できるたくさんの関数も、同様
kaeruuuun

2021/06/07 01:41

>の上のコードを読んでも、意味が分かりません nが変わろうと、nに連動してstが変わろうと、それに連動してrが変わっているわけではないので、for n...のループを何回回そうと、同じrから計算した最大値は常に同じです 「たくさんのr(80:200)」から「一つのr(80:200)」を取り出す、が無い それは意図通りですか? 確かによく考えてみるとr(j)は常に同じ値が入っていて,stとかnが変化しても変わりませんね. for st=1:sfreq*fshift:n_sample-len pwr=0; for i=1:len x1(i)=x(i+st)*win(i); pwr=pwr+x1(i)*x1(i); end n_frame=n_frame+1; tp(n_frame)=fwidth/2+(n_frame-1)*fshift; logpwr(n_frame)=10*log10(pwr); end 自己相関関数はx1との自己相関関数を求めることになり,これがx1の定義ですが,これでもnやstに連動してrは変化しませんか?
kaeruuuun

2021/06/07 01:42

>[maxval, maxpos]=max(r(80:200)); この範囲での最大値がmaxvalでmaxposが最大値の位置ですか?
jbpb0

2021/06/07 01:51

>>[maxval, maxpos]=max(r(80:200)); > この範囲での最大値がmaxvalでmaxposが最大値の位置ですか? 説明に抜けがありました すみません maxvalはそうですが、maxposは「最大値の位置」の定義によっては違います r(80:200)に対して計算してるので、もしmaxposが1の場合は、もともとの要素数が200あるr全体の中での位置は80です 欲しい位置が、r(80:200)の中の位置か、もともとのr全体の中での位置か、によります もし後者が欲しいなら、maxposに79(=80-1)を足します
kaeruuuun

2021/06/07 01:55

r(80:200)に対して計算してるので、もしmaxposが1の場合は、もともとの要素数が200あるr全体の中での位置は80です 欲しい位置が、r(80:200)の中の位置か、もともとのr全体の中での位置か、によります もし後者が欲しいなら、maxposに79(=80-1)を足します わかりました. rが80と返して欲しいので前者です.
jbpb0

2021/06/07 02:13 編集

> これでもnやstに連動してrは変化しませんか? しません その上のコードで、for st...のループで毎回stを変えた計算をしてますが、その結果は「同じx1」に上書き代入してるので、前回までに計算したx1の値は消えてしまい、ループが終わった後でx1に入っているのは、ループの最終回での計算結果だけです そのx1から計算したrもまた、音声データの一番最後のものだけです そのことは、 https://teratail.com/questions/341747 で、何度も指摘してます > x1にはstのループの最後の回の計算値だけが入ってますが、それは意図通りですか? > xの最後の512個にしか関係してないx1の自己相関関数が計算できたら、それでいいのですか? xの他の部分は、要らないのですか? のように 質問者さんがやりたいことを実現するには、ループの毎回で計算してるx1を全部残さないといけないのです 現状のコードは、そうなってません (繰り返し書きますが、同じx1に毎回上書きしてる) 現状のコードでは、x1は要素数がlen個の配列になってると思います 質問者さんの意図通りにするには、x1は要素数がn_frame, len個の2次元配列になるはず 1セットがlen個のデータで、それがn_frameセットあるはずだから
guest

回答1

0

ベストアンサー

「質問への追記・修正の依頼」にいろいろ書いてますが、もともとの質問の

r(80)からr(200)での最大値を求めてその最大値の位置を返す

に沿って回答します

scilab

1 max=0; 2 for j=80:200 3 4 [z,argmax]=max(r(j)); 5 6 end

↓ 修正

scilab

1 [z,argmax]=max(r(80:200));

zが最大値、argmaxが最大値の位置です

ただし、argmaxはr(80:200)の中の位置なので、たとえばargmaxが1の場合は、もともとの要素数が200あるr全体の中での位置は80です
欲しい位置が、もともとのr全体の中での位置ならば、argmaxに79(=80-1)を足します

投稿2021/06/07 03:22

編集2021/06/07 04:11
jbpb0

総合スコア7651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問