|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?我要加入
x
文章引自:http://www.mathworks.com/support/tech-notes/1100/1109.html
文章介绍了代码向量化的常用技术,比较经典,希望大家可以多多学习!
Tools and Techniques- MATLAB Indexing or Referencing (Subscripted, Linear, and Logical)
- Array Operations vs. Matrix Operations
- Boolean Array Operations
- Constructing Matrices from Vectors
- Utility Functions
Extended Examples- Matrix Functions of Two Vectors
- Ordering, Setting, and Counting Operations
- Sparse Matrix Structures
- Additional Examples
More Resources- Matrix Indexing and Manipulation
- Matrix Memory Preallocation
- Maximizing MATLAB Performance
Tools and Techniques
Section 1: MATLAB Indexing or ReferencingMATLAB enables you to select subsets of an array or matrix. There are three basic types of indexing available in MATLAB: subscripted, linear, and logical. These methods are explained in the MATLAB Digest article, Matrix Indexing in MATLAB. While this article goes into detail on MATLAB indexing, the remainder of this section is a good introduction. If you are not familiar with MATLAB indexing, you should read the MATLAB Digest article, and/or the documentation on colon, paren (round(), square[], and curly{} braces) and end.
Subscripted IndexingIn subscripted indexing, the values of the subscripts are the indices of the matrix where the matrix's elements are desired. That is, elements = matrix(subscripts). Thus, if A = 6:10, then A([3,5]) denotes the third and fifth elements of matrix A:
A = 6:10; A([3,5])ans=
8 10
For multidimensional arrays, multiple index parameters are used for subscripted indexing:
A = [11 14 17; ... 12 15 18; ... 13 16 19]; A(2:3,2)ans=
15
16
Linear IndexingIn linear, or absolute indexing, every element of a matrix can be referenced by its subscripted indices (as described above), or by its single, columnwise, linear index:
A = [11 14 17; ... 12 15 18; ... 13 16 19]; A(6) ans=
16
A([3,1,8]) ans=
13 11 18
See the functions SUB2IND and IND2SUB for more information.
Also, notice how the returned elements of the indexed matrix preserve the shape that was specified by the index variable. In the previous example, the index variable was a vector of size 1-by-3, and so the result was also of size 1-by-3. If an index variable of size 3-by-1 was used, a preserved shape would have been seen in the results:
A([3;1;8])ans=
13
11
18
Logical IndexingWith logical, or Boolean, indexing, the index parameter is a logical matrix that is the same size as A and contains only 0's and 1's.
The elements of A that are selected have a '1' in the corresponding position of the logical indexing matrix. For example, if A = 6:10, then A(logical([0 0 1 0 1])) denotes the third and fifth elements of A:
A = 6:10; A(logical([0 0 1 0 1]))ans=
8 10
For more information on matrix indexing and matrix manipulation, see the resources listed under Section 10 of this technical note.
Section 2: Array Operations vs. Matrix Operations y(i) = fcn(x1(i), x2(i), ...)The simplest type of vector operations, array operations, can be thought of as bulk processing. In this approach, the same operation is performed for each corresponding element in a data set, which may include more than one matrix. The operation is performed on an element-by-element basis.
Matrix operations, or linear algebra operations, operate according to the rules of linear algebra. This type of operation is sometimes useful for vectorization as illustrated in Section 6 and Section 8 of this technical note.
For example, you may have data measurements from an experiment that measures the volume of a cone, (V = 1/12 * pi * D^2 * H), by recording the diameter (D) of the end, and the height (H). If you had run the experiment once, you would just have one value for each of the two variables; however, D and H are scalars. Here is the calculation you will need to run in MATLAB:
V = 1/12*pi*(D^2)*H;Now, suppose that you actually run the experiment 100 times. Now D and H are vectors of length 100, and you want to calculate the corresponding vector V, which represents the volume for each run.
In most programming languages, you would set up a loop, the equivalent of the following MATLAB code:
for n = 1:100 V(n) = 1/12*pi*(D(n)^2)*H(n);end With MATLAB, you can ignore the fact that you ran 100 experiments. You can perform the calculation element-by-element over each vector, with (almost) the same syntax as the first equation, above.
% Provide data so that the code can be executed % Use of negative values will be apparent later D = [-0.2 1.0 1.5 3.0 -1.0 4.2 3.1]; H = [ 2.1 2.4 1.8 2.6 2.6 2.2 1.8]; % Perform the vectorized calculation V = 1/12*pi*(D.^2).*H;The only difference is the use of the .* and ./ operators. These differentiate array operators (element-by-element operators) from the matrix operators (linear algebra operators), * and /.
For more information, refer to the Matrices and Linear Algebra section of the MATLAB Mathematics documentation.
Section 3: Boolean Array Operations y = bool(x1, x2, ...)A logical extension of the bulk processing technique is to vectorize comparisons and decision making. MATLAB comparison operators, like the array operators above, accept vector inputs and produce vector outputs.
Suppose that after running the above experiment, you find that negative numbers have been measured for the diameter. As these values are clearly erroneous, you decide that those runs for the experiment are invalid.
You can find out which runs are valid using the >= operator on the vector D:
D = [-0.2 1.0 1.5 3.0 -1.0 4.2 3.14]; D >= 0 ans=
0 1 1 1 0 1 1
Now you can exploit the logical indexing power of MATLAB to remove the erroneous values:
Vgood = V(D>=0);This selects the subset of V for which the corresponding elements of D are nonnegative.
Suppose that if all values for masses are negative, you want to display a warning message and exit the routine. You need a way to condense the vector of Boolean values into a single value. There are two vectorized Boolean operators, ANY and ALL, which perform Boolean AND and OR functions over a vector. Thus you can perform the following test:
if all(D < 0) warning('All values of diameter are negative.'); return; endYou can also compare two vectors of the same size using the Boolean operators, resulting in expressions such as:
(V >= 0) & (D > H)ans=
0 0 0 1 0 1 1
The result is a vector of the same size as the inputs.
Additionally, since MATLAB uses IEEE arithmetic, there are special values to denote overflow, underflow, and undefined operations: INF , -INF , and NaN , respectively.INF and -INF are supported by relational operators (i.e., Inf==Inf returns true, and Inf<1 returns false). However, by the IEEE standard, NaN is never equal to anything, even itself (NaN==NaN returns false). Therefore, there are special Boolean operators, ISINF and ISNAN, to perform logical tests for these values. For example, in some applications, it's useful to exclude NaNs in order to make valid computations:
x = [2 -1 0 3 NaN 2 NaN 11 4 Inf]; xvalid = x(~isnan(x))xvalid =
2 -1 0 3 2 11 4 Inf
Also, if you try to compare two matrices of different sizes, an error will occur. You need to check sizes explicitly if the operands might not be the same size. See the documentation on SIZE, ISEQUAL, and ISEQUALWITHEQUALNANS(R13 and later) for more information.
Section 4: Constructing Matrices from Vectorsy(:,i) = fcn(x(:))Creating simple matrices, such as constant matrices, is easy in MATLAB. The following code creates a size 5-by-5 matrix of all 10s:
A = ones(5,5)*10The multiplication here is not necessary; you can achieve the same result using the indexing technique described in the next example.
Another common application involves selecting specified elements of a vector to create a new matrix. This is often a simple application of the indexing power of MATLAB. The next example creates a matrix corresponding to elements [2, 3; 5, 6; 8, 9; 11, 12; ...] of a vector x:
% Create a vector from 1 to 51 x = 1:51; % Reshape it such that it wraps through 3 rows x = reshape(x, 3, length(x)/3); % Select the 2nd and 3rd rows, and transpose itA = x(2:3,:)';In this example, indexing is used to exploit the pattern of the desired matrix. There are several tools available to exploit different types of patterns and symmetry. Relevant functions are summarized in Section 5 of this technical note.
There is a well-known technique for duplicating a vector of size M-by-1 n times, to create a matrix of size M-by-N. In this method, known as Tony's Trick, the first column of the vector is indexed (or referenced) n times:
v = (1:5)' n = 3; M = v(:,ones(n,1))M =
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
Now it is apparent how the first matrix, size 5-by-5 constant matrix of all 10's, can be created without the array multiplication operation:
A = 10; A = A(ones(5,5))A =
10 10 10 10 10
10 10 10 10 10
10 10 10 10 10
10 10 10 10 10
10 10 10 10 10
The same technique can be applied to row vectors by switching the subscripts. It can also duplicate specific rows or columns of a matrix. For example,
B = magic(3) B =
8 1 6
3 5 7
4 9 2
N = 2; B(:,N(ones(1,3))) ans=
1 1 1
5 5 5
9 9 9
While it is good to understand how this technique works, usually you do not need to use it explicitly. Instead, you can use the functions REPMAT and MESHGRID, which implement this technique. Refer to the documentation and Section 6 for more information and examples.
|
|