Code and Output

Code 8.1.1:

% College_Admissions_5

% Assuming that SATs and GPAs are related to IQs,
% this program generates dummy data for SATs, GPAs, 
% Extra- curriculars (EC), and distance (Dist) from the
% college, giving larger scores to greater  distance from
% the college (for geographical diversity).
% The SATS and GPAs are summed, each of the  student's
% three new scores (Acad, EC, and Dist) are normed, and
% then the  min required score for admission is gradually
% increased until the number  admitted no longer exceeds
% max_admits_allowed.

% Clear variables, clear and open the commandwindow
clear all
clc
commandwindow

% Set constants
applications = 30;
max_admits_allowed = 10;

IQmean = 110;
IQsd = 20;
SATQmean = 500;
SATQsd = 100;
SATVmean = 500;
SATVsd = 100;
ECsd = 10;
GPAmean = 2.0;
GPAsd = 10;

% Preallocate arrays using deal
[IQ SATQ SATV GPA Acad EC Dist] = deal(zeros(applications,1));

% Generate dummy scores to test the program
IQ = IQmean + (randn(applications,1)) * IQsd;
SATQ = SATQmean + (randn(applications,1)) * SATQsd;
SATV = SATVmean + (randn(applications,1)) * SATVsd;
GPA = GPAmean + (randn(applications,1)) * GPAsd;
EC = abs(randn(applications,1) * ECsd);
Dist = abs(randn(applications,1));
Acad = SATQ + SATV + 100 * GPA;

% Normalize the scores
Acad = (Acad - min(Acad)) ./ (max(Acad)-min(Acad));
EC = (EC -min(EC)) ./(max(EC)-min(EC));
Dist = (Dist - min(Dist)) ./(max(Dist)-min(Dist));

% Create a Scores matrix, including, in the final column,
% each student's total score
Scores = [[1:applications]' Acad EC Dist];
Scores(:,5) = [Acad + EC + Dist];

% Admit the top max_admits_allowed students (plus any ties)
SortedScores = sortrows(Scores,-5);
criterion = SortedScores(max_admits_allowed,5);
SortedScores(:,6) = 0;
SortedScores((SortedScores(:,5) >= criterion),6) = 1;
ScoresAndAcceptances = sortrows(SortedScores,1);

% Display the results
fprintf('App.\tAcad.\tExtra.\tDist.\tTotal\tAccept\n\n')
fprintf(...
  '%4d\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%4d\n',ScoresAndAcceptances')
fprintf('\r')
Students_Accepted = find(ScoresAndAcceptances(:,6));
fprintf('Accepted Students:\n');
fprintf('%3d',Students_Accepted);
fprintf('\n\n')
fprintf('Cutoff score: %5.03f\n', criterion);

Output 8.1.1:

App.  Acad.         Extra.   Dist.         Total         Accept

1    0.48     0.26     0.34     1.08      0
2    0.33     0.03     0.45     0.82      0
3    0.21     0.74     0.08     1.03      0
4    0.24     0.91     0.09     1.24      0
5    0.70     0.17     0.30     1.17      0
6    0.59     0.00     0.09     0.68      0
7    0.79     0.41     0.10     1.30      0
8    0.53     0.24     0.33     1.10      0
9    0.56     0.08     0.43     1.07      0
10    0.11     0.07     0.71     0.89      0
11    0.43     0.31     0.31     1.05      0
12    0.67     0.92     0.36     1.96      1
13    0.51     0.05     0.00     0.56      0
14    0.98     0.48     0.01     1.48      1
15    0.00     0.08     0.02     0.10      0
16    0.52     1.00     0.22     1.75      1
17    0.64     0.00     0.07     0.71      0
18    0.41     0.61     0.10     1.12      0
19    0.62     0.44     0.49     1.56      1
20    1.00     0.51     0.42     1.93      1
21    0.34     0.67     0.06     1.08      0
22    0.51     0.10     0.38     1.00      0
23    0.19     0.11     0.14     0.44      0
24    0.82     0.24     0.39     1.46      1
25    0.21     0.04     0.28     0.53      0
26    0.38     0.43     1.00     1.81      1
27    0.98     0.49     0.17     1.64      1
28    0.83     0.28     0.57     1.68      1
29    0.41     0.41     0.17     0.99      0
30    0.92     0.23     0.28     1.42      1

Accepted Students:
12 14 16 19 20 24 26 27 28 30

Cutoff score: 1.423

Code 8.1.2:

% College_Admissions_Main.m

Clear_Start;
Set_Constants;
Generate_Dummy_Scores;
Normalize_Scores;
Create_Scores_Matrix;
Select_Students;
Display_Results;

Code 8.1.3:

% Clear_Start.m
% Called by College_Admissions_Main.m
clear all
clc
commandwindow

Code 8.1.4:

% Set_Constants.m
% Called by College_Admissions_Main.m
applications = 30;
max_admits_allowed = 10;
IQmean = 110;
IQsd = 20;
SATQmean = 500;
SATQsd = 100;
SATVmean = 500;
SATVsd = 100;
ECsd = 10;
GPAmean = 2.0;
GPAsd = 10;
[IQ SATQ SATV GPA Acad EC Dist] = deal(zeros(applications,1));

Code 8.1.5:

% Generate_Dummy_Scores.m
% Called by College_Admissions_Main.m
IQ = IQmean + (randn(applications,1)) * IQsd;
SATQ = SATQmean + (randn(applications,1)) * SATQsd;
SATV = SATVmean + (randn(applications,1)) * SATVsd;
GPA = GPAmean + (randn(applications,1)) * GPAsd;
EC = abs(randn(applications,1) * ECsd);
Dist = abs(randn(applications,1));
Acad = SATQ + SATV + 100 * GPA;

Code 8.1.6:

% Normalize_Scores.m
% Called by College_Admissions_Main.m
Acad = (Acad - min(Acad)) ./ (max(Acad) - min(Acad));
EC = (EC -min(EC)) ./(max(EC) - min(EC));
Dist = (Dist - min(Dist)) ./(max(Dist) - min(Dist));

Code 8.1.7:

% Create_Scores_Matrix.m
% Called by College_Admissions_Main.m
Scores = [[1:applications]' Acad EC Dist];
Scores(:,5) = Acad + EC + Dist;

Code 8.1.8:

% Select_Students.m
% Called by College_Admissions_Main.m
SortedScores = sortrows(Scores,-5);
criterion = SortedScores(max_admits_allowed,5);
SortedScores(:,6) = 0;
SortedScores((SortedScores(:,5) >= criterion),6) = 1;
ScoresAndAcceptances = sortrows(SortedScores,1);

Code 8.1.9:

% Display_Results.m
% Called by College_Admissions_Main.m
fprintf('App.\tAcad.\tExtra.\tDist.\tTotal\tAccept\n\n')
fprintf(...
   '%4d\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%4d\n',ScoresAndAcceptances')
fprintf('\r')
Students_Accepted = find(ScoresAndAcceptances(:,6));
fprintf('Accepted Students:\n');
fprintf('%3d',Students_Accepted);
fprintf('\n')
fprintf('Cutoff score: %5.03f\n', criterion);

Code 8.2.1:

 r = [1:99];
mean_r = mean(r)

Output 8.2.1:

mean_r =
50

Code 8.2.2:

meanA = (1+3+5+7+9)/5
a = pi;
b = 1492;
c = 6.02;
meanB = (a+b+c)/3
meanC = sum(1:10)/10

Output 8.2.2:

meanA =
5
meanB =
500.3872
meanC =
5.5000

Code 8.2.3:

% function mymean.m
function myresult = mymean(inputarray);
myresult = sum(inputarray)/length(inputarray)
return

Code 8.2.4:

meanD = mymean([1 3 5 7 9])
meanE = mymean([pi 1492 6.02])
meanF = mymean([1:10])

Output 8.2.4:

meanD =
5
meanE =
500.3872
meanF =
5.5000

Code 8.2.4:

% normalize.m

function y = normalize(x)
y = (x - min(x)) ./ (max(x)-min(x));
end

Code 8.2.5:

 x = [1:8]
normalized_values = normalize(x)

Output 8.2.5:

x =
1     2     3     4     5     6     7     8
normalized_values =
    0    0.1429    0.2857    0.4286    0.5714    0.7143    0.8571    1.0000

Code 8.2.6:

a = [1:8];
normalized_values = normalize(a)

Output 8.2.6:

x =
1     2     3     4     5     6     7     8
normalized_values =
    0    0.1429    0.2857    0.4286    0.5714    0.7143    0.8571    1.0000

Code 8.2.7:

a = [1:8];
normalize(a);
y

Output 8.2.7:

??? Undefined function or variable 'y'.

Code 8.3.1:

function [ly, uy] = normalize_split(x)

lx = x(x <=median(x));
ux = x(x > median(x));
uy = (ux - min(ux)) ./ (max(ux)-min(ux));
ly = (lx - min(lx)) ./ (max(lx)-min(lx));
return

Code 8.3.2:

 a = randi(10,1,14);
[lower_normed, upper_normed] = normalize_split(a) 

Output 8.3.2:

lower_normed =
0.3333    0.3333    0.3333    0.3333         0         0    1.0000
upper_normed =
1.0000    1.0000    0.2500    0.2500    1.0000         0    0.5000

Code 8.3.3:

% myroot.m
function result = myroot(x)
if x > 0
    result = sqrt(x);
else
    fprintf('\nCan''t take the square root of a negative number\n');
    result = NaN;
end
return

Code 8.3.4:

Result_1 = myroot(2)
Result_2 = myroot(-2)

Output 8.3.4:

Result_1 =
1.414213562373095

Can't take the square root of a negative number
Result_2 =
NaN

Code 8.4.1:

% normalize_split_two_args.m
% Splits array in first argument into
% lower and upper halves, using the 
% criterion ('mean' or 'median')
% specified in the second argument

function [ly, uy] = normalize_split_two_args(x,typeofsplit);

lx = [];
ux = [];

if strcmp(typeofsplit,'median')  % median split
    lx = x(x<=median(x));
    ux = x(x>median(x));

elseif strcmp(typeofsplit,'mean') % mean split
    lx = x(x<=mean(x));
    ux = x(x>mean(x));

else   % error feedback
    disp(['Error: An invalid type of split'...
    ' in the call to normalize_split_two_args']);
    [ly, uy] = deal(NaN);
    return
end

ly = (lx - min(lx)) ./ (max(lx)- min(lx));
uy = (ux - min(ux)) ./ (max(ux)- min(ux));
return

Code 8.4.2:

a = logspace(0,2,8)
[median_based_lower_norm,median_based_upper_norm_mean] = ...
   normalize_split_two_args(a,'mean')
[mean_based_lower_norm,mean_based_upper_norm] = ...
   normalize_split_two_args(a,'median')
[other_based_lower_norm,other_based_upper_norm_mean] = ...
   normalize_split_two_args(a,'anyOtherTerm')

Output 8.4.2:

a =
1.0000    1.9307    3.7276    7.1969   13.8950   26.8270   51.7947  100.0000
median_based_lower_norm =
     0    0.0722    0.2115    0.4806    1.0000
median_based_upper_norm_mean =
     0    0.3412    1.0000
mean_based_lower_norm =
     0    0.1502    0.4402    1.0000
mean_based_upper_norm =
     0    0.1502    0.4402    1.0000
Error: An invalid type of split in the call to normalize_split
other_based_lower_norm =
NaN
other_based_upper_norm_mean =
NaN

Code 8.5.1:

% mean_and_trimmed_mean.m
function [y,ty] = mean_and_trimmed_mean(x)
y = mean(x);
ty = mean(trimmed(x));
return

function zz = trimmed(w)
w = sort(w);
zz = [w(2:end-1)];
return

Code 8.5.2:

 x = randperm(5).^2
[theMean theTrimmedMean] = mean_and_trimmed_mean(x)

Output 8.5.2:

x =
25     9    16     4     1
theMean =
11
theTrimmedMean =
9.6667

Code 8.5.3:

% ComputeMeans_Fails.m
x = randperm(5).^2;
[theMean theTrimmedMean] = mean_and_trimmed_mean(x)

function [y,ty] = mean_and_trimmed_mean(x)
y = mean(x);
ty = mean(trimmed(x));
return

function zz = trimmed(w)
w = sort(w);
zz = [w(2:end-1)];
return

Output 8.5.3:

Error: File: ComputeMeans_Fails.m Line: 5 Column: 1
Function definitions are not permitted in this context.

Code 8.5.4:

% ComputeMeans_Succeeds.m
function main
x = randperm(5).^2
[theMean theTrimmedMean] = mean_and_trimmed_mean(x)
return
end  % main function

function [y,ty] = mean_and_trimmed_mean(x)
y = mean(x);
ty = mean(trimmed(x));
return
end % mean_and_trimmed_mean

function zz = trimmed(w)
w = sort(w);
zz = [w(2:end-1)];
return
end % trimmed

Output 8.5.4:

theMean =
11
theTrimmedMean =
9.6667

Code 8.5.5:

% ComputeMeans_Nested.m
function main
x = randperm(5).^2
mean_and_trimmed_mean
theMean
theTrimmedMean
return

    function mean_and_trimmed_mean
        theMean = mean(x);
        trimmed;
        return
    end % function mean_and_trimmed_mean

    function trimmed
        w = sort(x);
        theTrimmedMean = [w(2:end-1)];
        return
    end % function trimmed

end %function main

Output 8.5.5:

theMean =
11
theTrimmedMean =
9.6667

Code 8.5.6:

% College_Admissions_Nested
function main;
clear all
clc
commandwindow

% Set constants
applications = 30;
max_admits_allowed = 10;

IQmean = 110;
IQsd = 20;
SATQmean = 500;
SATQsd = 100;
SATVmean = 500;
SATVsd = 100;
ECsd = 10;
GPAmean = 2.0;
GPAsd = 10;
% Use deal to initialize all these variables in one command
[IQ SATQ SATV GPA Acad EC Dist] = deal(zeros(applications,1));
Scores = [];
ScoresAndAcceptances = [];
criterion = [];

% Program sequence
Generate_Dummy_Scores;
Normalize_Scores;
Create_Scores_Matrix
Select_Students
Display_Results
return

    function Generate_Dummy_Scores;
        IQ = IQmean + (randn(1,applications)) * IQsd;
        SATQ = SATQmean + (randn(1,applications)) * SATQsd;
        SATV = SATVmean + (randn(1,applications)) * SATVsd;
        GPA = GPAmean + (randn(1,applications)) * GPAsd;
        EC = abs(randn(1,applications)) * ECsd;
        Dist = abs(randn(1,applications));
        Acad = SATQ + SATV + 100 * GPA;
        return
    end %  Generate_Dummy_Scores

    function Normalize_Scores;
        Acad = (Acad - min(Acad)) ./ (max(Acad)-min(Acad));
        EC = (EC -min(EC)) ./(max(EC)-min(EC));
        Dist = (Dist - min(Dist)) ./(max(Dist)-min(Dist));
        return
    end % function Normalize_Scores

    function Create_Scores_Matrix;
        % Create a Scores matrix, including, in the final column,
        % each student's total score
        Scores = [[1:applications]' Acad EC Dist];
        Scores(:,5) = Acad + EC + Dist;
        return
    end %  Create_Scores_Matrix

    function Select_Students;
        % Admit the top max_admits_allowed students (plus any ties)
        SortedScores = sortrows(Scores,-5);
        criterion = SortedScores(max_admits_allowed,5);
        SortedScores(  :                             ,6) = 0;
        SortedScores((SortedScores(:,5) >= criterion),6) = 1;
        ScoresAndAcceptances = sortrows(SortedScores,1);
        return
    end % Select_Students;

    function Display_Results;
        % Display the results
        fprintf('App.\tAcad.\tExtra.\tDist.\tTotal\tAccept\n\n')
        fprintf(['%4d\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%4d\n'...
           ',ScoresAndAcceptances'])
        fprintf('\r')
        Students_Accepted = find(ScoresAndAcceptances(:,6));
        fprintf('Accepted Students:\n');
        fprintf('%3d',Students_Accepted);
        fprintf('\n')
        fprintf('Cutoff score: %5.03f\n', criterion);
        return
    end % function Display_Results

end % Function Main

Code 8.6.1:

b = mean_and_trimmed_mean(x)
c = mean_and_trimmed_mean(x)
[d e] = mean_and_trimmed_mean(x)
[f g h] = mean_and_trimmed_mean(x)

Output 8.6.1:

b =
3
c =
3
d =
3
e =
2.5009
??? Error using ==> mean_and_trimmed_mean
Too many output arguments.

Code 8.7.1:

% Example of recursive routine, equivalent of 5 nested FOR loops
function recursiveFunction
loopdepth = 5;
thislevel = 0
Doaloop(thislevel, loopdepth);
% end of recursiveFunction

% ========= Local function called repeatedly by self
function Doaloop(thislevel,loopdepth);
thislevel = thislevel + 1;
enteringlevel = thislevel;
fprintf('Entering Level %d\n',thislevel');
if thislevel == loopdepth
    % Do what needs to be done in the 'innermost' loop;
    % necessary parameters would have been set
    % at each level of depth...
    fprintf('  At the lowest level\n');
    return
else
    % Not deep enough yet.
    % Set whatever parameters need to be set at this level
    % then call self recursively at a deeper level)
    Doaloop(thislevel,loopdepth);
end
leavinglevel = thislevel;
fprintf('Leaving Level %d\n',thislevel');
% end of Doaloop

Output 8.7.1:

thislevel =
0
Entering Level 1
Entering Level 2
Entering Level 3
Entering Level 4
Entering Level 5
At the lowest level
Leaving Level 4
Leaving Level 3
Leaving Level 2
Leaving Level 1

Code 8.7.2:

clc
fprintf(['Joint values        T  S  E  W\n'...
     '                   __ __ __ __\n']);
for  trunkvalue = [-1:1]
  for  shouldervalue = [-1:1]
    for  elbowvalue = [-1:1]
      for  wristvalue = [-1:1]
        fprintf('Processing values %3.0f%3.0f%3.0f%3.0f\n',...
          trunkvalue, shouldervalue, elbowvalue, wristvalue);
      end
    end
  end
end

Output 8.7.2:

Joint values        T  S  E  W
__ __ __ __
Processing values  -1 -1 -1 -1
Processing values  -1 -1 -1  0
Processing values  -1 -1 -1  1
Processing values  -1 -1  0 -1
Processing values  -1 -1  0  0
Processing values  -1 -1  0  1
... 69 lines of output omitted...
Processing values   1  1  0 -1
Processing values   1  1  0  0
Processing values   1  1  0  1
Processing values   1  1  1 -1
Processing values   1  1  1  0
Processing values   1  1  1  1

Code 8.7.3:

% Code 8_7_3.m
function recursiveKinematics
clc
loopdepth = 5;
thislevel = 0;
jointvalues = zeros(1,4);
fprintf(['Joint values        T  S  E  W\n'...
     '                   __ __ __ __\n']);
Doaloop(thislevel, loopdepth,{'Trunk','Shoulder','Elbow','Wrist'},jointvalues);
return

% ========= Recursive function

function Doaloop(thislevel,loopdepth,joints,jointvalues);
thislevel = thislevel + 1;
enteringlevel = thislevel;
if thislevel == loopdepth
   fprintf('Processing values %3.0f%3.0f%3.0f%3.0f\n',jointvalues);
   return
else
   for i = -1:1
       jointvalues(thislevel) = i;
   Doaloop(thislevel,loopdepth,joints,jointvalues);
   end
end

return

Solutions

% Solutions_Chapter_08

% Solutions for selected problems from MATLAB for Behavioral Scientists,
% Second Edition (D. A. Rosenbaum, J. Vaughan, & B. Wyble),
% (c) 2015, Taylor & Francis

% To generate the solution for one problem, copy and run the code for that
% problem in a file or paste it into the Command window. Show the Command
% window to see the results.

% To generate sll the solutions for Chapter 8, save this code as a
% MATLAB script file and run the program.

function main % Problems in this chapter will have nested or local
% functions so the Problem 8 file must itself be a function
clc
commandwindow
format short
Solution_8_9_1 %Run each of the problem functions in turn.
Solution_8_9_2
Solution_8_9_3
Solution_8_9_4
Solution_8_9_5
Solution_8_9_6
Solution_8_9_7
end % function main

% Problem 8.9.1
% Write a function to convert any specified value of a normally
% distributed 1000 × 1 random sample, MYSAMPLE, to a z score. The z score
% of such a value is its signed number of sample standard deviations
% away from the sample mean. What arguments will the function need to
% call? Save your function in an .m file, and call it from another script
% or the Command window, with one argument, mysample.  Then make it a
% nested function, and call it from the main function in your .m file.
% Test the function with random samples of different sizes, means and
% standard deviations.

% NOTE: for the problem answer, only the nested function version is
% presented; the .m-file function version is left to the student.
% Call the function
function Solution_8_9_1
fprintf('\n\n          %s\n\n','Output 8.9.1')


% Call the nested function eight times
mysample = randn(10,1) * 5 + 10;
% nominal mean of mysample = 10, nominal std of mysample = 5
% Thus, the z-score of 5 should be one STD below the mean of 10;
% and the z-score of 20 should be two STD's above the mean of 10

myzscore5_sample10 = findzscore(mysample, 5) % what is the zscore of 5?
myzscore20_sample10 = findzscore(mysample, 20) % what is the zscore of 20?

mysample = randn(1000,1) * 5 + 10;
myzscore5_sample1000 = findzscore(mysample, 5)
myzscore20_sample1000 = findzscore(mysample, 20)

mysample = randn(100000,1) * 5 + 10;
myzscore5_sample100000 = findzscore(mysample, 5)
myzscore20_sample100000 = findzscore(mysample, 20)

mysample = randn(10000000,1) * 5 + 10;
myzscore5_sample10000000 = findzscore(mysample, 5)
myzscore20_sample10000000 = findzscore(mysample, 20)

% Use a nested function
    function thezscore = findzscore(thedistribution, thescore)
        m = mean(thedistribution);
        s = std(thedistribution);
        thezscore = (thescore - m)/s;
    end % function zscore

end % function Solution_8_9_1

%
% Problem 8.9.2
%
% In Problems 5.9.2 and 5.9.3 you were asked to identify participants who
% had mean reaction times greater than 500 ms and proportions correct
% greater than .65. If you solved the problem and followed the instruction
% to use material presented up to that point only or information given in
% the problems themselves, you did so without creating a function. Now
% write a function that takes as input these three variables: (1) the
% name of the matrix containing reaction times and proportions correct;
% (2) the reaction time cutoff; and (3) the proportion-correct cutoff.
% The function should return the following:
% (1) Identified_Participants; (2) OK_Scores; (3) Mean_of_OK_reaction_times;
% and (4) Mean_Proportion_Correct.
function Solution_8_9_2
fprintf('\n\n          %s\n\n','Output 8.9.2')
fprintf('Solution left to the student.\n\n');
end % function Solution_8_9_2


% Problem 8.9.3
%
% It would be desirable to apply the function you created in the last
% problem to a larger data set than the one given in Problem 5.8.2. You
% needn't collect actual data for this purpose. Instead, you can generate
% model data via simulation. Generate model data that reflect the
% following constraints: (1) There are 1000 trials; (2) The probability
% of a correct response on any given trial is .90; (3,4) Reaction times in
% correct trials are drawn from a normal distribution with mu = 700 ms
% and std = 20 ms; (5,6) Reaction times in incorrect trials are drawn from
% a normal distribution with mu = 600 ms and std = 80 ms; Reaction
% times less than 0 ms are undefined. Generate the model data based on
% the above constraints with a single function that has five arguments
% corresponding to the values of constraints 1-6, so that you could run
% the function with a different set of constraint values in the future.
function Solution_8_9_3
fprintf('\n\n          %s\n\n','Output 8.9.3')
% test with small n, to verify correctness
myDataSet = GenerateDataSet(10,.50,900,5,500,5)
% work with large n
myDataSet = GenerateDataSet(1000,.90,700,20,600,80);
end % function Solution_8_9_3

% Use a local function
function theDataSet = GenerateDataSet(N,PC,MRTc,SDc,MRTi,SDi);
theDataSet = [1:N]';
theDataSet(:,2) = rand(N,1) >= PC;
for i = 1:N
    if theDataSet(i,2) % Correct trial
        theDataSet(i,3) = randn(1,1)*SDc + MRTc;
    else
        theDataSet(i,3) = randn(1,1)*SDi + MRTi;
    end
end
end % function theDataSet

%
% Problem 8.9.4
%
% Write a function to compute the probability of getting exactly k
% successes in n tries given the constraints outlined below (such as
% getting exactly four heads in 10 flips of a fair coin). Quoting from
% an August 31, 2006 entry in
% Wikipedia (http://en.wikipedia.org/wiki/Binomial_distribution),
% "...if the random variable X follows the binomial distribution with
% parameters n and p, we write X ~ B(n, p). The probability of
% getting exactly k successes is given by the probability mass function:"
%
%    [see text for function]
%
% for k = 0, 1, 2, ..., n, where
%
%    [see text for function]
%
% Recall that n! is called "n factorial" and is equal to
% 1 × 2 × 3 × ... × (n - 1) × n. Likewise, k! is called "k factorial" and is
% equal to 1 × 2 × 3 × ... × (k - 1) × k. You might wish to start by
% exploring HELP FACTORIAL, or write your own program to generate the
% factorial of an argument using a recursive function. How would you verify
% the accuracy of your function? Can you model the process using randomly
% generated data?
function Solution_8_9_4
fprintf('Solution left to the student.\n\n');
end

%
% Problem 8.9.5
%
% Pascal's triangle is an arrangement of numbers such that the numbers
% in each row are generated from the sum of the two numbers directly above
% and to the left. The first four lines of the triangle are:
%
% 1
% 1  1
% 1  2  1
% 1  3  3  1
%
% Each line can be generated from the immediately prior line as:
% nextrow = [thisrow 0] + [0 thisrow] ; thus the next line in the above
% list would be [1 3 3 1 0] + [0 1 3 3 1], or [1 4 6 4 1]. Implement the
% generation of Pascal's triangle, starting with thisrow = 1, by a
% recursive function nextrow = PascalOf(thisrow), where the criterion
% for stopping the recursion is length(thisrow) >= 12. After each
% iteration, print both each line and the sum of the values in that
% line. Is there any regularity in the growth of the sum from line to line?
function Solution_8_9_5
fprintf('\n\n          %s\n\n','Output 8.9.5')
fprintf('Pascal''s triangle, and the sum of values in each line:\n\n');
SizeLimit = 12;
PascalOf(1);

% Uses Nested Function, sharing variables with calling function
    function PascalOf(thisrow)
        fprintf('%4d',thisrow);
        fprintf('     => %d',sum(thisrow));
        fprintf('\n');

        if length(thisrow) >= SizeLimit + 1
            return
        else
            nextrow = [thisrow 0] + [0 thisrow];
            PascalOf(nextrow);
        end
    end % function PascalOf(thisrow)
end % function Solution_8_9_5

% Problem 8.9.6
%
% Find a problem that you solved for a prior chapter that would profit
% from being organized in modular fashion, and rewrite it using either
% local functions (in the same file as a main function) or nested functions.
% Look for programs where you have had to execute the same computation
% repeatedly, varying only one or two arguments of the computation.
function Solution_8_9_6
fprintf('\n\n          %s\n\n','Output 8.9.6')
fprintf('Solution left to the student.\n');
end

% Problem 8.9.7
%
% In Problem 7.7.4 you were asked to write a program to administer a
% computerized questionnaire on a topic of interest to you. You were asked
% to use a structure data type and to allow participants to answer with
% whole sentences or phrases for at least some items. You were asked to
% save the data in an external file, and you were asked to record the
% times taken to answer the questions. Make this program modular and,
% having done so, take advantage of that modularity to pursue different
% lines of questions depending on participants' answers to particular
% questions.
function Solution_8_9_7
fprintf('\n\n          %s\n\n','Output 8.9.7')
fprintf('Solution left to the student.\n');
end

Output 8.9.1

myzscore5_sample10 =
   -1.9504
myzscore20_sample10 =
    2.9018
myzscore5_sample1000 =
   -0.9663
myzscore20_sample1000 =
    2.0632
myzscore5_sample100000 =
   -1.0021
myzscore20_sample100000 =
    2.0068
myzscore5_sample10000000 =
   -1.0004
myzscore20_sample10000000 =
    2.0000

Output 8.9.2

Solution left to the student.

Output 8.9.3

myDataSet =
    1.0000    1.0000  897.0140
    2.0000         0  497.1327
    3.0000    1.0000  898.6423
    4.0000    1.0000  904.4190
    5.0000         0  496.0067
    6.0000         0  502.0479
    7.0000    1.0000  898.6435
    8.0000         0  502.1820
    9.0000         0  496.2328
   10.0000         0  499.7241
Solution left to the student.

Output 8.9.5

Pascal's triangle, and the sum of values in each line:

1     => 1
1   1     => 2
1   2   1     => 4
1   3   3   1     => 8
1   4   6   4   1     => 16
1   5  10  10   5   1     => 32
1   6  15  20  15   6   1     => 64
1   7  21  35  35  21   7   1     => 128
1   8  28  56  70  56  28   8   1     => 256
1   9  36  84 126 126  84  36   9   1     => 512
1  10  45 120 210 252 210 120  45  10   1     => 1024
1  11  55 165 330 462 462 330 165  55  11   1     => 2048
1  12  66 220 495 792 924 792 495 220  66  12   1     => 4096

Output 8.9.6

Solution left to the student.

Output 8.9.7

Solution left to the student.