Mercurial > hg > machine-learning-hw1
changeset 0:7ddec0077b6f
Initial commit
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Tue, 18 Oct 2011 23:51:27 -0500 |
parents | |
children | f6e454c0fd8e |
files | computeCost.m computeCostMulti.m ex1.m ex1_multi.m ex1data1.txt ex1data2.txt featureNormalize.m gradientDescent.m gradientDescentMulti.m normalEqn.m plotData.m submit.m warmUpExercise.m |
diffstat | 13 files changed, 984 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/computeCost.m @@ -0,0 +1,22 @@ +function J = computeCost(X, y, theta) +%COMPUTECOST Compute cost for linear regression +% J = COMPUTECOST(X, y, theta) computes the cost of using theta as the +% parameter for linear regression to fit the data points in X and y + +% Initialize some useful values +m = length(y); % number of training examples + +% You need to return the following variables correctly +J = 0; + +% ====================== YOUR CODE HERE ====================== +% Instructions: Compute the cost of a particular choice of theta +% You should set J to the cost. + + + + + +% ========================================================================= + +end
new file mode 100644 --- /dev/null +++ b/computeCostMulti.m @@ -0,0 +1,22 @@ +function J = computeCostMulti(X, y, theta) +%COMPUTECOSTMULTI Compute cost for linear regression with multiple variables +% J = COMPUTECOSTMULTI(X, y, theta) computes the cost of using theta as the +% parameter for linear regression to fit the data points in X and y + +% Initialize some useful values +m = length(y); % number of training examples + +% You need to return the following variables correctly +J = 0; + +% ====================== YOUR CODE HERE ====================== +% Instructions: Compute the cost of a particular choice of theta +% You should set J to the cost. + + + + + +% ========================================================================= + +end
new file mode 100644 --- /dev/null +++ b/ex1.m @@ -0,0 +1,122 @@ +%% Machine Learning Online Class - Exercise 1: Linear Regression + +% Instructions +% ------------ +% +% This file contains code that helps you get started on the +% linear exercise. You will need to complete the following functions +% in this exericse: +% +% warmUpExercise.m +% plotData.m +% gradientDescent.m +% computeCost.m +% gradientDescentMulti.m +% computeCostMulti.m +% featureNormalize.m +% normalEqn.m +% +% For this exercise, you will not need to change any code in this file, +% or any other files other than those mentioned above. +% +% x refers to the population size in 10,000s +% y refers to the profit in $10,000s +% + +%% Initialization +clear all; close all; clc + +%% ==================== Part 1: Basic Function ==================== +% Complete warmUpExercise.m +fprintf('Running warmUpExercise ... \n'); +fprintf('5x5 Identity Matrix: \n'); +warmUpExercise() + +fprintf('Program paused. Press enter to continue.\n'); +pause; + + +%% ======================= Part 2: Plotting ======================= +fprintf('Plotting Data ...\n') +data = load('ex1data1.txt'); +X = data(:, 1); y = data(:, 2); +m = length(y); % number of training examples + +% Plot Data +% Note: You have to complete the code in plotData.m +plotData(X, y); + +fprintf('Program paused. Press enter to continue.\n'); +pause; + +%% =================== Part 3: Gradient descent =================== +fprintf('Running Gradient Descent ...\n') + +X = [ones(m, 1), data(:,1)]; % Add a column of ones to x +theta = zeros(2, 1); % initialize fitting parameters + +% Some gradient descent settings +iterations = 1500; +alpha = 0.01; + +% compute and display initial cost +computeCost(X, y, theta) + +% run gradient descent +theta = gradientDescent(X, y, theta, alpha, iterations); + +% print theta to screen +fprintf('Theta found by gradient descent: '); +fprintf('%f %f \n', theta(1), theta(2)); + +% Plot the linear fit +hold on; % keep previous plot visible +plot(X(:,2), X*theta, '-') +legend('Training data', 'Linear regression') +hold off % don't overlay any more plots on this figure + +% Predict values for population sizes of 35,000 and 70,000 +predict1 = [1, 3.5] *theta; +fprintf('For population = 35,000, we predict a profit of %f\n',... + predict1*10000); +predict2 = [1, 7] * theta; +fprintf('For population = 70,000, we predict a profit of %f\n',... + predict2*10000); + +fprintf('Program paused. Press enter to continue.\n'); +pause; + +%% ============= Part 4: Visualizing J(theta_0, theta_1) ============= +fprintf('Visualizing J(theta_0, theta_1) ...\n') + +% Grid over which we will calculate J +theta0_vals = linspace(-10, 10, 100); +theta1_vals = linspace(-1, 4, 100); + +% initialize J_vals to a matrix of 0's +J_vals = zeros(length(theta0_vals), length(theta1_vals)); + +% Fill out J_vals +for i = 1:length(theta0_vals) + for j = 1:length(theta1_vals) + t = [theta0_vals(i); theta1_vals(j)]; + J_vals(i,j) = computeCost(X, y, t); + end +end + + +% Because of the way meshgrids work in the surf command, we need to +% transpose J_vals before calling surf, or else the axes will be flipped +J_vals = J_vals'; +% Surface plot +figure; +surf(theta0_vals, theta1_vals, J_vals) +xlabel('\theta_0'); ylabel('\theta_1'); + +% Contour plot +figure; +% Plot J_vals as 15 contours spaced logarithmically between 0.01 and 100 +contour(theta0_vals, theta1_vals, J_vals, logspace(-2, 3, 20)) +xlabel('\theta_0'); ylabel('\theta_1'); +hold on; +plot(theta(1), theta(2), 'rx', 'MarkerSize', 10, 'LineWidth', 2);
new file mode 100644 --- /dev/null +++ b/ex1_multi.m @@ -0,0 +1,159 @@ +%% Machine Learning Online Class +% Exercise 1: Linear regression with multiple variables +% +% Instructions +% ------------ +% +% This file contains code that helps you get started on the +% linear regression exercise. +% +% You will need to complete the following functions in this +% exericse: +% +% warmUpExercise.m +% plotData.m +% gradientDescent.m +% computeCost.m +% gradientDescentMulti.m +% computeCostMulti.m +% featureNormalize.m +% normalEqn.m +% +% For this part of the exercise, you will need to change some +% parts of the code below for various experiments (e.g., changing +% learning rates). +% + +%% Initialization + +%% ================ Part 1: Feature Normalization ================ + +%% Clear and Close Figures +clear all; close all; clc + +fprintf('Loading data ...\n'); + +%% Load Data +data = load('ex1data2.txt'); +X = data(:, 1:2); +y = data(:, 3); +m = length(y); + +% Print out some data points +fprintf('First 10 examples from the dataset: \n'); +fprintf(' x = [%.0f %.0f], y = %.0f \n', [X(1:10,:) y(1:10,:)]'); + +fprintf('Program paused. Press enter to continue.\n'); +pause; + +% Scale features and set them to zero mean +fprintf('Normalizing Features ...\n'); + +[X mu sigma] = featureNormalize(X); + +% Add intercept term to X +X = [ones(m, 1) X]; + + +%% ================ Part 2: Gradient Descent ================ + +% ====================== YOUR CODE HERE ====================== +% Instructions: We have provided you with the following starter +% code that runs gradient descent with a particular +% learning rate (alpha). +% +% Your task is to first make sure that your functions - +% computeCost and gradientDescent already work with +% this starter code and support multiple variables. +% +% After that, try running gradient descent with +% different values of alpha and see which one gives +% you the best result. +% +% Finally, you should complete the code at the end +% to predict the price of a 1650 sq-ft, 3 br house. +% +% Hint: By using the 'hold on' command, you can plot multiple +% graphs on the same figure. +% +% Hint: At prediction, make sure you do the same feature normalization. +% + +fprintf('Running gradient descent ...\n'); + +% Choose some alpha value +alpha = 0.01; +num_iters = 100; + +% Init Theta and Run Gradient Descent +theta = zeros(3, 1); +[theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters); + +% Plot the convergence graph +figure; +plot(1:numel(J_history), J_history, '-b', 'LineWidth', 2); +xlabel('Number of iterations'); +ylabel('Cost J'); + +% Display gradient descent's result +fprintf('Theta computed from gradient descent: \n'); +fprintf(' %f \n', theta); +fprintf('\n'); + +% Estimate the price of a 1650 sq-ft, 3 br house +% ====================== YOUR CODE HERE ====================== +% Recall that the first column of X is all-ones. Thus, it does +% not need to be normalized. +price = 0; % You should change this + + +% ============================================================ + +fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ... + '(using gradient descent):\n $%f\n'], price); + +fprintf('Program paused. Press enter to continue.\n'); +pause; + +%% ================ Part 3: Normal Equations ================ + +fprintf('Solving with normal equations...\n'); + +% ====================== YOUR CODE HERE ====================== +% Instructions: The following code computes the closed form +% solution for linear regression using the normal +% equations. You should complete the code in +% normalEqn.m +% +% After doing so, you should complete this code +% to predict the price of a 1650 sq-ft, 3 br house. +% + +%% Load Data +data = csvread('ex1data2.txt'); +X = data(:, 1:2); +y = data(:, 3); +m = length(y); + +% Add intercept term to X +X = [ones(m, 1) X]; + +% Calculate the parameters from the normal equation +theta = normalEqn(X, y); + +% Display normal equation's result +fprintf('Theta computed from the normal equations: \n'); +fprintf(' %f \n', theta); +fprintf('\n'); + + +% Estimate the price of a 1650 sq-ft, 3 br house +% ====================== YOUR CODE HERE ====================== +price = 0; % You should change this + + +% ============================================================ + +fprintf(['Predicted price of a 1650 sq-ft, 3 br house ' ... + '(using normal equations):\n $%f\n'], price); +
new file mode 100644 --- /dev/null +++ b/ex1data1.txt @@ -0,0 +1,97 @@ +6.1101,17.592 +5.5277,9.1302 +8.5186,13.662 +7.0032,11.854 +5.8598,6.8233 +8.3829,11.886 +7.4764,4.3483 +8.5781,12 +6.4862,6.5987 +5.0546,3.8166 +5.7107,3.2522 +14.164,15.505 +5.734,3.1551 +8.4084,7.2258 +5.6407,0.71618 +5.3794,3.5129 +6.3654,5.3048 +5.1301,0.56077 +6.4296,3.6518 +7.0708,5.3893 +6.1891,3.1386 +20.27,21.767 +5.4901,4.263 +6.3261,5.1875 +5.5649,3.0825 +18.945,22.638 +12.828,13.501 +10.957,7.0467 +13.176,14.692 +22.203,24.147 +5.2524,-1.22 +6.5894,5.9966 +9.2482,12.134 +5.8918,1.8495 +8.2111,6.5426 +7.9334,4.5623 +8.0959,4.1164 +5.6063,3.3928 +12.836,10.117 +6.3534,5.4974 +5.4069,0.55657 +6.8825,3.9115 +11.708,5.3854 +5.7737,2.4406 +7.8247,6.7318 +7.0931,1.0463 +5.0702,5.1337 +5.8014,1.844 +11.7,8.0043 +5.5416,1.0179 +7.5402,6.7504 +5.3077,1.8396 +7.4239,4.2885 +7.6031,4.9981 +6.3328,1.4233 +6.3589,-1.4211 +6.2742,2.4756 +5.6397,4.6042 +9.3102,3.9624 +9.4536,5.4141 +8.8254,5.1694 +5.1793,-0.74279 +21.279,17.929 +14.908,12.054 +18.959,17.054 +7.2182,4.8852 +8.2951,5.7442 +10.236,7.7754 +5.4994,1.0173 +20.341,20.992 +10.136,6.6799 +7.3345,4.0259 +6.0062,1.2784 +7.2259,3.3411 +5.0269,-2.6807 +6.5479,0.29678 +7.5386,3.8845 +5.0365,5.7014 +10.274,6.7526 +5.1077,2.0576 +5.7292,0.47953 +5.1884,0.20421 +6.3557,0.67861 +9.7687,7.5435 +6.5159,5.3436 +8.5172,4.2415 +9.1802,6.7981 +6.002,0.92695 +5.5204,0.152 +5.0594,2.8214 +5.7077,1.8451 +7.6366,4.2959 +5.8707,7.2029 +5.3054,1.9869 +8.2934,0.14454 +13.394,9.0551 +5.4369,0.61705
new file mode 100644 --- /dev/null +++ b/ex1data2.txt @@ -0,0 +1,47 @@ +2104,3,399900 +1600,3,329900 +2400,3,369000 +1416,2,232000 +3000,4,539900 +1985,4,299900 +1534,3,314900 +1427,3,198999 +1380,3,212000 +1494,3,242500 +1940,4,239999 +2000,3,347000 +1890,3,329999 +4478,5,699900 +1268,3,259900 +2300,4,449900 +1320,2,299900 +1236,3,199900 +2609,4,499998 +3031,4,599000 +1767,3,252900 +1888,2,255000 +1604,3,242900 +1962,4,259900 +3890,3,573900 +1100,3,249900 +1458,3,464500 +2526,3,469000 +2200,3,475000 +2637,3,299900 +1839,2,349900 +1000,1,169900 +2040,4,314900 +3137,3,579900 +1811,4,285900 +1437,3,249900 +1239,3,229900 +2132,4,345000 +4215,4,549000 +2162,4,287000 +1664,2,368500 +2238,3,329900 +2567,4,314000 +1200,3,299000 +852,2,179900 +1852,4,299900 +1203,3,239500
new file mode 100644 --- /dev/null +++ b/featureNormalize.m @@ -0,0 +1,39 @@ +function [X_norm, mu, sigma] = featureNormalize(X) +%FEATURENORMALIZE Normalizes the features in X +% FEATURENORMALIZE(X) returns a normalized version of X where +% the mean value of each feature is 0 and the standard deviation +% is 1. This is often a good preprocessing step to do when +% working with learning algorithms. + +% You need to set these values correctly +X_norm = X; +mu = zeros(1, size(X, 2)); +sigma = zeros(1, size(X, 2)); + +% ====================== YOUR CODE HERE ====================== +% Instructions: First, for each feature dimension, compute the mean +% of the feature and subtract it from the dataset, +% storing the mean value in mu. Next, compute the +% standard deviation of each feature and divide +% each feature by it's standard deviation, storing +% the standard deviation in sigma. +% +% Note that X is a matrix where each column is a +% feature and each row is an example. You need +% to perform the normalization separately for +% each feature. +% +% Hint: You might find the 'mean' and 'std' functions useful. +% + + + + + + + + + +% ============================================================ + +end
new file mode 100644 --- /dev/null +++ b/gradientDescent.m @@ -0,0 +1,33 @@ +function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters) +%GRADIENTDESCENT Performs gradient descent to learn theta +% theta = GRADIENTDESENT(X, y, theta, alpha, num_iters) updates theta by +% taking num_iters gradient steps with learning rate alpha + +% Initialize some useful values +m = length(y); % number of training examples +J_history = zeros(num_iters, 1); + +for iter = 1:num_iters + + % ====================== YOUR CODE HERE ====================== + % Instructions: Perform a single gradient step on the parameter vector + % theta. + % + % Hint: While debugging, it can be useful to print out the values + % of the cost function (computeCost) and gradient here. + % + + + + + + + + % ============================================================ + + % Save the cost J in every iteration + J_history(iter) = computeCost(X, y, theta); + +end + +end
new file mode 100644 --- /dev/null +++ b/gradientDescentMulti.m @@ -0,0 +1,37 @@ +function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters) +%GRADIENTDESCENTMULTI Performs gradient descent to learn theta +% theta = GRADIENTDESCENTMULTI(x, y, theta, alpha, num_iters) updates theta by +% taking num_iters gradient steps with learning rate alpha + +% Initialize some useful values +m = length(y); % number of training examples +J_history = zeros(num_iters, 1); + +for iter = 1:num_iters + + % ====================== YOUR CODE HERE ====================== + % Instructions: Perform a single gradient step on the parameter vector + % theta. + % + % Hint: While debugging, it can be useful to print out the values + % of the cost function (computeCostMulti) and gradient here. + % + + + + + + + + + + + + % ============================================================ + + % Save the cost J in every iteration + J_history(iter) = computeCostMulti(X, y, theta); + +end + +end
new file mode 100644 --- /dev/null +++ b/normalEqn.m @@ -0,0 +1,23 @@ +function [theta] = normalEqn(X, y) +%NORMALEQN Computes the closed-form solution to linear regression +% NORMALEQN(X,y) computes the closed-form solution to linear +% regression using the normal equations. + +theta = zeros(size(X, 2), 1); + +% ====================== YOUR CODE HERE ====================== +% Instructions: Complete the code to compute the closed form solution +% to linear regression and put the result in theta. +% + +% ---------------------- Sample Solution ---------------------- + + + + +% ------------------------------------------------------------- + + +% ============================================================ + +end
new file mode 100644 --- /dev/null +++ b/plotData.m @@ -0,0 +1,26 @@ +function plotData(x, y) +%PLOTDATA Plots the data points x and y into a new figure +% PLOTDATA(x,y) plots the data points and gives the figure axes labels of +% population and profit. + +% ====================== YOUR CODE HERE ====================== +% Instructions: Plot the training data into a figure using the +% "figure" and "plot" commands. Set the axes labels using +% the "xlabel" and "ylabel" commands. Assume the +% population and revenue data have been passed in +% as the x and y arguments of this function. +% +% Hint: You can use the 'rx' option with plot to have the markers +% appear as red crosses. Furthermore, you can make the +% markers larger by using plot(..., 'rx', 'MarkerSize', 10); + +figure; % open a new figure window + + + + + + +% ============================================================ + +end
new file mode 100644 --- /dev/null +++ b/submit.m @@ -0,0 +1,336 @@ +function submit(part) +%SUBMIT Submit your code and output to the ml-class servers +% SUBMIT() will connect to the ml-class server and submit your solution + + fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ... + homework_id()); + if ~exist('part', 'var') || isempty(part) + partId = promptPart(); + end + + % Check valid partId + partNames = validParts(); + if ~isValidPartId(partId) + fprintf('!! Invalid homework part selected.\n'); + fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames) + 1); + fprintf('!! Submission Cancelled\n'); + return + end + + [login password] = loginPrompt(); + if isempty(login) + fprintf('!! Submission Cancelled\n'); + return + end + + fprintf('\n== Connecting to ml-class ... '); + if exist('OCTAVE_VERSION') + fflush(stdout); + end + + % Setup submit list + if partId == numel(partNames) + 1 + submitParts = 1:numel(partNames); + else + submitParts = [partId]; + end + + for s = 1:numel(submitParts) + % Submit this part + partId = submitParts(s); + + % Get Challenge + [login, ch, signature] = getChallenge(login); + if isempty(login) || isempty(ch) || isempty(signature) + % Some error occured, error string in first return element. + fprintf('\n!! Error: %s\n\n', login); + return + end + + % Attempt Submission with Challenge + ch_resp = challengeResponse(login, password, ch); + [result, str] = submitSolution(login, ch_resp, partId, output(partId), ... + source(partId), signature); + + fprintf('\n== [ml-class] Submitted Homework %s - Part %d - %s\n', ... + homework_id(), partId, partNames{partId}); + fprintf('== %s\n', strtrim(str)); + if exist('OCTAVE_VERSION') + fflush(stdout); + end + end + +end + +% ================== CONFIGURABLES FOR EACH HOMEWORK ================== + +function id = homework_id() + id = '1'; +end + +function [partNames] = validParts() + partNames = { 'Warm up exercise ', ... + 'Computing Cost (for one variable)', ... + 'Gradient Descent (for one variable)', ... + 'Feature Normalization', ... + 'Computing Cost (for multiple variables)', ... + 'Gradient Descent (for multiple variables)', ... + 'Normal Equations'}; +end + +function srcs = sources() + % Separated by part + srcs = { { 'warmUpExercise.m' }, ... + { 'computeCost.m' }, ... + { 'gradientDescent.m' }, ... + { 'featureNormalize.m' }, ... + { 'computeCostMulti.m' }, ... + { 'gradientDescentMulti.m' }, ... + { 'normalEqn.m' }, ... + }; +end + +function out = output(partId) + % Random Test Cases + X1 = [ones(20,1) (exp(1) + exp(2) * (0.1:0.1:2))']; + Y1 = X1(:,2) + sin(X1(:,1)) + cos(X1(:,2)); + X2 = [X1 X1(:,2).^0.5 X1(:,2).^0.25]; + Y2 = Y1.^0.5 + Y1; + if partId == 1 + out = sprintf('%0.5f ', warmUpExercise()); + elseif partId == 2 + out = sprintf('%0.5f ', computeCost(X1, Y1, [0.5 -0.5]')); + elseif partId == 3 + out = sprintf('%0.5f ', gradientDescent(X1, Y1, [0.5 -0.5]', 0.01, 10)); + elseif partId == 4 + out = sprintf('%0.5f ', featureNormalize(X2(:,2:4))); + elseif partId == 5 + out = sprintf('%0.5f ', computeCostMulti(X2, Y2, [0.1 0.2 0.3 0.4]')); + elseif partId == 6 + out = sprintf('%0.5f ', gradientDescentMulti(X2, Y2, [-0.1 -0.2 -0.3 -0.4]', 0.01, 10)); + elseif partId == 7 + out = sprintf('%0.5f ', normalEqn(X2, Y2)); + end +end + +function url = challenge_url() + url = 'http://www.ml-class.org/course/homework/challenge'; +end + +function url = submit_url() + url = 'http://www.ml-class.org/course/homework/submit'; +end + +% ========================= CHALLENGE HELPERS ========================= + +function src = source(partId) + src = ''; + src_files = sources(); + if partId <= numel(src_files) + flist = src_files{partId}; + for i = 1:numel(flist) + fid = fopen(flist{i}); + while ~feof(fid) + line = fgets(fid); + src = [src line]; + end + src = [src '||||||||']; + end + end +end + +function ret = isValidPartId(partId) + partNames = validParts(); + ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames) + 1); +end + +function partId = promptPart() + fprintf('== Select which part(s) to submit:\n', ... + homework_id()); + partNames = validParts(); + srcFiles = sources(); + for i = 1:numel(partNames) + fprintf('== %d) %s [', i, partNames{i}); + fprintf(' %s ', srcFiles{i}{:}); + fprintf(']\n'); + end + fprintf('== %d) All of the above \n==\nEnter your choice [1-%d]: ', ... + numel(partNames) + 1, numel(partNames) + 1); + selPart = input('', 's'); + partId = str2num(selPart); + if ~isValidPartId(partId) + partId = -1; + end +end + +function [email,ch,signature] = getChallenge(email) + str = urlread(challenge_url(), 'post', {'email_address', email}); + + str = strtrim(str); + [email, str] = strtok (str, '|'); + [ch, str] = strtok (str, '|'); + [signature, str] = strtok (str, '|'); +end + + +function [result, str] = submitSolution(email, ch_resp, part, output, ... + source, signature) + + params = {'homework', homework_id(), ... + 'part', num2str(part), ... + 'email', email, ... + 'output', output, ... + 'source', source, ... + 'challenge_response', ch_resp, ... + 'signature', signature}; + + str = urlread(submit_url(), 'post', params); + + % Parse str to read for success / failure + result = 0; + +end + +% =========================== LOGIN HELPERS =========================== + +function [login password] = loginPrompt() + % Prompt for password + [login password] = basicPrompt(); + + if isempty(login) || isempty(password) + login = []; password = []; + end +end + + +function [login password] = basicPrompt() + login = input('Login (Email address): ', 's'); + password = input('Password: ', 's'); +end + + +function [str] = challengeResponse(email, passwd, challenge) + salt = ')~/|]QMB3[!W`?OVt7qC"@+}'; + str = sha1([challenge sha1([salt email passwd])]); + sel = randperm(numel(str)); + sel = sort(sel(1:16)); + str = str(sel); +end + + +% =============================== SHA-1 ================================ + +function hash = sha1(str) + + % Initialize variables + h0 = uint32(1732584193); + h1 = uint32(4023233417); + h2 = uint32(2562383102); + h3 = uint32(271733878); + h4 = uint32(3285377520); + + % Convert to word array + strlen = numel(str); + + % Break string into chars and append the bit 1 to the message + mC = [double(str) 128]; + mC = [mC zeros(1, 4-mod(numel(mC), 4), 'uint8')]; + + numB = strlen * 8; + if exist('idivide') + numC = idivide(uint32(numB + 65), 512, 'ceil'); + else + numC = ceil(double(numB + 65)/512); + end + numW = numC * 16; + mW = zeros(numW, 1, 'uint32'); + + idx = 1; + for i = 1:4:strlen + 1 + mW(idx) = bitor(bitor(bitor( ... + bitshift(uint32(mC(i)), 24), ... + bitshift(uint32(mC(i+1)), 16)), ... + bitshift(uint32(mC(i+2)), 8)), ... + uint32(mC(i+3))); + idx = idx + 1; + end + + % Append length of message + mW(numW - 1) = uint32(bitshift(uint64(numB), -32)); + mW(numW) = uint32(bitshift(bitshift(uint64(numB), 32), -32)); + + % Process the message in successive 512-bit chs + for cId = 1 : double(numC) + cSt = (cId - 1) * 16 + 1; + cEnd = cId * 16; + ch = mW(cSt : cEnd); + + % Extend the sixteen 32-bit words into eighty 32-bit words + for j = 17 : 80 + ch(j) = ch(j - 3); + ch(j) = bitxor(ch(j), ch(j - 8)); + ch(j) = bitxor(ch(j), ch(j - 14)); + ch(j) = bitxor(ch(j), ch(j - 16)); + ch(j) = bitrotate(ch(j), 1); + end + + % Initialize hash value for this ch + a = h0; + b = h1; + c = h2; + d = h3; + e = h4; + + % Main loop + for i = 1 : 80 + if(i >= 1 && i <= 20) + f = bitor(bitand(b, c), bitand(bitcmp(b), d)); + k = uint32(1518500249); + elseif(i >= 21 && i <= 40) + f = bitxor(bitxor(b, c), d); + k = uint32(1859775393); + elseif(i >= 41 && i <= 60) + f = bitor(bitor(bitand(b, c), bitand(b, d)), bitand(c, d)); + k = uint32(2400959708); + elseif(i >= 61 && i <= 80) + f = bitxor(bitxor(b, c), d); + k = uint32(3395469782); + end + + t = bitrotate(a, 5); + t = bitadd(t, f); + t = bitadd(t, e); + t = bitadd(t, k); + t = bitadd(t, ch(i)); + e = d; + d = c; + c = bitrotate(b, 30); + b = a; + a = t; + + end + h0 = bitadd(h0, a); + h1 = bitadd(h1, b); + h2 = bitadd(h2, c); + h3 = bitadd(h3, d); + h4 = bitadd(h4, e); + + end + + hash = reshape(dec2hex(double([h0 h1 h2 h3 h4]), 8)', [1 40]); + + hash = lower(hash); + +end + +function ret = bitadd(iA, iB) + ret = double(iA) + double(iB); + ret = bitset(ret, 33, 0); + ret = uint32(ret); +end + +function ret = bitrotate(iA, places) + t = bitshift(iA, places - 32); + ret = bitshift(iA, places); + ret = bitor(ret, t); +end
new file mode 100644 --- /dev/null +++ b/warmUpExercise.m @@ -0,0 +1,21 @@ +function A = warmUpExercise() +%WARMUPEXERCISE Example function in octave +% A = WARMUPEXERCISE() is an example function that returns the 5x5 identity matrix + +A = []; +% ============= YOUR CODE HERE ============== +% Instructions: Return the 5x5 identity matrix +% In octave, we return values by defining which variables +% represent the return values (at the top of the file) +% and then set them accordingly. +A = eye(5); + + + + + + +% =========================================== + + +end