中心を軸とした配列の入れ替え

5 Ansichten (letzte 30 Tage)
wataru suzuki
wataru suzuki am 22 Dez. 2020
Kommentiert: wataru suzuki am 24 Dez. 2020
以下のような5×5の奇数列の配列Aを中心である3列目をそのままに
配列Bのように左右に入れ替えたいです。
しかしB=circshift(A,[0 5/2]); とすると
エラー: circshift
無効なシフト タイプ: 有限の実数の整数ベクトルでなければなりません。
と出てしまいます。fliperやfftshiftなどのコマンドをそのまま使ってもできなかったので
この場合どのように構文すべきか教えていただけないでしょうか?
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
B=
8 15 1 17 24
14 16 7 23 5
20 22 13 4 6
21 3 19 10 12
2 9 25 11 18

Akzeptierte Antwort

源樹 上林
源樹 上林 am 22 Dez. 2020
 マニュアルを見ると circshift の2つ目の引数は整数と書いてあります。エラーメッセージに書いてあるとおりです。ceilとかfloorで整数にしたところで希望する結果は得られません。
 関数1個で解決するに越したことはないのですが、最適なものを見つけられなかったり、存在しなくて簡単には解決しないこともよくあります。そういうときは泥臭い方法で解決するのも一つの手段です。
まず2回にシフトしてみました。
A = magic(5)
hw = ceil(size(A,2)/2);
B = circshift(A, [0 hw]);
B(:,[1:hw]) = circshift(B(:,[1:hw]), [0 -1]);
B
これだと偶数配列の場合はだめですね。
配列のインデックスを使って入れ替え。
A = magic(5)
% 最終的にこのようにしたい
% B = A;
% B(:,[4 5 1 2]) = A(:,[1 2 4 5]);
w = size(A,2);
hw = floor(w/2);
i = circshift( 1:w, hw );
ib = i(1:hw*2)
ia = circshift( ib, hw );
B = A;
B(:,ib) = A(:,ia);
B
良さそうだけど、長しい、何をやっているのかがわかりにくい。
あわせ技を思いつきました。
A = magic(5)
B = A;
i = [1 2 4 5];
B(:,i) = circshift(A(:,i), [0 2]);
B
これならスッキリしてて動作も理解しやすそうです。iさえ作れれば。
w = size(A,2);
i = 1:w;
if mod(w,2)
i(ceil(w/2)) = [];
end
こうなるのか。結局あまりきれいには書けませんでしたが、これでご希望の変換ができると思います。
  2 Kommentare
Shunichi Kusano
Shunichi Kusano am 23 Dez. 2020
上林さんの回答を見てすっきり書ける方法を思いついたので補足いたします。
A = magic(5)
i = [1 2 4 5]; % 5以外の場合、i = setdiff(1:size(A,2),ceil(size(A,2)/2));でOK
A(:,i) = A(:,circshift(i,2,2)); % 5以外の場合、シフト量は上と同様に変える
wataru suzuki
wataru suzuki am 24 Dez. 2020
お二人ともありがとうございます。お蔭様でできそうです!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!