Resizing and Reshaping Matrices

来源:互联网 发布:linq查询重复数据 编辑:程序博客网 时间:2024/05/16 04:58
Expanding the Size of a Matrix

You can expand the size of any existing matrix as long as doing so does not give the resulting matrix an irregular shape. (SeeKeeping Matrices Rectangular). For example, you can vertically combine a 4-by-3 matrix and 7-by-3 matrix because all rows of the resulting matrix have the same number of columns (3).

Two ways of expanding the size of an existing matrix are

  • Concatenating new elements onto the matrix

  • Storing to a location outside the bounds of the matrix

    Note   If you intend to expand the size of a matrix repeatedly over time as it requires more room (usually done in a programming loop), it is advisable to preallocate space for the matrix when you initially create it. SeePreallocating Memory.

Concatenating Onto the Matrix

Concatenation is most useful when you want to expand a matrix by adding new elements or blocks that are compatible in size with the original matrix. This means that the size of all matrices being joined along a specific dimension must be equal along that dimension. See Concatenating Matrices.

This example runs a user-defined function compareResults on the data in matricesstats04 and stats03. Each time through the loop, it concatenates the results of this function onto the end of the data stored incomp04:

col = 10;comp04 = [];for k = 1:50   t = compareResults(stats04(k,1:col), stats03(k,1:col));   comp04 = [comp04; t];end

Concatenating to a Structure or Cell Array.  You can add on to arrays of structures or cells in the same way as you do with ordinary matrices. This example creates a 3-by-8 matrix of structuresS, each having 3 fields: x, y, and z, and then concatenates a second structure matrixS2 onto the original:

Create a 3-by-8 structure array S:

for k = 1:24   S(k) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);endS = reshape(S, 3, 8);

Create a second array that is 3-by-2 and uses the same field names:

for k = 25:30   S2(k-24) = struct('x', 10*k, 'y', 10*k+1, 'z', 10*k+2);endS2= reshape(S2, 3, 2);

Concatenate S2 onto S along the horizontal dimension:

S = [S S2]S = 3x10 struct array with fields:    x    y    z
Adding Smaller Blocks to a Matrix

To add one or more elements to a matrix where the sizes are not compatible, you can often just store the new elements outside the boundaries of the original matrix. The MATLAB® software automatically pads the matrix with zeros to keep it rectangular.

Construct a 3-by-5 matrix, and attempt to add a new element to it using concatenation. The operation fails because you are attempting to join a one-column matrix with one that has five columns:

A = [ 10  20  30  40  50; ...      60  70  80  90 100; ...     110 120 130 140 150];A = [A; 160]Error using vertcatCAT arguments dimensions are not consistent.

Try this again, but this time do it in such a way that enables MATLAB to make adjustments to the size of the matrix. Store the new element in row 4, a row that does not yet exist in this matrix. MATLAB expands matrixA by an entire new row by padding columns 2 through 5 with zeros:

A(4,1) = 160A =    10    20    30    40    50    60    70    80    90   100   110   120   130   140   150   160     0     0     0     0

    Note   Attempting to read from nonexistent matrix locations generates an error. You can only write to these locations.

You can also expand the matrix by adding a matrix instead of just a single element:

A(4:6,1:3) = magic(3)+100A =    10    20    30    40    50    60    70    80    90   100   110   120   130   140   150   108   101   106     0     0   103   105   107     0     0   104   109   102     0     0

You do not have to add new elements sequentially. Wherever you store the new elements, MATLAB pads with zeros to make the resulting matrix rectangular in shape:

A(4,8) = 300A =    10    20    30    40    50     0     0     0    60    70    80    90   100     0     0     0   110   120   130   140   150     0     0     0     0     0     0     0     0     0     0   300

Expanding a Structure or Cell Array.  You can expand a structure or cell array in the same way that you can a matrix. This example adds an additional cell to a cell array by storing it beyond the bounds of the original array. MATLAB pads the data structure with empty cells ([]) to keep it rectangular.

The original array is 2-by-3:

C = {'Madison', 'G', [5 28 1967]; ...     46, '325 Maple Dr', 3015.28}C =  2×3 cell array    'Madison'    'G'               [1×3 double]    [     46]    '325 Maple Dr'    [3.0153e+03]

Add a cell to C{3,1} and MATLAB appends an entire row:

C{3,1} = ...struct('Fund_A', .45, 'Fund_E', .35, 'Fund_G', 20)C =  3×3 cell array    'Madison'       'G'               [1×3 double]    [        46]    '325 Maple Dr'    [3.0153e+03]    [1×1 struct]                []              []

Expanding a Character Array.  You can expand character arrays in the same manner as other MATLAB arrays, but it is generally not recommended. MATLAB expands any array by padding uninitialized elements with zeros. Because zero is interpreted by MATLAB and some other programming languages as the end of a character array, you may find that some functions treat the expanded character array as if it were less than its full length.

Expand a 1-by-5 character vector to twelve characters. The result appears at first to be a typical character vector:

greeting = 'Hello';    greeting(1,8:12) = 'World'greeting =   Hello  World

Closer inspection however reveals zeros at the point of expansion:

uint8(greeting)ans =  1×12 uint8 row vector    72   101   108   108   111     0     0    87   111   114   108   100

This causes some functions, like strcmp, to return what might be considered an unexpected result:

strcmp(greeting, 'Hello  World')ans =  logical   0
Delete Matrix Rows and Columns

You can deleterows and columns from a matrix by assigning the empty array[] to those rows or columns. Start with

A = magic(4)A =    16     2     3    13     5    11    10     8     9     7     6    12     4    14    15     1

Then, delete the second column of A using

A(:,2) = []

This changes matrix A to

A =    16    3   13    5   10    8    9    6   12    4   15    1

If you delete a single element from a matrix, the result is not a matrix anymore. So expressions like

A(1,2) = []

result in an error. However, you can use linear indexing to delete a single element, or a sequence of elements. This reshapes the remaining elements into a row vector:

A(2:2:10) = []

results in

A =     16     9     3     6    13    12     1
Reshaping a Matrix

The following functions change the shape of a matrix.

Function

Description

reshape

Modify the shape of a matrix.

rot90

Rotate the matrix by 90 degrees.

fliplr

Flip the matrix about a vertical axis.

flipud

Flip the matrix about a horizontal axis.

flip

Flip the matrix along the specified direction.

transpose

Flip a matrix about its main diagonal, turning row vectors into column vectors and vice versa.

ctranspose

Transpose a matrix and replace each element with its complex conjugate.

Examples

Here are a few examples to illustrate some of the ways you can reshape matrices.

Reshaping a Matrix.  Reshape 3-by-4 matrix A to have dimensions 2-by-6:

A = [1 4 7 10; 2 5 8 11; 3 6 9 12]A =    1    4    7    10    2    5    8    11    3    6    9    12B = reshape(A, 2, 6)B =    1    3    5    7    9   11    2    4    6    8   10   12

Transposing a Matrix.  Transpose A so that the row elements become columns. You can use either thetranspose function or the transpose operator (.') to do this:

B = A.'B =     1     2     3     4     5     6     7     8     9    10    11    12

There is a separate function called ctranspose that performs a complex conjugate transpose of a matrix. The equivalent operator forctranpose on a matrix A is A':

A = [1+9i 2-8i 3+7i; 4-6i 5+5i 6-4i]A =   1.0000 + 9.0000i   2.0000 - 8.0000i   3.0000 + 7.0000i   4.0000 - 6.0000i   5.0000 + 5.0000i   6.0000 - 4.0000iB = A'B =   1.0000 - 9.0000i   4.0000 + 6.0000i   2.0000 + 8.0000i   5.0000 - 5.0000i   3.0000 - 7.0000i   6.0000 + 4.0000i

Rotating a Matrix.  Rotate the matrix by 90 degrees:

B = rot90(A)B =    10    11    12     7     8     9     4     5     6     1     2     3

Flipping a Matrix.  Flip A in a left-to-right direction:

B = fliplr(A)B =    10     7     4     1    11     8     5     2    12     9     6     3
Preallocating Memory

Repeatedly expanding the size of an array over time, (for example, adding more elements to it each time through a programming loop), can adversely affect the performance of your program. This is because

  • MATLAB has to spend time allocating more memory each time you increase the size of the array.

  • This newly allocated memory is likely to be noncontiguous, thus slowing down any operations that MATLAB needs to perform on the array.

The preferred method for sizing an array that is expected to grow over time is to estimate the maximum possible size for the array, and preallocate this amount of memory for it at the time the array is created. In this way, your program performs one memory allocation that reserves one contiguous block.

The following command preallocates enough space for a 25,000 by 10,000 matrix, and initializes each element to zero:

A = zeros(25000, 10000);
Building a Preallocated Array

Once memory has been preallocated for the maximum estimated size of the array, you can store your data in the array as you need it, each time appending to the existing data. This example preallocates a large array, and then reads blocks of data from a file into the array until it gets to the end of the file:

blocksize = 5000;maxrows = 2500000; cols = 20;rp = 1;     % row pointer% Preallocate A to its maximum possible sizeA = zeros(maxrows, cols);% Open the data file, saving the file pointer.fid = fopen('statfile.dat', 'r'); while true   % Read from file into a cell array.  Stop at EOF.   block = textscan(fid, '%n', blocksize*cols);   if isempty(block{1})   break,   end;    % Convert cell array to matrix, reshape, place into A.   A(rp:rp+blocksize-1, 1:cols) = ...      reshape(cell2mat(block), blocksize, cols);    % Process the data in A.   evaluate_stats(A);               % User-defined function    % Update row pointer   rp = rp + blocksize;end

    Note   If you eventually need more room in a matrix than you had preallocated, you can preallocate additional storage in the same manner, and concatenate this additional storage onto the original array.

0 0
原创粉丝点击