2

Suppose the array is:

A =    a b c
       d e f
       g h i

I want to copy the diamond arrangement, i.e. the elements d,b,f,h,e into a new 1D array. The above array is just an example, the matrix could be any size rectangular matrix and the location of the diamond can be anywhere within the array.

HIMANK
  • 35
  • 3
  • Shortest or most efficient? Are you just interested in 3-by-3 matrices, or arbitrary square matrices, or even rectangular matrices? And I assume that you want to copy these elements to an array of zeros? Please edit your question to clarify these issues. – horchler Feb 06 '15 at 20:24
  • Yes, most efficient code and the matrix can be rectangular, and the diamond arrangement can be anywhere within a large array. I just want to get the idea using the example above... – HIMANK Feb 06 '15 at 20:30
  • Hi @HIMANK so did any of the answer below helped you solve your problem? If so please mark it as accepted. Thanks! – Benoit_11 Feb 08 '15 at 20:46

3 Answers3

1

Here is a solution that could work if you have the Image Processing Toolbox.

When performing morphological operations, there is a structuring element in the shape of a diamond that you can use (check here). Now if we play around with it we can extract the elements from a matrix like so. Note that since you have strings in A I use a cell array:

clear
clc

A = {'a' 'b' 'c';'d' 'e' 'f'; 'g' 'h' 'i'}

SE = strel('diamond', 1)

Matlab tells us that SE has the following attributes (actually it might not be an attribute...I don't know the right terminology sorry :P):

SE =

Flat STREL object containing 5 neighbors.

Neighborhood:
     0     1     0
     1     1     1
     0     1     0

Therefore, we can use the getnhood method of STREL as logical indices to fetch the appropriates values in A:

NewMatrix = transpose(A(SE.getnhood()))


 NewMatrix = 

    'd'    'b'    'e'    'h'    'f'

Here the transpose is used to get the values in the order from top to bottom, left to right.

So the whole code actually looks like this:

A = {'a' 'b' 'c';'d' 'e' 'f'; 'g' 'h' 'i'}
DSize = 1; %// Assign size to diamond.

SE = strel('diamond', DSize)
NewMatrix = transpose(A(SE.getnhood()))

If you need to move the diamond in the array to get its center somewhere else, you can translate the structuring element before using the last line. The function is appropriately named called translate

Hope that helps!

Benoit_11
  • 13,905
  • 2
  • 24
  • 35
1

This works by building a mask (logical index) with the desired diamond shape and a specified center. The mask is obtained by computing the L1 (or taxicab) distance from each entry to the diamond center and comparing to the appropriate threshold:

A = rand(7,9); %// example matrix
pos_row = 3; %// row index of diamond center
pos_col = 5; %// col index of diamond center
[n_rows, n_cols] = size(A);
d = min([pos_row-1 pos_col-1 n_rows-pos_row n_cols-pos_col]); %// distance threshold 
    %// to be used for mask. Obtained by extending until some matrix border is found
ind = bsxfun(@plus, abs((1:n_rows).'-pos_row), abs((1:n_cols)-pos_col))<=d; %'// mask
result = A(ind); %// get entries defined by mask
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
0

Assuming that you are looking only for 5-elements diamonds, in the order you specified, you could do:

% Previously locate the position of the middle element (e) 
% and store it in variable IND

[i, j] = ind2sub(size(A), IND);
J = sub2ind(size(A), i+[0 -1 0 1 0], j+[-1 0 +1 0 0]);

% Get diamond-linearized vector
dia = A(J);
Ratbert
  • 5,463
  • 2
  • 18
  • 37