For small jobs like the housing prices data we used for linear regression, your code does not need to be extremely fast. However, if your implementation for Exercise 1A or 1B used a for-loop as suggested, it is probably too slow to work well for large problems that are more interesting. This is because looping over the examples (or any other elements) sequentially in MATLAB is slow. To avoid for-loops, we want to rewrite our code to make use of optimized vector and matrix operations so that MATLAB will execute it quickly. (This is also useful for other languages, including Python and C/C++ — we want to re-use optimized operations when possible.)
Following are some examples for how to vectorize various operations in MATLAB.
Example: Many matrix-vector products
Frequently we want to compute matrix-vector products for many vectors at once, such as when we compute
With this notation, we can compute
So, when performing linear regression, we can use
Example: normalizing many vectors
Suppose we have many vectors
X_norm = sqrt( sum(X.^2,1) );
Y = bsxfun(@rdivide, X, X_norm);
This code squares all of the elements of X, then sums along the first dimension (the rows) of the result, and finally takes the square root of each element. This leaves us with a 1-by-m matrix containing bsxfun
routine can be thought of as expanding or cloning bsxfun
can be used with almost any binary element-wise function (e.g., @plus, @ge, or @eq). See the bsxfun
docs!
Example: matrix multiplication in gradient computations
In our linear regression gradient computation, we have a summation of the form:
Whenever we have a summation over a single index (in this case
Thus, to perform the entire computation for every
% X(j,i) = j'th coordinate of i'th example.
% y(i) = i'th value to be predicted; y is a column vector.
% theta = vector of parameters
y_hat = theta'*X; % so y_hat(i) = theta' * X(:,i). Note that y_hat is a *row-vector*.
g = X*(y_hat' - y);
Exercise 1A and 1B Redux
Go back to your Exercise 1A and 1B code. In the ex1a_linreg.m
file and ex1b_logreg.m
file you will find commented-out code that calls minFunc
using linear_regression_vec.m
and logistic_regression_vec.m
(respectively) instead of linear_regression.m
and logistic_regression.m
. For this exercise, fill in the linear_regression_vec.m
and logistic_regression_vec.m
files with a vectorized implementation of your previous solutions. Uncomment the calling code in ex1a_linreg.m
and ex1b_logreg.m
and compare the running times of each implementation. Verify that you get similar results to your original solutions!