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

조회 수: 4 (최근 30일)
wataru suzuki
wataru suzuki 2020년 12월 22일
댓글: wataru suzuki 2020년 12월 24일
以下のような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

채택된 답변

源樹 上林
源樹 上林 2020년 12월 22일
 マニュアルを見ると 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
Shunichi Kusano
Shunichi Kusano 2020년 12월 23일
上林さんの回答を見てすっきり書ける方法を思いついたので補足いたします。
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 2020년 12월 24일
お二人ともありがとうございます。お蔭様でできそうです!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 ループと条件付きステートメント에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!