astron 7 년 전
부모
커밋
b5c295ad59
32개의 변경된 파일3666개의 추가작업 그리고 0개의 파일을 삭제
  1. BIN
      machine learning/Machine Learning - Home _ Coursera-quiz-lesson 5-1.pdf
  2. BIN
      machine learning/Machine Learning - Home _ Coursera-quiz-lesson 5.pdf
  3. BIN
      machine learning/Machine Learning - Home _ Coursera-quiz-lesson 6-1.pdf
  4. BIN
      machine learning/Machine Learning - Home _ Coursera-quiz-lesson 6.pdf
  5. BIN
      machine learning/machine-learning-ex4/ex4/octave-workspace
  6. BIN
      machine learning/machine-learning-ex5/ex5.pdf
  7. 220 0
      machine learning/machine-learning-ex5/ex5/ex5.m
  8. BIN
      machine learning/machine-learning-ex5/ex5/ex5data1.mat
  9. 17 0
      machine learning/machine-learning-ex5/ex5/featureNormalize.m
  10. 175 0
      machine learning/machine-learning-ex5/ex5/fmincg.m
  11. 66 0
      machine learning/machine-learning-ex5/ex5/learningCurve.m
  12. 41 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/AUTHORS.txt
  13. 74 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/ChangeLog.txt
  14. 25 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/LICENSE_BSD.txt
  15. 394 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/README.txt
  16. 32 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/jsonopt.m
  17. 566 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/loadjson.m
  18. 528 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/loadubjson.m
  19. 33 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/mergestruct.m
  20. 475 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/savejson.m
  21. 504 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/saveubjson.m
  22. 40 0
      machine learning/machine-learning-ex5/ex5/lib/jsonlab/varargin2struct.m
  23. 30 0
      machine learning/machine-learning-ex5/ex5/lib/makeValidFieldName.m
  24. 179 0
      machine learning/machine-learning-ex5/ex5/lib/submitWithConfiguration.m
  25. 39 0
      machine learning/machine-learning-ex5/ex5/linearRegCostFunction.m
  26. 23 0
      machine learning/machine-learning-ex5/ex5/myex5.m
  27. 28 0
      machine learning/machine-learning-ex5/ex5/plotFit.m
  28. 25 0
      machine learning/machine-learning-ex5/ex5/polyFeatures.m
  29. 63 0
      machine learning/machine-learning-ex5/ex5/submit.m
  30. 15 0
      machine learning/machine-learning-ex5/ex5/token.mat
  31. 21 0
      machine learning/machine-learning-ex5/ex5/trainLinearReg.m
  32. 53 0
      machine learning/machine-learning-ex5/ex5/validationCurve.m

BIN
machine learning/Machine Learning - Home _ Coursera-quiz-lesson 5-1.pdf


BIN
machine learning/Machine Learning - Home _ Coursera-quiz-lesson 5.pdf


BIN
machine learning/Machine Learning - Home _ Coursera-quiz-lesson 6-1.pdf


BIN
machine learning/Machine Learning - Home _ Coursera-quiz-lesson 6.pdf


BIN
machine learning/machine-learning-ex4/ex4/octave-workspace


BIN
machine learning/machine-learning-ex5/ex5.pdf


+ 220 - 0
machine learning/machine-learning-ex5/ex5/ex5.m

@@ -0,0 +1,220 @@
+%% Machine Learning Online Class
+%  Exercise 5 | Regularized Linear Regression and Bias-Variance
+%
+%  Instructions
+%  ------------
+% 
+%  This file contains code that helps you get started on the
+%  exercise. You will need to complete the following functions:
+%
+%     linearRegCostFunction.m
+%     learningCurve.m
+%     validationCurve.m
+%
+%  For this exercise, you will not need to change any code in this file,
+%  or any other files other than those mentioned above.
+%
+
+%% Initialization
+clear ; close all; clc
+
+%% =========== Part 1: Loading and Visualizing Data =============
+%  We start the exercise by first loading and visualizing the dataset. 
+%  The following code will load the dataset into your environment and plot
+%  the data.
+%
+
+% Load Training Data
+fprintf('Loading and Visualizing Data ...\n')
+
+% Load from ex5data1: 
+% You will have X, y, Xval, yval, Xtest, ytest in your environment
+load ('ex5data1.mat');
+
+% m = Number of examples
+m = size(X, 1);
+
+% Plot training data
+plot(X, y, 'rx', 'MarkerSize', 10, 'LineWidth', 1.5);
+xlabel('Change in water level (x)');
+ylabel('Water flowing out of the dam (y)');
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+%% =========== Part 2: Regularized Linear Regression Cost =============
+%  You should now implement the cost function for regularized linear 
+%  regression. 
+%
+
+theta = [1 ; 1];
+J = linearRegCostFunction([ones(m, 1) X], y, theta, 1);
+
+fprintf(['Cost at theta = [1 ; 1]: %f '...
+         '\n(this value should be about 303.993192)\n'], J);
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+%% =========== Part 3: Regularized Linear Regression Gradient =============
+%  You should now implement the gradient for regularized linear 
+%  regression.
+%
+
+theta = [1 ; 1];
+[J, grad] = linearRegCostFunction([ones(m, 1) X], y, theta, 1);
+
+fprintf(['Gradient at theta = [1 ; 1]:  [%f; %f] '...
+         '\n(this value should be about [-15.303016; 598.250744])\n'], ...
+         grad(1), grad(2));
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+
+%% =========== Part 4: Train Linear Regression =============
+%  Once you have implemented the cost and gradient correctly, the
+%  trainLinearReg function will use your cost function to train 
+%  regularized linear regression.
+% 
+%  Write Up Note: The data is non-linear, so this will not give a great 
+%                 fit.
+%
+
+%  Train linear regression with lambda = 0
+lambda = 0;
+[theta] = trainLinearReg([ones(m, 1) X], y, lambda);
+
+%  Plot fit over the data
+plot(X, y, 'rx', 'MarkerSize', 10, 'LineWidth', 1.5);
+xlabel('Change in water level (x)');
+ylabel('Water flowing out of the dam (y)');
+hold on;
+plot(X, [ones(m, 1) X]*theta, '--', 'LineWidth', 2)
+hold off;
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+
+%% =========== Part 5: Learning Curve for Linear Regression =============
+%  Next, you should implement the learningCurve function. 
+%
+%  Write Up Note: Since the model is underfitting the data, we expect to
+%                 see a graph with "high bias" -- Figure 3 in ex5.pdf 
+%
+
+lambda = 0;
+[error_train, error_val] = ...
+    learningCurve([ones(m, 1) X], y, ...
+                  [ones(size(Xval, 1), 1) Xval], yval, ...
+                  lambda);
+
+plot(1:m, error_train, 1:m, error_val);
+title('Learning curve for linear regression')
+legend('Train', 'Cross Validation')
+xlabel('Number of training examples')
+ylabel('Error')
+axis([0 13 0 150])
+
+fprintf('# Training Examples\tTrain Error\tCross Validation Error\n');
+for i = 1:m
+    fprintf('  \t%d\t\t%f\t%f\n', i, error_train(i), error_val(i));
+end
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+%% =========== Part 6: Feature Mapping for Polynomial Regression =============
+%  One solution to this is to use polynomial regression. You should now
+%  complete polyFeatures to map each example into its powers
+%
+
+p = 8;
+
+% Map X onto Polynomial Features and Normalize
+X_poly = polyFeatures(X, p);
+[X_poly, mu, sigma] = featureNormalize(X_poly);  % Normalize
+X_poly = [ones(m, 1), X_poly];                   % Add Ones
+
+% Map X_poly_test and normalize (using mu and sigma)
+X_poly_test = polyFeatures(Xtest, p);
+X_poly_test = bsxfun(@minus, X_poly_test, mu);
+X_poly_test = bsxfun(@rdivide, X_poly_test, sigma);
+X_poly_test = [ones(size(X_poly_test, 1), 1), X_poly_test];         % Add Ones
+
+% Map X_poly_val and normalize (using mu and sigma)
+X_poly_val = polyFeatures(Xval, p);
+X_poly_val = bsxfun(@minus, X_poly_val, mu);
+X_poly_val = bsxfun(@rdivide, X_poly_val, sigma);
+X_poly_val = [ones(size(X_poly_val, 1), 1), X_poly_val];           % Add Ones
+
+fprintf('Normalized Training Example 1:\n');
+fprintf('  %f  \n', X_poly(1, :));
+
+fprintf('\nProgram paused. Press enter to continue.\n');
+pause;
+
+
+
+%% =========== Part 7: Learning Curve for Polynomial Regression =============
+%  Now, you will get to experiment with polynomial regression with multiple
+%  values of lambda. The code below runs polynomial regression with 
+%  lambda = 0. You should try running the code with different values of
+%  lambda to see how the fit and learning curve change.
+%
+
+lambda = 0;
+[theta] = trainLinearReg(X_poly, y, lambda);
+
+% Plot training data and fit
+figure(1);
+plot(X, y, 'rx', 'MarkerSize', 10, 'LineWidth', 1.5);
+plotFit(min(X), max(X), mu, sigma, theta, p);
+xlabel('Change in water level (x)');
+ylabel('Water flowing out of the dam (y)');
+title (sprintf('Polynomial Regression Fit (lambda = %f)', lambda));
+
+figure(2);
+[error_train, error_val] = ...
+    learningCurve(X_poly, y, X_poly_val, yval, lambda);
+plot(1:m, error_train, 1:m, error_val);
+
+title(sprintf('Polynomial Regression Learning Curve (lambda = %f)', lambda));
+xlabel('Number of training examples')
+ylabel('Error')
+axis([0 13 0 100])
+legend('Train', 'Cross Validation')
+
+fprintf('Polynomial Regression (lambda = %f)\n\n', lambda);
+fprintf('# Training Examples\tTrain Error\tCross Validation Error\n');
+for i = 1:m
+    fprintf('  \t%d\t\t%f\t%f\n', i, error_train(i), error_val(i));
+end
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;
+
+%% =========== Part 8: Validation for Selecting Lambda =============
+%  You will now implement validationCurve to test various values of 
+%  lambda on a validation set. You will then use this to select the
+%  "best" lambda value.
+%
+
+[lambda_vec, error_train, error_val] = ...
+    validationCurve(X_poly, y, X_poly_val, yval);
+
+close all;
+plot(lambda_vec, error_train, lambda_vec, error_val);
+legend('Train', 'Cross Validation');
+xlabel('lambda');
+ylabel('Error');
+
+fprintf('lambda\t\tTrain Error\tValidation Error\n');
+for i = 1:length(lambda_vec)
+	fprintf(' %f\t%f\t%f\n', ...
+            lambda_vec(i), error_train(i), error_val(i));
+end
+
+fprintf('Program paused. Press enter to continue.\n');
+pause;

BIN
machine learning/machine-learning-ex5/ex5/ex5data1.mat


+ 17 - 0
machine learning/machine-learning-ex5/ex5/featureNormalize.m

@@ -0,0 +1,17 @@
+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.
+
+mu = mean(X);
+X_norm = bsxfun(@minus, X, mu);
+
+sigma = std(X_norm);
+X_norm = bsxfun(@rdivide, X_norm, sigma);
+
+
+% ============================================================
+
+end

+ 175 - 0
machine learning/machine-learning-ex5/ex5/fmincg.m

@@ -0,0 +1,175 @@
+function [X, fX, i] = fmincg(f, X, options, P1, P2, P3, P4, P5)
+% Minimize a continuous differentialble multivariate function. Starting point
+% is given by "X" (D by 1), and the function named in the string "f", must
+% return a function value and a vector of partial derivatives. The Polack-
+% Ribiere flavour of conjugate gradients is used to compute search directions,
+% and a line search using quadratic and cubic polynomial approximations and the
+% Wolfe-Powell stopping criteria is used together with the slope ratio method
+% for guessing initial step sizes. Additionally a bunch of checks are made to
+% make sure that exploration is taking place and that extrapolation will not
+% be unboundedly large. The "length" gives the length of the run: if it is
+% positive, it gives the maximum number of line searches, if negative its
+% absolute gives the maximum allowed number of function evaluations. You can
+% (optionally) give "length" a second component, which will indicate the
+% reduction in function value to be expected in the first line-search (defaults
+% to 1.0). The function returns when either its length is up, or if no further
+% progress can be made (ie, we are at a minimum, or so close that due to
+% numerical problems, we cannot get any closer). If the function terminates
+% within a few iterations, it could be an indication that the function value
+% and derivatives are not consistent (ie, there may be a bug in the
+% implementation of your "f" function). The function returns the found
+% solution "X", a vector of function values "fX" indicating the progress made
+% and "i" the number of iterations (line searches or function evaluations,
+% depending on the sign of "length") used.
+%
+% Usage: [X, fX, i] = fmincg(f, X, options, P1, P2, P3, P4, P5)
+%
+% See also: checkgrad 
+%
+% Copyright (C) 2001 and 2002 by Carl Edward Rasmussen. Date 2002-02-13
+%
+%
+% (C) Copyright 1999, 2000 & 2001, Carl Edward Rasmussen
+% 
+% Permission is granted for anyone to copy, use, or modify these
+% programs and accompanying documents for purposes of research or
+% education, provided this copyright notice is retained, and note is
+% made of any changes that have been made.
+% 
+% These programs and documents are distributed without any warranty,
+% express or implied.  As the programs were written for research
+% purposes only, they have not been tested to the degree that would be
+% advisable in any important application.  All use of these programs is
+% entirely at the user's own risk.
+%
+% [ml-class] Changes Made:
+% 1) Function name and argument specifications
+% 2) Output display
+%
+
+% Read options
+if exist('options', 'var') && ~isempty(options) && isfield(options, 'MaxIter')
+    length = options.MaxIter;
+else
+    length = 100;
+end
+
+
+RHO = 0.01;                            % a bunch of constants for line searches
+SIG = 0.5;       % RHO and SIG are the constants in the Wolfe-Powell conditions
+INT = 0.1;    % don't reevaluate within 0.1 of the limit of the current bracket
+EXT = 3.0;                    % extrapolate maximum 3 times the current bracket
+MAX = 20;                         % max 20 function evaluations per line search
+RATIO = 100;                                      % maximum allowed slope ratio
+
+argstr = ['feval(f, X'];                      % compose string used to call function
+for i = 1:(nargin - 3)
+  argstr = [argstr, ',P', int2str(i)];
+end
+argstr = [argstr, ')'];
+
+if max(size(length)) == 2, red=length(2); length=length(1); else red=1; end
+S=['Iteration '];
+
+i = 0;                                            % zero the run length counter
+ls_failed = 0;                             % no previous line search has failed
+fX = [];
+[f1 df1] = eval(argstr);                      % get function value and gradient
+i = i + (length<0);                                            % count epochs?!
+s = -df1;                                        % search direction is steepest
+d1 = -s'*s;                                                 % this is the slope
+z1 = red/(1-d1);                                  % initial step is red/(|s|+1)
+
+while i < abs(length)                                      % while not finished
+  i = i + (length>0);                                      % count iterations?!
+
+  X0 = X; f0 = f1; df0 = df1;                   % make a copy of current values
+  X = X + z1*s;                                             % begin line search
+  [f2 df2] = eval(argstr);
+  i = i + (length<0);                                          % count epochs?!
+  d2 = df2'*s;
+  f3 = f1; d3 = d1; z3 = -z1;             % initialize point 3 equal to point 1
+  if length>0, M = MAX; else M = min(MAX, -length-i); end
+  success = 0; limit = -1;                     % initialize quanteties
+  while 1
+    while ((f2 > f1+z1*RHO*d1) || (d2 > -SIG*d1)) && (M > 0) 
+      limit = z1;                                         % tighten the bracket
+      if f2 > f1
+        z2 = z3 - (0.5*d3*z3*z3)/(d3*z3+f2-f3);                 % quadratic fit
+      else
+        A = 6*(f2-f3)/z3+3*(d2+d3);                                 % cubic fit
+        B = 3*(f3-f2)-z3*(d3+2*d2);
+        z2 = (sqrt(B*B-A*d2*z3*z3)-B)/A;       % numerical error possible - ok!
+      end
+      if isnan(z2) || isinf(z2)
+        z2 = z3/2;                  % if we had a numerical problem then bisect
+      end
+      z2 = max(min(z2, INT*z3),(1-INT)*z3);  % don't accept too close to limits
+      z1 = z1 + z2;                                           % update the step
+      X = X + z2*s;
+      [f2 df2] = eval(argstr);
+      M = M - 1; i = i + (length<0);                           % count epochs?!
+      d2 = df2'*s;
+      z3 = z3-z2;                    % z3 is now relative to the location of z2
+    end
+    if f2 > f1+z1*RHO*d1 || d2 > -SIG*d1
+      break;                                                % this is a failure
+    elseif d2 > SIG*d1
+      success = 1; break;                                             % success
+    elseif M == 0
+      break;                                                          % failure
+    end
+    A = 6*(f2-f3)/z3+3*(d2+d3);                      % make cubic extrapolation
+    B = 3*(f3-f2)-z3*(d3+2*d2);
+    z2 = -d2*z3*z3/(B+sqrt(B*B-A*d2*z3*z3));        % num. error possible - ok!
+    if ~isreal(z2) || isnan(z2) || isinf(z2) || z2 < 0 % num prob or wrong sign?
+      if limit < -0.5                               % if we have no upper limit
+        z2 = z1 * (EXT-1);                 % the extrapolate the maximum amount
+      else
+        z2 = (limit-z1)/2;                                   % otherwise bisect
+      end
+    elseif (limit > -0.5) && (z2+z1 > limit)         % extraplation beyond max?
+      z2 = (limit-z1)/2;                                               % bisect
+    elseif (limit < -0.5) && (z2+z1 > z1*EXT)       % extrapolation beyond limit
+      z2 = z1*(EXT-1.0);                           % set to extrapolation limit
+    elseif z2 < -z3*INT
+      z2 = -z3*INT;
+    elseif (limit > -0.5) && (z2 < (limit-z1)*(1.0-INT))  % too close to limit?
+      z2 = (limit-z1)*(1.0-INT);
+    end
+    f3 = f2; d3 = d2; z3 = -z2;                  % set point 3 equal to point 2
+    z1 = z1 + z2; X = X + z2*s;                      % update current estimates
+    [f2 df2] = eval(argstr);
+    M = M - 1; i = i + (length<0);                             % count epochs?!
+    d2 = df2'*s;
+  end                                                      % end of line search
+
+  if success                                         % if line search succeeded
+    f1 = f2; fX = [fX' f1]';
+    fprintf('%s %4i | Cost: %4.6e\r', S, i, f1);
+    s = (df2'*df2-df1'*df2)/(df1'*df1)*s - df2;      % Polack-Ribiere direction
+    tmp = df1; df1 = df2; df2 = tmp;                         % swap derivatives
+    d2 = df1'*s;
+    if d2 > 0                                      % new slope must be negative
+      s = -df1;                              % otherwise use steepest direction
+      d2 = -s'*s;    
+    end
+    z1 = z1 * min(RATIO, d1/(d2-realmin));          % slope ratio but max RATIO
+    d1 = d2;
+    ls_failed = 0;                              % this line search did not fail
+  else
+    X = X0; f1 = f0; df1 = df0;  % restore point from before failed line search
+    if ls_failed || i > abs(length)          % line search failed twice in a row
+      break;                             % or we ran out of time, so we give up
+    end
+    tmp = df1; df1 = df2; df2 = tmp;                         % swap derivatives
+    s = -df1;                                                    % try steepest
+    d1 = -s'*s;
+    z1 = 1/(1-d1);                     
+    ls_failed = 1;                                    % this line search failed
+  end
+  if exist('OCTAVE_VERSION')
+    fflush(stdout);
+  end
+end
+fprintf('\n');

+ 66 - 0
machine learning/machine-learning-ex5/ex5/learningCurve.m

@@ -0,0 +1,66 @@
+function [error_train, error_val] = ...
+    learningCurve(X, y, Xval, yval, lambda)
+%LEARNINGCURVE Generates the train and cross validation set errors needed 
+%to plot a learning curve
+%   [error_train, error_val] = ...
+%       LEARNINGCURVE(X, y, Xval, yval, lambda) returns the train and
+%       cross validation set errors for a learning curve. In particular, 
+%       it returns two vectors of the same length - error_train and 
+%       error_val. Then, error_train(i) contains the training error for
+%       i examples (and similarly for error_val(i)).
+%
+%   In this function, you will compute the train and test errors for
+%   dataset sizes from 1 up to m. In practice, when working with larger
+%   datasets, you might want to do this in larger intervals.
+%
+
+% Number of training examples
+m = size(X, 1);
+
+% You need to return these values correctly
+error_train = zeros(m, 1);
+error_val   = zeros(m, 1);
+
+% ====================== YOUR CODE HERE ======================
+% Instructions: Fill in this function to return training errors in 
+%               error_train and the cross validation errors in error_val. 
+%               i.e., error_train(i) and 
+%               error_val(i) should give you the errors
+%               obtained after training on i examples.
+%
+% Note: You should evaluate the training error on the first i training
+%       examples (i.e., X(1:i, :) and y(1:i)).
+%
+%       For the cross-validation error, you should instead evaluate on
+%       the _entire_ cross validation set (Xval and yval).
+%
+% Note: If you are using your cost function (linearRegCostFunction)
+%       to compute the training and cross validation error, you should 
+%       call the function with the lambda argument set to 0. 
+%       Do note that you will still need to use lambda when running
+%       the training to obtain the theta parameters.
+%
+% Hint: You can loop over the examples with the following:
+%
+%       for i = 1:m
+%           % Compute train/cross validation errors using training examples 
+%           % X(1:i, :) and y(1:i), storing the result in 
+%           % error_train(i) and error_val(i)
+%           ....
+%           
+%       end
+%
+
+% ---------------------- Sample Solution ----------------------
+
+
+
+
+
+
+
+% -------------------------------------------------------------
+
+% =========================================================================
+
+end

+ 41 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/AUTHORS.txt

@@ -0,0 +1,41 @@
+The author of "jsonlab" toolbox is Qianqian Fang. Qianqian
+is currently an Assistant Professor at Massachusetts General Hospital, 
+Harvard Medical School.
+
+Address: Martinos Center for Biomedical Imaging, 
+         Massachusetts General Hospital, 
+         Harvard Medical School
+         Bldg 149, 13th St, Charlestown, MA 02129, USA
+URL: http://nmr.mgh.harvard.edu/~fangq/
+Email: <fangq at nmr.mgh.harvard.edu> or <fangqq at gmail.com>
+
+
+The script loadjson.m was built upon previous works by
+
+- Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713
+       date: 2009/11/02
+- François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393
+       date: 2009/03/22
+- Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565
+       date: 2008/07/03
+
+
+This toolbox contains patches submitted by the following contributors:
+
+- Blake Johnson <bjohnso at bbn.com>
+  part of revision 341
+
+- Niclas Borlin <Niclas.Borlin at cs.umu.se>
+  various fixes in revision 394, including
+  - loadjson crashes for all-zero sparse matrix.
+  - loadjson crashes for empty sparse matrix.
+  - Non-zero size of 0-by-N and N-by-0 empty matrices is lost after savejson/loadjson.
+  - loadjson crashes for sparse real column vector.
+  - loadjson crashes for sparse complex column vector.
+  - Data is corrupted by savejson for sparse real row vector.
+  - savejson crashes for sparse complex row vector. 
+
+- Yul Kang <yul.kang.on at gmail.com>
+  patches for svn revision 415.
+  - savejson saves an empty cell array as [] instead of null
+  - loadjson differentiates an empty struct from an empty array

+ 74 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/ChangeLog.txt

@@ -0,0 +1,74 @@
+============================================================================
+
+   JSONlab - a toolbox to encode/decode JSON/UBJSON files in MATLAB/Octave
+
+----------------------------------------------------------------------------
+
+JSONlab ChangeLog (key features marked by *):
+
+== JSONlab 1.0 (codename: Optimus - Final), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2015/01/02 polish help info for all major functions, update examples, finalize 1.0
+ 2014/12/19 fix a bug to strictly respect NoRowBracket in savejson
+
+== JSONlab 1.0.0-RC2 (codename: Optimus - RC2), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2014/11/22 show progress bar in loadjson ('ShowProgress') 
+ 2014/11/17 add Compact option in savejson to output compact JSON format ('Compact')
+ 2014/11/17 add FastArrayParser in loadjson to specify fast parser applicable levels
+ 2014/09/18 start official github mirror: https://github.com/fangq/jsonlab
+
+== JSONlab 1.0.0-RC1 (codename: Optimus - RC1), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2014/09/17  fix several compatibility issues when running on octave versions 3.2-3.8
+ 2014/09/17  support 2D cell and struct arrays in both savejson and saveubjson
+ 2014/08/04  escape special characters in a JSON string
+ 2014/02/16  fix a bug when saving ubjson files
+
+== JSONlab 0.9.9 (codename: Optimus - beta), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2014/01/22  use binary read and write in saveubjson and loadubjson
+
+== JSONlab 0.9.8-1 (codename: Optimus - alpha update 1), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2013/10/07 better round-trip conservation for empty arrays and structs (patch submitted by Yul Kang)
+
+== JSONlab 0.9.8 (codename: Optimus - alpha), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+ 2013/08/23 *universal Binary JSON (UBJSON) support, including both saveubjson and loadubjson
+
+== JSONlab 0.9.1 (codename: Rodimus, update 1), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+ 2012/12/18 *handling of various empty and sparse matrices (fixes submitted by Niclas Borlin)
+
+== JSONlab 0.9.0 (codename: Rodimus), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2012/06/17 *new format for an invalid leading char, unpacking hex code in savejson
+ 2012/06/01  support JSONP in savejson
+ 2012/05/25  fix the empty cell bug (reported by Cyril Davin)
+ 2012/04/05  savejson can save to a file (suggested by Patrick Rapin)
+
+== JSONlab 0.8.1 (codename: Sentiel, Update 1), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2012/02/28  loadjson quotation mark escape bug, see http://bit.ly/yyk1nS
+ 2012/01/25  patch to handle root-less objects, contributed by Blake Johnson
+
+== JSONlab 0.8.0 (codename: Sentiel), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2012/01/13 *speed up loadjson by 20 fold when parsing large data arrays in matlab
+ 2012/01/11  remove row bracket if an array has 1 element, suggested by Mykel Kochenderfer
+ 2011/12/22 *accept sequence of 'param',value input in savejson and loadjson
+ 2011/11/18  fix struct array bug reported by Mykel Kochenderfer
+
+== JSONlab 0.5.1 (codename: Nexus Update 1), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2011/10/21  fix a bug in loadjson, previous code does not use any of the acceleration
+ 2011/10/20  loadjson supports JSON collections - concatenated JSON objects
+
+== JSONlab 0.5.0 (codename: Nexus), FangQ <fangq (at) nmr.mgh.harvard.edu> ==
+
+ 2011/10/16  package and release jsonlab 0.5.0
+ 2011/10/15 *add json demo and regression test, support cpx numbers, fix double quote bug
+ 2011/10/11 *speed up readjson dramatically, interpret _Array* tags, show data in root level
+ 2011/10/10  create jsonlab project, start jsonlab website, add online documentation
+ 2011/10/07 *speed up savejson by 25x using sprintf instead of mat2str, add options support
+ 2011/10/06 *savejson works for structs, cells and arrays
+ 2011/09/09  derive loadjson from JSON parser from MATLAB Central, draft savejson.m

+ 25 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/LICENSE_BSD.txt

@@ -0,0 +1,25 @@
+Copyright 2011-2015 Qianqian Fang <fangq at nmr.mgh.harvard.edu>. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice, this list of
+      conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright notice, this list
+      of conditions and the following disclaimer in the documentation and/or other materials
+      provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of the copyright holders.

+ 394 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/README.txt

@@ -0,0 +1,394 @@
+===============================================================================
+=                                 JSONLab                                     =
+=           An open-source MATLAB/Octave JSON encoder and decoder             =
+===============================================================================
+
+*Copyright (C) 2011-2015  Qianqian Fang <fangq at nmr.mgh.harvard.edu>
+*License: BSD License, see License_BSD.txt for details
+*Version: 1.0 (Optimus - Final)
+
+-------------------------------------------------------------------------------
+
+Table of Content:
+
+I.  Introduction
+II. Installation
+III.Using JSONLab
+IV. Known Issues and TODOs
+V.  Contribution and feedback
+
+-------------------------------------------------------------------------------
+
+I.  Introduction
+
+JSON ([http://www.json.org/ JavaScript Object Notation]) is a highly portable, 
+human-readable and "[http://en.wikipedia.org/wiki/JSON fat-free]" text format 
+to represent complex and hierarchical data. It is as powerful as 
+[http://en.wikipedia.org/wiki/XML XML], but less verbose. JSON format is widely 
+used for data-exchange in applications, and is essential for the wild success 
+of [http://en.wikipedia.org/wiki/Ajax_(programming) Ajax] and 
+[http://en.wikipedia.org/wiki/Web_2.0 Web2.0]. 
+
+UBJSON (Universal Binary JSON) is a binary JSON format, specifically 
+optimized for compact file size and better performance while keeping
+the semantics as simple as the text-based JSON format. Using the UBJSON
+format allows to wrap complex binary data in a flexible and extensible
+structure, making it possible to process complex and large dataset 
+without accuracy loss due to text conversions.
+
+We envision that both JSON and its binary version will serve as part of 
+the mainstream data-exchange formats for scientific research in the future. 
+It will provide the flexibility and generality achieved by other popular 
+general-purpose file specifications, such as
+[http://www.hdfgroup.org/HDF5/whatishdf5.html HDF5], with significantly 
+reduced complexity and enhanced performance.
+
+JSONLab is a free and open-source implementation of a JSON/UBJSON encoder 
+and a decoder in the native MATLAB language. It can be used to convert a MATLAB 
+data structure (array, struct, cell, struct array and cell array) into 
+JSON/UBJSON formatted strings, or to decode a JSON/UBJSON file into MATLAB 
+data structure. JSONLab supports both MATLAB and  
+[http://www.gnu.org/software/octave/ GNU Octave] (a free MATLAB clone).
+
+-------------------------------------------------------------------------------
+
+II. Installation
+
+The installation of JSONLab is no different than any other simple
+MATLAB toolbox. You only need to download/unzip the JSONLab package
+to a folder, and add the folder's path to MATLAB/Octave's path list
+by using the following command:
+
+    addpath('/path/to/jsonlab');
+
+If you want to add this path permanently, you need to type "pathtool", 
+browse to the jsonlab root folder and add to the list, then click "Save".
+Then, run "rehash" in MATLAB, and type "which loadjson", if you see an 
+output, that means JSONLab is installed for MATLAB/Octave.
+
+-------------------------------------------------------------------------------
+
+III.Using JSONLab
+
+JSONLab provides two functions, loadjson.m -- a MATLAB->JSON decoder, 
+and savejson.m -- a MATLAB->JSON encoder, for the text-based JSON, and 
+two equivallent functions -- loadubjson and saveubjson for the binary 
+JSON. The detailed help info for the four functions can be found below:
+
+=== loadjson.m ===
+<pre>
+  data=loadjson(fname,opt)
+     or
+  data=loadjson(fname,'param1',value1,'param2',value2,...)
+ 
+  parse a JSON (JavaScript Object Notation) file or string
+ 
+  authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+  created on 2011/09/09, including previous works from 
+ 
+          Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713
+             created on 2009/11/02
+          François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393
+             created on  2009/03/22
+          Joel Feenstra:
+          http://www.mathworks.com/matlabcentral/fileexchange/20565
+             created on 2008/07/03
+ 
+  $Id: loadjson.m 452 2014-11-22 16:43:33Z fangq $
+ 
+  input:
+       fname: input file name, if fname contains "{}" or "[]", fname
+              will be interpreted as a JSON string
+       opt: a struct to store parsing options, opt can be replaced by 
+            a list of ('param',value) pairs - the param string is equivallent
+            to a field in opt. opt can have the following 
+            fields (first in [.|.] is the default)
+ 
+            opt.SimplifyCell [0|1]: if set to 1, loadjson will call cell2mat
+                          for each element of the JSON data, and group 
+                          arrays based on the cell2mat rules.
+            opt.FastArrayParser [1|0 or integer]: if set to 1, use a
+                          speed-optimized array parser when loading an 
+                          array object. The fast array parser may 
+                          collapse block arrays into a single large
+                          array similar to rules defined in cell2mat; 0 to 
+                          use a legacy parser; if set to a larger-than-1
+                          value, this option will specify the minimum
+                          dimension to enable the fast array parser. For
+                          example, if the input is a 3D array, setting
+                          FastArrayParser to 1 will return a 3D array;
+                          setting to 2 will return a cell array of 2D
+                          arrays; setting to 3 will return to a 2D cell
+                          array of 1D vectors; setting to 4 will return a
+                          3D cell array.
+            opt.ShowProgress [0|1]: if set to 1, loadjson displays a progress bar.
+ 
+  output:
+       dat: a cell array, where {...} blocks are converted into cell arrays,
+            and [...] are converted to arrays
+ 
+  examples:
+       dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}')
+       dat=loadjson(['examples' filesep 'example1.json'])
+       dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',1)
+</pre>
+
+=== savejson.m ===
+
+<pre>
+  json=savejson(rootname,obj,filename)
+     or
+  json=savejson(rootname,obj,opt)
+  json=savejson(rootname,obj,'param1',value1,'param2',value2,...)
+ 
+  convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
+  Object Notation) string
+ 
+  author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+  created on 2011/09/09
+ 
+  $Id: savejson.m 458 2014-12-19 22:17:17Z fangq $
+ 
+  input:
+       rootname: the name of the root-object, when set to '', the root name
+         is ignored, however, when opt.ForceRootName is set to 1 (see below),
+         the MATLAB variable name will be used as the root name.
+       obj: a MATLAB object (array, cell, cell array, struct, struct array).
+       filename: a string for the file name to save the output JSON data.
+       opt: a struct for additional options, ignore to use default values.
+         opt can have the following fields (first in [.|.] is the default)
+ 
+         opt.FileName [''|string]: a file name to save the output JSON data
+         opt.FloatFormat ['%.10g'|string]: format to show each numeric element
+                          of a 1D/2D array;
+         opt.ArrayIndent [1|0]: if 1, output explicit data array with
+                          precedent indentation; if 0, no indentation
+         opt.ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
+                          array in JSON array format; if sets to 1, an
+                          array will be shown as a struct with fields
+                          "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
+                          sparse arrays, the non-zero elements will be
+                          saved to _ArrayData_ field in triplet-format i.e.
+                          (ix,iy,val) and "_ArrayIsSparse_" will be added
+                          with a value of 1; for a complex array, the 
+                          _ArrayData_ array will include two columns 
+                          (4 for sparse) to record the real and imaginary 
+                          parts, and also "_ArrayIsComplex_":1 is added. 
+         opt.ParseLogical [0|1]: if this is set to 1, logical array elem
+                          will use true/false rather than 1/0.
+         opt.NoRowBracket [1|0]: if this is set to 1, arrays with a single
+                          numerical element will be shown without a square
+                          bracket, unless it is the root object; if 0, square
+                          brackets are forced for any numerical arrays.
+         opt.ForceRootName [0|1]: when set to 1 and rootname is empty, savejson
+                          will use the name of the passed obj variable as the 
+                          root object name; if obj is an expression and 
+                          does not have a name, 'root' will be used; if this 
+                          is set to 0 and rootname is empty, the root level 
+                          will be merged down to the lower level.
+         opt.Inf ['"$1_Inf_"'|string]: a customized regular expression pattern
+                          to represent +/-Inf. The matched pattern is '([-+]*)Inf'
+                          and $1 represents the sign. For those who want to use
+                          1e999 to represent Inf, they can set opt.Inf to '$11e999'
+         opt.NaN ['"_NaN_"'|string]: a customized regular expression pattern
+                          to represent NaN
+         opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
+                          for example, if opt.JSONP='foo', the JSON data is
+                          wrapped inside a function call as 'foo(...);'
+         opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
+                          back to the string form
+         opt.SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode.
+         opt.Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs)
+ 
+         opt can be replaced by a list of ('param',value) pairs. The param 
+         string is equivallent to a field in opt and is case sensitive.
+  output:
+       json: a string in the JSON format (see http://json.org)
+ 
+  examples:
+       jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 
+                'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
+                'MeshTri',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
+                           2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
+                'MeshCreator','FangQ','MeshTitle','T6 Cube',...
+                'SpecialData',[nan, inf, -inf]);
+       savejson('jmesh',jsonmesh)
+       savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g')
+ </pre>
+
+=== loadubjson.m ===
+
+<pre>
+  data=loadubjson(fname,opt)
+     or
+  data=loadubjson(fname,'param1',value1,'param2',value2,...)
+ 
+  parse a JSON (JavaScript Object Notation) file or string
+ 
+  authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+  created on 2013/08/01
+ 
+  $Id: loadubjson.m 436 2014-08-05 20:51:40Z fangq $
+ 
+  input:
+       fname: input file name, if fname contains "{}" or "[]", fname
+              will be interpreted as a UBJSON string
+       opt: a struct to store parsing options, opt can be replaced by 
+            a list of ('param',value) pairs - the param string is equivallent
+            to a field in opt. opt can have the following 
+            fields (first in [.|.] is the default)
+ 
+            opt.SimplifyCell [0|1]: if set to 1, loadubjson will call cell2mat
+                          for each element of the JSON data, and group 
+                          arrays based on the cell2mat rules.
+            opt.IntEndian [B|L]: specify the endianness of the integer fields
+                          in the UBJSON input data. B - Big-Endian format for 
+                          integers (as required in the UBJSON specification); 
+                          L - input integer fields are in Little-Endian order.
+ 
+  output:
+       dat: a cell array, where {...} blocks are converted into cell arrays,
+            and [...] are converted to arrays
+ 
+  examples:
+       obj=struct('string','value','array',[1 2 3]);
+       ubjdata=saveubjson('obj',obj);
+       dat=loadubjson(ubjdata)
+       dat=loadubjson(['examples' filesep 'example1.ubj'])
+       dat=loadubjson(['examples' filesep 'example1.ubj'],'SimplifyCell',1)
+</pre>
+
+=== saveubjson.m ===
+
+<pre>
+  json=saveubjson(rootname,obj,filename)
+     or
+  json=saveubjson(rootname,obj,opt)
+  json=saveubjson(rootname,obj,'param1',value1,'param2',value2,...)
+ 
+  convert a MATLAB object (cell, struct or array) into a Universal 
+  Binary JSON (UBJSON) binary string
+ 
+  author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+  created on 2013/08/17
+ 
+  $Id: saveubjson.m 440 2014-09-17 19:59:45Z fangq $
+ 
+  input:
+       rootname: the name of the root-object, when set to '', the root name
+         is ignored, however, when opt.ForceRootName is set to 1 (see below),
+         the MATLAB variable name will be used as the root name.
+       obj: a MATLAB object (array, cell, cell array, struct, struct array)
+       filename: a string for the file name to save the output UBJSON data
+       opt: a struct for additional options, ignore to use default values.
+         opt can have the following fields (first in [.|.] is the default)
+ 
+         opt.FileName [''|string]: a file name to save the output JSON data
+         opt.ArrayToStruct[0|1]: when set to 0, saveubjson outputs 1D/2D
+                          array in JSON array format; if sets to 1, an
+                          array will be shown as a struct with fields
+                          "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
+                          sparse arrays, the non-zero elements will be
+                          saved to _ArrayData_ field in triplet-format i.e.
+                          (ix,iy,val) and "_ArrayIsSparse_" will be added
+                          with a value of 1; for a complex array, the 
+                          _ArrayData_ array will include two columns 
+                          (4 for sparse) to record the real and imaginary 
+                          parts, and also "_ArrayIsComplex_":1 is added. 
+         opt.ParseLogical [1|0]: if this is set to 1, logical array elem
+                          will use true/false rather than 1/0.
+         opt.NoRowBracket [1|0]: if this is set to 1, arrays with a single
+                          numerical element will be shown without a square
+                          bracket, unless it is the root object; if 0, square
+                          brackets are forced for any numerical arrays.
+         opt.ForceRootName [0|1]: when set to 1 and rootname is empty, saveubjson
+                          will use the name of the passed obj variable as the 
+                          root object name; if obj is an expression and 
+                          does not have a name, 'root' will be used; if this 
+                          is set to 0 and rootname is empty, the root level 
+                          will be merged down to the lower level.
+         opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
+                          for example, if opt.JSON='foo', the JSON data is
+                          wrapped inside a function call as 'foo(...);'
+         opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
+                          back to the string form
+ 
+         opt can be replaced by a list of ('param',value) pairs. The param 
+         string is equivallent to a field in opt and is case sensitive.
+  output:
+       json: a binary string in the UBJSON format (see http://ubjson.org)
+ 
+  examples:
+       jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 
+                'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
+                'MeshTri',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
+                           2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
+                'MeshCreator','FangQ','MeshTitle','T6 Cube',...
+                'SpecialData',[nan, inf, -inf]);
+       saveubjson('jsonmesh',jsonmesh)
+       saveubjson('jsonmesh',jsonmesh,'meshdata.ubj')
+</pre>
+
+
+=== examples ===
+
+Under the "examples" folder, you can find several scripts to demonstrate the
+basic utilities of JSONLab. Running the "demo_jsonlab_basic.m" script, you 
+will see the conversions from MATLAB data structure to JSON text and backward.
+In "jsonlab_selftest.m", we load complex JSON files downloaded from the Internet
+and validate the loadjson/savejson functions for regression testing purposes.
+Similarly, a "demo_ubjson_basic.m" script is provided to test the saveubjson
+and loadubjson pairs for various matlab data structures.
+
+Please run these examples and understand how JSONLab works before you use
+it to process your data.
+
+-------------------------------------------------------------------------------
+
+IV. Known Issues and TODOs
+
+JSONLab has several known limitations. We are striving to make it more general
+and robust. Hopefully in a few future releases, the limitations become less.
+
+Here are the known issues:
+
+# 3D or higher dimensional cell/struct-arrays will be converted to 2D arrays;
+# When processing names containing multi-byte characters, Octave and MATLAB \
+can give different field-names; you can use feature('DefaultCharacterSet','latin1') \
+in MATLAB to get consistant results
+# savejson can not handle class and dataset.
+# saveubjson converts a logical array into a uint8 ([U]) array
+# an unofficial N-D array count syntax is implemented in saveubjson. We are \
+actively communicating with the UBJSON spec maintainer to investigate the \
+possibility of making it upstream
+# loadubjson can not parse all UBJSON Specification (Draft 9) compliant \
+files, however, it can parse all UBJSON files produced by saveubjson.
+
+-------------------------------------------------------------------------------
+
+V. Contribution and feedback
+
+JSONLab is an open-source project. This means you can not only use it and modify
+it as you wish, but also you can contribute your changes back to JSONLab so
+that everyone else can enjoy the improvement. For anyone who want to contribute,
+please download JSONLab source code from it's subversion repository by using the
+following command:
+
+ svn checkout svn://svn.code.sf.net/p/iso2mesh/code/trunk/jsonlab jsonlab
+
+You can make changes to the files as needed. Once you are satisfied with your
+changes, and ready to share it with others, please cd the root directory of 
+JSONLab, and type
+
+ svn diff > yourname_featurename.patch
+
+You then email the .patch file to JSONLab's maintainer, Qianqian Fang, at
+the email address shown in the beginning of this file. Qianqian will review 
+the changes and commit it to the subversion if they are satisfactory.
+
+We appreciate any suggestions and feedbacks from you. Please use iso2mesh's
+mailing list to report any questions you may have with JSONLab:
+
+http://groups.google.com/group/iso2mesh-users?hl=en&pli=1
+
+(Subscription to the mailing list is needed in order to post messages).

+ 32 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/jsonopt.m

@@ -0,0 +1,32 @@
+function val=jsonopt(key,default,varargin)
+%
+% val=jsonopt(key,default,optstruct)
+%
+% setting options based on a struct. The struct can be produced
+% by varargin2struct from a list of 'param','value' pairs
+%
+% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+%
+% $Id: loadjson.m 371 2012-06-20 12:43:06Z fangq $
+%
+% input:
+%      key: a string with which one look up a value from a struct
+%      default: if the key does not exist, return default
+%      optstruct: a struct where each sub-field is a key 
+%
+% output:
+%      val: if key exists, val=optstruct.key; otherwise val=default
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details
+%
+% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+% 
+
+val=default;
+if(nargin<=2) return; end
+opt=varargin{1};
+if(isstruct(opt) && isfield(opt,key))
+    val=getfield(opt,key);
+end
+

+ 566 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/loadjson.m

@@ -0,0 +1,566 @@
+function data = loadjson(fname,varargin)
+%
+% data=loadjson(fname,opt)
+%    or
+% data=loadjson(fname,'param1',value1,'param2',value2,...)
+%
+% parse a JSON (JavaScript Object Notation) file or string
+%
+% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% created on 2011/09/09, including previous works from 
+%
+%         Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713
+%            created on 2009/11/02
+%         François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393
+%            created on  2009/03/22
+%         Joel Feenstra:
+%         http://www.mathworks.com/matlabcentral/fileexchange/20565
+%            created on 2008/07/03
+%
+% $Id: loadjson.m 460 2015-01-03 00:30:45Z fangq $
+%
+% input:
+%      fname: input file name, if fname contains "{}" or "[]", fname
+%             will be interpreted as a JSON string
+%      opt: a struct to store parsing options, opt can be replaced by 
+%           a list of ('param',value) pairs - the param string is equivallent
+%           to a field in opt. opt can have the following 
+%           fields (first in [.|.] is the default)
+%
+%           opt.SimplifyCell [0|1]: if set to 1, loadjson will call cell2mat
+%                         for each element of the JSON data, and group 
+%                         arrays based on the cell2mat rules.
+%           opt.FastArrayParser [1|0 or integer]: if set to 1, use a
+%                         speed-optimized array parser when loading an 
+%                         array object. The fast array parser may 
+%                         collapse block arrays into a single large
+%                         array similar to rules defined in cell2mat; 0 to 
+%                         use a legacy parser; if set to a larger-than-1
+%                         value, this option will specify the minimum
+%                         dimension to enable the fast array parser. For
+%                         example, if the input is a 3D array, setting
+%                         FastArrayParser to 1 will return a 3D array;
+%                         setting to 2 will return a cell array of 2D
+%                         arrays; setting to 3 will return to a 2D cell
+%                         array of 1D vectors; setting to 4 will return a
+%                         3D cell array.
+%           opt.ShowProgress [0|1]: if set to 1, loadjson displays a progress bar.
+%
+% output:
+%      dat: a cell array, where {...} blocks are converted into cell arrays,
+%           and [...] are converted to arrays
+%
+% examples:
+%      dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}')
+%      dat=loadjson(['examples' filesep 'example1.json'])
+%      dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',1)
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details 
+%
+% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+global pos inStr len  esc index_esc len_esc isoct arraytoken
+
+if(regexp(fname,'[\{\}\]\[]','once'))
+   string=fname;
+elseif(exist(fname,'file'))
+   fid = fopen(fname,'rb');
+   string = fread(fid,inf,'uint8=>char')';
+   fclose(fid);
+else
+   error('input file does not exist');
+end
+
+pos = 1; len = length(string); inStr = string;
+isoct=exist('OCTAVE_VERSION','builtin');
+arraytoken=find(inStr=='[' | inStr==']' | inStr=='"');
+jstr=regexprep(inStr,'\\\\','  ');
+escquote=regexp(jstr,'\\"');
+arraytoken=sort([arraytoken escquote]);
+
+% String delimiters and escape chars identified to improve speed:
+esc = find(inStr=='"' | inStr=='\' ); % comparable to: regexp(inStr, '["\\]');
+index_esc = 1; len_esc = length(esc);
+
+opt=varargin2struct(varargin{:});
+
+if(jsonopt('ShowProgress',0,opt)==1)
+    opt.progressbar_=waitbar(0,'loading ...');
+end
+jsoncount=1;
+while pos <= len
+    switch(next_char)
+        case '{'
+            data{jsoncount} = parse_object(opt);
+        case '['
+            data{jsoncount} = parse_array(opt);
+        otherwise
+            error_pos('Outer level structure must be an object or an array');
+    end
+    jsoncount=jsoncount+1;
+end % while
+
+jsoncount=length(data);
+if(jsoncount==1 && iscell(data))
+    data=data{1};
+end
+
+if(~isempty(data))
+      if(isstruct(data)) % data can be a struct array
+          data=jstruct2array(data);
+      elseif(iscell(data))
+          data=jcell2array(data);
+      end
+end
+if(isfield(opt,'progressbar_'))
+    close(opt.progressbar_);
+end
+
+%%
+function newdata=jcell2array(data)
+len=length(data);
+newdata=data;
+for i=1:len
+      if(isstruct(data{i}))
+          newdata{i}=jstruct2array(data{i});
+      elseif(iscell(data{i}))
+          newdata{i}=jcell2array(data{i});
+      end
+end
+
+%%-------------------------------------------------------------------------
+function newdata=jstruct2array(data)
+fn=fieldnames(data);
+newdata=data;
+len=length(data);
+for i=1:length(fn) % depth-first
+    for j=1:len
+        if(isstruct(getfield(data(j),fn{i})))
+            newdata(j)=setfield(newdata(j),fn{i},jstruct2array(getfield(data(j),fn{i})));
+        end
+    end
+end
+if(~isempty(strmatch('x0x5F_ArrayType_',fn)) && ~isempty(strmatch('x0x5F_ArrayData_',fn)))
+  newdata=cell(len,1);
+  for j=1:len
+    ndata=cast(data(j).x0x5F_ArrayData_,data(j).x0x5F_ArrayType_);
+    iscpx=0;
+    if(~isempty(strmatch('x0x5F_ArrayIsComplex_',fn)))
+        if(data(j).x0x5F_ArrayIsComplex_)
+           iscpx=1;
+        end
+    end
+    if(~isempty(strmatch('x0x5F_ArrayIsSparse_',fn)))
+        if(data(j).x0x5F_ArrayIsSparse_)
+            if(~isempty(strmatch('x0x5F_ArraySize_',fn)))
+                dim=data(j).x0x5F_ArraySize_;
+                if(iscpx && size(ndata,2)==4-any(dim==1))
+                    ndata(:,end-1)=complex(ndata(:,end-1),ndata(:,end));
+                end
+                if isempty(ndata)
+                    % All-zeros sparse
+                    ndata=sparse(dim(1),prod(dim(2:end)));
+                elseif dim(1)==1
+                    % Sparse row vector
+                    ndata=sparse(1,ndata(:,1),ndata(:,2),dim(1),prod(dim(2:end)));
+                elseif dim(2)==1
+                    % Sparse column vector
+                    ndata=sparse(ndata(:,1),1,ndata(:,2),dim(1),prod(dim(2:end)));
+                else
+                    % Generic sparse array.
+                    ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3),dim(1),prod(dim(2:end)));
+                end
+            else
+                if(iscpx && size(ndata,2)==4)
+                    ndata(:,3)=complex(ndata(:,3),ndata(:,4));
+                end
+                ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3));
+            end
+        end
+    elseif(~isempty(strmatch('x0x5F_ArraySize_',fn)))
+        if(iscpx && size(ndata,2)==2)
+             ndata=complex(ndata(:,1),ndata(:,2));
+        end
+        ndata=reshape(ndata(:),data(j).x0x5F_ArraySize_);
+    end
+    newdata{j}=ndata;
+  end
+  if(len==1)
+      newdata=newdata{1};
+  end
+end
+
+%%-------------------------------------------------------------------------
+function object = parse_object(varargin)
+    parse_char('{');
+    object = [];
+    if next_char ~= '}'
+        while 1
+            str = parseStr(varargin{:});
+            if isempty(str)
+                error_pos('Name of value at position %d cannot be empty');
+            end
+            parse_char(':');
+            val = parse_value(varargin{:});
+            eval( sprintf( 'object.%s  = val;', valid_field(str) ) );
+            if next_char == '}'
+                break;
+            end
+            parse_char(',');
+        end
+    end
+    parse_char('}');
+
+%%-------------------------------------------------------------------------
+
+function object = parse_array(varargin) % JSON array is written in row-major order
+global pos inStr isoct
+    parse_char('[');
+    object = cell(0, 1);
+    dim2=[];
+    arraydepth=jsonopt('JSONLAB_ArrayDepth_',1,varargin{:});
+    pbar=jsonopt('progressbar_',-1,varargin{:});
+
+    if next_char ~= ']'
+	if(jsonopt('FastArrayParser',1,varargin{:})>=1 && arraydepth>=jsonopt('FastArrayParser',1,varargin{:}))
+            [endpos, e1l, e1r, maxlevel]=matching_bracket(inStr,pos);
+            arraystr=['[' inStr(pos:endpos)];
+            arraystr=regexprep(arraystr,'"_NaN_"','NaN');
+            arraystr=regexprep(arraystr,'"([-+]*)_Inf_"','$1Inf');
+            arraystr(arraystr==sprintf('\n'))=[];
+            arraystr(arraystr==sprintf('\r'))=[];
+            %arraystr=regexprep(arraystr,'\s*,',','); % this is slow,sometimes needed
+            if(~isempty(e1l) && ~isempty(e1r)) % the array is in 2D or higher D
+        	astr=inStr((e1l+1):(e1r-1));
+        	astr=regexprep(astr,'"_NaN_"','NaN');
+        	astr=regexprep(astr,'"([-+]*)_Inf_"','$1Inf');
+        	astr(astr==sprintf('\n'))=[];
+        	astr(astr==sprintf('\r'))=[];
+        	astr(astr==' ')='';
+        	if(isempty(find(astr=='[', 1))) % array is 2D
+                    dim2=length(sscanf(astr,'%f,',[1 inf]));
+        	end
+            else % array is 1D
+        	astr=arraystr(2:end-1);
+        	astr(astr==' ')='';
+        	[obj, count, errmsg, nextidx]=sscanf(astr,'%f,',[1,inf]);
+        	if(nextidx>=length(astr)-1)
+                    object=obj;
+                    pos=endpos;
+                    parse_char(']');
+                    return;
+        	end
+            end
+            if(~isempty(dim2))
+        	astr=arraystr;
+        	astr(astr=='[')='';
+        	astr(astr==']')='';
+        	astr(astr==' ')='';
+        	[obj, count, errmsg, nextidx]=sscanf(astr,'%f,',inf);
+        	if(nextidx>=length(astr)-1)
+                    object=reshape(obj,dim2,numel(obj)/dim2)';
+                    pos=endpos;
+                    parse_char(']');
+                    if(pbar>0)
+                        waitbar(pos/length(inStr),pbar,'loading ...');
+                    end
+                    return;
+        	end
+            end
+            arraystr=regexprep(arraystr,'\]\s*,','];');
+	else
+            arraystr='[';
+	end
+        try
+           if(isoct && regexp(arraystr,'"','once'))
+                error('Octave eval can produce empty cells for JSON-like input');
+           end
+           object=eval(arraystr);
+           pos=endpos;
+        catch
+         while 1
+            newopt=varargin2struct(varargin{:},'JSONLAB_ArrayDepth_',arraydepth+1);
+            val = parse_value(newopt);
+            object{end+1} = val;
+            if next_char == ']'
+                break;
+            end
+            parse_char(',');
+         end
+        end
+    end
+    if(jsonopt('SimplifyCell',0,varargin{:})==1)
+      try
+        oldobj=object;
+        object=cell2mat(object')';
+        if(iscell(oldobj) && isstruct(object) && numel(object)>1 && jsonopt('SimplifyCellArray',1,varargin{:})==0)
+            object=oldobj;
+        elseif(size(object,1)>1 && ndims(object)==2)
+            object=object';
+        end
+      catch
+      end
+    end
+    parse_char(']');
+    
+    if(pbar>0)
+        waitbar(pos/length(inStr),pbar,'loading ...');
+    end
+%%-------------------------------------------------------------------------
+
+function parse_char(c)
+    global pos inStr len
+    skip_whitespace;
+    if pos > len || inStr(pos) ~= c
+        error_pos(sprintf('Expected %c at position %%d', c));
+    else
+        pos = pos + 1;
+        skip_whitespace;
+    end
+
+%%-------------------------------------------------------------------------
+
+function c = next_char
+    global pos inStr len
+    skip_whitespace;
+    if pos > len
+        c = [];
+    else
+        c = inStr(pos);
+    end
+
+%%-------------------------------------------------------------------------
+
+function skip_whitespace
+    global pos inStr len
+    while pos <= len && isspace(inStr(pos))
+        pos = pos + 1;
+    end
+
+%%-------------------------------------------------------------------------
+function str = parseStr(varargin)
+    global pos inStr len  esc index_esc len_esc
+ % len, ns = length(inStr), keyboard
+    if inStr(pos) ~= '"'
+        error_pos('String starting with " expected at position %d');
+    else
+        pos = pos + 1;
+    end
+    str = '';
+    while pos <= len
+        while index_esc <= len_esc && esc(index_esc) < pos
+            index_esc = index_esc + 1;
+        end
+        if index_esc > len_esc
+            str = [str inStr(pos:len)];
+            pos = len + 1;
+            break;
+        else
+            str = [str inStr(pos:esc(index_esc)-1)];
+            pos = esc(index_esc);
+        end
+        nstr = length(str); switch inStr(pos)
+            case '"'
+                pos = pos + 1;
+                if(~isempty(str))
+                    if(strcmp(str,'_Inf_'))
+                        str=Inf;
+                    elseif(strcmp(str,'-_Inf_'))
+                        str=-Inf;
+                    elseif(strcmp(str,'_NaN_'))
+                        str=NaN;
+                    end
+                end
+                return;
+            case '\'
+                if pos+1 > len
+                    error_pos('End of file reached right after escape character');
+                end
+                pos = pos + 1;
+                switch inStr(pos)
+                    case {'"' '\' '/'}
+                        str(nstr+1) = inStr(pos);
+                        pos = pos + 1;
+                    case {'b' 'f' 'n' 'r' 't'}
+                        str(nstr+1) = sprintf(['\' inStr(pos)]);
+                        pos = pos + 1;
+                    case 'u'
+                        if pos+4 > len
+                            error_pos('End of file reached in escaped unicode character');
+                        end
+                        str(nstr+(1:6)) = inStr(pos-1:pos+4);
+                        pos = pos + 5;
+                end
+            otherwise % should never happen
+                str(nstr+1) = inStr(pos), keyboard
+                pos = pos + 1;
+        end
+    end
+    error_pos('End of file while expecting end of inStr');
+
+%%-------------------------------------------------------------------------
+
+function num = parse_number(varargin)
+    global pos inStr len isoct
+    currstr=inStr(pos:end);
+    numstr=0;
+    if(isoct~=0)
+        numstr=regexp(currstr,'^\s*-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+\-]?\d+)?','end');
+        [num, one] = sscanf(currstr, '%f', 1);
+        delta=numstr+1;
+    else
+        [num, one, err, delta] = sscanf(currstr, '%f', 1);
+        if ~isempty(err)
+            error_pos('Error reading number at position %d');
+        end
+    end
+    pos = pos + delta-1;
+
+%%-------------------------------------------------------------------------
+
+function val = parse_value(varargin)
+    global pos inStr len
+    true = 1; false = 0;
+    
+    pbar=jsonopt('progressbar_',-1,varargin{:});
+    if(pbar>0)
+        waitbar(pos/len,pbar,'loading ...');
+    end
+    
+    switch(inStr(pos))
+        case '"'
+            val = parseStr(varargin{:});
+            return;
+        case '['
+            val = parse_array(varargin{:});
+            return;
+        case '{'
+            val = parse_object(varargin{:});
+            if isstruct(val)
+                if(~isempty(strmatch('x0x5F_ArrayType_',fieldnames(val), 'exact')))
+                    val=jstruct2array(val);
+                end
+            elseif isempty(val)
+                val = struct;
+            end
+            return;
+        case {'-','0','1','2','3','4','5','6','7','8','9'}
+            val = parse_number(varargin{:});
+            return;
+        case 't'
+            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'true')
+                val = true;
+                pos = pos + 4;
+                return;
+            end
+        case 'f'
+            if pos+4 <= len && strcmpi(inStr(pos:pos+4), 'false')
+                val = false;
+                pos = pos + 5;
+                return;
+            end
+        case 'n'
+            if pos+3 <= len && strcmpi(inStr(pos:pos+3), 'null')
+                val = [];
+                pos = pos + 4;
+                return;
+            end
+    end
+    error_pos('Value expected at position %d');
+%%-------------------------------------------------------------------------
+
+function error_pos(msg)
+    global pos inStr len
+    poShow = max(min([pos-15 pos-1 pos pos+20],len),1);
+    if poShow(3) == poShow(2)
+        poShow(3:4) = poShow(2)+[0 -1];  % display nothing after
+    end
+    msg = [sprintf(msg, pos) ': ' ...
+    inStr(poShow(1):poShow(2)) '<error>' inStr(poShow(3):poShow(4)) ];
+    error( ['JSONparser:invalidFormat: ' msg] );
+
+%%-------------------------------------------------------------------------
+
+function str = valid_field(str)
+global isoct
+% From MATLAB doc: field names must begin with a letter, which may be
+% followed by any combination of letters, digits, and underscores.
+% Invalid characters will be converted to underscores, and the prefix
+% "x0x[Hex code]_" will be added if the first character is not a letter.
+    pos=regexp(str,'^[^A-Za-z]','once');
+    if(~isempty(pos))
+        if(~isoct)
+            str=regexprep(str,'^([^A-Za-z])','x0x${sprintf(''%X'',unicode2native($1))}_','once');
+        else
+            str=sprintf('x0x%X_%s',char(str(1)),str(2:end));
+        end
+    end
+    if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' ))) return;  end
+    if(~isoct)
+        str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_');
+    else
+        pos=regexp(str,'[^0-9A-Za-z_]');
+        if(isempty(pos)) return; end
+        str0=str;
+        pos0=[0 pos(:)' length(str)];
+        str='';
+        for i=1:length(pos)
+            str=[str str0(pos0(i)+1:pos(i)-1) sprintf('_0x%X_',str0(pos(i)))];
+        end
+        if(pos(end)~=length(str))
+            str=[str str0(pos0(end-1)+1:pos0(end))];
+        end
+    end
+    %str(~isletter(str) & ~('0' <= str & str <= '9')) = '_';
+
+%%-------------------------------------------------------------------------
+function endpos = matching_quote(str,pos)
+len=length(str);
+while(pos<len)
+    if(str(pos)=='"')
+        if(~(pos>1 && str(pos-1)=='\'))
+            endpos=pos;
+            return;
+        end        
+    end
+    pos=pos+1;
+end
+error('unmatched quotation mark');
+%%-------------------------------------------------------------------------
+function [endpos, e1l, e1r, maxlevel] = matching_bracket(str,pos)
+global arraytoken
+level=1;
+maxlevel=level;
+endpos=0;
+bpos=arraytoken(arraytoken>=pos);
+tokens=str(bpos);
+len=length(tokens);
+pos=1;
+e1l=[];
+e1r=[];
+while(pos<=len)
+    c=tokens(pos);
+    if(c==']')
+        level=level-1;
+        if(isempty(e1r)) e1r=bpos(pos); end
+        if(level==0)
+            endpos=bpos(pos);
+            return
+        end
+    end
+    if(c=='[')
+        if(isempty(e1l)) e1l=bpos(pos); end
+        level=level+1;
+        maxlevel=max(maxlevel,level);
+    end
+    if(c=='"')
+        pos=matching_quote(tokens,pos+1);
+    end
+    pos=pos+1;
+end
+if(endpos==0) 
+    error('unmatched "]"');
+end
+

+ 528 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/loadubjson.m

@@ -0,0 +1,528 @@
+function data = loadubjson(fname,varargin)
+%
+% data=loadubjson(fname,opt)
+%    or
+% data=loadubjson(fname,'param1',value1,'param2',value2,...)
+%
+% parse a JSON (JavaScript Object Notation) file or string
+%
+% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% created on 2013/08/01
+%
+% $Id: loadubjson.m 460 2015-01-03 00:30:45Z fangq $
+%
+% input:
+%      fname: input file name, if fname contains "{}" or "[]", fname
+%             will be interpreted as a UBJSON string
+%      opt: a struct to store parsing options, opt can be replaced by 
+%           a list of ('param',value) pairs - the param string is equivallent
+%           to a field in opt. opt can have the following 
+%           fields (first in [.|.] is the default)
+%
+%           opt.SimplifyCell [0|1]: if set to 1, loadubjson will call cell2mat
+%                         for each element of the JSON data, and group 
+%                         arrays based on the cell2mat rules.
+%           opt.IntEndian [B|L]: specify the endianness of the integer fields
+%                         in the UBJSON input data. B - Big-Endian format for 
+%                         integers (as required in the UBJSON specification); 
+%                         L - input integer fields are in Little-Endian order.
+%
+% output:
+%      dat: a cell array, where {...} blocks are converted into cell arrays,
+%           and [...] are converted to arrays
+%
+% examples:
+%      obj=struct('string','value','array',[1 2 3]);
+%      ubjdata=saveubjson('obj',obj);
+%      dat=loadubjson(ubjdata)
+%      dat=loadubjson(['examples' filesep 'example1.ubj'])
+%      dat=loadubjson(['examples' filesep 'example1.ubj'],'SimplifyCell',1)
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details 
+%
+% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+global pos inStr len  esc index_esc len_esc isoct arraytoken fileendian systemendian
+
+if(regexp(fname,'[\{\}\]\[]','once'))
+   string=fname;
+elseif(exist(fname,'file'))
+   fid = fopen(fname,'rb');
+   string = fread(fid,inf,'uint8=>char')';
+   fclose(fid);
+else
+   error('input file does not exist');
+end
+
+pos = 1; len = length(string); inStr = string;
+isoct=exist('OCTAVE_VERSION','builtin');
+arraytoken=find(inStr=='[' | inStr==']' | inStr=='"');
+jstr=regexprep(inStr,'\\\\','  ');
+escquote=regexp(jstr,'\\"');
+arraytoken=sort([arraytoken escquote]);
+
+% String delimiters and escape chars identified to improve speed:
+esc = find(inStr=='"' | inStr=='\' ); % comparable to: regexp(inStr, '["\\]');
+index_esc = 1; len_esc = length(esc);
+
+opt=varargin2struct(varargin{:});
+fileendian=upper(jsonopt('IntEndian','B',opt));
+[os,maxelem,systemendian]=computer;
+
+jsoncount=1;
+while pos <= len
+    switch(next_char)
+        case '{'
+            data{jsoncount} = parse_object(opt);
+        case '['
+            data{jsoncount} = parse_array(opt);
+        otherwise
+            error_pos('Outer level structure must be an object or an array');
+    end
+    jsoncount=jsoncount+1;
+end % while
+
+jsoncount=length(data);
+if(jsoncount==1 && iscell(data))
+    data=data{1};
+end
+
+if(~isempty(data))
+      if(isstruct(data)) % data can be a struct array
+          data=jstruct2array(data);
+      elseif(iscell(data))
+          data=jcell2array(data);
+      end
+end
+
+
+%%
+function newdata=parse_collection(id,data,obj)
+
+if(jsoncount>0 && exist('data','var')) 
+    if(~iscell(data))
+       newdata=cell(1);
+       newdata{1}=data;
+       data=newdata;
+    end
+end
+
+%%
+function newdata=jcell2array(data)
+len=length(data);
+newdata=data;
+for i=1:len
+      if(isstruct(data{i}))
+          newdata{i}=jstruct2array(data{i});
+      elseif(iscell(data{i}))
+          newdata{i}=jcell2array(data{i});
+      end
+end
+
+%%-------------------------------------------------------------------------
+function newdata=jstruct2array(data)
+fn=fieldnames(data);
+newdata=data;
+len=length(data);
+for i=1:length(fn) % depth-first
+    for j=1:len
+        if(isstruct(getfield(data(j),fn{i})))
+            newdata(j)=setfield(newdata(j),fn{i},jstruct2array(getfield(data(j),fn{i})));
+        end
+    end
+end
+if(~isempty(strmatch('x0x5F_ArrayType_',fn)) && ~isempty(strmatch('x0x5F_ArrayData_',fn)))
+  newdata=cell(len,1);
+  for j=1:len
+    ndata=cast(data(j).x0x5F_ArrayData_,data(j).x0x5F_ArrayType_);
+    iscpx=0;
+    if(~isempty(strmatch('x0x5F_ArrayIsComplex_',fn)))
+        if(data(j).x0x5F_ArrayIsComplex_)
+           iscpx=1;
+        end
+    end
+    if(~isempty(strmatch('x0x5F_ArrayIsSparse_',fn)))
+        if(data(j).x0x5F_ArrayIsSparse_)
+            if(~isempty(strmatch('x0x5F_ArraySize_',fn)))
+                dim=double(data(j).x0x5F_ArraySize_);
+                if(iscpx && size(ndata,2)==4-any(dim==1))
+                    ndata(:,end-1)=complex(ndata(:,end-1),ndata(:,end));
+                end
+                if isempty(ndata)
+                    % All-zeros sparse
+                    ndata=sparse(dim(1),prod(dim(2:end)));
+                elseif dim(1)==1
+                    % Sparse row vector
+                    ndata=sparse(1,ndata(:,1),ndata(:,2),dim(1),prod(dim(2:end)));
+                elseif dim(2)==1
+                    % Sparse column vector
+                    ndata=sparse(ndata(:,1),1,ndata(:,2),dim(1),prod(dim(2:end)));
+                else
+                    % Generic sparse array.
+                    ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3),dim(1),prod(dim(2:end)));
+                end
+            else
+                if(iscpx && size(ndata,2)==4)
+                    ndata(:,3)=complex(ndata(:,3),ndata(:,4));
+                end
+                ndata=sparse(ndata(:,1),ndata(:,2),ndata(:,3));
+            end
+        end
+    elseif(~isempty(strmatch('x0x5F_ArraySize_',fn)))
+        if(iscpx && size(ndata,2)==2)
+             ndata=complex(ndata(:,1),ndata(:,2));
+        end
+        ndata=reshape(ndata(:),data(j).x0x5F_ArraySize_);
+    end
+    newdata{j}=ndata;
+  end
+  if(len==1)
+      newdata=newdata{1};
+  end
+end
+
+%%-------------------------------------------------------------------------
+function object = parse_object(varargin)
+    parse_char('{');
+    object = [];
+    type='';
+    count=-1;
+    if(next_char == '$')
+        type=inStr(pos+1); % TODO
+        pos=pos+2;
+    end
+    if(next_char == '#')
+        pos=pos+1;
+        count=double(parse_number());
+    end
+    if next_char ~= '}'
+        num=0;
+        while 1
+            str = parseStr(varargin{:});
+            if isempty(str)
+                error_pos('Name of value at position %d cannot be empty');
+            end
+            %parse_char(':');
+            val = parse_value(varargin{:});
+            num=num+1;
+            eval( sprintf( 'object.%s  = val;', valid_field(str) ) );
+            if next_char == '}' || (count>=0 && num>=count)
+                break;
+            end
+            %parse_char(',');
+        end
+    end
+    if(count==-1)
+        parse_char('}');
+    end
+
+%%-------------------------------------------------------------------------
+function [cid,len]=elem_info(type)
+id=strfind('iUIlLdD',type);
+dataclass={'int8','uint8','int16','int32','int64','single','double'};
+bytelen=[1,1,2,4,8,4,8];
+if(id>0)
+    cid=dataclass{id};
+    len=bytelen(id);
+else
+    error_pos('unsupported type at position %d');
+end
+%%-------------------------------------------------------------------------
+
+
+function [data adv]=parse_block(type,count,varargin)
+global pos inStr isoct fileendian systemendian
+[cid,len]=elem_info(type);
+datastr=inStr(pos:pos+len*count-1);
+if(isoct)
+    newdata=int8(datastr);
+else
+    newdata=uint8(datastr);
+end
+id=strfind('iUIlLdD',type);
+if(id<=5 && fileendian~=systemendian)
+    newdata=swapbytes(typecast(newdata,cid));
+end
+data=typecast(newdata,cid);
+adv=double(len*count);
+
+%%-------------------------------------------------------------------------
+
+
+function object = parse_array(varargin) % JSON array is written in row-major order
+global pos inStr isoct
+    parse_char('[');
+    object = cell(0, 1);
+    dim=[];
+    type='';
+    count=-1;
+    if(next_char == '$')
+        type=inStr(pos+1);
+        pos=pos+2;
+    end
+    if(next_char == '#')
+        pos=pos+1;
+        if(next_char=='[')
+            dim=parse_array(varargin{:});
+            count=prod(double(dim));
+        else
+            count=double(parse_number());
+        end
+    end
+    if(~isempty(type))
+        if(count>=0)
+            [object adv]=parse_block(type,count,varargin{:});
+            if(~isempty(dim))
+                object=reshape(object,dim);
+            end
+            pos=pos+adv;
+            return;
+        else
+            endpos=matching_bracket(inStr,pos);
+            [cid,len]=elem_info(type);
+            count=(endpos-pos)/len;
+            [object adv]=parse_block(type,count,varargin{:});
+            pos=pos+adv;
+            parse_char(']');
+            return;
+        end
+    end
+    if next_char ~= ']'
+         while 1
+            val = parse_value(varargin{:});
+            object{end+1} = val;
+            if next_char == ']'
+                break;
+            end
+            %parse_char(',');
+         end
+    end
+    if(jsonopt('SimplifyCell',0,varargin{:})==1)
+      try
+        oldobj=object;
+        object=cell2mat(object')';
+        if(iscell(oldobj) && isstruct(object) && numel(object)>1 && jsonopt('SimplifyCellArray',1,varargin{:})==0)
+            object=oldobj;
+        elseif(size(object,1)>1 && ndims(object)==2)
+            object=object';
+        end
+      catch
+      end
+    end
+    if(count==-1)
+        parse_char(']');
+    end
+
+%%-------------------------------------------------------------------------
+
+function parse_char(c)
+    global pos inStr len
+    skip_whitespace;
+    if pos > len || inStr(pos) ~= c
+        error_pos(sprintf('Expected %c at position %%d', c));
+    else
+        pos = pos + 1;
+        skip_whitespace;
+    end
+
+%%-------------------------------------------------------------------------
+
+function c = next_char
+    global pos inStr len
+    skip_whitespace;
+    if pos > len
+        c = [];
+    else
+        c = inStr(pos);
+    end
+
+%%-------------------------------------------------------------------------
+
+function skip_whitespace
+    global pos inStr len
+    while pos <= len && isspace(inStr(pos))
+        pos = pos + 1;
+    end
+
+%%-------------------------------------------------------------------------
+function str = parseStr(varargin)
+    global pos inStr esc index_esc len_esc
+ % len, ns = length(inStr), keyboard
+    type=inStr(pos);
+    if type ~= 'S' && type ~= 'C' && type ~= 'H'
+        error_pos('String starting with S expected at position %d');
+    else
+        pos = pos + 1;
+    end
+    if(type == 'C')
+        str=inStr(pos);
+        pos=pos+1;
+        return;
+    end
+    bytelen=double(parse_number());
+    if(length(inStr)>=pos+bytelen-1)
+        str=inStr(pos:pos+bytelen-1);
+        pos=pos+bytelen;
+    else
+        error_pos('End of file while expecting end of inStr');
+    end
+
+%%-------------------------------------------------------------------------
+
+function num = parse_number(varargin)
+    global pos inStr len isoct fileendian systemendian
+    id=strfind('iUIlLdD',inStr(pos));
+    if(isempty(id))
+        error_pos('expecting a number at position %d');
+    end
+    type={'int8','uint8','int16','int32','int64','single','double'};
+    bytelen=[1,1,2,4,8,4,8];
+    datastr=inStr(pos+1:pos+bytelen(id));
+    if(isoct)
+        newdata=int8(datastr);
+    else
+        newdata=uint8(datastr);
+    end
+    if(id<=5 && fileendian~=systemendian)
+        newdata=swapbytes(typecast(newdata,type{id}));
+    end
+    num=typecast(newdata,type{id});
+    pos = pos + bytelen(id)+1;
+
+%%-------------------------------------------------------------------------
+
+function val = parse_value(varargin)
+    global pos inStr len
+    true = 1; false = 0;
+
+    switch(inStr(pos))
+        case {'S','C','H'}
+            val = parseStr(varargin{:});
+            return;
+        case '['
+            val = parse_array(varargin{:});
+            return;
+        case '{'
+            val = parse_object(varargin{:});
+            if isstruct(val)
+                if(~isempty(strmatch('x0x5F_ArrayType_',fieldnames(val), 'exact')))
+                    val=jstruct2array(val);
+                end
+            elseif isempty(val)
+                val = struct;
+            end
+            return;
+        case {'i','U','I','l','L','d','D'}
+            val = parse_number(varargin{:});
+            return;
+        case 'T'
+            val = true;
+            pos = pos + 1;
+            return;
+        case 'F'
+            val = false;
+            pos = pos + 1;
+            return;
+        case {'Z','N'}
+            val = [];
+            pos = pos + 1;
+            return;
+    end
+    error_pos('Value expected at position %d');
+%%-------------------------------------------------------------------------
+
+function error_pos(msg)
+    global pos inStr len
+    poShow = max(min([pos-15 pos-1 pos pos+20],len),1);
+    if poShow(3) == poShow(2)
+        poShow(3:4) = poShow(2)+[0 -1];  % display nothing after
+    end
+    msg = [sprintf(msg, pos) ': ' ...
+    inStr(poShow(1):poShow(2)) '<error>' inStr(poShow(3):poShow(4)) ];
+    error( ['JSONparser:invalidFormat: ' msg] );
+
+%%-------------------------------------------------------------------------
+
+function str = valid_field(str)
+global isoct
+% From MATLAB doc: field names must begin with a letter, which may be
+% followed by any combination of letters, digits, and underscores.
+% Invalid characters will be converted to underscores, and the prefix
+% "x0x[Hex code]_" will be added if the first character is not a letter.
+    pos=regexp(str,'^[^A-Za-z]','once');
+    if(~isempty(pos))
+        if(~isoct)
+            str=regexprep(str,'^([^A-Za-z])','x0x${sprintf(''%X'',unicode2native($1))}_','once');
+        else
+            str=sprintf('x0x%X_%s',char(str(1)),str(2:end));
+        end
+    end
+    if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' ))) return;  end
+    if(~isoct)
+        str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_');
+    else
+        pos=regexp(str,'[^0-9A-Za-z_]');
+        if(isempty(pos)) return; end
+        str0=str;
+        pos0=[0 pos(:)' length(str)];
+        str='';
+        for i=1:length(pos)
+            str=[str str0(pos0(i)+1:pos(i)-1) sprintf('_0x%X_',str0(pos(i)))];
+        end
+        if(pos(end)~=length(str))
+            str=[str str0(pos0(end-1)+1:pos0(end))];
+        end
+    end
+    %str(~isletter(str) & ~('0' <= str & str <= '9')) = '_';
+
+%%-------------------------------------------------------------------------
+function endpos = matching_quote(str,pos)
+len=length(str);
+while(pos<len)
+    if(str(pos)=='"')
+        if(~(pos>1 && str(pos-1)=='\'))
+            endpos=pos;
+            return;
+        end        
+    end
+    pos=pos+1;
+end
+error('unmatched quotation mark');
+%%-------------------------------------------------------------------------
+function [endpos e1l e1r maxlevel] = matching_bracket(str,pos)
+global arraytoken
+level=1;
+maxlevel=level;
+endpos=0;
+bpos=arraytoken(arraytoken>=pos);
+tokens=str(bpos);
+len=length(tokens);
+pos=1;
+e1l=[];
+e1r=[];
+while(pos<=len)
+    c=tokens(pos);
+    if(c==']')
+        level=level-1;
+        if(isempty(e1r)) e1r=bpos(pos); end
+        if(level==0)
+            endpos=bpos(pos);
+            return
+        end
+    end
+    if(c=='[')
+        if(isempty(e1l)) e1l=bpos(pos); end
+        level=level+1;
+        maxlevel=max(maxlevel,level);
+    end
+    if(c=='"')
+        pos=matching_quote(tokens,pos+1);
+    end
+    pos=pos+1;
+end
+if(endpos==0) 
+    error('unmatched "]"');
+end
+

+ 33 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/mergestruct.m

@@ -0,0 +1,33 @@
+function s=mergestruct(s1,s2)
+%
+% s=mergestruct(s1,s2)
+%
+% merge two struct objects into one
+%
+% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% date: 2012/12/22
+%
+% input:
+%      s1,s2: a struct object, s1 and s2 can not be arrays
+%
+% output:
+%      s: the merged struct object. fields in s1 and s2 will be combined in s.
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details 
+%
+% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+if(~isstruct(s1) || ~isstruct(s2))
+    error('input parameters contain non-struct');
+end
+if(length(s1)>1 || length(s2)>1)
+    error('can not merge struct arrays');
+end
+fn=fieldnames(s2);
+s=s1;
+for i=1:length(fn)              
+    s=setfield(s,fn{i},getfield(s2,fn{i}));
+end
+

+ 475 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/savejson.m

@@ -0,0 +1,475 @@
+function json=savejson(rootname,obj,varargin)
+%
+% json=savejson(rootname,obj,filename)
+%    or
+% json=savejson(rootname,obj,opt)
+% json=savejson(rootname,obj,'param1',value1,'param2',value2,...)
+%
+% convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
+% Object Notation) string
+%
+% author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% created on 2011/09/09
+%
+% $Id: savejson.m 460 2015-01-03 00:30:45Z fangq $
+%
+% input:
+%      rootname: the name of the root-object, when set to '', the root name
+%        is ignored, however, when opt.ForceRootName is set to 1 (see below),
+%        the MATLAB variable name will be used as the root name.
+%      obj: a MATLAB object (array, cell, cell array, struct, struct array).
+%      filename: a string for the file name to save the output JSON data.
+%      opt: a struct for additional options, ignore to use default values.
+%        opt can have the following fields (first in [.|.] is the default)
+%
+%        opt.FileName [''|string]: a file name to save the output JSON data
+%        opt.FloatFormat ['%.10g'|string]: format to show each numeric element
+%                         of a 1D/2D array;
+%        opt.ArrayIndent [1|0]: if 1, output explicit data array with
+%                         precedent indentation; if 0, no indentation
+%        opt.ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
+%                         array in JSON array format; if sets to 1, an
+%                         array will be shown as a struct with fields
+%                         "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
+%                         sparse arrays, the non-zero elements will be
+%                         saved to _ArrayData_ field in triplet-format i.e.
+%                         (ix,iy,val) and "_ArrayIsSparse_" will be added
+%                         with a value of 1; for a complex array, the 
+%                         _ArrayData_ array will include two columns 
+%                         (4 for sparse) to record the real and imaginary 
+%                         parts, and also "_ArrayIsComplex_":1 is added. 
+%        opt.ParseLogical [0|1]: if this is set to 1, logical array elem
+%                         will use true/false rather than 1/0.
+%        opt.NoRowBracket [1|0]: if this is set to 1, arrays with a single
+%                         numerical element will be shown without a square
+%                         bracket, unless it is the root object; if 0, square
+%                         brackets are forced for any numerical arrays.
+%        opt.ForceRootName [0|1]: when set to 1 and rootname is empty, savejson
+%                         will use the name of the passed obj variable as the 
+%                         root object name; if obj is an expression and 
+%                         does not have a name, 'root' will be used; if this 
+%                         is set to 0 and rootname is empty, the root level 
+%                         will be merged down to the lower level.
+%        opt.Inf ['"$1_Inf_"'|string]: a customized regular expression pattern
+%                         to represent +/-Inf. The matched pattern is '([-+]*)Inf'
+%                         and $1 represents the sign. For those who want to use
+%                         1e999 to represent Inf, they can set opt.Inf to '$11e999'
+%        opt.NaN ['"_NaN_"'|string]: a customized regular expression pattern
+%                         to represent NaN
+%        opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
+%                         for example, if opt.JSONP='foo', the JSON data is
+%                         wrapped inside a function call as 'foo(...);'
+%        opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
+%                         back to the string form
+%        opt.SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode.
+%        opt.Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs)
+%
+%        opt can be replaced by a list of ('param',value) pairs. The param 
+%        string is equivallent to a field in opt and is case sensitive.
+% output:
+%      json: a string in the JSON format (see http://json.org)
+%
+% examples:
+%      jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 
+%               'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
+%               'MeshTri',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
+%                          2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
+%               'MeshCreator','FangQ','MeshTitle','T6 Cube',...
+%               'SpecialData',[nan, inf, -inf]);
+%      savejson('jmesh',jsonmesh)
+%      savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g')
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details
+%
+% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+if(nargin==1)
+   varname=inputname(1);
+   obj=rootname;
+   if(isempty(varname)) 
+      varname='root';
+   end
+   rootname=varname;
+else
+   varname=inputname(2);
+end
+if(length(varargin)==1 && ischar(varargin{1}))
+   opt=struct('FileName',varargin{1});
+else
+   opt=varargin2struct(varargin{:});
+end
+opt.IsOctave=exist('OCTAVE_VERSION','builtin');
+rootisarray=0;
+rootlevel=1;
+forceroot=jsonopt('ForceRootName',0,opt);
+if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || iscell(obj)) && isempty(rootname) && forceroot==0)
+    rootisarray=1;
+    rootlevel=0;
+else
+    if(isempty(rootname))
+        rootname=varname;
+    end
+end
+if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot)
+    rootname='root';
+end
+
+whitespaces=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
+if(jsonopt('Compact',0,opt)==1)
+    whitespaces=struct('tab','','newline','','sep',',');
+end
+if(~isfield(opt,'whitespaces_'))
+    opt.whitespaces_=whitespaces;
+end
+
+nl=whitespaces.newline;
+
+json=obj2json(rootname,obj,rootlevel,opt);
+if(rootisarray)
+    json=sprintf('%s%s',json,nl);
+else
+    json=sprintf('{%s%s%s}\n',nl,json,nl);
+end
+
+jsonp=jsonopt('JSONP','',opt);
+if(~isempty(jsonp))
+    json=sprintf('%s(%s);%s',jsonp,json,nl);
+end
+
+% save to a file if FileName is set, suggested by Patrick Rapin
+if(~isempty(jsonopt('FileName','',opt)))
+    if(jsonopt('SaveBinary',0,opt)==1)
+	    fid = fopen(opt.FileName, 'wb');
+	    fwrite(fid,json);
+    else
+	    fid = fopen(opt.FileName, 'wt');
+	    fwrite(fid,json,'char');
+    end
+    fclose(fid);
+end
+
+%%-------------------------------------------------------------------------
+function txt=obj2json(name,item,level,varargin)
+
+if(iscell(item))
+    txt=cell2json(name,item,level,varargin{:});
+elseif(isstruct(item))
+    txt=struct2json(name,item,level,varargin{:});
+elseif(ischar(item))
+    txt=str2json(name,item,level,varargin{:});
+else
+    txt=mat2json(name,item,level,varargin{:});
+end
+
+%%-------------------------------------------------------------------------
+function txt=cell2json(name,item,level,varargin)
+txt='';
+if(~iscell(item))
+        error('input is not a cell');
+end
+
+dim=size(item);
+if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
+    item=reshape(item,dim(1),numel(item)/dim(1));
+    dim=size(item);
+end
+len=numel(item);
+ws=jsonopt('whitespaces_',struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n')),varargin{:});
+padding0=repmat(ws.tab,1,level);
+padding2=repmat(ws.tab,1,level+1);
+nl=ws.newline;
+if(len>1)
+    if(~isempty(name))
+        txt=sprintf('%s"%s": [%s',padding0, checkname(name,varargin{:}),nl); name=''; 
+    else
+        txt=sprintf('%s[%s',padding0,nl); 
+    end
+elseif(len==0)
+    if(~isempty(name))
+        txt=sprintf('%s"%s": []',padding0, checkname(name,varargin{:})); name=''; 
+    else
+        txt=sprintf('%s[]',padding0); 
+    end
+end
+for j=1:dim(2)
+    if(dim(1)>1) txt=sprintf('%s%s[%s',txt,padding2,nl); end
+    for i=1:dim(1)
+       txt=sprintf('%s%s',txt,obj2json(name,item{i,j},level+(dim(1)>1)+1,varargin{:}));
+       if(i<dim(1)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
+    end
+    if(dim(1)>1) txt=sprintf('%s%s%s]',txt,nl,padding2); end
+    if(j<dim(2)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
+    %if(j==dim(2)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
+end
+if(len>1) txt=sprintf('%s%s%s]',txt,nl,padding0); end
+
+%%-------------------------------------------------------------------------
+function txt=struct2json(name,item,level,varargin)
+txt='';
+if(~isstruct(item))
+	error('input is not a struct');
+end
+dim=size(item);
+if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
+    item=reshape(item,dim(1),numel(item)/dim(1));
+    dim=size(item);
+end
+len=numel(item);
+ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'));
+ws=jsonopt('whitespaces_',ws,varargin{:});
+padding0=repmat(ws.tab,1,level);
+padding2=repmat(ws.tab,1,level+1);
+padding1=repmat(ws.tab,1,level+(dim(1)>1)+(len>1));
+nl=ws.newline;
+
+if(~isempty(name)) 
+    if(len>1) txt=sprintf('%s"%s": [%s',padding0,checkname(name,varargin{:}),nl); end
+else
+    if(len>1) txt=sprintf('%s[%s',padding0,nl); end
+end
+for j=1:dim(2)
+  if(dim(1)>1) txt=sprintf('%s%s[%s',txt,padding2,nl); end
+  for i=1:dim(1)
+    names = fieldnames(item(i,j));
+    if(~isempty(name) && len==1)
+        txt=sprintf('%s%s"%s": {%s',txt,padding1, checkname(name,varargin{:}),nl); 
+    else
+        txt=sprintf('%s%s{%s',txt,padding1,nl); 
+    end
+    if(~isempty(names))
+      for e=1:length(names)
+	    txt=sprintf('%s%s',txt,obj2json(names{e},getfield(item(i,j),...
+             names{e}),level+(dim(1)>1)+1+(len>1),varargin{:}));
+        if(e<length(names)) txt=sprintf('%s%s',txt,','); end
+        txt=sprintf('%s%s',txt,nl);
+      end
+    end
+    txt=sprintf('%s%s}',txt,padding1);
+    if(i<dim(1)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
+  end
+  if(dim(1)>1) txt=sprintf('%s%s%s]',txt,nl,padding2); end
+  if(j<dim(2)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
+end
+if(len>1) txt=sprintf('%s%s%s]',txt,nl,padding0); end
+
+%%-------------------------------------------------------------------------
+function txt=str2json(name,item,level,varargin)
+txt='';
+if(~ischar(item))
+        error('input is not a string');
+end
+item=reshape(item, max(size(item),[1 0]));
+len=size(item,1);
+ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
+ws=jsonopt('whitespaces_',ws,varargin{:});
+padding1=repmat(ws.tab,1,level);
+padding0=repmat(ws.tab,1,level+1);
+nl=ws.newline;
+sep=ws.sep;
+
+if(~isempty(name)) 
+    if(len>1) txt=sprintf('%s"%s": [%s',padding1,checkname(name,varargin{:}),nl); end
+else
+    if(len>1) txt=sprintf('%s[%s',padding1,nl); end
+end
+isoct=jsonopt('IsOctave',0,varargin{:});
+for e=1:len
+    if(isoct)
+        val=regexprep(item(e,:),'\\','\\');
+        val=regexprep(val,'"','\"');
+        val=regexprep(val,'^"','\"');
+    else
+        val=regexprep(item(e,:),'\\','\\\\');
+        val=regexprep(val,'"','\\"');
+        val=regexprep(val,'^"','\\"');
+    end
+    val=escapejsonstring(val);
+    if(len==1)
+        obj=['"' checkname(name,varargin{:}) '": ' '"',val,'"'];
+	if(isempty(name)) obj=['"',val,'"']; end
+        txt=sprintf('%s%s%s%s',txt,padding1,obj);
+    else
+        txt=sprintf('%s%s%s%s',txt,padding0,['"',val,'"']);
+    end
+    if(e==len) sep=''; end
+    txt=sprintf('%s%s',txt,sep);
+end
+if(len>1) txt=sprintf('%s%s%s%s',txt,nl,padding1,']'); end
+
+%%-------------------------------------------------------------------------
+function txt=mat2json(name,item,level,varargin)
+if(~isnumeric(item) && ~islogical(item))
+        error('input is not an array');
+end
+ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
+ws=jsonopt('whitespaces_',ws,varargin{:});
+padding1=repmat(ws.tab,1,level);
+padding0=repmat(ws.tab,1,level+1);
+nl=ws.newline;
+sep=ws.sep;
+
+if(length(size(item))>2 || issparse(item) || ~isreal(item) || ...
+   isempty(item) ||jsonopt('ArrayToStruct',0,varargin{:}))
+    if(isempty(name))
+    	txt=sprintf('%s{%s%s"_ArrayType_": "%s",%s%s"_ArraySize_": %s,%s',...
+              padding1,nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl);
+    else
+    	txt=sprintf('%s"%s": {%s%s"_ArrayType_": "%s",%s%s"_ArraySize_": %s,%s',...
+              padding1,checkname(name,varargin{:}),nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl);
+    end
+else
+    if(numel(item)==1 && jsonopt('NoRowBracket',1,varargin{:})==1 && level>0)
+        numtxt=regexprep(regexprep(matdata2json(item,level+1,varargin{:}),'^\[',''),']','');
+    else
+        numtxt=matdata2json(item,level+1,varargin{:});
+    end
+    if(isempty(name))
+    	txt=sprintf('%s%s',padding1,numtxt);
+    else
+        if(numel(item)==1 && jsonopt('NoRowBracket',1,varargin{:})==1)
+           	txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),numtxt);
+        else
+    	    txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),numtxt);
+        end
+    end
+    return;
+end
+dataformat='%s%s%s%s%s';
+
+if(issparse(item))
+    [ix,iy]=find(item);
+    data=full(item(find(item)));
+    if(~isreal(item))
+       data=[real(data(:)),imag(data(:))];
+       if(size(item,1)==1)
+           % Kludge to have data's 'transposedness' match item's.
+           % (Necessary for complex row vector handling below.)
+           data=data';
+       end
+       txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sep);
+    end
+    txt=sprintf(dataformat,txt,padding0,'"_ArrayIsSparse_": ','1', sep);
+    if(size(item,1)==1)
+        % Row vector, store only column indices.
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
+           matdata2json([iy(:),data'],level+2,varargin{:}), nl);
+    elseif(size(item,2)==1)
+        % Column vector, store only row indices.
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
+           matdata2json([ix,data],level+2,varargin{:}), nl);
+    else
+        % General case, store row and column indices.
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
+           matdata2json([ix,iy,data],level+2,varargin{:}), nl);
+    end
+else
+    if(isreal(item))
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
+            matdata2json(item(:)',level+2,varargin{:}), nl);
+    else
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sep);
+        txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
+            matdata2json([real(item(:)) imag(item(:))],level+2,varargin{:}), nl);
+    end
+end
+txt=sprintf('%s%s%s',txt,padding1,'}');
+
+%%-------------------------------------------------------------------------
+function txt=matdata2json(mat,level,varargin)
+
+ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
+ws=jsonopt('whitespaces_',ws,varargin{:});
+tab=ws.tab;
+nl=ws.newline;
+
+if(size(mat,1)==1)
+    pre='';
+    post='';
+    level=level-1;
+else
+    pre=sprintf('[%s',nl);
+    post=sprintf('%s%s]',nl,repmat(tab,1,level-1));
+end
+
+if(isempty(mat))
+    txt='null';
+    return;
+end
+floatformat=jsonopt('FloatFormat','%.10g',varargin{:});
+%if(numel(mat)>1)
+    formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],%s',nl)]];
+%else
+%    formatstr=[repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf(',\n')]];
+%end
+
+if(nargin>=2 && size(mat,1)>1 && jsonopt('ArrayIndent',1,varargin{:})==1)
+    formatstr=[repmat(tab,1,level) formatstr];
+end
+
+txt=sprintf(formatstr,mat');
+txt(end-length(nl):end)=[];
+if(islogical(mat) && jsonopt('ParseLogical',0,varargin{:})==1)
+   txt=regexprep(txt,'1','true');
+   txt=regexprep(txt,'0','false');
+end
+%txt=regexprep(mat2str(mat),'\s+',',');
+%txt=regexprep(txt,';',sprintf('],\n['));
+% if(nargin>=2 && size(mat,1)>1)
+%     txt=regexprep(txt,'\[',[repmat(sprintf('\t'),1,level) '[']);
+% end
+txt=[pre txt post];
+if(any(isinf(mat(:))))
+    txt=regexprep(txt,'([-+]*)Inf',jsonopt('Inf','"$1_Inf_"',varargin{:}));
+end
+if(any(isnan(mat(:))))
+    txt=regexprep(txt,'NaN',jsonopt('NaN','"_NaN_"',varargin{:}));
+end
+
+%%-------------------------------------------------------------------------
+function newname=checkname(name,varargin)
+isunpack=jsonopt('UnpackHex',1,varargin{:});
+newname=name;
+if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once')))
+    return
+end
+if(isunpack)
+    isoct=jsonopt('IsOctave',0,varargin{:});
+    if(~isoct)
+        newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${native2unicode(hex2dec($2))}');
+    else
+        pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start');
+        pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end');
+        if(isempty(pos)) return; end
+        str0=name;
+        pos0=[0 pend(:)' length(name)];
+        newname='';
+        for i=1:length(pos)
+            newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))];
+        end
+        if(pos(end)~=length(name))
+            newname=[newname str0(pos0(end-1)+1:pos0(end))];
+        end
+    end
+end
+
+%%-------------------------------------------------------------------------
+function newstr=escapejsonstring(str)
+newstr=str;
+isoct=exist('OCTAVE_VERSION','builtin');
+if(isoct)
+   vv=sscanf(OCTAVE_VERSION,'%f');
+   if(vv(1)>=3.8) isoct=0; end
+end
+if(isoct)
+  escapechars={'\a','\f','\n','\r','\t','\v'};
+  for i=1:length(escapechars);
+    newstr=regexprep(newstr,escapechars{i},escapechars{i});
+  end
+else
+  escapechars={'\a','\b','\f','\n','\r','\t','\v'};
+  for i=1:length(escapechars);
+    newstr=regexprep(newstr,escapechars{i},regexprep(escapechars{i},'\\','\\\\'));
+  end
+end

+ 504 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/saveubjson.m

@@ -0,0 +1,504 @@
+function json=saveubjson(rootname,obj,varargin)
+%
+% json=saveubjson(rootname,obj,filename)
+%    or
+% json=saveubjson(rootname,obj,opt)
+% json=saveubjson(rootname,obj,'param1',value1,'param2',value2,...)
+%
+% convert a MATLAB object (cell, struct or array) into a Universal 
+% Binary JSON (UBJSON) binary string
+%
+% author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% created on 2013/08/17
+%
+% $Id: saveubjson.m 460 2015-01-03 00:30:45Z fangq $
+%
+% input:
+%      rootname: the name of the root-object, when set to '', the root name
+%        is ignored, however, when opt.ForceRootName is set to 1 (see below),
+%        the MATLAB variable name will be used as the root name.
+%      obj: a MATLAB object (array, cell, cell array, struct, struct array)
+%      filename: a string for the file name to save the output UBJSON data
+%      opt: a struct for additional options, ignore to use default values.
+%        opt can have the following fields (first in [.|.] is the default)
+%
+%        opt.FileName [''|string]: a file name to save the output JSON data
+%        opt.ArrayToStruct[0|1]: when set to 0, saveubjson outputs 1D/2D
+%                         array in JSON array format; if sets to 1, an
+%                         array will be shown as a struct with fields
+%                         "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
+%                         sparse arrays, the non-zero elements will be
+%                         saved to _ArrayData_ field in triplet-format i.e.
+%                         (ix,iy,val) and "_ArrayIsSparse_" will be added
+%                         with a value of 1; for a complex array, the 
+%                         _ArrayData_ array will include two columns 
+%                         (4 for sparse) to record the real and imaginary 
+%                         parts, and also "_ArrayIsComplex_":1 is added. 
+%        opt.ParseLogical [1|0]: if this is set to 1, logical array elem
+%                         will use true/false rather than 1/0.
+%        opt.NoRowBracket [1|0]: if this is set to 1, arrays with a single
+%                         numerical element will be shown without a square
+%                         bracket, unless it is the root object; if 0, square
+%                         brackets are forced for any numerical arrays.
+%        opt.ForceRootName [0|1]: when set to 1 and rootname is empty, saveubjson
+%                         will use the name of the passed obj variable as the 
+%                         root object name; if obj is an expression and 
+%                         does not have a name, 'root' will be used; if this 
+%                         is set to 0 and rootname is empty, the root level 
+%                         will be merged down to the lower level.
+%        opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
+%                         for example, if opt.JSON='foo', the JSON data is
+%                         wrapped inside a function call as 'foo(...);'
+%        opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
+%                         back to the string form
+%
+%        opt can be replaced by a list of ('param',value) pairs. The param 
+%        string is equivallent to a field in opt and is case sensitive.
+% output:
+%      json: a binary string in the UBJSON format (see http://ubjson.org)
+%
+% examples:
+%      jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 
+%               'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
+%               'MeshTri',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
+%                          2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
+%               'MeshCreator','FangQ','MeshTitle','T6 Cube',...
+%               'SpecialData',[nan, inf, -inf]);
+%      saveubjson('jsonmesh',jsonmesh)
+%      saveubjson('jsonmesh',jsonmesh,'meshdata.ubj')
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details
+%
+% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+if(nargin==1)
+   varname=inputname(1);
+   obj=rootname;
+   if(isempty(varname)) 
+      varname='root';
+   end
+   rootname=varname;
+else
+   varname=inputname(2);
+end
+if(length(varargin)==1 && ischar(varargin{1}))
+   opt=struct('FileName',varargin{1});
+else
+   opt=varargin2struct(varargin{:});
+end
+opt.IsOctave=exist('OCTAVE_VERSION','builtin');
+rootisarray=0;
+rootlevel=1;
+forceroot=jsonopt('ForceRootName',0,opt);
+if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || iscell(obj)) && isempty(rootname) && forceroot==0)
+    rootisarray=1;
+    rootlevel=0;
+else
+    if(isempty(rootname))
+        rootname=varname;
+    end
+end
+if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot)
+    rootname='root';
+end
+json=obj2ubjson(rootname,obj,rootlevel,opt);
+if(~rootisarray)
+    json=['{' json '}'];
+end
+
+jsonp=jsonopt('JSONP','',opt);
+if(~isempty(jsonp))
+    json=[jsonp '(' json ')'];
+end
+
+% save to a file if FileName is set, suggested by Patrick Rapin
+if(~isempty(jsonopt('FileName','',opt)))
+    fid = fopen(opt.FileName, 'wb');
+    fwrite(fid,json);
+    fclose(fid);
+end
+
+%%-------------------------------------------------------------------------
+function txt=obj2ubjson(name,item,level,varargin)
+
+if(iscell(item))
+    txt=cell2ubjson(name,item,level,varargin{:});
+elseif(isstruct(item))
+    txt=struct2ubjson(name,item,level,varargin{:});
+elseif(ischar(item))
+    txt=str2ubjson(name,item,level,varargin{:});
+else
+    txt=mat2ubjson(name,item,level,varargin{:});
+end
+
+%%-------------------------------------------------------------------------
+function txt=cell2ubjson(name,item,level,varargin)
+txt='';
+if(~iscell(item))
+        error('input is not a cell');
+end
+
+dim=size(item);
+if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
+    item=reshape(item,dim(1),numel(item)/dim(1));
+    dim=size(item);
+end
+len=numel(item); % let's handle 1D cell first
+if(len>1) 
+    if(~isempty(name))
+        txt=[S_(checkname(name,varargin{:})) '[']; name=''; 
+    else
+        txt='['; 
+    end
+elseif(len==0)
+    if(~isempty(name))
+        txt=[S_(checkname(name,varargin{:})) 'Z']; name=''; 
+    else
+        txt='Z'; 
+    end
+end
+for j=1:dim(2)
+    if(dim(1)>1) txt=[txt '[']; end
+    for i=1:dim(1)
+       txt=[txt obj2ubjson(name,item{i,j},level+(len>1),varargin{:})];
+    end
+    if(dim(1)>1) txt=[txt ']']; end
+end
+if(len>1) txt=[txt ']']; end
+
+%%-------------------------------------------------------------------------
+function txt=struct2ubjson(name,item,level,varargin)
+txt='';
+if(~isstruct(item))
+	error('input is not a struct');
+end
+dim=size(item);
+if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
+    item=reshape(item,dim(1),numel(item)/dim(1));
+    dim=size(item);
+end
+len=numel(item);
+
+if(~isempty(name)) 
+    if(len>1) txt=[S_(checkname(name,varargin{:})) '[']; end
+else
+    if(len>1) txt='['; end
+end
+for j=1:dim(2)
+  if(dim(1)>1) txt=[txt '[']; end
+  for i=1:dim(1)
+     names = fieldnames(item(i,j));
+     if(~isempty(name) && len==1)
+        txt=[txt S_(checkname(name,varargin{:})) '{']; 
+     else
+        txt=[txt '{']; 
+     end
+     if(~isempty(names))
+       for e=1:length(names)
+	     txt=[txt obj2ubjson(names{e},getfield(item(i,j),...
+             names{e}),level+(dim(1)>1)+1+(len>1),varargin{:})];
+       end
+     end
+     txt=[txt '}'];
+  end
+  if(dim(1)>1) txt=[txt ']']; end
+end
+if(len>1) txt=[txt ']']; end
+
+%%-------------------------------------------------------------------------
+function txt=str2ubjson(name,item,level,varargin)
+txt='';
+if(~ischar(item))
+        error('input is not a string');
+end
+item=reshape(item, max(size(item),[1 0]));
+len=size(item,1);
+
+if(~isempty(name)) 
+    if(len>1) txt=[S_(checkname(name,varargin{:})) '[']; end
+else
+    if(len>1) txt='['; end
+end
+isoct=jsonopt('IsOctave',0,varargin{:});
+for e=1:len
+    val=item(e,:);
+    if(len==1)
+        obj=['' S_(checkname(name,varargin{:})) '' '',S_(val),''];
+	if(isempty(name)) obj=['',S_(val),'']; end
+        txt=[txt,'',obj];
+    else
+        txt=[txt,'',['',S_(val),'']];
+    end
+end
+if(len>1) txt=[txt ']']; end
+
+%%-------------------------------------------------------------------------
+function txt=mat2ubjson(name,item,level,varargin)
+if(~isnumeric(item) && ~islogical(item))
+        error('input is not an array');
+end
+
+if(length(size(item))>2 || issparse(item) || ~isreal(item) || ...
+   isempty(item) || jsonopt('ArrayToStruct',0,varargin{:}))
+      cid=I_(uint32(max(size(item))));
+      if(isempty(name))
+    	txt=['{' S_('_ArrayType_'),S_(class(item)),S_('_ArraySize_'),I_a(size(item),cid(1)) ];
+      else
+          if(isempty(item))
+              txt=[S_(checkname(name,varargin{:})),'Z'];
+              return;
+          else
+    	      txt=[S_(checkname(name,varargin{:})),'{',S_('_ArrayType_'),S_(class(item)),S_('_ArraySize_'),I_a(size(item),cid(1))];
+          end
+      end
+else
+    if(isempty(name))
+    	txt=matdata2ubjson(item,level+1,varargin{:});
+    else
+        if(numel(item)==1 && jsonopt('NoRowBracket',1,varargin{:})==1)
+            numtxt=regexprep(regexprep(matdata2ubjson(item,level+1,varargin{:}),'^\[',''),']','');
+           	txt=[S_(checkname(name,varargin{:})) numtxt];
+        else
+    	    txt=[S_(checkname(name,varargin{:})),matdata2ubjson(item,level+1,varargin{:})];
+        end
+    end
+    return;
+end
+if(issparse(item))
+    [ix,iy]=find(item);
+    data=full(item(find(item)));
+    if(~isreal(item))
+       data=[real(data(:)),imag(data(:))];
+       if(size(item,1)==1)
+           % Kludge to have data's 'transposedness' match item's.
+           % (Necessary for complex row vector handling below.)
+           data=data';
+       end
+       txt=[txt,S_('_ArrayIsComplex_'),'T'];
+    end
+    txt=[txt,S_('_ArrayIsSparse_'),'T'];
+    if(size(item,1)==1)
+        % Row vector, store only column indices.
+        txt=[txt,S_('_ArrayData_'),...
+           matdata2ubjson([iy(:),data'],level+2,varargin{:})];
+    elseif(size(item,2)==1)
+        % Column vector, store only row indices.
+        txt=[txt,S_('_ArrayData_'),...
+           matdata2ubjson([ix,data],level+2,varargin{:})];
+    else
+        % General case, store row and column indices.
+        txt=[txt,S_('_ArrayData_'),...
+           matdata2ubjson([ix,iy,data],level+2,varargin{:})];
+    end
+else
+    if(isreal(item))
+        txt=[txt,S_('_ArrayData_'),...
+            matdata2ubjson(item(:)',level+2,varargin{:})];
+    else
+        txt=[txt,S_('_ArrayIsComplex_'),'T'];
+        txt=[txt,S_('_ArrayData_'),...
+            matdata2ubjson([real(item(:)) imag(item(:))],level+2,varargin{:})];
+    end
+end
+txt=[txt,'}'];
+
+%%-------------------------------------------------------------------------
+function txt=matdata2ubjson(mat,level,varargin)
+if(isempty(mat))
+    txt='Z';
+    return;
+end
+if(size(mat,1)==1)
+    level=level-1;
+end
+type='';
+hasnegtive=(mat<0);
+if(isa(mat,'integer') || isinteger(mat) || (isfloat(mat) && all(mod(mat(:),1) == 0)))
+    if(isempty(hasnegtive))
+       if(max(mat(:))<=2^8)
+           type='U';
+       end
+    end
+    if(isempty(type))
+        % todo - need to consider negative ones separately
+        id= histc(abs(max(mat(:))),[0 2^7 2^15 2^31 2^63]);
+        if(isempty(find(id)))
+            error('high-precision data is not yet supported');
+        end
+        key='iIlL';
+	type=key(find(id));
+    end
+    txt=[I_a(mat(:),type,size(mat))];
+elseif(islogical(mat))
+    logicalval='FT';
+    if(numel(mat)==1)
+        txt=logicalval(mat+1);
+    else
+        txt=['[$U#' I_a(size(mat),'l') typecast(swapbytes(uint8(mat(:)')),'uint8')];
+    end
+else
+    if(numel(mat)==1)
+        txt=['[' D_(mat) ']'];
+    else
+        txt=D_a(mat(:),'D',size(mat));
+    end
+end
+
+%txt=regexprep(mat2str(mat),'\s+',',');
+%txt=regexprep(txt,';',sprintf('],['));
+% if(nargin>=2 && size(mat,1)>1)
+%     txt=regexprep(txt,'\[',[repmat(sprintf('\t'),1,level) '[']);
+% end
+if(any(isinf(mat(:))))
+    txt=regexprep(txt,'([-+]*)Inf',jsonopt('Inf','"$1_Inf_"',varargin{:}));
+end
+if(any(isnan(mat(:))))
+    txt=regexprep(txt,'NaN',jsonopt('NaN','"_NaN_"',varargin{:}));
+end
+
+%%-------------------------------------------------------------------------
+function newname=checkname(name,varargin)
+isunpack=jsonopt('UnpackHex',1,varargin{:});
+newname=name;
+if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once')))
+    return
+end
+if(isunpack)
+    isoct=jsonopt('IsOctave',0,varargin{:});
+    if(~isoct)
+        newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${native2unicode(hex2dec($2))}');
+    else
+        pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start');
+        pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end');
+        if(isempty(pos)) return; end
+        str0=name;
+        pos0=[0 pend(:)' length(name)];
+        newname='';
+        for i=1:length(pos)
+            newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))];
+        end
+        if(pos(end)~=length(name))
+            newname=[newname str0(pos0(end-1)+1:pos0(end))];
+        end
+    end
+end
+%%-------------------------------------------------------------------------
+function val=S_(str)
+if(length(str)==1)
+  val=['C' str];
+else
+  val=['S' I_(int32(length(str))) str];
+end
+%%-------------------------------------------------------------------------
+function val=I_(num)
+if(~isinteger(num))
+    error('input is not an integer');
+end
+if(num>=0 && num<255)
+   val=['U' data2byte(swapbytes(cast(num,'uint8')),'uint8')];
+   return;
+end
+key='iIlL';
+cid={'int8','int16','int32','int64'};
+for i=1:4
+  if((num>0 && num<2^(i*8-1)) || (num<0 && num>=-2^(i*8-1)))
+    val=[key(i) data2byte(swapbytes(cast(num,cid{i})),'uint8')];
+    return;
+  end
+end
+error('unsupported integer');
+
+%%-------------------------------------------------------------------------
+function val=D_(num)
+if(~isfloat(num))
+    error('input is not a float');
+end
+
+if(isa(num,'single'))
+  val=['d' data2byte(num,'uint8')];
+else
+  val=['D' data2byte(num,'uint8')];
+end
+%%-------------------------------------------------------------------------
+function data=I_a(num,type,dim,format)
+id=find(ismember('iUIlL',type));
+
+if(id==0)
+  error('unsupported integer array');
+end
+
+% based on UBJSON specs, all integer types are stored in big endian format
+
+if(id==1)
+  data=data2byte(swapbytes(int8(num)),'uint8');
+  blen=1;
+elseif(id==2)
+  data=data2byte(swapbytes(uint8(num)),'uint8');
+  blen=1;
+elseif(id==3)
+  data=data2byte(swapbytes(int16(num)),'uint8');
+  blen=2;
+elseif(id==4)
+  data=data2byte(swapbytes(int32(num)),'uint8');
+  blen=4;
+elseif(id==5)
+  data=data2byte(swapbytes(int64(num)),'uint8');
+  blen=8;
+end
+
+if(nargin>=3 && length(dim)>=2 && prod(dim)~=dim(2))
+  format='opt';
+end
+if((nargin<4 || strcmp(format,'opt')) && numel(num)>1)
+  if(nargin>=3 && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2))))
+      cid=I_(uint32(max(dim)));
+      data=['$' type '#' I_a(dim,cid(1)) data(:)'];
+  else
+      data=['$' type '#' I_(int32(numel(data)/blen)) data(:)'];
+  end
+  data=['[' data(:)'];
+else
+  data=reshape(data,blen,numel(data)/blen);
+  data(2:blen+1,:)=data;
+  data(1,:)=type;
+  data=data(:)';
+  data=['[' data(:)' ']'];
+end
+%%-------------------------------------------------------------------------
+function data=D_a(num,type,dim,format)
+id=find(ismember('dD',type));
+
+if(id==0)
+  error('unsupported float array');
+end
+
+if(id==1)
+  data=data2byte(single(num),'uint8');
+elseif(id==2)
+  data=data2byte(double(num),'uint8');
+end
+
+if(nargin>=3 && length(dim)>=2 && prod(dim)~=dim(2))
+  format='opt';
+end
+if((nargin<4 || strcmp(format,'opt')) && numel(num)>1)
+  if(nargin>=3 && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2))))
+      cid=I_(uint32(max(dim)));
+      data=['$' type '#' I_a(dim,cid(1)) data(:)'];
+  else
+      data=['$' type '#' I_(int32(numel(data)/(id*4))) data(:)'];
+  end
+  data=['[' data];
+else
+  data=reshape(data,(id*4),length(data)/(id*4));
+  data(2:(id*4+1),:)=data;
+  data(1,:)=type;
+  data=data(:)';
+  data=['[' data(:)' ']'];
+end
+%%-------------------------------------------------------------------------
+function bytes=data2byte(varargin)
+bytes=typecast(varargin{:});
+bytes=bytes(:)';

+ 40 - 0
machine learning/machine-learning-ex5/ex5/lib/jsonlab/varargin2struct.m

@@ -0,0 +1,40 @@
+function opt=varargin2struct(varargin)
+%
+% opt=varargin2struct('param1',value1,'param2',value2,...)
+%   or
+% opt=varargin2struct(...,optstruct,...)
+%
+% convert a series of input parameters into a structure
+%
+% authors:Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
+% date: 2012/12/22
+%
+% input:
+%      'param', value: the input parameters should be pairs of a string and a value
+%       optstruct: if a parameter is a struct, the fields will be merged to the output struct
+%
+% output:
+%      opt: a struct where opt.param1=value1, opt.param2=value2 ...
+%
+% license:
+%     BSD, see LICENSE_BSD.txt files for details 
+%
+% -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
+%
+
+len=length(varargin);
+opt=struct;
+if(len==0) return; end
+i=1;
+while(i<=len)
+    if(isstruct(varargin{i}))
+        opt=mergestruct(opt,varargin{i});
+    elseif(ischar(varargin{i}) && i<len)
+        opt=setfield(opt,varargin{i},varargin{i+1});
+        i=i+1;
+    else
+        error('input must be in the form of ...,''name'',value,... pairs or structs');
+    end
+    i=i+1;
+end
+

+ 30 - 0
machine learning/machine-learning-ex5/ex5/lib/makeValidFieldName.m

@@ -0,0 +1,30 @@
+function str = makeValidFieldName(str)
+% From MATLAB doc: field names must begin with a letter, which may be
+% followed by any combination of letters, digits, and underscores.
+% Invalid characters will be converted to underscores, and the prefix
+% "x0x[Hex code]_" will be added if the first character is not a letter.
+    isoct=exist('OCTAVE_VERSION','builtin');
+    pos=regexp(str,'^[^A-Za-z]','once');
+    if(~isempty(pos))
+        if(~isoct)
+            str=regexprep(str,'^([^A-Za-z])','x0x${sprintf(''%X'',unicode2native($1))}_','once');
+        else
+            str=sprintf('x0x%X_%s',char(str(1)),str(2:end));
+        end
+    end
+    if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' ))) return;  end
+    if(~isoct)
+        str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_');
+    else
+        pos=regexp(str,'[^0-9A-Za-z_]');
+        if(isempty(pos)) return; end
+        str0=str;
+        pos0=[0 pos(:)' length(str)];
+        str='';
+        for i=1:length(pos)
+            str=[str str0(pos0(i)+1:pos(i)-1) sprintf('_0x%X_',str0(pos(i)))];
+        end
+        if(pos(end)~=length(str))
+            str=[str str0(pos0(end-1)+1:pos0(end))];
+        end
+    end

+ 179 - 0
machine learning/machine-learning-ex5/ex5/lib/submitWithConfiguration.m

@@ -0,0 +1,179 @@
+function submitWithConfiguration(conf)
+  addpath('./lib/jsonlab');
+
+  parts = parts(conf);
+
+  fprintf('== Submitting solutions | %s...\n', conf.itemName);
+
+  tokenFile = 'token.mat';
+  if exist(tokenFile, 'file')
+    load(tokenFile);
+    [email token] = promptToken(email, token, tokenFile);
+  else
+    [email token] = promptToken('', '', tokenFile);
+  end
+
+  if isempty(token)
+    fprintf('!! Submission Cancelled\n');
+    return
+  end
+
+  try
+    response = submitParts(conf, email, token, parts);
+  catch
+    e = lasterror();
+    fprintf('\n!! Submission failed: %s\n', e.message);
+    fprintf('\n\nFunction: %s\nFileName: %s\nLineNumber: %d\n', ...
+      e.stack(1,1).name, e.stack(1,1).file, e.stack(1,1).line);
+    fprintf('\nPlease correct your code and resubmit.\n');
+    return
+  end
+
+  if isfield(response, 'errorMessage')
+    fprintf('!! Submission failed: %s\n', response.errorMessage);
+  elseif isfield(response, 'errorCode')
+    fprintf('!! Submission failed: %s\n', response.message);
+  else
+    showFeedback(parts, response);
+    save(tokenFile, 'email', 'token');
+  end
+end
+
+function [email token] = promptToken(email, existingToken, tokenFile)
+  if (~isempty(email) && ~isempty(existingToken))
+    prompt = sprintf( ...
+      'Use token from last successful submission (%s)? (Y/n): ', ...
+      email);
+    reenter = input(prompt, 's');
+
+    if (isempty(reenter) || reenter(1) == 'Y' || reenter(1) == 'y')
+      token = existingToken;
+      return;
+    else
+      delete(tokenFile);
+    end
+  end
+  email = input('Login (email address): ', 's');
+  token = input('Token: ', 's');
+end
+
+function isValid = isValidPartOptionIndex(partOptions, i)
+  isValid = (~isempty(i)) && (1 <= i) && (i <= numel(partOptions));
+end
+
+function response = submitParts(conf, email, token, parts)
+  body = makePostBody(conf, email, token, parts);
+  submissionUrl = submissionUrl();
+
+  responseBody = getResponse(submissionUrl, body);
+  jsonResponse = validateResponse(responseBody);
+  response = loadjson(jsonResponse);
+end
+
+function body = makePostBody(conf, email, token, parts)
+  bodyStruct.assignmentSlug = conf.assignmentSlug;
+  bodyStruct.submitterEmail = email;
+  bodyStruct.secret = token;
+  bodyStruct.parts = makePartsStruct(conf, parts);
+
+  opt.Compact = 1;
+  body = savejson('', bodyStruct, opt);
+end
+
+function partsStruct = makePartsStruct(conf, parts)
+  for part = parts
+    partId = part{:}.id;
+    fieldName = makeValidFieldName(partId);
+    outputStruct.output = conf.output(partId);
+    partsStruct.(fieldName) = outputStruct;
+  end
+end
+
+function [parts] = parts(conf)
+  parts = {};
+  for partArray = conf.partArrays
+    part.id = partArray{:}{1};
+    part.sourceFiles = partArray{:}{2};
+    part.name = partArray{:}{3};
+    parts{end + 1} = part;
+  end
+end
+
+function showFeedback(parts, response)
+  fprintf('== \n');
+  fprintf('== %43s | %9s | %-s\n', 'Part Name', 'Score', 'Feedback');
+  fprintf('== %43s | %9s | %-s\n', '---------', '-----', '--------');
+  for part = parts
+    score = '';
+    partFeedback = '';
+    partFeedback = response.partFeedbacks.(makeValidFieldName(part{:}.id));
+    partEvaluation = response.partEvaluations.(makeValidFieldName(part{:}.id));
+    score = sprintf('%d / %3d', partEvaluation.score, partEvaluation.maxScore);
+    fprintf('== %43s | %9s | %-s\n', part{:}.name, score, partFeedback);
+  end
+  evaluation = response.evaluation;
+  totalScore = sprintf('%d / %d', evaluation.score, evaluation.maxScore);
+  fprintf('==                                   --------------------------------\n');
+  fprintf('== %43s | %9s | %-s\n', '', totalScore, '');
+  fprintf('== \n');
+end
+
+% use urlread or curl to send submit results to the grader and get a response
+function response = getResponse(url, body)
+% try using urlread() and a secure connection
+  params = {'jsonBody', body};
+  [response, success] = urlread(url, 'post', params);
+
+  if (success == 0)
+    % urlread didn't work, try curl & the peer certificate patch
+    if ispc
+      % testing note: use 'jsonBody =' for a test case
+      json_command = sprintf('echo jsonBody=%s | curl -k -X POST -d @- %s', body, url);
+    else
+      % it's linux/OS X, so use the other form
+      json_command = sprintf('echo ''jsonBody=%s'' | curl -k -X POST -d @- %s', body, url);
+    end
+    % get the response body for the peer certificate patch method
+    [code, response] = system(json_command);
+    % test the success code
+    if (code ~= 0)
+      fprintf('[error] submission with curl() was not successful\n');
+    end
+  end
+end
+
+% validate the grader's response
+function response = validateResponse(resp)
+  % test if the response is json or an HTML page
+  isJson = length(resp) > 0 && resp(1) == '{';
+  isHtml = findstr(lower(resp), '<html');
+
+  if (isJson)
+    response = resp;
+  elseif (isHtml)
+    % the response is html, so it's probably an error message
+    printHTMLContents(resp);
+    error('Grader response is an HTML message');
+  else
+    error('Grader sent no response');
+  end
+end
+
+% parse a HTML response and print it's contents
+function printHTMLContents(response)
+  strippedResponse = regexprep(response, '<[^>]+>', ' ');
+  strippedResponse = regexprep(strippedResponse, '[\t ]+', ' ');
+  fprintf(strippedResponse);
+end
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Service configuration
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+function submissionUrl = submissionUrl()
+  submissionUrl = 'https://www-origin.coursera.org/api/onDemandProgrammingImmediateFormSubmissions.v1';
+end

+ 39 - 0
machine learning/machine-learning-ex5/ex5/linearRegCostFunction.m

@@ -0,0 +1,39 @@
+function [J, grad] = linearRegCostFunction(X, y, theta, lambda)
+%LINEARREGCOSTFUNCTION Compute cost and gradient for regularized linear 
+%regression with multiple variables
+%   [J, grad] = LINEARREGCOSTFUNCTION(X, y, theta, lambda) computes the 
+%   cost of using theta as the parameter for linear regression to fit the 
+%   data points in X and y. Returns the cost in J and the gradient in grad
+
+% Initialize some useful values
+m = length(y); % number of training examples
+
+% You need to return the following variables correctly 
+J = 0;
+grad = zeros(size(theta));
+
+% ====================== YOUR CODE HERE ======================
+% Instructions: Compute the cost and gradient of regularized linear 
+%               regression for a particular choice of theta.
+%
+%               You should set J to the cost and grad to the gradient.
+%
+h_theta = X * theta - y;
+J = 1 / (2 * m) * sum (h_theta .^2) + lambda / (2 * m) * sum(theta(2:end) .^2);
+
+reg = lambda / m * theta .* [0; ones(rows(theta)-1, 1)];
+reg
+grad = 1 / m * sum(X' * h_theta ) + reg;
+
+
+
+
+
+
+
+
+% =========================================================================
+
+grad = grad(:);
+
+end

+ 23 - 0
machine learning/machine-learning-ex5/ex5/myex5.m

@@ -0,0 +1,23 @@
+% =========== Part 2: Regularized Linear Regression Cost =============
+%  You should now implement the cost function for regularized linear 
+%  regression. 
+%
+
+theta = [1 ; 1];
+J = linearRegCostFunction([ones(m, 1) X], y, theta, 1);
+
+fprintf(['Cost at theta = [1 ; 1]: %f '...
+         '\n(this value should be about 303.993192)\n'], J);
+
+fprintf('Program paused. Press enter to continue.\n');
+
+theta = [1 ; 1];
+[J, grad] = linearRegCostFunction([ones(m, 1) X], y, theta, 1);
+
+fprintf(['Gradient at theta = [1 ; 1]:  [%f; %f] '...
+         '\n(this value should be about [-15.303016; 598.250744])\n'], ...
+         grad(1), grad(2));
+
+fprintf('Program paused. Press enter to continue.\n');
+
+

+ 28 - 0
machine learning/machine-learning-ex5/ex5/plotFit.m

@@ -0,0 +1,28 @@
+function plotFit(min_x, max_x, mu, sigma, theta, p)
+%PLOTFIT Plots a learned polynomial regression fit over an existing figure.
+%Also works with linear regression.
+%   PLOTFIT(min_x, max_x, mu, sigma, theta, p) plots the learned polynomial
+%   fit with power p and feature normalization (mu, sigma).
+
+% Hold on to the current figure
+hold on;
+
+% We plot a range slightly bigger than the min and max values to get
+% an idea of how the fit will vary outside the range of the data points
+x = (min_x - 15: 0.05 : max_x + 25)';
+
+% Map the X values 
+X_poly = polyFeatures(x, p);
+X_poly = bsxfun(@minus, X_poly, mu);
+X_poly = bsxfun(@rdivide, X_poly, sigma);
+
+% Add ones
+X_poly = [ones(size(x, 1), 1) X_poly];
+
+% Plot
+plot(x, X_poly * theta, '--', 'LineWidth', 2)
+
+% Hold off to the current figure
+hold off
+
+end

+ 25 - 0
machine learning/machine-learning-ex5/ex5/polyFeatures.m

@@ -0,0 +1,25 @@
+function [X_poly] = polyFeatures(X, p)
+%POLYFEATURES Maps X (1D vector) into the p-th power
+%   [X_poly] = POLYFEATURES(X, p) takes a data matrix X (size m x 1) and
+%   maps each example into its polynomial features where
+%   X_poly(i, :) = [X(i) X(i).^2 X(i).^3 ...  X(i).^p];
+%
+
+
+% You need to return the following variables correctly.
+X_poly = zeros(numel(X), p);
+
+% ====================== YOUR CODE HERE ======================
+% Instructions: Given a vector X, return a matrix X_poly where the p-th 
+%               column of X contains the values of X to the p-th power.
+%
+% 
+
+
+
+
+
+
+% =========================================================================
+
+end

+ 63 - 0
machine learning/machine-learning-ex5/ex5/submit.m

@@ -0,0 +1,63 @@
+function submit()
+  addpath('./lib');
+
+  conf.assignmentSlug = 'regularized-linear-regression-and-bias-variance';
+  conf.itemName = 'Regularized Linear Regression and Bias/Variance';
+  conf.partArrays = { ...
+    { ...
+      '1', ...
+      { 'linearRegCostFunction.m' }, ...
+      'Regularized Linear Regression Cost Function', ...
+    }, ...
+    { ...
+      '2', ...
+      { 'linearRegCostFunction.m' }, ...
+      'Regularized Linear Regression Gradient', ...
+    }, ...
+    { ...
+      '3', ...
+      { 'learningCurve.m' }, ...
+      'Learning Curve', ...
+    }, ...
+    { ...
+      '4', ...
+      { 'polyFeatures.m' }, ...
+      'Polynomial Feature Mapping', ...
+    }, ...
+    { ...
+      '5', ...
+      { 'validationCurve.m' }, ...
+      'Validation Curve', ...
+    }, ...
+  };
+  conf.output = @output;
+
+  submitWithConfiguration(conf);
+end
+
+function out = output(partId, auxstring)
+  % Random Test Cases
+  X = [ones(10,1) sin(1:1.5:15)' cos(1:1.5:15)'];
+  y = sin(1:3:30)';
+  Xval = [ones(10,1) sin(0:1.5:14)' cos(0:1.5:14)'];
+  yval = sin(1:10)';
+  if partId == '1'
+    [J] = linearRegCostFunction(X, y, [0.1 0.2 0.3]', 0.5);
+    out = sprintf('%0.5f ', J);
+  elseif partId == '2'
+    [J, grad] = linearRegCostFunction(X, y, [0.1 0.2 0.3]', 0.5);
+    out = sprintf('%0.5f ', grad);
+  elseif partId == '3'
+    [error_train, error_val] = ...
+        learningCurve(X, y, Xval, yval, 1);
+    out = sprintf('%0.5f ', [error_train(:); error_val(:)]);
+  elseif partId == '4'
+    [X_poly] = polyFeatures(X(2,:)', 8);
+    out = sprintf('%0.5f ', X_poly);
+  elseif partId == '5'
+    [lambda_vec, error_train, error_val] = ...
+        validationCurve(X, y, Xval, yval);
+    out = sprintf('%0.5f ', ...
+        [lambda_vec(:); error_train(:); error_val(:)]);
+  end 
+end

+ 15 - 0
machine learning/machine-learning-ex5/ex5/token.mat

@@ -0,0 +1,15 @@
+# Created by Octave 4.2.2, Tue Nov 20 00:07:44 2018 HKT <astron@astron>
+# name: email
+# type: sq_string
+# elements: 1
+# length: 20
+larry1chan@gmail.com
+
+
+# name: token
+# type: sq_string
+# elements: 1
+# length: 16
+CLfSg3sPAa1sbNvm
+
+

+ 21 - 0
machine learning/machine-learning-ex5/ex5/trainLinearReg.m

@@ -0,0 +1,21 @@
+function [theta] = trainLinearReg(X, y, lambda)
+%TRAINLINEARREG Trains linear regression given a dataset (X, y) and a
+%regularization parameter lambda
+%   [theta] = TRAINLINEARREG (X, y, lambda) trains linear regression using
+%   the dataset (X, y) and regularization parameter lambda. Returns the
+%   trained parameters theta.
+%
+
+% Initialize Theta
+initial_theta = zeros(size(X, 2), 1); 
+
+% Create "short hand" for the cost function to be minimized
+costFunction = @(t) linearRegCostFunction(X, y, t, lambda);
+
+% Now, costFunction is a function that takes in only one argument
+options = optimset('MaxIter', 200, 'GradObj', 'on');
+
+% Minimize using fmincg
+theta = fmincg(costFunction, initial_theta, options);
+
+end

+ 53 - 0
machine learning/machine-learning-ex5/ex5/validationCurve.m

@@ -0,0 +1,53 @@
+function [lambda_vec, error_train, error_val] = ...
+    validationCurve(X, y, Xval, yval)
+%VALIDATIONCURVE Generate the train and validation errors needed to
+%plot a validation curve that we can use to select lambda
+%   [lambda_vec, error_train, error_val] = ...
+%       VALIDATIONCURVE(X, y, Xval, yval) returns the train
+%       and validation errors (in error_train, error_val)
+%       for different values of lambda. You are given the training set (X,
+%       y) and validation set (Xval, yval).
+%
+
+% Selected values of lambda (you should not change this)
+lambda_vec = [0 0.001 0.003 0.01 0.03 0.1 0.3 1 3 10]';
+
+% You need to return these variables correctly.
+error_train = zeros(length(lambda_vec), 1);
+error_val = zeros(length(lambda_vec), 1);
+
+% ====================== YOUR CODE HERE ======================
+% Instructions: Fill in this function to return training errors in 
+%               error_train and the validation errors in error_val. The 
+%               vector lambda_vec contains the different lambda parameters 
+%               to use for each calculation of the errors, i.e, 
+%               error_train(i), and error_val(i) should give 
+%               you the errors obtained after training with 
+%               lambda = lambda_vec(i)
+%
+% Note: You can loop over lambda_vec with the following:
+%
+%       for i = 1:length(lambda_vec)
+%           lambda = lambda_vec(i);
+%           % Compute train / val errors when training linear 
+%           % regression with regularization parameter lambda
+%           % You should store the result in error_train(i)
+%           % and error_val(i)
+%           ....
+%           
+%       end
+%
+%
+
+
+
+
+
+
+
+
+
+
+% =========================================================================
+
+end