├── PA5 ├── .gitignore ├── partner.txt ├── GibMix1.jpg ├── firstrun.jpg ├── octave-core ├── pa5_1112.pdf ├── GibsVar1_1.jpg ├── GibsVar3_1.jpg ├── MHGibsMix_1.jpg ├── MHSW1Mix_1.jpg ├── MHSW1Var1_1.jpg ├── MHSW1Var3_1.jpg ├── MHSW2Mix_1.jpg ├── MHSW2Var1_1.jpg ├── MHSW2Var3_1.jpg ├── MHGibsVar1_1.jpg ├── MHGibsVar3_1.jpg ├── UniformMix_1.jpg ├── UniformVar1_1.jpg ├── UniformVar3_1.jpg ├── exampleIOPA5.mat ├── submit_input.mat ├── VariableToFactorCorrespondence.m ├── VisualizeToyImageMarginals.m ├── LogProbOfJointAssignment.m ├── smooth.m ├── rand.m ├── EdgeToFactorCorrespondence.m ├── MHGibbsTrans.m ├── AssignmentToIndex.m ├── IndexToAssignment.m ├── randi.m ├── GetValueOfAssignment.m ├── SetValueOfAssignment.m ├── MHUniformTrans.m ├── GetNextClusters.m ├── GibbsTrans.m ├── NaiveGetNextClusters.m ├── ExtractMarginalsFromSamples.m ├── CheckConvergence.m ├── randsample.m ├── TestToy.m ├── FactorMarginalization.m ├── ConstructToyNetwork.m ├── ConstructRandNetwork.m ├── SmartGetNextClusters.m ├── CreateClusterGraph.m ├── ObserveEvidence.m ├── ComputeInitialPotentials.m ├── FactorProduct.m ├── gaimc │ ├── sparse_to_csr.m │ └── scomponents.m ├── VisualizeMCMCMarginals.m └── ComputeApproxMarginalsBP.m ├── PA3 ├── .gitignore ├── partner.txt ├── text.txt ├── PA3Data.mat ├── PA3Models.mat ├── PA3Description.pdf ├── PA3SampleCases.mat ├── inference │ ├── doinference-mac │ ├── doinference.exe │ └── doinference-linux ├── IndexToAssignment.m ├── AssignmentToIndex.m ├── ImageSimilarity.m ├── ComputeImageFactor.m ├── VisualizeWord.m ├── ComputeEqualPairwiseFactors.m ├── ComputeAllSimilarityFactors.m ├── ComputeSingletonFactors.m ├── ChooseTopSimilarityFactors.m ├── ComputeSimilarityFactor.m ├── SerializeFactorsFg.m ├── ComputeWordPredictions.m ├── ComputeTripletFactors.m ├── ComputePairwiseFactors.m ├── RunInference.m └── ScorePredictions.m ├── PA4 ├── partner.txt ├── PA4Sample.mat ├── ProgrammingAssignment4.pdf ├── DecodedMarginalsToChars.m ├── AssignmentToIndex.m ├── IndexToAssignment.m ├── GetValueOfAssignment.m ├── MaxDecoding.m ├── SetValueOfAssignment.m ├── ComputeMarginal.m ├── ComputeJointDistribution.m ├── EliminateVar.m ├── FactorMarginalization.m ├── PruneTree.m ├── GetNextCliques.m ├── ComputeExactMarginalsBP.m ├── FactorMaxMarginalization.m ├── ObserveEvidence.m ├── ComputeInitialPotentials.m ├── FactorProduct.m └── CreateCliqueTree.m ├── PA6 ├── partner.txt ├── FullI.mat ├── TestI0.mat ├── MultipleUtilityI.mat ├── CS228-ProgrammingAssignment6.pdf ├── NormalizeFactorValues.m ├── results ├── PrintFactor.m ├── AssignmentToIndex.m ├── IndexToAssignment.m ├── SimpleOptimizeMEU.m ├── GetValueOfAssignment.m ├── NormalizeCPDFactors.m ├── SetValueOfAssignment.m ├── CPDFromFactor.m ├── CalculateExpectedUtilityFactor.m ├── EliminateVar.m ├── SimpleCalcExpectedUtility.m ├── VariableElimination.m ├── FactorMarginalization.m ├── FactorProduct.m ├── ObserveEvidence.m └── OptimizeMEU.m ├── PA7 ├── partner.txt ├── Test1X.mat ├── Test1Y.mat ├── Train1X.mat ├── Train1Y.mat ├── Train2X.mat ├── Train2Y.mat ├── Part2Sample.mat ├── Part2Test.mat ├── sigmoid.m ├── Part1Lambdas.mat ├── Part2LogZTest.mat ├── Validation1X.mat ├── Validation1Y.mat ├── Validation2X.mat ├── Validation2Y.mat ├── Part2FullDataset.mat ├── ValidationAccuracy.mat ├── CS228_ProgrammingAssignment7.pdf ├── EmptyFactorStruct.m ├── EmptyFeatureStruct.m ├── NumParamsForUnconditionedFeatures.m ├── NumParamsForConditionedFeatures.m ├── SerializeVector.m ├── LRPredict.m ├── ComputeUnconditionedSingleFeatures.m ├── IndexToAssignment.m ├── LRAccuracy.m ├── SaveECPredictions.m ├── AssignmentToIndex.m ├── ComputeUnconditionedPairFeatures.m ├── MaxDecoding.m ├── ComputeConditionedSingletonFeatures.m ├── ComputeJointDistribution.m ├── GetValueOfAssignment.m ├── ComputeMarginal.m ├── SetValueOfAssignment.m ├── LRSearchLambdaSGD.m ├── LRTrainSGD.m ├── EliminateVar.m ├── LRCostSGD.m ├── FactorMarginalization.m ├── StochasticGradientDescent.m ├── FactorMaxMarginalization.m ├── GetNextCliques.m ├── ObserveEvidence.m ├── PruneTree.m ├── FactorProduct.m ├── FactorSum.m ├── CreateCliqueTree.m ├── ComputeExactMarginalsBP.m └── GenerateAllFeatures.m ├── PA8 ├── partner.txt ├── PA8Data.mat ├── submit_input.mat ├── PA8SampleCases.mat ├── CS228_ProgrammingAssignment8.pdf ├── lognormpdf.m ├── SampleGaussian.m ├── VisualizeDataset.m ├── SampleMultinomial.m ├── FitGaussianParameters.m ├── GaussianMutualInformation.m ├── ConvertAtoG.m ├── VisualizeModels.m ├── LearnGraphStructure.m ├── LearnGraphAndCPDs.m ├── ShowPose.m ├── FitLinearGaussianParameters.m ├── MaxSpanningTree.m ├── ClassifyDataset.m ├── ComputeLogLikelihood.m └── LearnCPDsGivenGraph.m ├── PA9 ├── partner.txt ├── PA9Data.mat ├── Predictions.mat ├── submit_input.mat ├── PA9SampleCases.mat ├── ProgrammingAssignment9.pdf ├── VisualizeDataset.m ├── logsumexp.m ├── FitGaussianParameters.m ├── SavePredictions.m ├── IndexToAssignment.m ├── lognormpdf.m ├── AssignmentToIndex.m ├── FactorMarginalization.m ├── YourMethod.txt ├── ShowPose.m ├── ComputeExactMarginalsHMM.m ├── FitLinearGaussianParameters.m └── CreateCliqueTreeHMM.m ├── .gitignore └── README.md /PA5/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.jpg 3 | *.m 4 | -------------------------------------------------------------------------------- /PA3/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | inf.log 3 | factors.fg 4 | -------------------------------------------------------------------------------- /PA3/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA3/text.txt: -------------------------------------------------------------------------------- 1 | CS228 learning Git 2 | 3 | Zahan learning too 4 | -------------------------------------------------------------------------------- /PA4/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA5/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA6/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA7/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA8/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /PA9/partner.txt: -------------------------------------------------------------------------------- 1 | Jinchao, Ye, jcye 2 | Zahan, Malkani, zahanm 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | .*.swp 4 | *~ 5 | 6 | 228_login_data.mat 7 | -------------------------------------------------------------------------------- /PA6/FullI.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA6/FullI.mat -------------------------------------------------------------------------------- /PA6/TestI0.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA6/TestI0.mat -------------------------------------------------------------------------------- /PA7/Test1X.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Test1X.mat -------------------------------------------------------------------------------- /PA7/Test1Y.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Test1Y.mat -------------------------------------------------------------------------------- /PA3/PA3Data.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/PA3Data.mat -------------------------------------------------------------------------------- /PA5/GibMix1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/GibMix1.jpg -------------------------------------------------------------------------------- /PA5/firstrun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/firstrun.jpg -------------------------------------------------------------------------------- /PA5/octave-core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/octave-core -------------------------------------------------------------------------------- /PA5/pa5_1112.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/pa5_1112.pdf -------------------------------------------------------------------------------- /PA7/Train1X.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Train1X.mat -------------------------------------------------------------------------------- /PA7/Train1Y.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Train1Y.mat -------------------------------------------------------------------------------- /PA7/Train2X.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Train2X.mat -------------------------------------------------------------------------------- /PA7/Train2Y.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Train2Y.mat -------------------------------------------------------------------------------- /PA8/PA8Data.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA8/PA8Data.mat -------------------------------------------------------------------------------- /PA9/PA9Data.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA9/PA9Data.mat -------------------------------------------------------------------------------- /PA3/PA3Models.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/PA3Models.mat -------------------------------------------------------------------------------- /PA4/PA4Sample.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA4/PA4Sample.mat -------------------------------------------------------------------------------- /PA5/GibsVar1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/GibsVar1_1.jpg -------------------------------------------------------------------------------- /PA5/GibsVar3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/GibsVar3_1.jpg -------------------------------------------------------------------------------- /PA5/MHGibsMix_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHGibsMix_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW1Mix_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW1Mix_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW1Var1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW1Var1_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW1Var3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW1Var3_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW2Mix_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW2Mix_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW2Var1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW2Var1_1.jpg -------------------------------------------------------------------------------- /PA5/MHSW2Var3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHSW2Var3_1.jpg -------------------------------------------------------------------------------- /PA7/Part2Sample.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Part2Sample.mat -------------------------------------------------------------------------------- /PA7/Part2Test.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Part2Test.mat -------------------------------------------------------------------------------- /PA7/sigmoid.m: -------------------------------------------------------------------------------- 1 | function s = sigmoid (z) 2 | 3 | s = 1 ./ (1 + exp (-z)); 4 | 5 | end 6 | -------------------------------------------------------------------------------- /PA9/Predictions.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA9/Predictions.mat -------------------------------------------------------------------------------- /PA5/MHGibsVar1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHGibsVar1_1.jpg -------------------------------------------------------------------------------- /PA5/MHGibsVar3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/MHGibsVar3_1.jpg -------------------------------------------------------------------------------- /PA5/UniformMix_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/UniformMix_1.jpg -------------------------------------------------------------------------------- /PA5/UniformVar1_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/UniformVar1_1.jpg -------------------------------------------------------------------------------- /PA5/UniformVar3_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/UniformVar3_1.jpg -------------------------------------------------------------------------------- /PA5/exampleIOPA5.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/exampleIOPA5.mat -------------------------------------------------------------------------------- /PA5/submit_input.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA5/submit_input.mat -------------------------------------------------------------------------------- /PA7/Part1Lambdas.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Part1Lambdas.mat -------------------------------------------------------------------------------- /PA7/Part2LogZTest.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Part2LogZTest.mat -------------------------------------------------------------------------------- /PA7/Validation1X.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Validation1X.mat -------------------------------------------------------------------------------- /PA7/Validation1Y.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Validation1Y.mat -------------------------------------------------------------------------------- /PA7/Validation2X.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Validation2X.mat -------------------------------------------------------------------------------- /PA7/Validation2Y.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Validation2Y.mat -------------------------------------------------------------------------------- /PA8/submit_input.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA8/submit_input.mat -------------------------------------------------------------------------------- /PA9/submit_input.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA9/submit_input.mat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### CS 228 Programming assignments 2 | 3 | - Zahan Malkani 4 | - Jinchao Ye 5 | 6 | -------------------------------------------------------------------------------- /PA3/PA3Description.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/PA3Description.pdf -------------------------------------------------------------------------------- /PA3/PA3SampleCases.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/PA3SampleCases.mat -------------------------------------------------------------------------------- /PA6/MultipleUtilityI.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA6/MultipleUtilityI.mat -------------------------------------------------------------------------------- /PA7/Part2FullDataset.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/Part2FullDataset.mat -------------------------------------------------------------------------------- /PA8/PA8SampleCases.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA8/PA8SampleCases.mat -------------------------------------------------------------------------------- /PA9/PA9SampleCases.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA9/PA9SampleCases.mat -------------------------------------------------------------------------------- /PA7/ValidationAccuracy.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/ValidationAccuracy.mat -------------------------------------------------------------------------------- /PA3/inference/doinference-mac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/inference/doinference-mac -------------------------------------------------------------------------------- /PA3/inference/doinference.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/inference/doinference.exe -------------------------------------------------------------------------------- /PA3/inference/doinference-linux: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA3/inference/doinference-linux -------------------------------------------------------------------------------- /PA4/ProgrammingAssignment4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA4/ProgrammingAssignment4.pdf -------------------------------------------------------------------------------- /PA9/ProgrammingAssignment9.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA9/ProgrammingAssignment9.pdf -------------------------------------------------------------------------------- /PA6/CS228-ProgrammingAssignment6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA6/CS228-ProgrammingAssignment6.pdf -------------------------------------------------------------------------------- /PA7/CS228_ProgrammingAssignment7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA7/CS228_ProgrammingAssignment7.pdf -------------------------------------------------------------------------------- /PA8/CS228_ProgrammingAssignment8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datajunkie007/cs228/HEAD/PA8/CS228_ProgrammingAssignment8.pdf -------------------------------------------------------------------------------- /PA7/EmptyFactorStruct.m: -------------------------------------------------------------------------------- 1 | function f = EmptyFactorStruct 2 | 3 | f = struct ('var', [], 'card', [], 'val', []); 4 | 5 | end 6 | 7 | -------------------------------------------------------------------------------- /PA7/EmptyFeatureStruct.m: -------------------------------------------------------------------------------- 1 | function s = EmptyFeatureStruct 2 | 3 | s = struct('var', [], 'assignment', [], 'paramIdx', []); 4 | 5 | end 6 | 7 | -------------------------------------------------------------------------------- /PA7/NumParamsForUnconditionedFeatures.m: -------------------------------------------------------------------------------- 1 | function n = NumParamsForUnconditionedFeatures (features) 2 | 3 | n = max([features.paramIdx]); 4 | 5 | end 6 | 7 | -------------------------------------------------------------------------------- /PA4/DecodedMarginalsToChars.m: -------------------------------------------------------------------------------- 1 | function DecodedMarginalsToChars(decodedMarginals) 2 | chars = 'abcdefghijklmnopqrstuvwxyz'; 3 | fprintf('%c', chars(decodedMarginals)); 4 | fprintf('\n'); 5 | end 6 | -------------------------------------------------------------------------------- /PA6/NormalizeFactorValues.m: -------------------------------------------------------------------------------- 1 | function F = NormalizeFactorValues( F ) 2 | 3 | for i=1:length(F) 4 | ThisFactor = F(i); 5 | ThisFactor.val = ThisFactor.val / sum(ThisFactor.val); 6 | F(i) = ThisFactor; 7 | end 8 | -------------------------------------------------------------------------------- /PA8/lognormpdf.m: -------------------------------------------------------------------------------- 1 | % CS228 PA8 Winter 2011-2012 2 | % File: lognormpdf.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function val = lognormpdf(x, mu, sigma) 6 | val = - (x - mu).^2 / (2*sigma^2) - log (sqrt(2*pi) * sigma); -------------------------------------------------------------------------------- /PA6/results: -------------------------------------------------------------------------------- 1 | 2 | T1 without t -> d 3 | ans = -350.43 4 | 5 | T1 with t -> d 6 | ans = 155.17 7 | 8 | T2 without 9 | -350.43 10 | 11 | T2 with 12 | -216.46 13 | 14 | T3 without 15 | -350.43 16 | 17 | T3 with 18 | 323.75 19 | -------------------------------------------------------------------------------- /PA7/NumParamsForConditionedFeatures.m: -------------------------------------------------------------------------------- 1 | function n = NumParamsForConditionedFeatures (features, numObservedStates) 2 | 3 | maxParam = max([features.paramIdx]); 4 | n = maxParam + numObservedStates - 1 - mod(maxParam - 1, numObservedStates); 5 | 6 | end 7 | -------------------------------------------------------------------------------- /PA5/VariableToFactorCorrespondence.m: -------------------------------------------------------------------------------- 1 | function V2F = VariableToFactorCorrespondence(V, F) 2 | 3 | V2F = cell(length(V), 1); 4 | 5 | for f = 1:length(F) 6 | for i = 1:length(F(f).var) 7 | v = F(f).var(i); 8 | V2F{v} = union(V2F{v}, f); 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /PA5/VisualizeToyImageMarginals.m: -------------------------------------------------------------------------------- 1 | function VisualizeToyImageMarginals(G, M) 2 | 3 | n = sqrt(length(G.names)); 4 | marginal_vector = []; 5 | for i = 1:length(M) 6 | marginal_vector(end+1) = M(i).val(1); 7 | end 8 | clims = [0, 1]; 9 | imagesc(reshape(marginal_vector, n, n), clims); 10 | colormap(gray); -------------------------------------------------------------------------------- /PA5/LogProbOfJointAssignment.m: -------------------------------------------------------------------------------- 1 | % Returns the log probability of an assignment A in a distribution defined by factors F 2 | function logp = LogProbOfJointAssignment(F, A) 3 | 4 | % work in log-space to prevent underflow 5 | logp = 0.0; 6 | for i = 1:length(F) 7 | logp = logp + log(GetValueOfAssignment(F(i), A, 1:length(A))); 8 | end 9 | 10 | -------------------------------------------------------------------------------- /PA8/SampleGaussian.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: SampleGuassian.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function sample = SampleGaussian(mu, sigma) 7 | 8 | % sample from the Gaussian distribution specifed by mean value mu and standard deviation sigma 9 | 10 | sample = mu + sigma*randn(1,1); 11 | -------------------------------------------------------------------------------- /PA9/VisualizeDataset.m: -------------------------------------------------------------------------------- 1 | % CS228 PA3 Winter 2011 2 | % File: VisualizeDataset.m 3 | % Copyright (C) 2011, Stanford University 4 | % contact: Huayan Wang, huayanw@cs.stanford.edu 5 | 6 | function VisualizeDataset(Dataset) 7 | 8 | figure 9 | for i=1:size(Dataset,1) 10 | img = ShowPose(reshape(Dataset(i,:,:), [10 3])); 11 | imshow(img); 12 | pause(0.3); 13 | end 14 | -------------------------------------------------------------------------------- /PA7/SerializeVector.m: -------------------------------------------------------------------------------- 1 | function out = SerializeVector(x, tol) 2 | % Serializes a numeric vector. 3 | numLines = length(x); 4 | lines = cell(numLines,1); 5 | if (nargin == 1) 6 | tol = ''; 7 | else 8 | tol = sprintf(':%s', tol); 9 | end 10 | for i=1:numLines 11 | lines{i} = sprintf('%.4f%s\n', x(i), tol); 12 | end 13 | out = sprintf('%s', lines{:}); 14 | end 15 | -------------------------------------------------------------------------------- /PA9/logsumexp.m: -------------------------------------------------------------------------------- 1 | % CS228 PA9 Winter 2011-2012 2 | % File: logsumexp.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function out = logsumexp(A) 6 | 7 | % LOGSUMEXP 8 | % Computes log( sum( exp( ) ) ) of each row in A in a way that avoids underflow. 9 | % If A is an N x M matrix, then out is a N x 1 vector. 10 | 11 | pi_max = max(A, [], 2); 12 | out = pi_max + log(sum(exp(bsxfun(@minus, A, pi_max)), 2)); 13 | -------------------------------------------------------------------------------- /PA8/VisualizeDataset.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: VisualizeDataset.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function VisualizeDataset(Dataset) 7 | 8 | f = figure; 9 | for i=1:size(Dataset,1) 10 | img = ShowPose(reshape(Dataset(i,:,:), [10 3])); 11 | imshow(img); 12 | pause(0.3) 13 | if (~ishandle(f)) break; end; % quit loop when user closes the figure 14 | end 15 | -------------------------------------------------------------------------------- /PA8/SampleMultinomial.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: SampleMultinomial.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function sample = SampleMultinomial(probabilities) 7 | 8 | dice = rand(1,1); 9 | accumulate = 0; 10 | for i=1:length(probabilities) 11 | accumulate = accumulate + probabilities(i); 12 | if accumulate/sum(probabilities) > dice 13 | break 14 | end 15 | end 16 | sample = i; 17 | 18 | 19 | -------------------------------------------------------------------------------- /PA5/smooth.m: -------------------------------------------------------------------------------- 1 | function [YY] = smooth(Y,window) 2 | if(~exist('window','var')) 3 | window =5; 4 | end 5 | if(mod(window,2)==0) 6 | window = window+1; 7 | end 8 | mid = (window+1)/2; 9 | 10 | len = length(Y); 11 | Smoother =zeros(len); 12 | for i=1:len 13 | dev = min([mid-1 min([i-1 len-i])]); 14 | Smoother(i,(i-dev):(i+dev))=1; 15 | end 16 | if(size(Y,2)>size(Y,1)) 17 | Y = Y'; 18 | end 19 | 20 | col = sum(Smoother,2); 21 | YY = Smoother*Y; 22 | YY = YY./col; 23 | -------------------------------------------------------------------------------- /PA8/FitGaussianParameters.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: FitGaussianParameters.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function [mu sigma] = FitGaussianParameters(X) 7 | 8 | % X: (N x 1): N examples (1 dimensional) 9 | % Fit N(mu, sigma^2) to the empirical distribution 10 | mu = mean(X); 11 | sigma = sqrt(mean(X .^ 2) - mean(X) ^ 2); 12 | 13 | %%%%%%%%%%%%%%%%%%%%%%%%%% 14 | % YOUR CODE HERE 15 | %%%%%%%%%%%%%%%%%%%%%%%%%% 16 | -------------------------------------------------------------------------------- /PA9/FitGaussianParameters.m: -------------------------------------------------------------------------------- 1 | % CS228 PA9 Winter 2011-2012 2 | % File: FitGaussianParameters.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function [mu sigma] = FitGaussianParameters(X, W) 6 | 7 | % X: (N x 1): N examples (1 dimensional) 8 | % W: (N x 1): Weights over examples (W(i) is the weight for X(i)) 9 | 10 | % Fit N(mu, sigma^2) to the empirical distribution 11 | 12 | mu = 0; 13 | sigma = 1; 14 | 15 | mu = W'*X/sum(W); 16 | v = W'*(X.*X)/sum(W) - mu^2; 17 | sigma = sqrt(v); 18 | -------------------------------------------------------------------------------- /PA5/rand.m: -------------------------------------------------------------------------------- 1 | function [val] = rand(arg1,arg2); 2 | val = -1; 3 | gran = 1e6; 4 | 5 | if(nargin>0&&ischar(arg1)) 6 | if(nargin==1) 7 | arg2=1; 8 | end 9 | randi(arg1,arg2); 10 | val=0; 11 | else 12 | if(nargin==0) 13 | val = randi(1e6)/(1e6); 14 | else 15 | if(nargin==1) 16 | if(length(arg1)>1) 17 | arg2=arg1(2); 18 | arg1=arg1(1); 19 | else 20 | arg2=arg1; 21 | end 22 | end 23 | val = randi(1e6,arg1,arg2)/1e6; 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /PA5/EdgeToFactorCorrespondence.m: -------------------------------------------------------------------------------- 1 | % Returns a matrix that maps edges to a list of factors in which both ends partake 2 | function E2F = EdgeToFactorCorrespondence(V, F) 3 | 4 | E2F = cell(length(V), length(V)); 5 | 6 | for f = 1:length(F) 7 | for i = 1:length(F(f).var) 8 | for j = i+1:length(F(f).var) 9 | u = F(f).var(i); 10 | v = F(f).var(j); 11 | E2F{u,v} = union(E2F{u,v}, f); 12 | E2F{v,u} = union(E2F{v,u}, f); 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /PA7/LRPredict.m: -------------------------------------------------------------------------------- 1 | % pred = LRPredict(X, theta) uses the LR classifier encoded by theta 2 | % to predict the labels on data X. 3 | % 4 | % Inputs: 5 | % X data. (numInstances x numFeatures matrix) 6 | % theta LR parameters. (numFeatures x 1 vector) 7 | % 8 | % Outputs: 9 | % pred predicted labels for X. (numInstances x 1 binary vector). 10 | 11 | 12 | function pred = LRPredict (X, theta) 13 | 14 | thresh = 0.5; 15 | h = sigmoid (X * theta); 16 | pred = h > thresh; 17 | 18 | end 19 | 20 | -------------------------------------------------------------------------------- /PA6/PrintFactor.m: -------------------------------------------------------------------------------- 1 | function [] = PrintFactor(F) 2 | % Pretty print the factor F. 3 | % The first row lists the variables and subsequent rows are 4 | % the joint assignment and their associated factor value in 5 | % the last column. 6 | 7 | for i=1:length(F.var) 8 | fprintf(1, '%d\t', F.var(i)); 9 | end 10 | fprintf(1, '\n'); 11 | 12 | for i=1:length(F.val) 13 | A = IndexToAssignment(i, F.card); 14 | for j=1:length(A) 15 | fprintf(1, '%d\t', A(j)); 16 | end 17 | fprintf(1, '%f\n', F.val(i)); 18 | end 19 | 20 | 21 | end -------------------------------------------------------------------------------- /PA7/ComputeUnconditionedSingleFeatures.m: -------------------------------------------------------------------------------- 1 | function features = ComputeUnconditionedSingleFeatures (y, modelParams) 2 | 3 | nSingleFeatures = length(y) * modelParams.numHiddenStates; 4 | features(nSingleFeatures) = EmptyFeatureStruct(); 5 | 6 | K = modelParams.numHiddenStates; 7 | featureIdx = 0; 8 | 9 | for st = 1:K 10 | paramVal = st; 11 | for v = 1:length(y) 12 | featureIdx = featureIdx + 1; 13 | features(featureIdx).var = v; 14 | features(featureIdx).assignment = st; 15 | features(featureIdx).paramIdx = paramVal; 16 | 17 | end 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /PA9/SavePredictions.m: -------------------------------------------------------------------------------- 1 | function SavePredictions (yourPredictions) 2 | % This function will save your test set predictions into a mat file. The 3 | % submit script for will then read in that 4 | % file to send your predictions to the grading server. 5 | % 6 | % The input `yourPredictions' should be a 90x1 vector where 7 | % yourPredictions(i) is the predicted class (1-3) for the i'th action. 8 | 9 | if (~isequal([90 1], size(yourPredictions))) 10 | error ('The input to SavePredictions is not the right size.'); 11 | end 12 | 13 | save('Predictions.mat', 'yourPredictions'); 14 | 15 | 16 | end 17 | 18 | -------------------------------------------------------------------------------- /PA9/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = bsxfun(@mod, floor(bsxfun(@rdivide, I(:) - 1, cumprod([1, D(1:end - 1)]))), D) + 1; 14 | 15 | end 16 | -------------------------------------------------------------------------------- /PA5/MHGibbsTrans.m: -------------------------------------------------------------------------------- 1 | % MHGIBBSTRANS 2 | % 3 | % MCMC Metropolis-Hastings transition function that 4 | % utilizes the Gibbs sampling distribution for proposals. 5 | % A - The current joint assignment. This should be 6 | % updated to be the next assignment 7 | % G - The network 8 | % F - List of all factors 9 | function A = MHGibbsTrans(A, G, F) 10 | 11 | % Draw proposed new state from Gibbs Transition distribution 12 | A_prop = GibbsTrans(A, G, F); 13 | 14 | % Compute acceptance probability 15 | p_acceptance = 1.0; 16 | 17 | % Accept or reject proposal 18 | if rand() < p_acceptance 19 | A = A_prop; 20 | end -------------------------------------------------------------------------------- /PA8/GaussianMutualInformation.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2011 2 | % File: GaussianMutualInformation.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function I = GaussianMutualInformation(X, Y) 7 | 8 | if isequal(X,Y) 9 | I = 0; 10 | return; 11 | end 12 | % X: (N x D1), D1 dimensions, N samples 13 | % Y: (N x D2), D2 dimensions, N samples 14 | 15 | % I(X, Y) = 1/2 * log( | Sigma_XX | * | Sigma_YY | / | Sigma |) 16 | % Sigma = [ Sigma_XX, Sigma_XY ; 17 | % Sigma_XY, Sigma_YY ] 18 | 19 | Sxx = cov(X); 20 | Syy = cov(Y); 21 | S = cov([X,Y]); 22 | I = .5*log(det(Sxx)*det(Syy)/det(S)); -------------------------------------------------------------------------------- /PA8/ConvertAtoG.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: ConvertAtoG.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function G = ConvertAtoG(A) 7 | 8 | G = zeros(10,2); 9 | A = A + A'; 10 | 11 | G(1,:) = [0 0]; 12 | visited = zeros(10,1); 13 | visited(1) = 1; 14 | 15 | 16 | cnt = 0; 17 | while sum(visited) < 10 18 | cnt = cnt+1; 19 | for i=2:10 20 | for j=1:10 21 | if A(i,j) == 1 && visited(j) 22 | visited(i) = 1; 23 | G(i,1) = 1; 24 | G(i,2) = j; 25 | break; 26 | end 27 | end 28 | end 29 | end -------------------------------------------------------------------------------- /PA9/lognormpdf.m: -------------------------------------------------------------------------------- 1 | % CS228 PA9 Winter 2011-2012 2 | % File: lognormpdf.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function [log_prob] = lognormpdf(x,mu,sigma) 6 | 7 | % LOGNORMPDF Natural logarithm of the normal probability density function (pdf) 8 | % Y = lognormpdf(X,MU,SIGMA) returns the log of the pdf of the normal 9 | % distribution parameterized by mean MU and standard deviation SIGMA evaluated 10 | % at each value in the vector X. Thus, the size of the return 11 | % vector Y is the size of X. 12 | % 13 | % MU and X should have the same dimensions. 14 | 15 | log_prob = -log(sigma*sqrt(2*pi))-(x-mu).^2 ./ (2*sigma.^2); 16 | -------------------------------------------------------------------------------- /PA9/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | I = sum(bsxfun(@times, A - 1, cumprod([1, D(1:end - 1)])), 2) + 1; 16 | end; 17 | 18 | end 19 | -------------------------------------------------------------------------------- /PA4/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | I = sum(repmat(cumprod([1, D(1:end - 1)]), size(A, 1), 1) .* (A - 1), 2) + 1; 16 | end; 17 | 18 | end 19 | -------------------------------------------------------------------------------- /PA5/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | I = sum(repmat(cumprod([1, D(1:end - 1)]), size(A, 1), 1) .* (A - 1), 2) + 1; 16 | end; 17 | 18 | end 19 | -------------------------------------------------------------------------------- /PA6/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | I = sum(repmat(cumprod([1, D(1:end - 1)]), size(A, 1), 1) .* (A - 1), 2) + 1; 16 | end; 17 | 18 | end 19 | -------------------------------------------------------------------------------- /PA4/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ... 14 | repmat(D, length(I), 1)) + 1; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PA5/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ... 14 | repmat(D, length(I), 1)) + 1; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PA6/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ... 14 | repmat(D, length(I), 1)) + 1; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PA7/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ... 14 | repmat(D, length(I), 1)) + 1; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PA3/IndexToAssignment.m: -------------------------------------------------------------------------------- 1 | % IndexToAssignment Convert index to variable assignment. 2 | % 3 | % A = IndexToAssignment(I, D) converts an index, I, into the .val vector 4 | % into an assignment over variables with cardinality D. If I is a vector, 5 | % then the function produces a matrix of assignments, one assignment 6 | % per row. 7 | % 8 | % See also AssignmentToIndex.m and SampleFactors.m 9 | 10 | function A = IndexToAssignment(I, D) 11 | 12 | D = D(:)'; % ensure that D is a row vector 13 | A = mod(floor(repmat(I(:) - 1, 1, length(D)) ./ repmat(cumprod([1, D(1:end - 1)]), length(I), 1)), ... 14 | repmat(D, length(I), 1)) + 1; 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PA7/LRAccuracy.m: -------------------------------------------------------------------------------- 1 | % function err = LRAccuracy(GroundTruth, Predictions) compares the 2 | % vector of predictions with the vector of ground truth values, 3 | % and returns the error rate. 4 | % 5 | % Input: 6 | % GroundTruth (numInstances x 1 vector) 7 | % Predictions (numInstances x 1 vector) 8 | % 9 | % Output: 10 | % err (scalar between 0 and 1 inclusive) 11 | 12 | function err = LRAccuracy(GroundTruth, Predictions) 13 | 14 | GroundTruth = GroundTruth(:); 15 | Predictions = Predictions(:); 16 | assert(all(size(GroundTruth) == size(Predictions))); 17 | 18 | err = 1 - (sum(GroundTruth ~= Predictions) / length(GroundTruth)); 19 | 20 | end 21 | -------------------------------------------------------------------------------- /PA3/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m and SampleFactors.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | I = sum(repmat(cumprod([1, D(1:end - 1)]), size(A, 1), 1) .* (A - 1), 2) + 1; 16 | end; 17 | 18 | end 19 | -------------------------------------------------------------------------------- /PA7/SaveECPredictions.m: -------------------------------------------------------------------------------- 1 | function SaveECPredictions (yourPredictions) 2 | % This function will save your test set predictions into a text file. The 3 | % submit script for the extra credit submission will then read in that text 4 | % file to send your predictions to the grading server. 5 | % 6 | % The input `yourPredictions' should be an 80x3 matrix where 7 | % yourPredictions(i,j) is the predicted value (1-26) of the j'th character 8 | % in the i'th word. That is, the predicted value for testData(i).y(j). 9 | 10 | if (~isequal([80 3], size(yourPredictions))) 11 | error ('The input to SaveECPredictions is not the right size.'); 12 | end 13 | 14 | save('ECPredictions.mat', 'yourPredictions'); 15 | 16 | 17 | end 18 | 19 | -------------------------------------------------------------------------------- /PA3/ImageSimilarity.m: -------------------------------------------------------------------------------- 1 | function sim = ImageSimilarity (im1, im2) 2 | % This function computes the "similarity score" between two images. You 3 | % should use the value for the similarity factor value when the two images 4 | % are assigned the same character. 5 | % 6 | % Input: 7 | % im1, im2: Two images from the provided dataset (they should be 16x8 8 | % matrices of 0s and 1s). 9 | % 10 | % Output: 11 | % sim: The similarity score of those images. 12 | 13 | a = im1(:); 14 | b = im2(:); 15 | 16 | meanSim = 0.283; % Avg sim score computed over held-out data. 17 | 18 | cosDist = (a' * b) / (norm(a) * norm(b)); 19 | 20 | if (cosDist > 3 * meanSim) 21 | sim = 5.0; 22 | else 23 | sim = 1.0; 24 | end 25 | 26 | end 27 | 28 | -------------------------------------------------------------------------------- /PA7/AssignmentToIndex.m: -------------------------------------------------------------------------------- 1 | % AssignmentToIndex Convert assignment to index. 2 | % 3 | % I = AssignmentToIndex(A, D) converts an assignment, A, over variables 4 | % with cardinality D to an index into the .val vector for a factor. 5 | % If A is a matrix then the function converts each row of A to an index. 6 | % 7 | % See also IndexToAssignment.m 8 | 9 | function I = AssignmentToIndex(A, D) 10 | 11 | D = D(:)'; % ensure that D is a row vector 12 | if (any(size(A) == 1)), 13 | I = cumprod([1, D(1:end - 1)]) * (A(:) - 1) + 1; 14 | else 15 | % I = sum(repmat(cumprod([1, D(1:end - 1)]), size(A, 1), 1) .* (A - 1), 2) + 1; 16 | I = sum( bsxfun(@times, cumprod([1, D(1:end - 1)]), (A - 1)) , 2) + 1; 17 | end; 18 | 19 | end 20 | -------------------------------------------------------------------------------- /PA7/ComputeUnconditionedPairFeatures.m: -------------------------------------------------------------------------------- 1 | function features = ComputeUnconditionedPairFeatures (y, modelParams) 2 | 3 | len = length(y); 4 | if (len < 2) 5 | features = []; 6 | return; 7 | end 8 | 9 | K = modelParams.numHiddenStates; 10 | nPairFeatures = (len - 1) * K * K; 11 | 12 | features(nPairFeatures) = EmptyFeatureStruct(); 13 | 14 | featureIdx = 0; 15 | for s1 = 1:K 16 | for s2 = 1:K 17 | paramVal = sub2ind([K K], s2, s1); 18 | for v = 1:(len - 1) 19 | featureIdx = featureIdx + 1; 20 | features(featureIdx).var = [v v+1]; 21 | features(featureIdx).assignment = [s1 s2]; 22 | features(featureIdx).paramIdx = paramVal; 23 | end 24 | end 25 | end 26 | 27 | 28 | end 29 | -------------------------------------------------------------------------------- /PA3/ComputeImageFactor.m: -------------------------------------------------------------------------------- 1 | function P = ComputeImageFactor (img, imgModel) 2 | % This function computes the singleton OCR factor values for a single 3 | % image. 4 | % 5 | % Input: 6 | % img: The 16x8 matrix of the image 7 | % imgModel: The provided, trained image model 8 | % 9 | % Output: 10 | % P: A K-by-1 array of the factor values for each of the K possible 11 | % character assignments to the given image 12 | 13 | X = img(:); 14 | N = length(X); 15 | K = imgModel.K; 16 | 17 | theta = reshape(imgModel.params(1:N*(K-1)), K-1, N); 18 | bias = reshape(imgModel.params((1+N*(K-1)):end), K-1, 1); 19 | 20 | W = [ bsxfun(@plus, theta * X, bias) ; 0 ]; 21 | W = bsxfun(@minus, W, max(W)); 22 | W = exp(W); 23 | 24 | P=bsxfun(@rdivide, W, sum(W)); 25 | 26 | 27 | end 28 | 29 | -------------------------------------------------------------------------------- /PA3/VisualizeWord.m: -------------------------------------------------------------------------------- 1 | function VisualizeWord (word) 2 | % This function allows you to visualize the characters for a single word. 3 | % 4 | % Input: 5 | % word: A struct array, each with an 'img' attribute that gives the 16x8 6 | % pixel matrix for that image. 7 | 8 | padding = zeros(size(word(1).img, 1), 1); 9 | 10 | totalWidth = 10 * length(word); 11 | im = zeros(16, totalWidth); 12 | for i = 1:length(word) 13 | charIm = [padding word(i).img padding]; 14 | im(:, (1 + 10 * (i-1)) + (1:10)) = charIm; 15 | end 16 | 17 | width = size(im, 2); 18 | padding = zeros(1, width); 19 | im = [padding; im; padding]; 20 | 21 | figure; 22 | colormap(gray); 23 | imagesc(1 - im); 24 | axis equal; 25 | [height, width] = size(im); 26 | axis([0 width 0 height]); 27 | 28 | end 29 | 30 | -------------------------------------------------------------------------------- /PA8/VisualizeModels.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: VisualizeModels.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function VisualizeModels(P, G) 7 | K = length(P.c); 8 | 9 | f = figure; 10 | while(1) 11 | for k=1:K 12 | subplot(1,K,k); 13 | if size(G,3) == 1 % same graph structure for all classes 14 | 15 | pose = SamplePose(P,G,k); 16 | 17 | else % different graph structure for each class 18 | 19 | pose = SamplePose(P,G(:,:,k),k); 20 | 21 | end 22 | 23 | img = ShowPose(pose); 24 | imshow(img); 25 | pause(0.3) 26 | if (~ishandle(f)) return; end; % quit loop when user closes the figure 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /PA7/MaxDecoding.m: -------------------------------------------------------------------------------- 1 | %MAXDECODING Finds the best assignment for each variable from the marginals 2 | %passed in. Returns A such that A(i) returns the index of the best 3 | %instantiation for variable i. 4 | % 5 | % For instance: Let's say we have two variables 1 and 2. 6 | % Marginals for 1 = [0.1, 0.3, 0.6] 7 | % Marginals for 2 = [0.92, 0.08] 8 | % A(1) = 3, A(2) = 1. 9 | % 10 | % See also COMPUTEEXACTMARGINALSBP 11 | 12 | % CS228 Probabilistic Graphical Models(Winter 2012) 13 | % Copyright (C) 2012, Stanford University 14 | 15 | function A = MaxDecoding( M ) 16 | 17 | % Compute the best assignment for variables in the network. 18 | A = zeros(1, length(M)); 19 | for i = 1:length(M) 20 | % Iterate through variables 21 | [maxVal, idx] = max(M(i).val); 22 | A(i) = idx; 23 | end 24 | 25 | end 26 | 27 | -------------------------------------------------------------------------------- /PA9/FactorMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMarginalization Sums given variables out of a factor in log space. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | 11 | function B = FactorMarginalization(A,V) 12 | B.var = A.var(2); 13 | B.card = A.card(1); 14 | Val = reshape(A.val,B.card,B.card); 15 | 16 | if(V==A.var(2)) 17 | Val = Val'; 18 | B.var = A.var(1); 19 | end 20 | 21 | B.val = log(sum(exp(bsxfun(@minus, Val, max(Val)))))+max(Val); 22 | -------------------------------------------------------------------------------- /PA6/SimpleOptimizeMEU.m: -------------------------------------------------------------------------------- 1 | function [MEU OptimalDecisionRule] = SimpleOptimizeMEU(I) 2 | 3 | % We assume there is only one decision rule in this function. 4 | D = I.DecisionFactors(1); 5 | 6 | PossibleDecisionRules = EnumerateDecisionRules(D); 7 | 8 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 | % 10 | % YOUR CODE HERE 11 | % 1. You must find which of the decision rules you have enumerated has the 12 | % highest expected utility. You should use your implementation of 13 | % SimpleCalcExpectedUtility from P1. Set the values of MEU and OptimalDecisionRule 14 | % to the best achieved expected utility and the corresponding decision 15 | % rule respectively. 16 | % 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | 20 | end 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /PA3/ComputeEqualPairwiseFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ComputeEqualPairwiseFactors (images, K) 2 | % This function computes the pairwise factors for one word in which every 3 | % factor value is set to be 1. 4 | % 5 | % Input: 6 | % images: An array of structs containing the 'img' value for each 7 | % character in the word. 8 | % K: The alphabet size (accessible in imageModel.K for the provided 9 | % imageModel). 10 | % 11 | % Output: 12 | % factors: The pairwise factors for this word. Every entry in the factor 13 | % vals should be 1. 14 | 15 | 16 | n = length(images); 17 | 18 | factors = repmat(struct('var', [], 'card', [], 'val', []), n - 1, 1); 19 | 20 | % Your code here: 21 | % factors = []; %% REMOVE THIS LINE 22 | for i = 1:n-1 23 | factors(i).var = [i+1,i]; 24 | factors(i).card = [K, K]; 25 | factors(i).val = ones(prod(factors(i).card),1); 26 | end 27 | 28 | end 29 | -------------------------------------------------------------------------------- /PA4/GetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | % GetValueOfAssignment Gets the value of a variable assignment in a factor. 2 | % 3 | % v = GetValueOfAssignment(F, A) returns the value of a variable assignment, 4 | % A, in factor F. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % v = GetValueOfAssignment(F, A, VO) gets the value of a variable assignment, 8 | % A, in factor F. The order of the variables in A are given by the vector VO. 9 | % 10 | % See also SetValueOfAssignment.m and SampleFactors.m 11 | 12 | function v = GetValueOfAssignment(F, A, VO) 13 | 14 | if (nargin == 2), 15 | indx = AssignmentToIndex(A, F.card); 16 | else 17 | map = zeros(length(F.var), 1); 18 | for i = 1:length(F.var), 19 | map(i) = find(VO == F.var(i)); 20 | end; 21 | indx = AssignmentToIndex(A(map), F.card); 22 | end; 23 | 24 | v = F.val(indx); 25 | 26 | end 27 | -------------------------------------------------------------------------------- /PA6/GetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | % GetValueOfAssignment Gets the value of a variable assignment in a factor. 2 | % 3 | % v = GetValueOfAssignment(F, A) returns the value of a variable assignment, 4 | % A, in factor F. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % v = GetValueOfAssignment(F, A, VO) gets the value of a variable assignment, 8 | % A, in factor F. The order of the variables in A are given by the vector VO. 9 | % 10 | % See also SetValueOfAssignment.m and SampleFactors.m 11 | 12 | function v = GetValueOfAssignment(F, A, VO) 13 | 14 | if (nargin == 2), 15 | indx = AssignmentToIndex(A, F.card); 16 | else 17 | map = zeros(length(F.var), 1); 18 | for i = 1:length(F.var), 19 | map(i) = find(VO == F.var(i)); 20 | end; 21 | indx = AssignmentToIndex(A(map), F.card); 22 | end; 23 | 24 | v = F.val(indx); 25 | 26 | end 27 | -------------------------------------------------------------------------------- /PA7/ComputeConditionedSingletonFeatures.m: -------------------------------------------------------------------------------- 1 | function features = ComputeConditionedSingletonFeatures (y, X, modelParams) 2 | 3 | [len, featureSize] = size(X); 4 | assert (len == length(y)); 5 | 6 | K = modelParams.numHiddenStates; 7 | L = modelParams.numObservedStates; 8 | 9 | numFeatures = len * K * featureSize; 10 | features(numFeatures) = EmptyFeatureStruct(); 11 | 12 | featureIdx = 0; 13 | 14 | for hiddenSt = 1:K 15 | for featureNum = 1:featureSize 16 | for v = 1:len 17 | featureIdx = featureIdx + 1; 18 | obs = X(v, featureNum); 19 | features(featureIdx).var = v; 20 | features(featureIdx).assignment = hiddenSt; 21 | features(featureIdx).paramIdx = sub2ind([L featureSize K], ... 22 | obs, featureNum, hiddenSt); 23 | end 24 | end 25 | end 26 | 27 | end 28 | -------------------------------------------------------------------------------- /PA6/NormalizeCPDFactors.m: -------------------------------------------------------------------------------- 1 | function [F] = NormalizeCPDFactors(F) 2 | 3 | NumFactors = length(F); 4 | for i=1:NumFactors 5 | 6 | f = F(i); 7 | dummy.var = f.var(2:end); 8 | dummy.card = f.card(2:end); 9 | dummy.val = zeros(1,prod(dummy.card)); 10 | 11 | % Now for each joint assignment to parents, renormalize the 12 | % values for that joint assignment to sum to 1. 13 | 14 | for a=1:length(dummy.val) 15 | A = IndexToAssignment(a, dummy.card); 16 | Indices = []; 17 | for d=1:f.card(end) 18 | Indices = [Indices AssignmentToIndex([d A], f.card);]; 19 | end 20 | if sum(f.val(Indices)) == 0 21 | % Set f.val(Indices) to 0 22 | f.val(Indices) = 0; 23 | else 24 | f.val(Indices) = f.val(Indices) / sum(f.val(Indices)); 25 | end 26 | end 27 | 28 | f.val(find(isnan(f.val))) = 0; 29 | 30 | F(i) = f; 31 | 32 | end 33 | 34 | -------------------------------------------------------------------------------- /PA3/ComputeAllSimilarityFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ComputeAllSimilarityFactors (images, K) 2 | % This function computes all of the similarity factors for the images in 3 | % one word. 4 | % 5 | % Input: 6 | % images: An array of structs containing the 'img' value for each 7 | % character in the word. 8 | % K: The alphabet size (accessible in imageModel.K for the provided 9 | % imageModel). 10 | % 11 | % Output: 12 | % factors: Every similarity factor in the word. You should use 13 | % ComputeSimilarityFactor to compute these. 14 | 15 | n = length(images); 16 | nFactors = nchoosek (n, 2); 17 | 18 | factors = repmat(struct('var', [], 'card', [], 'val', []), nFactors, 1); 19 | 20 | % Your code here: 21 | % factors = []; %% REMOVE THIS LINE 22 | Count = 0; 23 | for i = 1:n 24 | for j = i+1:n 25 | Count = Count + 1; 26 | factors(Count) = ComputeSimilarityFactor (images, K, i, j); 27 | end 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /PA5/randi.m: -------------------------------------------------------------------------------- 1 | function [num mv] = randi(arg1,arg2,arg3) 2 | 3 | num = -1; 4 | persistent x_i; 5 | persistent p1; 6 | persistent p2; 7 | if(isempty(x_i)) 8 | x_i = 1; 9 | p1 = 160481183; 10 | p2 = 179424673; 11 | end 12 | mv=p2; 13 | if(ischar(arg1)==1) 14 | if(strcmp(arg1,'seed')) 15 | if(nargin>1) 16 | x_i = arg2; 17 | num = 0; 18 | else 19 | x_i=1; 20 | num=0; 21 | end 22 | else 23 | 'Unrecognized option. The only accepted option to this random library is -seed-.' 24 | end 25 | else 26 | if(arg1>p2) 27 | 'Max too high, range cutoff at 1 million' 28 | end 29 | if(nargin>1) 30 | if(nargin==2) 31 | arg3=arg2; 32 | end 33 | num = zeros(arg2,arg3); 34 | for i=1:arg2 35 | for j = 1:arg3 36 | x_i = mod(x_i*(p1+1)+p1,p2); 37 | num(i,j) = mod(x_i,arg1)+1; 38 | end 39 | end 40 | else 41 | x_i = mod(x_i*(p1+1)+p1,p2); 42 | num=mod(x_i,arg1)+1; 43 | end 44 | end 45 | 46 | -------------------------------------------------------------------------------- /PA7/ComputeJointDistribution.m: -------------------------------------------------------------------------------- 1 | %ComputeJointDistribution Computes the joint distribution defined by a set 2 | % of given factors 3 | % 4 | % Joint = ComputeJointDistribution(F) computes the joint distribution 5 | % defined by a set of given factors 6 | % 7 | % Joint is a factor that encapsulates the joint distribution given by F 8 | % F is a vector of factors (struct array) containing the factors 9 | % defining the distribution 10 | % 11 | 12 | function Joint = ComputeJointDistribution(F) 13 | 14 | % Check for empty factor list 15 | assert(numel(F) ~= 0, 'Error: empty factor list'); 16 | 17 | if (length(F) == 0) 18 | % There are no factors, so create an empty factor list 19 | Joint = struct('var', [], 'card', [], 'val', []); 20 | else 21 | Joint = F(1); 22 | for i = 2:length(F) 23 | % Iterate through factors and incorporate them into the joint distribution 24 | Joint = FactorProduct(Joint, F(i)); 25 | end 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /PA5/GetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | %GETVALUEOFASSIGNMENT Gets the value of a variable assignment in a factor. 2 | % 3 | % v = GETVALUEOFASSIGNMENT(F, A) returns the value of a variable assignment, 4 | % A, in factor F. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % v = GETVALUEOFASSIGNMENT(F, A, VO) gets the value of a variable assignment, 8 | % A, in factor F. The order of the variables in A are given by the vector VO. 9 | % 10 | % See also SETVALUEOFASSIGNMENT 11 | 12 | % CS228 Probabilistic Models in AI (Winter 2007) 13 | % Copyright (C) 2007, Stanford University 14 | 15 | function v = GetValueOfAssignment(F, A, VO); 16 | 17 | if (nargin == 2), 18 | indx = AssignmentToIndex(A, F.card); 19 | else 20 | map = zeros(length(F.var), 1); 21 | for i = 1:length(F.var), 22 | map(i) = find(VO == F.var(i)); 23 | end; 24 | indx = AssignmentToIndex(A(map), F.card); 25 | end; 26 | 27 | v = F.val(indx); 28 | -------------------------------------------------------------------------------- /PA7/GetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | %GETVALUEOFASSIGNMENT Gets the value of a variable assignment in a factor. 2 | % 3 | % v = GETVALUEOFASSIGNMENT(F, A) returns the value of a variable assignment, 4 | % A, in factor F. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % v = GETVALUEOFASSIGNMENT(F, A, VO) gets the value of a variable assignment, 8 | % A, in factor F. The order of the variables in A are given by the vector VO. 9 | % 10 | % See also SETVALUEOFASSIGNMENT 11 | 12 | % CS228 Probabilistic Models in AI (Winter 2007) 13 | % Copyright (C) 2007, Stanford University 14 | 15 | function v = GetValueOfAssignment(F, A, VO); 16 | 17 | if (nargin == 2), 18 | indx = AssignmentToIndex(A, F.card); 19 | else 20 | map = zeros(length(F.var), 1); 21 | for i = 1:length(F.var), 22 | map(i) = find(VO == F.var(i)); 23 | end; 24 | indx = AssignmentToIndex(A(map), F.card); 25 | end; 26 | 27 | v = F.val(indx); 28 | -------------------------------------------------------------------------------- /PA7/ComputeMarginal.m: -------------------------------------------------------------------------------- 1 | %ComputeMarginal Computes the marginal over a set of given variables 2 | % M = ComputeMarginal(V, F, E) computes the marginal over variables V 3 | % in the distribution induced by the set of factors F, given evidence E 4 | % 5 | % M is a factor containing the marginal over variables V 6 | % V is a vector containing the variables in the marginal e.g. [1 2 3] for 7 | % X_1, X_2 and X_3. 8 | % F is a vector of factors (struct array) containing the factors 9 | % defining the distribution 10 | % E is an N-by-2 matrix, each row being a variable/value pair. 11 | % Variables are in the first column and values are in the second column. 12 | 13 | 14 | function M = ComputeMarginal(V, F, E) 15 | 16 | % Check for empty factor list 17 | assert(numel(F) ~= 0, 'Error: empty factor list'); 18 | 19 | F = ObserveEvidence(F, E); 20 | Joint = ComputeJointDistribution(F); 21 | Joint.val = Joint.val ./ sum(Joint.val); 22 | M = FactorMarginalization(Joint, setdiff(Joint.var, V)); 23 | end 24 | -------------------------------------------------------------------------------- /PA4/MaxDecoding.m: -------------------------------------------------------------------------------- 1 | %MAXDECODING Finds the best assignment for each variable from the marginals M 2 | %passed in. Returns A such that A(i) returns the index of the best 3 | %instantiation for variable i. 4 | % 5 | % For instance: Let's say we have two variables 1 and 2. 6 | % Marginals for 1 = [0.1, 0.3, 0.6] 7 | % Marginals for 2 = [0.92, 0.08] 8 | % A(1) = 3, A(2) = 1. 9 | % 10 | % M is a list of factors, where each factor is only over one variable. 11 | % 12 | % See also ComputeExactMarginalsBP 13 | 14 | % CS228 Probabilistic Graphical Models(Winter 2012) 15 | % Copyright (C) 2012, Stanford University 16 | 17 | function A = MaxDecoding( M ) 18 | 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | % YOUR CODE HERE 21 | % Compute the best assignment for variables in the network. 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | 24 | A = ones(1, length(M)); 25 | 26 | for i = 1:length(A) 27 | [dummy, index] = max(M(i).val); 28 | A(i) = index; 29 | end 30 | 31 | end 32 | 33 | -------------------------------------------------------------------------------- /PA5/SetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | %SETVALUEOFASSIGNMENT Sets the value of a variable assignment in a factor. 2 | % 3 | % F = SETVALUEOFASSIGNMENT(F, A, v) sets the value of a variable assignment, 4 | % A, in factor F to v. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % F = SETVALUEOFASSIGNMENT(F, A, v, VO) sets the value of a variable 8 | % assignment, A, in factor F to v. The order of the variables in A are given 9 | % by the vector VO. 10 | % 11 | % See also GETVALUEOFASSIGNMENT 12 | 13 | % CS228 Probabilistic Models in AI (Winter 2007) 14 | % Copyright (C) 2007, Stanford University 15 | 16 | function F = SetValueOfAssignment(F, A, v, VO); 17 | 18 | if (nargin == 3), 19 | indx = AssignmentToIndex(A, F.card); 20 | else 21 | map = zeros(length(F.var), 1); 22 | for i = 1:length(F.var), 23 | map(i) = find(VO == F.var(i)); 24 | end; 25 | indx = AssignmentToIndex(A(map), F.card); 26 | end; 27 | 28 | F.val(indx) = v; 29 | -------------------------------------------------------------------------------- /PA7/SetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | %SETVALUEOFASSIGNMENT Sets the value of a variable assignment in a factor. 2 | % 3 | % F = SETVALUEOFASSIGNMENT(F, A, v) sets the value of a variable assignment, 4 | % A, in factor F to v. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % F = SETVALUEOFASSIGNMENT(F, A, v, VO) sets the value of a variable 8 | % assignment, A, in factor F to v. The order of the variables in A are given 9 | % by the vector VO. 10 | % 11 | % See also GETVALUEOFASSIGNMENT 12 | 13 | % CS228 Probabilistic Models in AI (Winter 2007) 14 | % Copyright (C) 2007, Stanford University 15 | 16 | function F = SetValueOfAssignment(F, A, v, VO); 17 | 18 | if (nargin == 3), 19 | indx = AssignmentToIndex(A, F.card); 20 | else 21 | map = zeros(length(F.var), 1); 22 | for i = 1:length(F.var), 23 | map(i) = find(VO == F.var(i)); 24 | end; 25 | indx = AssignmentToIndex(A(map), F.card); 26 | end; 27 | 28 | F.val(indx) = v; 29 | -------------------------------------------------------------------------------- /PA3/ComputeSingletonFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ComputeSingletonFactors (images, imageModel) 2 | % This function computes the single OCR factors for all of the images in a 3 | % word. 4 | % 5 | % Input: 6 | % images: An array of structs containing the 'img' value for each 7 | % character in the word. You could, for example, pass in allWords{1} to 8 | % use the first word of the provided dataset. 9 | % imageModel: The provided OCR image model. 10 | % 11 | % Output: 12 | % factors: An array of the OCR factors, one for every character in the 13 | % image. 14 | % 15 | % Hint: You will want to use ComputeImageFactor.m when computing the 'val' 16 | % entry for each factor. 17 | 18 | % The number of characters in the word 19 | n = length(images); 20 | 21 | % Preallocate the array of factors 22 | factors = repmat(struct('var', [], 'card', [], 'val', []), n, 1); 23 | 24 | % Your code here: 25 | 26 | for i = 1:n; 27 | factors(i).var = [i]; 28 | factors(i).card = imageModel.K; 29 | factors(i).val = ComputeImageFactor( images(i).img, imageModel ); 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /PA5/MHUniformTrans.m: -------------------------------------------------------------------------------- 1 | % MHUNIFORMTRANS 2 | % 3 | % MCMC Metropolis-Hastings transition function that 4 | % utilizes the uniform proposal distribution. 5 | % A - The current joint assignment. This should be 6 | % updated to be the next assignment 7 | % G - The network 8 | % F - List of all factors 9 | function A = MHUniformTrans(A, G, F) 10 | 11 | % Draw proposed new state from uniform distribution 12 | A_prop = ceil(rand(1, length(A)) .* G.card); 13 | 14 | p_acceptance = 0.0; 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | % YOUR CODE HERE 17 | % Compute acceptance probability 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | 20 | forward = 1.0; 21 | backward = 1.0; 22 | 23 | for i = 1:length(F), 24 | forward = forward * GetValueOfAssignment(F(i), A_prop(F(i).var) ); 25 | backward = backward * GetValueOfAssignment(F(i), A(F(i).var) ); 26 | end 27 | 28 | p_acceptance = min([ 1 (forward / backward) ]); 29 | 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | 32 | % Accept or reject proposal 33 | if rand() < p_acceptance 34 | % disp('Accepted'); 35 | A = A_prop; 36 | end -------------------------------------------------------------------------------- /PA8/LearnGraphStructure.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: LearnGraphStructure.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function [A W] = LearnGraphStructure(dataset) 7 | 8 | % Input: 9 | % dataset: N x 10 x 3, N poses represented by 10 parts in (y, x, alpha) 10 | % 11 | % Output: 12 | % A: maximum spanning tree computed from the weight matrix W 13 | % W: 10 x 10 weight matrix, where W(i,j) is the mutual information between 14 | % node i and j. 15 | 16 | N = size(dataset, 1); 17 | K = size(dataset, 3); 18 | 19 | numparts = size(dataset, 2); 20 | W = zeros(numparts); 21 | 22 | % Compute weight matrix W 23 | % set the weights following Eq. (14) in PA description 24 | % you don't have to include M since all entries are scaled by the same M 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | % YOUR CODE HERE 27 | %%%%%%%%%%%%%%%%%%%%%%%%%%% 28 | 29 | for i = 1:numparts 30 | for j = 1:numparts 31 | Oi(:,:) = dataset(:, i, :); 32 | Oj(:,:) = dataset(:, j, :); 33 | W(i,j) = GaussianMutualInformation(Oi, Oj); 34 | end 35 | end 36 | 37 | % Compute maximum spanning tree 38 | A = MaxSpanningTree(W); 39 | -------------------------------------------------------------------------------- /PA5/GetNextClusters.m: -------------------------------------------------------------------------------- 1 | %GETNEXTCLUSTERS Takes in a cluster graph and returns the indices 2 | % of the nodes between which the next message should be passed. 3 | % 4 | % [i j] = GetNextClusters(P,Messages,oldMessages,m,useSmart) 5 | % 6 | % INPUT 7 | % P - our cluster graph 8 | % Messages - the current values of all messages in P 9 | % oldMessages - the previous values of all messages in P. Thus, 10 | % oldMessages(i,j) contains the value that Messages(i,j) contained 11 | % immediately before it was updated to its current value 12 | % m - the index of the message we are passing (ie, m=0 indicates we have 13 | % passed 0 messages prior to this one. m=5 means we've passed 5 messages 14 | % useSmart - indicates whether we should use the Naive or Smart message 15 | % passing order 16 | % 17 | % 18 | % Output [i j] 19 | % i = the origin of the m+1th message 20 | % j = the destination of the m+1th message 21 | % 22 | 23 | function [i j] = GetNextClusters(P,Messages,oldMessages,m,useSmart) 24 | 25 | if(~exist('useSmart','var')||~useSmart) 26 | [i j] = NaiveGetNextClusters(P,m); 27 | else 28 | [i j] = SmartGetNextClusters(P,Messages,oldMessages,m); 29 | end 30 | -------------------------------------------------------------------------------- /PA5/GibbsTrans.m: -------------------------------------------------------------------------------- 1 | % GIBBSTRANS 2 | % 3 | % MCMC transition function that performs Gibbs sampling. 4 | % A - The current joint assignment. This should be 5 | % updated to be the next assignment 6 | % G - The network 7 | % F - List of all factors 8 | function A = GibbsTrans(A, G, F) 9 | 10 | vars = unique([F(:).var]); 11 | 12 | for i = 1:length(G.names) 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | % YOUR CODE HERE 15 | % For each variable in the network sample a new value for it given everything 16 | % else consistent with A. Then update A with this new value for the 17 | % variable. NOTE: Your code should call BlockLogDistribution(). 18 | % IMPORTANT: you should call the function randsample() exactly once 19 | % here, and it should be the only random function you call. 20 | % 21 | % Also, note that randsample() requires arguments in raw probability space 22 | % be sure that the arguments you pass to it meet that criteria 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | 25 | lprob = BlockLogDistribution(vars(i), G, F, A); 26 | prob = exp(lprob); 27 | A(vars(i)) = randsample(G.card(vars(i)), 1, true, prob); 28 | 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | end 31 | -------------------------------------------------------------------------------- /PA3/ChooseTopSimilarityFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ChooseTopSimilarityFactors (allFactors, F) 2 | % This function chooses the similarity factors with the highest similarity 3 | % out of all the possibilities. 4 | % 5 | % Input: 6 | % allFactors: An array of all the similarity factors. 7 | % F: The number of factors to select. 8 | % 9 | % Output: 10 | % factors: The F factors out of allFactors for which the similarity score 11 | % is highest. 12 | % 13 | % Hint: Recall that the similarity score for two images will be in every 14 | % factor table entry (for those two images' factor) where they are 15 | % assigned the same character value. 16 | 17 | 18 | % If there are fewer than F factors total, just return all of them. 19 | if (length(allFactors) <= F) 20 | factors = allFactors; 21 | return; 22 | end 23 | 24 | % Your code here: 25 | % factors = allFactors; %%% REMOVE THIS LINE 26 | 27 | scores = zeros(length(allFactors), 1); 28 | 29 | for i = 1:length(allFactors) 30 | index = AssignmentToIndex([1, 1], allFactors(i).card); 31 | scores(i) = allFactors(i).val(index); 32 | end 33 | 34 | [sorted, ordering] = sort(scores); 35 | 36 | sortedFactors = allFactors(ordering); 37 | 38 | factors = sortedFactors(end:-1:end-F+1); 39 | 40 | end 41 | 42 | -------------------------------------------------------------------------------- /PA4/SetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | % SetValueOfAssignment Sets the value of a variable assignment in a factor. 2 | % 3 | % F = SetValueOfAssignment(F, A, v) sets the value of a variable assignment, 4 | % A, in factor F to v. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % F = SetValueOfAssignment(F, A, v, VO) sets the value of a variable 8 | % assignment, A, in factor F to v. The order of the variables in A are given 9 | % by the vector VO. 10 | % 11 | % Note that SetValueOfAssignment *does not modify* the factor F that is 12 | % passed into the function, but instead returns a modified factor with the 13 | % new value(s) for the specified assignment(s). This is why we have to 14 | % reassign F to the result of SetValueOfAssignment in the code snippets 15 | % shown above. 16 | % 17 | % See also GetValueOfAssignment.m and SampleFactors.m 18 | 19 | function F = SetValueOfAssignment(F, A, v, VO) 20 | 21 | if (nargin == 3), 22 | indx = AssignmentToIndex(A, F.card); 23 | else 24 | map = zeros(length(F.var), 1); 25 | for i = 1:length(F.var), 26 | map(i) = find(VO == F.var(i)); 27 | end; 28 | indx = AssignmentToIndex(A(map), F.card); 29 | end; 30 | 31 | F.val(indx) = v; 32 | 33 | end 34 | -------------------------------------------------------------------------------- /PA6/SetValueOfAssignment.m: -------------------------------------------------------------------------------- 1 | % SetValueOfAssignment Sets the value of a variable assignment in a factor. 2 | % 3 | % F = SetValueOfAssignment(F, A, v) sets the value of a variable assignment, 4 | % A, in factor F to v. The order of the variables in A are assumed to be the 5 | % same as the order in F.var. 6 | % 7 | % F = SetValueOfAssignment(F, A, v, VO) sets the value of a variable 8 | % assignment, A, in factor F to v. The order of the variables in A are given 9 | % by the vector VO. 10 | % 11 | % Note that SetValueOfAssignment *does not modify* the factor F that is 12 | % passed into the function, but instead returns a modified factor with the 13 | % new value(s) for the specified assignment(s). This is why we have to 14 | % reassign F to the result of SetValueOfAssignment in the code snippets 15 | % shown above. 16 | % 17 | % See also GetValueOfAssignment.m and SampleFactors.m 18 | 19 | function F = SetValueOfAssignment(F, A, v, VO) 20 | 21 | if (nargin == 3), 22 | indx = AssignmentToIndex(A, F.card); 23 | else 24 | map = zeros(length(F.var), 1); 25 | for i = 1:length(F.var), 26 | map(i) = find(VO == F.var(i)); 27 | end; 28 | indx = AssignmentToIndex(A(map), F.card); 29 | end; 30 | 31 | F.val(indx) = v; 32 | 33 | end 34 | -------------------------------------------------------------------------------- /PA3/ComputeSimilarityFactor.m: -------------------------------------------------------------------------------- 1 | function factor = ComputeSimilarityFactor (images, K, i, j) 2 | % This function computes the similarity factor between two character images 3 | % in one word --- which characters is given by indices i and j (a 4 | % description of how the factor should be computed is given below). 5 | % 6 | % Input: 7 | % images: A struct array of character images from one word. 8 | % K: The alphabet size. 9 | % i,j: The scope of that factor. That is, you should construct a factor 10 | % between characters i and j in the images array. 11 | % 12 | % Output: 13 | % factor: The similarity factor between these two characters. For any 14 | % assignment C_i != C_j, the factor value should be one. For any 15 | % assignment C_i == C_j, the factor value should be 16 | % ImageSimilarity(I_i, I_j) --- ie, the computed value given by 17 | % ImageSimilarity.m on the two images. 18 | 19 | factor = struct('var', [], 'card', [], 'val', []); 20 | 21 | n = length(images); 22 | 23 | % Your code here: 24 | factor.var = [i, j]; 25 | factor.card = [K, K]; 26 | 27 | factor.val = ones(prod(factor.card), 1); 28 | for kk = 1:K 29 | index = AssignmentToIndex([kk, kk], factor.card); 30 | factor.val(index) = ImageSimilarity(images(i).img, images(j).img); 31 | end 32 | 33 | end 34 | 35 | -------------------------------------------------------------------------------- /PA4/ComputeMarginal.m: -------------------------------------------------------------------------------- 1 | %ComputeMarginal Computes the marginal over a set of given variables 2 | % M = ComputeMarginal(V, F, E) computes the marginal over variables V 3 | % in the distribution induced by the set of factors F, given evidence E 4 | % 5 | % M is a factor containing the marginal over variables V 6 | % V is a vector containing the variables in the marginal e.g. [1 2 3] for 7 | % X_1, X_2 and X_3. 8 | % F is a vector of factors (struct array) containing the factors 9 | % defining the distribution 10 | % E is an N-by-2 matrix, each row being a variable/value pair. 11 | % Variables are in the first column and values are in the second column. 12 | 13 | 14 | function M = ComputeMarginal(V, F, E) 15 | 16 | % Check for empty factor list 17 | assert(numel(F) ~= 0, 'Error: empty factor list'); 18 | 19 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20 | % YOUR CODE HERE: 21 | % M should be a factor 22 | % Remember to renormalize the entries of M! 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | F = ObserveEvidence(F, E); 25 | Joint = ComputeJointDistribution(F); 26 | Joint.val = Joint.val ./ sum(Joint.val); 27 | M = FactorMarginalization(Joint, setdiff(Joint.var, V)); 28 | %M.val = M.val ./ sum(M.val); 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | end 31 | -------------------------------------------------------------------------------- /PA9/YourMethod.txt: -------------------------------------------------------------------------------- 1 | Describe your method used to recognize the unknown actions here. 2 | 3 | Start with training a different model for each of the training actions. 4 | 5 | Start with obtaining better initial probability estimates for class assignments for the poses. 6 | Use gmdistribution.fit method to find gaussian mixture with K components that best fits data of poses. 7 | The result probability gaussian mixture model is random to some extent. 8 | Needed to do some wrangling to get the clustering to work on 30-dimensional data. 9 | Then use posterior probabilities of which poses are assigned components for initial hidden state probabilities. 10 | Once InitialClassProb are initialized, we initialize InitialPairProb accordingly. We initialize each row of InitialPairProb as the same, representing state transform probability. 11 | Using the EM method to train an HMM. 12 | 13 | Then test for each action, by computing likelihood over each of the models. 14 | We compute the likelihood by constructing a clique tree consisting of three types of factors. 15 | The initial state prior, the transition CPDs and the emission CPDs. 16 | Calibrating this clique tree yields the likelihood from the unormalized beliefs after message passing is completed. 17 | 18 | We then choose the model with highest likelihood, and state that as our prediction. 19 | -------------------------------------------------------------------------------- /PA3/SerializeFactorsFg.m: -------------------------------------------------------------------------------- 1 | function out = SerializeFactorsFg(F) 2 | % Serializes a factor struct array into the .fg format for libDAI 3 | % http://cs.ru.nl/~jorism/libDAI/doc/fileformats.html 4 | % 5 | % To avoid incompatibilities with EOL markers, make sure you write the 6 | % string to a file using the appropriate file type ('wt' for windows, 'w' 7 | % for unix) 8 | 9 | 10 | lines = cell(5*numel(F) + 1, 1); 11 | 12 | lines{1} = sprintf('%d\n', numel(F)); 13 | lineIdx = 2; 14 | for i = 1:numel(F) 15 | lines{lineIdx} = sprintf('\n%d\n', numel(F(i).var)); 16 | lineIdx = lineIdx + 1; 17 | 18 | lines{lineIdx} = sprintf('%s\n', num2str(F(i).var(:)')); % ensure that we put in a row vector 19 | lineIdx = lineIdx + 1; 20 | 21 | lines{lineIdx} = sprintf('%s\n', num2str(F(i).card(:)')); % ensure that we put in a row vector 22 | lineIdx = lineIdx + 1; 23 | 24 | lines{lineIdx} = sprintf('%d\n', numel(F(i).val)); 25 | lineIdx = lineIdx + 1; 26 | 27 | % Internal storage of factor vals is already in the same indexing order 28 | % as what libDAI expects, so we don't need to convert the indices. 29 | vals = [0:(numel(F(i).val) - 1); F(i).val(:)']; 30 | lines{lineIdx} = sprintf('%d %0.8g\n', vals); 31 | lineIdx = lineIdx + 1; 32 | end 33 | 34 | out = sprintf('%s', lines{:}); 35 | end 36 | -------------------------------------------------------------------------------- /PA4/ComputeJointDistribution.m: -------------------------------------------------------------------------------- 1 | %ComputeJointDistribution Computes the joint distribution defined by a set 2 | % of given factors 3 | % 4 | % Joint = ComputeJointDistribution(F) computes the joint distribution 5 | % defined by a set of given factors 6 | % 7 | % Joint is a factor that encapsulates the joint distribution given by F 8 | % F is a vector of factors (struct array) containing the factors 9 | % defining the distribution 10 | % 11 | 12 | function Joint = ComputeJointDistribution(F) 13 | 14 | % Check for empty factor list 15 | assert(numel(F) ~= 0, 'Error: empty factor list'); 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | % YOUR CODE HERE: 19 | % Compute the joint distribution defined by F 20 | % You may assume that you are given legal CPDs so no input checking is required. 21 | % Find the factor product of all of the factors 22 | if (length(F) == 0) 23 | % There are no factors, so create an empty factor list 24 | Joint = struct('var', [], 'card', [], 'val', []); 25 | else 26 | Joint = F(1); 27 | for i = 2:length(F) 28 | % Iterate through factors and incorporate them into the joint distribution 29 | Joint = FactorProduct(Joint, F(i)); 30 | end 31 | end 32 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 | end 34 | 35 | -------------------------------------------------------------------------------- /PA6/CPDFromFactor.m: -------------------------------------------------------------------------------- 1 | function [CPD] = CPDFromFactor(F, Y) 2 | nvars = length(F.var); 3 | 4 | % Reorder the var, card and val fields of Fnew so that the last var is the 5 | % child variable. 6 | Fnew = F; 7 | YIndexInF = find(F.var == Y); 8 | this.card = F.card( YIndexInF ); 9 | 10 | % Parents is a dummy factor 11 | Parents.var = F.var(find(F.var ~= Y)); 12 | Parents.card = F.card(find(F.var ~= Y)); 13 | Parents.val = ones(prod(Parents.card),1); 14 | 15 | Fnew.var = [Parents.var Y]; 16 | Fnew.card = [Parents.card this.card]; 17 | for i=1:length(F.val) 18 | A = IndexToAssignment(i, F.card); 19 | y = A(YIndexInF); 20 | A( YIndexInF ) = []; 21 | A = [A y]; 22 | j = AssignmentToIndex(A, Fnew.card); 23 | Fnew.val(j) = F.val(i); 24 | end 25 | 26 | % For each assignment of Parents... 27 | for i=1:length(Parents.val) 28 | 29 | A = IndexToAssignment(i, Parents.card); 30 | SumValuesForA = 0; 31 | for j=1:this.card 32 | A_augmented = [A j]; 33 | idx = AssignmentToIndex(A_augmented, Fnew.card); 34 | SumValuesForA = SumValuesForA + Fnew.val( idx ); 35 | end 36 | 37 | for j=1:this.card 38 | A_augmented = [A j]; 39 | idx = AssignmentToIndex(A_augmented, Fnew.card); 40 | Fnew.val( idx ) = Fnew.val( idx ) / SumValuesForA; 41 | end 42 | 43 | end 44 | 45 | CPD = Fnew; -------------------------------------------------------------------------------- /PA7/LRSearchLambdaSGD.m: -------------------------------------------------------------------------------- 1 | % function allAcc = LRSearchLambdaSGD(Xtrain, Ytrain, Xvalidation, Yvalidation, lambdas) 2 | % For each value of lambda provided, fit parameters to the training data and return 3 | % the accuracy in the validation data in the corresponding entry of allAcc. 4 | % For instance, allAcc(i) = accuracy in the validation set using lambdas(i). 5 | % 6 | % Inputs: 7 | % Xtrain training data features (numTrainInstances x numFeatures) 8 | % Ytrain training set labels (numTrainInstances x 1) 9 | % Xvalidation validation data features (numValidInstances x num features) 10 | % Yvalidation validation set labels (numValidInstances x 1) 11 | % lambdas values of lambda to try (numLambdas x 1) 12 | % 13 | % Output: 14 | % allAcc vector of accuracies in validation set (numLambdas x 1) 15 | 16 | function allAcc = LRSearchLambdaSGD(Xtrain, Ytrain, Xvalidation, Yvalidation, lambdas) 17 | 18 | % You may use the functions we have provided such as LRTrainSGD, LRPredict, and LRAccuracy. 19 | 20 | %%%%%%%%%%%%%% 21 | %%% Student code 22 | 23 | allAcc = zeros(length(lambdas), 1); 24 | 25 | for i = 1:length(lambdas), 26 | thetaOpt = LRTrainSGD(Xtrain, Ytrain, lambdas(i)); 27 | pred = LRPredict(Xvalidation, thetaOpt); 28 | allAcc(i) = LRAccuracy(Yvalidation, pred); 29 | end 30 | 31 | %%%%%%%%%%% 32 | 33 | end 34 | -------------------------------------------------------------------------------- /PA8/LearnGraphAndCPDs.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: LearnGraphAndCPDs.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function [P G loglikelihood] = LearnGraphAndCPDs(dataset, labels) 7 | 8 | % dataset: N x 10 x 3, N poses represented by 10 parts in (y, x, alpha) 9 | % labels: N x 2 true class labels for the examples. labels(i,j)=1 if the 10 | % the ith example belongs to class j 11 | 12 | N = size(dataset, 1); 13 | K = size(labels, 2); 14 | 15 | G = zeros(10,2,K); % graph structures to learn 16 | % initialization 17 | for k=1:K 18 | G(2:end,:,k) = ones(9,2); 19 | end 20 | 21 | % estimate graph structure for each class 22 | for k=1:K 23 | % fill in G(:,:,k) 24 | % use ConvertAtoG to convert a maximum spanning tree to a graph G 25 | %%%%%%%%%%%%%%%%%%%%%%%%% 26 | % YOUR CODE HERE 27 | %%%%%%%%%%%%%%%%%%%%%%%%% 28 | [A W] = LearnGraphStructure(dataset(labels(:,k) == 1, :, :)); 29 | G(:,:,k) = ConvertAtoG(A); 30 | end 31 | 32 | % estimate parameters 33 | 34 | P.c = zeros(1,K); 35 | % compute P.c 36 | 37 | % the following code can be copied from LearnCPDsGivenGraph.m 38 | % with little or no modification 39 | %%%%%%%%%%%%%%%%%%%%%%%%% 40 | % YOUR CODE HERE 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | 43 | [P loglikelihood] = LearnCPDsGivenGraph(dataset, G, labels); 44 | 45 | fprintf('log likelihood: %f\n', loglikelihood); 46 | -------------------------------------------------------------------------------- /PA5/NaiveGetNextClusters.m: -------------------------------------------------------------------------------- 1 | %NAIVEGETNEXTCLUSTERS Takes in a node adjacency matrix and returns the indices 2 | % of the nodes between which the m+1th message should be passed. 3 | % 4 | % Output [i j] 5 | % i = the origin of the m+1th message 6 | % j = the destination of the m+1th message 7 | % 8 | % This method should iterate over the messages in increasing order where 9 | % messages are sorted in ascending ordered by their destination index and 10 | % ties are broken based on the origin index. (note: this differs from PA4's 11 | % ordering) 12 | % 13 | % Thus, if m is 0, [i j] will be the pair of clusters with the lowest j value 14 | % and (of those pairs over this j) lowest i value as this is the 'first' 15 | % element in our ordering. 16 | 17 | 18 | function [i, j] = NaiveGetNextClusters(P, m) 19 | 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | % YOUR CODE HERE 22 | % Find the indices between which to pass a cluster 23 | % The 'find' function may be useful 24 | % 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | [lli, llj] = find(P.edges, prod(size(P.edges))); 27 | numMessages = size(lli, 1); 28 | tempm = mod(m, numMessages); 29 | [tempi, tempj] = find(P.edges, tempm+1); 30 | i = tempi(end); 31 | j = tempj(end); 32 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /PA5/ExtractMarginalsFromSamples.m: -------------------------------------------------------------------------------- 1 | %EXTRACTMARGINALSFROMSAMPLES 2 | % 3 | % ExtractMarginalsFromSamples takes in a probabilistic network G, a list of samples, and a set 4 | % of indices into samples that specify which samples to use in the computation of the 5 | % marginals. The marginals are then computed using this subset of samples and returned. 6 | % 7 | % Samples is a matrix where each row is the assignment to all variables in 8 | % the network (samples(i,j)=k means in sample i the jth variable takes label k) 9 | % 10 | function M = ExtractMarginalsFromSamples(G, samples, collection_indx) 11 | 12 | collected_samples = samples(collection_indx, :); 13 | 14 | M = repmat(struct('var', 0, 'card', 0, 'val', []), length(G.names), 1); 15 | for i = 1:length(G.names) 16 | M(i).var = i; 17 | M(i).card = G.card(i); 18 | M(i).val = zeros(1, G.card(i)); 19 | end 20 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21 | % YOUR CODE HERE 22 | % Populate M so that M(i) contains the marginal probability over 23 | % variable i 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | 26 | for i = 1:length(G.names) 27 | for val = 1:M(i).card 28 | p = sum(collected_samples(:, i) == val) / size(collected_samples, 1); 29 | M(i) = SetValueOfAssignment(M(i), [ val ], p); 30 | end 31 | end 32 | 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | -------------------------------------------------------------------------------- /PA7/LRTrainSGD.m: -------------------------------------------------------------------------------- 1 | % thetaOpt = LRTrainSGD(X, y, lambda) trains a logistic regression 2 | % classifier using stochastic gradient descent. It returns the optimal theta values. 3 | % 4 | % Inputs: 5 | % X data. (numInstances x numFeatures matrix) 6 | % X(:,1) is all ones, i.e., it encodes the intercept/bias term. 7 | % y data labels. (numInstances x 1 vector) 8 | % lambda (L2) regularization parameter. (scalar) 9 | % 10 | % Outputs: 11 | % thetaOpt optimal LR parameters. (numFeatures x 1 vector) 12 | 13 | 14 | function thetaOpt = LRTrainSGD(X, y, lambda) 15 | 16 | numFeatures = size(X, 2); 17 | 18 | % This sets up an anonymous function gradFn 19 | % such that gradFn(theta, i) = LRCostSGD(X, y, theta, lambda, i). 20 | % We need to do this because GradientDescent takes in a function 21 | % handle gradFunc(theta, i), where gradFunc only takes two input params. 22 | % 23 | % For more info, you may check out the official documentation: 24 | % Matlab - http://www.mathworks.com/help/techdoc/matlab_prog/f4-70115.html 25 | % Octave - http://www.gnu.org/software/octave/doc/interpreter/Anonymous-Functions.html 26 | gradFn = @(theta, i)LRCostSGD(X, y, theta, lambda, i); 27 | 28 | % Calculate optimal theta values 29 | thetaOpt = StochasticGradientDescent(gradFn, zeros(numFeatures, 1), 5000); 30 | 31 | end 32 | -------------------------------------------------------------------------------- /PA5/CheckConvergence.m: -------------------------------------------------------------------------------- 1 | % CHECKCONVERGENCE Ascertain whether the messages indicate that we have converged 2 | % converged = CHECKCONVERGENCE(MNEW,MOLD) compares lists of messages MNEW 3 | % and MOLD. If the values listed in any message differs by more than the 4 | % value 'thresh' then we determine that convergence has not occured and 5 | % return converged=0, otherwise we have converged and converged=1 6 | % 7 | % The 'message' data structure is an array of structs with the following 3 fields: 8 | % -.var: the variables covered in this message 9 | % -.card: the cardinalities of those variables 10 | % -.val: the value of the message w.r.t. the message's variables 11 | % 12 | % MNEW and MOLD are the message where M(i,j).val gives the values associated 13 | % with the message from cluster i to cluster j. 14 | % 15 | % 16 | 17 | function converged = CheckConvergence(mNew, mOld); 18 | 19 | thresh = 1.0e-6; 20 | %converged should be 1 if converged, 0 otherwise. 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % YOUR CODE HERE 24 | % 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | 27 | converged = 1; 28 | 29 | for i = 1:size(mNew, 1) 30 | for j = 1:size(mNew, 2) 31 | if any(abs(mNew(i,j).val - mOld(i,j).val) > thresh) 32 | converged = 0; 33 | return; 34 | end 35 | end 36 | end 37 | 38 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 39 | 40 | return; 41 | -------------------------------------------------------------------------------- /PA3/ComputeWordPredictions.m: -------------------------------------------------------------------------------- 1 | function wordPredictions = ComputeWordPredictions (allWords, imageModel, pairwiseModel, tripletList) 2 | % This function computes the predicted character assignments for a list of 3 | % words. 4 | % 5 | % Input: 6 | % allWords: A cell array where allWords{i} is the struct array for the ith 7 | % word (this is the structure of the provided 'allWords' data). 8 | % imageModel: The provided image model struct. 9 | % pairwiseModel: A K-by-K matrix (K is the alphabet size) where pairwiseModel(i,j) 10 | % is the factor value for the pairwise factor of character i followed by 11 | % character j. 12 | % tripletModel: The array of character triplets we will consider (along 13 | % with their corresponding factor values). 14 | % 15 | % Output: 16 | % wordPredictions: A cell array in which the ith entry is the array of 17 | % predicted characters for the ith word. For example, if you predict 18 | % that the 3rd word is cat, then wordPredictions{3} = [3 1 20]. 19 | % 20 | % Hint: For each word, you need to first construct the list of factors 21 | % (BuildOCRNetwork is helpful here). Given those, RunInference computes the 22 | % predictions you need for that word. 23 | 24 | 25 | numWords = length(allWords); 26 | wordPredictions = cell(numWords, 1); 27 | 28 | % Your code here: 29 | 30 | for i = 1:numWords; 31 | network = BuildOCRNetwork(allWords{i}, imageModel, pairwiseModel, tripletList); 32 | wordPredictions{i} = RunInference(network); 33 | end 34 | 35 | end 36 | 37 | -------------------------------------------------------------------------------- /PA3/ComputeTripletFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ComputeTripletFactors (images, tripletList, K) 2 | % This function computes the triplet factor values for one word. 3 | % 4 | % Input: 5 | % images: An array of structs containing the 'img' value for each 6 | % character in the word. 7 | % tripletList: An array of the character triplets we will consider (other 8 | % factor values should be 1). tripletList(i).chars gives character 9 | % assignment, and triplistList(i).factorVal gives the value for that 10 | % entry in the factor table. 11 | % K: The alphabet size (accessible in imageModel.K for the provided 12 | % imageModel). 13 | % 14 | % Hint: Every character triple in the word will use the same 'val' table. 15 | % Consider computing that array once and then resusing for each factor. 16 | 17 | 18 | 19 | n = length(images); 20 | 21 | % If the word has fewer than three characters, then return an empty list. 22 | if (n < 3) 23 | factors = []; 24 | return 25 | end 26 | 27 | factors = repmat(struct('var', [], 'card', [], 'val', []), n - 2, 1); 28 | 29 | % Your code here: 30 | % factors = []; %% REMOVE THIS LINE 31 | for i = 1:n-2 32 | factors(i).var = [i+2, i+1,i]; 33 | factors(i).card = [K, K, K]; 34 | factors(i).val = ones(prod(factors(i).card),1); 35 | for j = 1:length(tripletList) 36 | myindex = AssignmentToIndex(tripletList(j).chars(end:-1:1),factors(i).card); 37 | factors(i).val(myindex) = tripletList(j).factorVal; 38 | end 39 | 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /PA6/CalculateExpectedUtilityFactor.m: -------------------------------------------------------------------------------- 1 | function EUF = CalculateExpectedUtilityFactor( I ) 2 | 3 | % Inputs: An influence diagram I with a single decision node and a single utility node. 4 | % I.RandomFactors = list of factors for each random variable. These are CPDs, with 5 | % the child variable = D.var(1) 6 | % I.DecisionFactors = factor for the decision node. 7 | % I.UtilityFactors = list of factors representing conditional utilities. 8 | % Return value: A factor over the scope of the decision rule D from I that 9 | % gives the conditional utility given each assignment for D.var 10 | % 11 | % Note - We assume I has a single decision node and utility node. 12 | 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | % 15 | % YOUR CODE HERE... 16 | % 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | 19 | EUF = struct('var', [], 'card', [], 'val', []); 20 | 21 | F = [ I.RandomFactors I.UtilityFactors ]; 22 | X = I.RandomFactors; 23 | D = I.DecisionFactors(1); 24 | U = I.UtilityFactors(1); 25 | 26 | % EUF.var = D.var; 27 | % EUF.card = D.card; 28 | 29 | allVars = unique([ F(:).var ]); 30 | toKeep = D.var; 31 | toEliminate = setdiff(allVars, toKeep); 32 | factors = VariableElimination(F, toEliminate, []); 33 | 34 | parentsD = factors(1); 35 | for i = 2:length(factors), 36 | parentsD = FactorProduct(parentsD, factors(i)); 37 | end 38 | 39 | EUF = parentsD; 40 | 41 | end 42 | -------------------------------------------------------------------------------- /PA7/EliminateVar.m: -------------------------------------------------------------------------------- 1 | % Function used in production of clique trees 2 | function [newF C E] = EliminateVar(F, C, E, Z) 3 | 4 | useFactors = []; 5 | scope = []; 6 | 7 | for i=1:length(F) 8 | if any(F(i).var == Z) 9 | useFactors = [useFactors i]; 10 | scope = union(scope, F(i).var); 11 | end 12 | end 13 | 14 | % update edge map 15 | % These represent the induced edges for the VE graph. 16 | for i=1:length(scope) 17 | for j=1:length(scope) 18 | 19 | if i~=j 20 | E(scope(i),scope(j)) = 1; 21 | E(scope(j),scope(i)) = 1; 22 | end 23 | end 24 | end 25 | 26 | E(Z,:) = 0; 27 | E(:,Z) = 0; 28 | 29 | 30 | nonUseFactors = setdiff(1:length(F),[useFactors]); 31 | 32 | for i=1:length(nonUseFactors) 33 | newF(i) = F(nonUseFactors(i)); 34 | newmap(nonUseFactors(i)) = i; 35 | end 36 | 37 | newFactor = struct('var', [], 'card', [], 'val', []); 38 | for i=1:length(useFactors) 39 | newFactor = FactorProduct(newFactor,F(useFactors(i))); 40 | end 41 | 42 | newFactor = FactorMarginalization(newFactor,Z); 43 | newF(length(nonUseFactors)+1) = newFactor; 44 | 45 | newC = length(C.nodes)+1; 46 | C.nodes{newC} = scope; 47 | C.factorInds(newC) = length(nonUseFactors)+1; 48 | for i=1:newC-1 49 | if ismember(C.factorInds(i), useFactors) 50 | C.edges(i,newC) = 1; 51 | C.edges(newC,i) = 1; 52 | C.factorInds(i) = 0; 53 | else 54 | if C.factorInds(i) ~= 0 55 | C.factorInds(i) = newmap(C.factorInds(i)); 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /PA4/EliminateVar.m: -------------------------------------------------------------------------------- 1 | % Function used in production of clique trees 2 | function [newF C E] = EliminateVar(F, C, E, Z) 3 | 4 | useFactors = []; 5 | scope = []; 6 | 7 | for i=1:length(F) 8 | if any(F(i).var == Z) 9 | useFactors = [useFactors i]; 10 | scope = union(scope, F(i).var); 11 | end 12 | end 13 | 14 | % update edge map 15 | % These represent the induced edges for the VE graph. 16 | for i=1:length(scope) 17 | for j=1:length(scope) 18 | 19 | if i~=j 20 | E(scope(i),scope(j)) = 1; 21 | E(scope(j),scope(i)) = 1; 22 | end 23 | end 24 | end 25 | 26 | E(Z,:) = 0; 27 | E(:,Z) = 0; 28 | 29 | 30 | nonUseFactors = setdiff(1:length(F),[useFactors]); 31 | 32 | for i=1:length(nonUseFactors) 33 | newF(i) = F(nonUseFactors(i)); 34 | newmap(nonUseFactors(i)) = i; 35 | end 36 | 37 | newFactor = struct('var', [], 'card', [], 'val', []); 38 | 39 | for i=1:length(useFactors) 40 | newFactor = FactorProduct(newFactor,F(useFactors(i))); 41 | end 42 | 43 | newFactor = FactorMarginalization(newFactor,Z); 44 | newF(length(nonUseFactors)+1) = newFactor; 45 | 46 | newC = length(C.nodes)+1; 47 | C.nodes{newC} = scope; 48 | C.factorInds(newC) = length(nonUseFactors)+1; 49 | for i=1:newC-1 50 | if ismember(C.factorInds(i), useFactors) 51 | C.edges(i,newC) = 1; 52 | C.edges(newC,i) = 1; 53 | C.factorInds(i) = 0; 54 | else 55 | if C.factorInds(i) ~= 0 56 | C.factorInds(i) = newmap(C.factorInds(i)); 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /PA7/LRCostSGD.m: -------------------------------------------------------------------------------- 1 | % [cost, grad] = LRCostSGD(X, y, theta, lambda, i) calculates the LR cost / objective 2 | % function with respect to data instance (i mod n), given the LR classifier parameterized 3 | % by theta and where n = the number of data instances. Also returns the gradient of 4 | % the cost function with respect to data instance (i mod n). 5 | % The aim of LR training is to find the theta that minimizes this function. 6 | % 7 | % Inputs: 8 | % X data. (numInstances x numFeatures matrix) 9 | % X(:,1) is all ones, i.e., it encodes the intercept/bias term. 10 | % y data labels. (numInstances x 1 vector) 11 | % theta LR parameters. (numFeatures x 1 vector) 12 | % lambda (L2) regularization parameter. (scalar) 13 | % i index of a data sample. (integer from 1:size(X,1)) 14 | % 15 | % Outputs: 16 | % cost cost function of the LR classifier evaluated on (X,y). (scalar) 17 | % grad gradient of the cost function. (numFeatures x 1 vector) 18 | 19 | 20 | function [cost, grad] = LRCostSGD(X, y, theta, lambda, i) 21 | i = mod(i, size(X,1)) + 1; 22 | 23 | h = sigmoid (X(i,:) * theta); 24 | 25 | % Calculate cost function 26 | cost = sum((-y(i) .* log(h)) - ((1 - y(i)) .* log(1 - h))) + 0.5 * lambda * sum(theta(2:end) .^ 2); 27 | 28 | % Calculate gradient 29 | grad = X(i,:)' * (h - y(i)); 30 | 31 | % Apply regularization to the weights (but not the bias term) 32 | grad(2:end) = grad(2:end) + lambda * theta(2:end); 33 | 34 | end 35 | -------------------------------------------------------------------------------- /PA3/ComputePairwiseFactors.m: -------------------------------------------------------------------------------- 1 | function factors = ComputePairwiseFactors (images, pairwiseModel, K) 2 | % This function computes the pairwise factors for one word and uses the 3 | % given pairwise model to set the factor values. 4 | % 5 | % Input: 6 | % images: An array of structs containing the 'img' value for each 7 | % character in the word. 8 | % pairwiseModel: The provided pairwise model. It is a K-by-K matrix. For 9 | % character i followed by character j, the factor value should be 10 | % pairwiseModel(i, j). 11 | % K: The alphabet size (accessible in imageModel.K for the provided 12 | % imageModel). 13 | % 14 | % Output: 15 | % factors: The pairwise factors for this word. 16 | % 17 | % Hint: Every character pair in the word will use the same 'val' table. 18 | % Consider computing that array once and then resusing for each factor. 19 | 20 | 21 | n = length(images); 22 | 23 | % If there are fewer than 2 characters, return an empty factor list. 24 | if (n < 2) 25 | factors = []; 26 | return; 27 | end 28 | 29 | factors = repmat(struct('var', [], 'card', [], 'val', []), n - 1, 1); 30 | 31 | % Your code here: 32 | % factors = []; %% REMOVE THIS LINE 33 | for i = 1:n-1 34 | factors(i).var = [i+1,i]; 35 | factors(i).card = [K, K]; 36 | % for j = 1:K 37 | % for kk = 1:K 38 | % myIndex = AssignmentToIndex([j,kk],factors(i).card); 39 | % factors(i).val(myIndex) = pairwiseModel(kk,j); 40 | % end 41 | % end 42 | factors(i).val = reshape(pairwiseModel',prod(factors(i).card),1); 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /PA9/ShowPose.m: -------------------------------------------------------------------------------- 1 | % CS228 PA3 Winter 2012 2 | % File: ShowPose.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | % visualize a configuration the body parts 6 | 7 | function img = ShowPose( pose ) 8 | 9 | % pose 10 x 3. 10 : body parts, 10 | % 3 : y, x, alpha 11 | 12 | pose(:,1) = pose(:,1) + 100; 13 | pose(:,2) = pose(:,2) + 150; 14 | 15 | 16 | 17 | pose = reshape(pose, [10 3]); 18 | part_length = [60, 20, 32, 33, 32, 33, 46, 49, 46, 49]; 19 | part_width = [18, 10, 7, 5, 7, 5, 10, 7, 10, 7]; 20 | img = zeros(300, 300); 21 | for part = 1:10 22 | 23 | startpt = round(pose(part, 1:2)); 24 | axis = [sin(pose(part,3) - pi/2) cos(pose(part,3) - pi/2)]; 25 | xaxis = [cos(pose(part,3) - pi/2) -sin(pose(part,3) - pi/2)]; 26 | endpt = round(startpt + part_length(part) * axis); 27 | 28 | corner1 = round(startpt + xaxis * part_width(part)); 29 | corner2 = round(startpt - xaxis * part_width(part)); 30 | corner3 = round(endpt + xaxis * part_width(part)); 31 | corner4 = round(endpt - xaxis * part_width(part)); 32 | 33 | img = func_DrawLine(img, corner1(1), corner1(2), corner2(1), corner2(2),1); 34 | img = func_DrawLine(img, corner1(1), corner1(2), corner3(1), corner3(2),1); 35 | img = func_DrawLine(img, corner4(1), corner4(2), corner2(1), corner2(2),1); 36 | img = func_DrawLine(img, corner4(1), corner4(2), corner3(1), corner3(2),1); 37 | 38 | if startpt(1) > 3 && startpt(1) < 298 && startpt(2) > 3 && startpt(2) < 298 39 | img(startpt(1)-3 : startpt(1) + 3, startpt(2) - 3 : startpt(2)+3) = ones(7,7); 40 | end 41 | end 42 | 43 | -------------------------------------------------------------------------------- /PA8/ShowPose.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: ShowPose.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang, Andrew Duchi 5 | 6 | % visualize a configuration the body parts 7 | 8 | function img = ShowPose( pose ) 9 | 10 | % pose 10 x 3. 10 : body parts, 11 | % 3 : y, x, alpha 12 | 13 | pose(:,1) = pose(:,1) + 100; 14 | pose(:,2) = pose(:,2) + 150; 15 | 16 | 17 | 18 | pose = reshape(pose, [10 3]); 19 | part_length = [60, 20, 32, 33, 32, 33, 46, 49, 46, 49]; 20 | part_width = [18, 10, 7, 5, 7, 5, 10, 7, 10, 7]; 21 | img = zeros(300, 300); 22 | for part = 1:10 23 | 24 | startpt = round(pose(part, 1:2)); 25 | axis = [sin(pose(part,3) - pi/2) cos(pose(part,3) - pi/2)]; 26 | xaxis = [cos(pose(part,3) - pi/2) -sin(pose(part,3) - pi/2)]; 27 | endpt = round(startpt + part_length(part) * axis); 28 | 29 | corner1 = round(startpt + xaxis * part_width(part)); 30 | corner2 = round(startpt - xaxis * part_width(part)); 31 | corner3 = round(endpt + xaxis * part_width(part)); 32 | corner4 = round(endpt - xaxis * part_width(part)); 33 | 34 | img = func_DrawLine(img, corner1(1), corner1(2), corner2(1), corner2(2),1); 35 | img = func_DrawLine(img, corner1(1), corner1(2), corner3(1), corner3(2),1); 36 | img = func_DrawLine(img, corner4(1), corner4(2), corner2(1), corner2(2),1); 37 | img = func_DrawLine(img, corner4(1), corner4(2), corner3(1), corner3(2),1); 38 | 39 | if startpt(1) > 3 && startpt(1) < 298 && startpt(2) > 3 && startpt(2) < 298 40 | img(startpt(1)-3 : startpt(1) + 3, startpt(2) - 3 : startpt(2)+3) = ones(7,7); 41 | end 42 | end 43 | 44 | -------------------------------------------------------------------------------- /PA6/EliminateVar.m: -------------------------------------------------------------------------------- 1 | % Function used in production of clique trees 2 | % F = list of factors 3 | % E = adjacency matrix for variables 4 | % Z = variable to eliminate 5 | function [newF E] = EliminateVar(F, E, Z) 6 | 7 | % Index of factors to multiply (b/c they contain Z) 8 | useFactors = []; 9 | 10 | % Union of scopes of factors to multiply 11 | scope = []; 12 | 13 | for i=1:length(F) 14 | if any(F(i).var == Z) 15 | useFactors = [useFactors i]; 16 | scope = union(scope, F(i).var); 17 | end 18 | end 19 | 20 | % update edge map 21 | % These represent the induced edges for the VE graph. 22 | for i=1:length(scope) 23 | for j=1:length(scope) 24 | 25 | if i~=j 26 | E(scope(i),scope(j)) = 1; 27 | E(scope(j),scope(i)) = 1; 28 | end 29 | end 30 | end 31 | 32 | % Remove all adjacencies for the variable to be eliminated 33 | E(Z,:) = 0; 34 | E(:,Z) = 0; 35 | 36 | 37 | % nonUseFactors = list of factors (not indices!) which are passed through 38 | % in this round 39 | nonUseFactors = setdiff(1:length(F),[useFactors]); 40 | 41 | for i=1:length(nonUseFactors) 42 | 43 | % newF = list of factors we will return 44 | newF(i) = F(nonUseFactors(i)); 45 | 46 | % newmap = ? 47 | newmap(nonUseFactors(i)) = i; 48 | 49 | end 50 | 51 | % Multiply factors which involve Z -> newFactor 52 | newFactor = struct('var', [], 'card', [], 'val', []); 53 | for i=1:length(useFactors) 54 | newFactor = FactorProduct(newFactor,F(useFactors(i))); 55 | end 56 | 57 | newFactor = FactorMarginalization(newFactor,Z); 58 | newF(length(nonUseFactors)+1) = newFactor; 59 | 60 | -------------------------------------------------------------------------------- /PA7/FactorMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMarginalization Sums given variables out of a factor. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | % 11 | % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m 12 | 13 | function B = FactorMarginalization(A, V) 14 | 15 | % Check for empty factor or variable list 16 | if (isempty(A.var) || isempty(V)), B = A; return; end; 17 | 18 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 19 | % and mapping between variables in A and B 20 | [B.var, mapB] = setdiff(A.var, V); 21 | 22 | % Check for empty resultant factor 23 | if isempty(B.var) 24 | %error('Error: Resultant factor has empty scope'); 25 | B.var = []; 26 | B.card = []; 27 | B.val = []; 28 | return; 29 | end; 30 | 31 | % Initialize B.card and B.val 32 | B.card = A.card(mapB); 33 | B.val = zeros(1,prod(B.card)); 34 | 35 | % Compute some helper indices 36 | % These will be very useful for calculating C.val 37 | % so make sure you understand what these lines are doing 38 | assignments = IndexToAssignment(1:length(A.val), A.card); 39 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 40 | 41 | for i = 1:length(A.val), 42 | B.val(indxB(i)) = B.val(indxB(i)) + A.val(i); 43 | end; 44 | 45 | end 46 | -------------------------------------------------------------------------------- /PA5/randsample.m: -------------------------------------------------------------------------------- 1 | %randsample(V,n,true,distribution) returns a set of n values sampled 2 | % at random from the integers 1 through V with replacement using distribution 3 | % 'distribution' 4 | % 5 | % replacing true with false causes sampling w/out replacement 6 | % omitting the distribution causes a default to the uniform distribution 7 | 8 | function [v] = randsample(vals,numSamp,replace,weightIncrements) 9 | 10 | vals = vals(:); 11 | if(length(vals)==1) 12 | maxval = vals; 13 | vals = 1:maxval; 14 | else 15 | maxval = length(vals); 16 | end 17 | 18 | if(exist('replace','var')~=1) 19 | replace = true; 20 | end 21 | if(exist('weightIncrements','var')~=1) 22 | weightIncrements = (1/maxval)*ones(maxval,1); 23 | weights = (1/maxval):(1/maxval):1; 24 | else 25 | weightIncrements = weightIncrements(:)/sum(weightIncrements(:)); 26 | weights = zeros(size(weightIncrements)); 27 | weights(1) = weightIncrements(1); 28 | for i = 2:length(weightIncrements) 29 | weights(i) = weightIncrements(i)+weights(i-1); 30 | end 31 | end 32 | 33 | weights = [0; weights(:)]; 34 | 35 | %now do the sampling 36 | v = []; 37 | probs = rand(numSamp,1); 38 | for i=1:numSamp 39 | curInd = find((weights(1:end-1)<=probs(i))&(weights(2:end)>=probs(i))); 40 | v(end+1)=vals(curInd); 41 | if(replace~=true) 42 | vals(curInd)=[]; 43 | weightIncrements(curInd)=[]; 44 | weightIncrements = weightIncrements(:)/sum(weightIncrements(:)); 45 | weights = zeros(size(weightIncrements)); 46 | for i = 2:length(weightIncrements) 47 | weights(i) = weightIncrements(i)+weights(i-1); 48 | end 49 | end 50 | end 51 | 52 | 53 | end 54 | -------------------------------------------------------------------------------- /PA6/SimpleCalcExpectedUtility.m: -------------------------------------------------------------------------------- 1 | function EU = SimpleCalcExpectedUtility(I) 2 | 3 | % Inputs: An influence diagram, I (as described in the writeup). 4 | % I.RandomFactors = list of factors for each random variable. These are CPDs, with 5 | % the child variable = D.var(1) 6 | % I.DecisionFactors = factor for the decision node. 7 | % I.UtilityFactors = list of factors representing conditional utilities. 8 | % Return Value: the expected utility of I 9 | % Given a fully instantiated influence diagram with a single utility node and decision node, 10 | % calculate and return the expected utility. Note - assumes that the decision rule for the 11 | % decision node is fully assigned. 12 | 13 | % In this function, we assume there is only one utility node. 14 | F = [I.RandomFactors I.DecisionFactors]; 15 | U = I.UtilityFactors(1); 16 | 17 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 18 | % 19 | % YOUR CODE HERE 20 | % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | allVars = unique([ F(:).var ]); 24 | toEliminate = setdiff(allVars, U.var); 25 | factors = VariableElimination(F, toEliminate, []); 26 | parentU = factors(1); 27 | for i = 2:length(factors) 28 | parentU = FactorProduct(parentU, factors(i)); 29 | end 30 | parentU.val = parentU.val ./ sum(parentU.val); 31 | EU = 0.0; 32 | [ dummy, mapU ] = ismember(U.var, parentU.var); 33 | for i = 1:prod(parentU.card) 34 | assignment = IndexToAssignment(i, parentU.card); 35 | reorder = assignment(mapU); 36 | EU = EU + GetValueOfAssignment(parentU, assignment) * GetValueOfAssignment(U, reorder); 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /PA7/StochasticGradientDescent.m: -------------------------------------------------------------------------------- 1 | % function thetaOpt = StochasticGradientDescent (gradFunc, theta0, maxiter) 2 | % runs gradient descent until convergence, returning the optimal parameters thetaOpt. 3 | % 4 | % Inputs: 5 | % gradFunc function handle to a function [cost, grad] = gradFunc(theta, i) 6 | % that computes the LR cost / objective function and the gradient 7 | % of the negative log likelihood of the ith data instance, given 8 | % parameters theta. 9 | % theta0 initial value of theta to start gradient descent from. 10 | % maxIter number of iterations to run SGD for. 11 | % 12 | % Output: 13 | % thetaOpt optimal value of theta. 14 | % 15 | % 16 | % Note - function handles may be new to some of you. Briefly, function handles 17 | % are a way of passing a function to another function as an argument. The 18 | % syntax for calling a function handle is exactly the same as for calling any 19 | % other function. 20 | % 21 | % For more information, refer to the official documentation: 22 | % Matlab - http://www.mathworks.com/help/techdoc/matlab_prog/f2-38133.html 23 | % Octave - http://www.gnu.org/software/octave/doc/interpreter/Function-Handles.html 24 | 25 | 26 | function thetaOpt = StochasticGradientDescent (gradFunc, theta0, maxIter) 27 | 28 | % The grader will accept all answers that are near enough 29 | % to the optimal value, so don't worry about being off by one 30 | % iteration etc. 31 | 32 | %%%%%%%%%%%%%% 33 | %%% Student code 34 | theta = theta0; 35 | for i = 1:maxIter 36 | [cost grad] = gradFunc(theta,i); 37 | alpha = 0.1/(1+sqrt(i)); 38 | theta = theta-alpha*grad; 39 | end 40 | thetaOpt = theta; 41 | %%%%%%%%%%% 42 | end 43 | 44 | -------------------------------------------------------------------------------- /PA5/TestToy.m: -------------------------------------------------------------------------------- 1 | rand('seed', 1); 2 | 3 | % Construct the toy network 4 | [toy_network, toy_factors] = ConstructToyNetwork(0.2,1); 5 | toy_evidence = zeros(1, length(toy_network.names)); 6 | %toy_clique_tree = CreateCliqueTree(toy_factors, []); 7 | %toy_cluster_graph = CreateClusterGraph(toy_factors,[]); 8 | 9 | % Exact Inference 10 | ExactM = ComputeExactMarginalsBP(toy_factors, toy_evidence, 0) 11 | figure, VisualizeToyImageMarginals(toy_network, ExactM); 12 | 13 | % Comment this in to run Approximate Inference on the toy network 14 | % Approximate Inference 15 | % % ApproxM = ApproxInference(toy_cluster_graph, toy_factors, toy_evidence); 16 | % figure, VisualizeToyImageMarginals(toy_network, ApproxM); 17 | 18 | 19 | 20 | % MCMC Inference 21 | transition_names = {'Gibbs', 'MHUniform', 'MHGibbs', 'MHSwendsenWang1', 'MHSwendsenWang2'}; 22 | 23 | for j = 1:length(transition_names) 24 | samples_list = {}; 25 | 26 | num_chains_to_run = 3; 27 | for i = 1:num_chains_to_run 28 | % Random Initialization 29 | A0 = ceil(rand(1, length(toy_network.names)) .* toy_network.card); 30 | 31 | % Initialization to all ones 32 | % A0 = i * ones(1, length(toy_network.names)); 33 | 34 | [M, all_samples] = ... 35 | MCMCInference(toy_network, toy_factors, toy_evidence, transition_names{j}, 0, 4000, 1, A0); 36 | samples_list{i} = all_samples; 37 | figure, VisualizeToyImageMarginals(toy_network, M); 38 | end 39 | 40 | vis_vars = [1 3]; 41 | VisualizeMCMCMarginals(samples_list, vis_vars, toy_network.card(vis_vars), toy_factors, ... 42 | 500); 43 | disp(['Displaying results for MCMC with transition ', transition_names{j}]); 44 | disp(['Hit enter to continue']); 45 | pause; 46 | end -------------------------------------------------------------------------------- /PA6/VariableElimination.m: -------------------------------------------------------------------------------- 1 | % VariableElimination takes in a list of factors F, a list of variables to eliminate, 2 | % evidence E, and returns the resulting factor(s) after running sum-product to eliminate 3 | % the given variables. 4 | % 5 | % Fnew = VariableElimination(F, Z, E) 6 | % F = list of factors 7 | % Z = list of variables to eliminate 8 | % E = vector of evidence; set this to [] if there is no evidence. 9 | % 10 | 11 | % CS228 Probabilistic Graphical Models(Winter 2012) 12 | % Copyright (C) 2012, Stanford University 13 | 14 | function Fnew = VariableElimination(F, Z, E) 15 | 16 | % List of all variables 17 | V = unique([F(:).var]); 18 | 19 | % Setting up the adjacency matrix. 20 | edges = zeros(length(V)); 21 | 22 | for i = 1:length(F) 23 | for j = 1:length(F(i).var) 24 | for k = 1:length(F(i).var) 25 | edges(F(i).var(j), F(i).var(k)) = 1; 26 | end 27 | end 28 | end 29 | 30 | variablesConsidered = 0; 31 | 32 | while variablesConsidered < length(Z) 33 | 34 | % Using Min-Neighbors where you prefer to eliminate the variable that has 35 | % the smallest number of edges connected to it. 36 | % Everytime you enter the loop, you look at the state of the graph and 37 | % pick the variable to be eliminated. 38 | bestVariable = 0; 39 | bestScore = inf; 40 | for i=Z 41 | score = sum(edges(i,:)); 42 | if score > 0 && score < bestScore 43 | bestScore = score; 44 | bestVariable = i; 45 | end 46 | end 47 | 48 | variablesConsidered = variablesConsidered + 1; 49 | [F, edges] = EliminateVar(F, edges, bestVariable); 50 | 51 | end 52 | 53 | Fnew = F; 54 | for j = 1:length(E) 55 | if (E(j) > 0) 56 | Fnew = ObserveEvidence(Fnew, [j, E(j)]); 57 | end 58 | end 59 | 60 | end 61 | 62 | 63 | -------------------------------------------------------------------------------- /PA7/FactorMaxMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMaxMarginalization Takes the max of given variables when marginalizing out of a factor. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | % 11 | % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m 12 | 13 | function B = FactorMaxMarginalization(A, V) 14 | 15 | % Check for empty factor or variable list 16 | if (isempty(A.var) || isempty(V)), B = A; return; end; 17 | 18 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 19 | % and mapping between variables in A and B 20 | [B.var, mapB] = setdiff(A.var, V); 21 | 22 | % Check for empty resultant factor 23 | if isempty(B.var) 24 | error('Error: Resultant factor has empty scope'); 25 | end; 26 | 27 | % Initialize B.card and B.val 28 | B.card = A.card(mapB); 29 | B.val = zeros(1,prod(B.card)); 30 | 31 | % Compute some helper indices 32 | % These will be very useful for calculating C.val 33 | % so make sure you understand what these lines are doing 34 | assignments = IndexToAssignment(1:length(A.val), A.card); 35 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 36 | 37 | for i = 1:length(A.val) 38 | % Iterate through the values of A 39 | if B.val(indxB(i)) == 0 40 | % B has not been initialized yet 41 | B.val(indxB(i)) = A.val(i); 42 | else 43 | B.val(indxB(i)) = max([B.val(indxB(i)), A.val(i)]); 44 | end 45 | end; 46 | 47 | end 48 | -------------------------------------------------------------------------------- /PA9/ComputeExactMarginalsHMM.m: -------------------------------------------------------------------------------- 1 | %COMPUTEEXACTMARGINALSHMM Runs exact inference and returns the marginals 2 | %over all the variables and the calibrated clique tree. 3 | 4 | % M = COMPUTEEXACTMARGINALSHMM(F) Takes a list of factors F, 5 | % and runs exact inference and returns the calibrated clique tree (unnormalized) and 6 | % final marginals (normalized) for the variables in the network. 7 | % It returns an array of size equal to the number of variables in the 8 | % network where M(i) represents the ith variable and M(i).val represents 9 | % the marginals of the ith variable. 10 | 11 | 12 | % CS228 Probabilistic Models in AI (Winter 2012) 13 | % Copyright (C) 2012, Stanford University 14 | 15 | function [M, PCalibrated] = ComputeExactMarginalsHMM(F) 16 | 17 | % M = repmat(struct('var', 0, 'card', 0, 'val', []), length(N), 1); 18 | % 19 | % where N is the number of variables in the network, which can be determined 20 | % from the factors F. 21 | 22 | % Create a clique tree, compute the initial potentails, calibrate the 23 | % clique tree, and find the belief for each varaible at a clique that has 24 | % that variable in its scope 25 | 26 | compressedCliqueTree = CreateCliqueTreeHMM(F); 27 | PCalibrated = CliqueTreeCalibrate(compressedCliqueTree); 28 | varsList = sort(unique([F(:).var])); 29 | M = repmat(struct('var', 0, 'card', 0, 'val', []), length(varsList), 1); 30 | for i = 1:length(varsList) 31 | if ~ all(varsList(i) == i) 32 | assert(0); 33 | end 34 | if (i == 1) 35 | clique = PCalibrated.cliqueList(i); 36 | M(i) = FactorMarginalization(clique, 2); 37 | else 38 | clique = PCalibrated.cliqueList(i-1); 39 | M(i) = FactorMarginalization(clique, i-1); 40 | end 41 | 42 | if any(M(i).val ~= 0) 43 | % Normalize 44 | M(i).val = M(i).val - logsumexp(M(i).val); 45 | end 46 | 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /PA4/FactorMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMarginalization Sums given variables out of a factor. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | % 11 | % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m 12 | 13 | function B = FactorMarginalization(A, V) 14 | 15 | % Check for empty factor or variable list 16 | if (isempty(A.var) || isempty(V)), B = A; return; end; 17 | 18 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 19 | % and mapping between variables in A and B 20 | [B.var, mapB] = setdiff(A.var, V); 21 | 22 | % Check for empty resultant factor 23 | if isempty(B.var) 24 | %error('Error: Resultant factor has empty scope'); 25 | B.var = []; 26 | B.card = []; 27 | B.val = []; 28 | return; 29 | end; 30 | 31 | % Initialize B.card and B.val 32 | B.card = A.card(mapB); 33 | B.val = zeros(1,prod(B.card)); 34 | 35 | % Compute some helper indices 36 | % These will be very useful for calculating C.val 37 | % so make sure you understand what these lines are doing 38 | assignments = IndexToAssignment(1:length(A.val), A.card); 39 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 40 | 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | % YOUR CODE HERE 43 | % Correctly populate the factor values of B 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | for i = 1:length(A.val), 46 | B.val(indxB(i)) = B.val(indxB(i)) + A.val(i); 47 | end; 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | end 50 | -------------------------------------------------------------------------------- /PA5/FactorMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMarginalization Sums given variables out of a factor. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | % 11 | % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m 12 | 13 | function B = FactorMarginalization(A, V) 14 | 15 | % Check for empty factor or variable list 16 | if (isempty(A.var) || isempty(V)), B = A; return; end; 17 | 18 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 19 | % and mapping between variables in A and B 20 | [B.var, mapB] = setdiff(A.var, V); 21 | 22 | % Check for empty resultant factor 23 | if isempty(B.var) 24 | %error('Error: Resultant factor has empty scope'); 25 | B.var = []; 26 | B.card = []; 27 | B.val = []; 28 | return; 29 | end; 30 | 31 | % Initialize B.card and B.val 32 | B.card = A.card(mapB); 33 | B.val = zeros(1,prod(B.card)); 34 | 35 | % Compute some helper indices 36 | % These will be very useful for calculating C.val 37 | % so make sure you understand what these lines are doing 38 | assignments = IndexToAssignment(1:length(A.val), A.card); 39 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 40 | 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | % YOUR CODE HERE 43 | % Correctly populate the factor values of B 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | for i = 1:length(A.val), 46 | B.val(indxB(i)) = B.val(indxB(i)) + A.val(i); 47 | end; 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | end 50 | -------------------------------------------------------------------------------- /PA6/FactorMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMarginalization Sums given variables out of a factor. 2 | % B = FactorMarginalization(A,V) computes the factor with the variables 3 | % in V summed out. The factor data structure has the following fields: 4 | % .var Vector of variables in the factor, e.g. [1 2 3] 5 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 6 | % .val Value table of size prod(.card) 7 | % 8 | % The resultant factor should have at least one variable remaining or this 9 | % function will throw an error. 10 | % 11 | % See also FactorProduct.m, IndexToAssignment.m, and AssignmentToIndex.m 12 | 13 | function B = FactorMarginalization(A, V) 14 | 15 | % Check for empty factor or variable list 16 | if (isempty(A.var) || isempty(V)), B = A; return; end; 17 | 18 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 19 | % and mapping between variables in A and B 20 | [B.var, mapB] = setdiff(A.var, V); 21 | 22 | % Check for empty resultant factor 23 | if isempty(B.var) 24 | %error('Error: Resultant factor has empty scope'); 25 | B.var = []; 26 | B.card = []; 27 | B.val = []; 28 | return; 29 | end; 30 | 31 | % Initialize B.card and B.val 32 | B.card = A.card(mapB); 33 | B.val = zeros(1,prod(B.card)); 34 | 35 | % Compute some helper indices 36 | % These will be very useful for calculating C.val 37 | % so make sure you understand what these lines are doing 38 | assignments = IndexToAssignment(1:length(A.val), A.card); 39 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 40 | 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | % YOUR CODE HERE 43 | % Correctly populate the factor values of B 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | for i = 1:length(A.val), 46 | B.val(indxB(i)) = B.val(indxB(i)) + A.val(i); 47 | end; 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | end 50 | -------------------------------------------------------------------------------- /PA3/RunInference.m: -------------------------------------------------------------------------------- 1 | function pred = RunInference (factors) 2 | % This function performs inference for a Markov network specified as a list 3 | % of factors. 4 | % 5 | % Input: 6 | % factors: An array of struct factors, each containing 'var', 'card', and 7 | % 'val' fields. 8 | % 9 | % Output: 10 | % pred: An array of predictions for every variable. In particular, 11 | % pred(i) is the predicted value for variable numbered i (as determined 12 | % by the 'var' fields in the input factors). 13 | 14 | binaries = {'.\inference\doinference.exe', ... 15 | './inference/doinference-mac', ... 16 | './inference/doinference-linux'}; 17 | 18 | kFactorsFilename = 'factors.fg'; 19 | kStderrFilename = 'inf.log'; 20 | kInfBinary = binaries{[ispc ismac isunix]}; % NB: need ismac first so that if ismac and isunix are both 1, then mac is chosen 21 | kInferenceType = 'map'; % choices are 'map' or 'pd' 22 | 23 | factorsString = SerializeFactorsFg (factors); 24 | 25 | fd = fopen(kFactorsFilename, 'wt'); 26 | fprintf (fd, '%s', factorsString); 27 | fclose(fd); 28 | 29 | if (isunix && ~ismac) 30 | command = [kInfBinary ' ' kFactorsFilename ' ' kInferenceType]; 31 | else 32 | command = [kInfBinary ' ' kFactorsFilename ' ' kInferenceType ' 2> ' kStderrFilename]; 33 | end 34 | 35 | [retVal, output] = system(command); 36 | 37 | if (retVal ~= 0) 38 | error('The doinference command failed. Look at the file %s to diagnose the cause', kStderrFilename); 39 | end 40 | 41 | pred = ParseOutput(output); 42 | 43 | end 44 | 45 | function pred = ParseOutput(output) 46 | 47 | lines = strread(output, '%s', 'delimiter', sprintf('\n')); 48 | lines(strcmp(lines, '')) = []; 49 | 50 | numVars = str2double(lines{1}); 51 | 52 | if (numVars ~= length(lines) - 1) 53 | error('Error parsing output: %s', output); 54 | end 55 | 56 | pred = zeros(numVars, 1); 57 | for i = 2:(numVars + 1) 58 | line = str2num(lines{i}); 59 | pred(i-1) = line(end); 60 | end 61 | 62 | end 63 | -------------------------------------------------------------------------------- /PA4/PruneTree.m: -------------------------------------------------------------------------------- 1 | function C = PruneTree(C) 2 | 3 | % Logic: 4 | % Start with a clique, scan through its neighbors. If you find a neighbor 5 | % such that it is a superset of the clique you started with, then you know 6 | % that you can prune the tree. For instance, let's take the following 7 | % clique tree: 8 | % ABE -- AB ---AD 9 | % Let's say we started with AB. We scan through its neighbors and find that 10 | % AB is a subset of ABE. So we cut off the edges connected to AB and add an 11 | % edge between ABE and all of AB's other neighbors. This maintains the 12 | % running intersection property and gives us a more compact clique tree 13 | % which looks like: ABE -- AD. 14 | 15 | toRemove = []; 16 | 17 | for i=1:length(C.nodes) 18 | 19 | if ismember(i,toRemove), continue, end; 20 | neighborsI = find(C.edges(i,:)); 21 | 22 | for c = 1: length(neighborsI), 23 | 24 | j = neighborsI(c); 25 | assert(i ~= j); 26 | 27 | if ismember(j,toRemove), continue, end; 28 | 29 | if (sum(ismember(C.nodes{i}, C.nodes{j})) == length(C.nodes{i})) 30 | 31 | for nk = neighborsI 32 | 33 | % find neighbors and connect with that. 34 | if length(intersect(C.nodes{i}, C.nodes{nk})) == length(C.nodes{i}) 35 | C.edges(setdiff(neighborsI,[nk]),nk) = 1; 36 | C.edges(nk,setdiff(neighborsI,[nk])) = 1; 37 | break; 38 | end 39 | end 40 | 41 | % kill the edges for the clique that is to be removed. 42 | C.edges(i,:) = 0; 43 | C.edges(:,i) = 0; 44 | toRemove = [i toRemove]; 45 | 46 | end 47 | end 48 | end 49 | 50 | toKeep = setdiff(1:length(C.nodes),toRemove); 51 | 52 | C.nodes(toRemove) = []; 53 | 54 | if isfield(C, 'edges') 55 | C.edges = C.edges(toKeep,toKeep); 56 | else 57 | C.edges = []; 58 | end 59 | 60 | end 61 | 62 | -------------------------------------------------------------------------------- /PA7/GetNextCliques.m: -------------------------------------------------------------------------------- 1 | %GETNEXTCLIQUES Find a pair of cliques ready for message passing 2 | % [i, j] = GETNEXTCLIQUES(P, messages) finds ready cliques in a given 3 | % clique tree, P, and current messages. Returns indices i and j 4 | % such that clique i is ready to transmit a message to clique j. 5 | % If no such cliques exist, returns i = j = 0 6 | % 7 | % See also CLIQUETREECALIBRATE 8 | 9 | % CS228 Probabilistic Graphical Models(Winter 2012) 10 | % Copyright (C) 2012, Stanford University 11 | 12 | function [i, j] = GetNextCliques(P, messages) 13 | 14 | ready = 0; 15 | 16 | for i = 1:size(P.edges, 1), 17 | for j = 1:size(P.edges, 2), 18 | 19 | % If clique i is ready to send a message to clique j then 20 | % set 'ready' to 1. 21 | % Make sure that message is ready by making sure that the cliques 22 | % share an edge, that no message has been sent, and that all of the 23 | % other messages to clique i have been sent 24 | if P.edges(i,j) == 0 25 | % There is no edge connecting clique i and clique j, so do not 26 | % consider sending a message 27 | continue 28 | end 29 | if (~isempty(messages(i,j).var)) 30 | % A message has already been sent from clique i to clique j, so 31 | % do not consider sending a message 32 | continue 33 | end 34 | messageIndexes = setdiff(find(P.edges(:, i) == 1), j); 35 | emptyFound = 0; 36 | for k = 1:length(messageIndexes) 37 | % Iterate through other incoming edges 38 | if isempty(messages(messageIndexes(k), i).var) 39 | % Not ready 40 | emptyFound = 1; 41 | break 42 | end 43 | end 44 | if emptyFound == 0 45 | % All necessary messages have been sent 46 | ready = 1; 47 | return; 48 | end 49 | 50 | end; 51 | end; 52 | 53 | i = 0; 54 | j = 0; 55 | 56 | return 57 | -------------------------------------------------------------------------------- /PA9/FitLinearGaussianParameters.m: -------------------------------------------------------------------------------- 1 | % CS228 PA9 Winter 2011-2012 2 | % File: FitLinearGaussianParameters.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function [Beta sigma] = FitLinearGaussianParameters(X, U, W) 6 | 7 | % Estimate parameters of the linear Gaussian model: 8 | % X|U ~ N(Beta(1)*U(1) + ... + Beta(K)*U(K) + Beta(K+1), sigma^2); 9 | 10 | % Note that Matlab index from 1, we can't write Beta(0). So Beta(K+1) is 11 | % essentially Beta(0) in PA3 description (and the text book). 12 | 13 | % X: (N x 1), the child variable, N examples 14 | % U: (N x K), K parent variables, N examples 15 | % W: (N x 1), weights over the examples. 16 | 17 | N = size(U,1); 18 | K = size(U,2); 19 | 20 | Beta = zeros(K+1,1); 21 | sigma = 1; 22 | 23 | % collect expectations and solve the linear system 24 | % A = [ E[U(1)], E[U(2)], ... , E[U(K)], 1 ; 25 | % E[U(1)*U(1)], E[U(2)*U(1)], ... , E[U(K)*U(1)], E[U(1)]; 26 | % ... , ... , ... , ... , ... ; 27 | % E[U(1)*U(K)], E[U(2)*U(K)], ... , E[U(K)*U(K)], E[U(K)] ] 28 | 29 | A = zeros(K,K); 30 | for j = 1:K 31 | row = 1:K; 32 | for x = 1:K 33 | mu = W'*(U(:,x).*U(:,j))/sum(W); 34 | row(x) = mu; 35 | end 36 | A(j,:) = row; 37 | end 38 | row1 = 1:K; 39 | for x = 1:K 40 | mu = W'*U(:,x)/sum(W); 41 | row1(x) = mu; 42 | end 43 | col2 = [1;row1']; 44 | A = [row1;A]; 45 | A = [A, col2]; 46 | 47 | % B = [ E[X]; E[X*U(1)]; ... ; E[X*U(K)] ] 48 | 49 | B = 1:K; 50 | for x = 1:K 51 | mu = W'*(X.*U(:,x))/sum(W); 52 | B(x) = mu; 53 | end 54 | 55 | mu = W'*X/sum(W); 56 | B = [mu;B']; 57 | 58 | % solve A*Beta = B 59 | Beta = A\B; 60 | 61 | % then compute sigma according to eq. (17) in PA description 62 | CovU = A(2:end, 1:K) - A(2:end, K+1) * A(1, 1:K); 63 | [MuX, SigmaX] = FitGaussianParameters(X, W); 64 | sigma = sqrt( SigmaX^2 - Beta(1:K)' * CovU * Beta(1:K) ); 65 | 66 | % catch in case sigma is badly conditioned 67 | if sigma == 0 || ~isreal(sigma) 68 | sigma = .01; 69 | else 70 | sigma = sigma + .01; 71 | end 72 | -------------------------------------------------------------------------------- /PA5/ConstructToyNetwork.m: -------------------------------------------------------------------------------- 1 | % 2 | % This is a script that constructs the toy network and outputs toy_network and toy_factors into 3 | % the environment. You should modify this file to change the parameters of the toy network. 4 | % 5 | % In this file, on_diag_weight represents the weight of the on-diagonal elements 6 | % in your pairwise CPDs (weight of agreement) while the off_diag_weight is the 7 | % weight for off-diagonal assignments (weight of disagreement between adjacent nodes) 8 | % 9 | function [toy_network, toy_factors] = ConstructToyNetwork(on_diag_weight, off_diag_weight) 10 | 11 | n = 4; % square length 12 | k = 2; % sub-square length 13 | V = 1:n*n; 14 | 15 | G = struct; 16 | G.names = {}; 17 | for i = 1:length(V) 18 | G.names{i} = ['pixel', num2str(i)]; 19 | G.card(i) = 2; 20 | end 21 | edges = zeros(length(V)); 22 | for i = 1:length(V) 23 | for j = i+1:length(V) 24 | % Four connected Markov Net 25 | [r_i, c_i] = ind2sub([n,n],i); 26 | [r_j, c_j] = ind2sub([n,n],j); 27 | if sum(abs([r_i, c_i] - [r_j, c_j])) == 1 28 | edges(i, j) = 1; 29 | end 30 | end 31 | end 32 | G.edges = or(edges, edges'); 33 | 34 | singleton_factors = []; 35 | for i = 1:length(V) 36 | singleton_factors(i).var = i; 37 | singleton_factors(i).card = 2; 38 | if i <= length(V) / 2 39 | singleton_factors(i).val = [0.4, 0.6]; 40 | else 41 | singleton_factors(i).val = [0.6, 0.4]; 42 | end 43 | end 44 | 45 | pairwise_factors = []; 46 | [r, c] = ind2sub([length(V), length(V)], find(edges)); 47 | edge_list = [r, c]; 48 | for i = 1:size(edge_list, 1) 49 | pairwise_factors(i).var = edge_list(i, :); 50 | pairwise_factors(i).card = [2, 2]; 51 | pairwise_factors(i).val = [on_diag_weight, off_diag_weight, ... 52 | off_diag_weight, on_diag_weight]; 53 | 54 | end 55 | 56 | F = [singleton_factors, pairwise_factors]; 57 | G.var2factors = VariableToFactorCorrespondence(V, F); 58 | 59 | toy_network = G; 60 | toy_factors = [singleton_factors, pairwise_factors]; 61 | -------------------------------------------------------------------------------- /PA7/ObserveEvidence.m: -------------------------------------------------------------------------------- 1 | % ObserveEvidence Modify a vector of factors given some evidence. 2 | % F = ObserveEvidence(F, E) sets all entries in the vector of factors, F, 3 | % that are not consistent with the evidence, E, to zero. F is a vector of 4 | % factors, each a data structure with the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % E is an N-by-2 matrix, where each row consists of a variable/value pair. 9 | % Variables are in the first column and values are in the second column. 10 | 11 | function F = ObserveEvidence(F, E) 12 | 13 | % Iterate through all evidence 14 | 15 | for i = 1:size(E, 1), 16 | v = E(i, 1); % variable 17 | x = E(i, 2); % value 18 | 19 | % Check validity of evidence 20 | if (x == 0), 21 | warning(['Evidence not set for variable ', int2str(v)]); 22 | continue; 23 | end; 24 | 25 | for j = 1:length(F), 26 | % Does factor contain variable? 27 | indx = find(F(j).var == v); 28 | 29 | if (~isempty(indx)), 30 | 31 | % Check validity of evidence 32 | if (x > F(j).card(indx) || x < 0 ), 33 | error(['Invalid evidence, X_', int2str(v), ' = ', int2str(x)]); 34 | end; 35 | 36 | % Adjust the factor F(j) to account for observed evidence 37 | for k = 1:length(F(j).val), 38 | % get assignment for this index 39 | A = IndexToAssignment(k, F(j).card); 40 | if (A(indx) ~= x), 41 | F(j).val(k) = 0; 42 | end; 43 | end; 44 | 45 | % Check validity of evidence / resulting factor 46 | if (all(F(j).val == 0)), 47 | warning(['Factor ', int2str(j), ' makes variable assignment impossible']); 48 | end; 49 | 50 | end; 51 | end; 52 | end; 53 | 54 | end 55 | -------------------------------------------------------------------------------- /PA7/PruneTree.m: -------------------------------------------------------------------------------- 1 | function C = PruneTree(C) 2 | 3 | % Logic: 4 | % Start with a clique, scan through its neighbors. If you find a neighbor 5 | % such that it is a superset of the clique you started with, then you know 6 | % that you can prune the tree. For instance, let's take the following 7 | % clique tree: 8 | % ABE -- AB ---AD 9 | % Let's say we started with AB. We scan through its neighbors and find that 10 | % AB is a subset of ABE. So we cut off the edges connected to AB and add an 11 | % edge between ABE and all of AB's other neighbors. This maintains the 12 | % running intersection property and gives us a more compact clique tree 13 | % which looks like: ABE -- AD. 14 | 15 | toRemove = []; 16 | for i=1:length(C.nodes) 17 | 18 | if ismember(i,toRemove), continue, end; 19 | 20 | neighborsI = find(C.edges(i,:)); 21 | 22 | for c = 1: length(neighborsI), 23 | 24 | j = neighborsI(c); 25 | 26 | assert(i ~= j); 27 | 28 | if ismember(j,toRemove), continue, end; 29 | 30 | if (sum(ismember(C.nodes{i}, C.nodes{j})) == length(C.nodes{i})) 31 | 32 | 33 | for nk = neighborsI 34 | 35 | % find neighbors and connect with that. 36 | if length(intersect(C.nodes{i}, C.nodes{nk})) == length(C.nodes{i}) 37 | 38 | 39 | C.edges(setdiff(neighborsI,[nk]),nk) = 1; 40 | C.edges(nk,setdiff(neighborsI,[nk])) = 1; 41 | 42 | break; 43 | end 44 | end 45 | 46 | % kill the edges for the clique that is to be removed. 47 | C.edges(i,:) = 0; 48 | C.edges(:,i) = 0; 49 | toRemove = [i toRemove]; 50 | end 51 | end 52 | end 53 | 54 | toKeep = setdiff(1:length(C.nodes),toRemove); 55 | 56 | C.nodes(toRemove) = []; 57 | 58 | if isfield(C, 'edges') 59 | C.edges = C.edges(toKeep,toKeep); 60 | else 61 | C.edges = []; 62 | end 63 | 64 | end 65 | 66 | -------------------------------------------------------------------------------- /PA4/GetNextCliques.m: -------------------------------------------------------------------------------- 1 | %GETNEXTCLIQUES Find a pair of cliques ready for message passing 2 | % [i, j] = GETNEXTCLIQUES(P, messages) finds ready cliques in a given 3 | % clique tree, P, and a matrix of current messages. Returns indices i and j 4 | % such that clique i is ready to transmit a message to clique j. 5 | % 6 | % We are doing clique tree message passing, so 7 | % do not return (i,j) if clique i has already passed a message to clique j. 8 | % 9 | % messages is a n x n matrix of passed messages, where messages(i,j) 10 | % represents the message going from clique i to clique j. 11 | % This matrix is initialized in CliqueTreeCalibrate as such: 12 | % MESSAGES = repmat(struct('var', [], 'card', [], 'val', []), N, N); 13 | % 14 | % If more than one message is ready to be transmitted, return 15 | % the pair (i,j) that is numerically smallest. If you use an outer 16 | % for loop over i and an inner for loop over j, breaking when you find a 17 | % ready pair of cliques, you will get the right answer. 18 | % 19 | % If no such cliques exist, returns i = j = 0. 20 | % 21 | % See also CLIQUETREECALIBRATE 22 | 23 | % CS228 Probabilistic Graphical Models(Winter 2012) 24 | % Copyright (C) 2012, Stanford University 25 | 26 | function [ii, jj] = GetNextCliques(P, messages) 27 | 28 | 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | % YOUR CODE HERE 31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | N = size(messages,1); 33 | ii = 0; 34 | jj = 0; 35 | for i = 1:N 36 | for j = 1:N 37 | if (P.edges(i,j) && isempty(messages(i,j).var)) 38 | readyToSend = 1; 39 | for k = 1:N 40 | if k ~= j && P.edges(k,i) 41 | if isempty(messages(k,i).var) 42 | readyToSend = 0; 43 | break; 44 | end 45 | end 46 | end 47 | if readyToSend 48 | ii = i; 49 | jj = j; 50 | return; 51 | end 52 | end 53 | end 54 | end 55 | 56 | return; 57 | -------------------------------------------------------------------------------- /PA5/ConstructRandNetwork.m: -------------------------------------------------------------------------------- 1 | % 2 | % This is a script that constructs the toy network and outputs toy_network and toy_factors into 3 | % the environment. You should modify this file to change the parameters of the toy network. 4 | % 5 | % In this file, on_diag_weight represents the weight of the on-diagonal elements 6 | % in your pairwise CPDs (weight of agreement) while the off_diag_weight is the 7 | % weight for off-diagonal assignments (weight of disagreement between adjacent nodes) 8 | % 9 | function [toy_network, toy_factors] = ConstructRandNetwork(on_diag_weight, off_diag_weight) 10 | rand('seed',1); 11 | n = 4; % square length 12 | k = 2; % sub-square length 13 | V = 1:n*n; 14 | 15 | G = struct; 16 | G.names = {}; 17 | for i = 1:length(V) 18 | G.names{i} = ['pixel', num2str(i)]; 19 | G.card(i) = 2; 20 | end 21 | edges = zeros(length(V)); 22 | for i = 1:length(V) 23 | for j = i+1:length(V) 24 | % Four connected Markov Net 25 | [r_i, c_i] = ind2sub([n,n],i); 26 | [r_j, c_j] = ind2sub([n,n],j); 27 | if sum(abs([r_i, c_i] - [r_j, c_j])) == 1 28 | edges(i, j) = 1; 29 | end 30 | end 31 | end 32 | G.edges = or(edges, edges'); 33 | 34 | singleton_factors = []; 35 | for i = 1:length(V) 36 | singleton_factors(i).var = i; 37 | singleton_factors(i).card = 2; 38 | if i <= length(V) / 2 39 | curval = rand(1,2); 40 | singleton_factors(i).val = curval/sum(curval); 41 | else 42 | singleton_factors(i).val = [0.6, 0.4]; 43 | end 44 | end 45 | 46 | pairwise_factors = []; 47 | [r, c] = ind2sub([length(V), length(V)], find(edges)); 48 | edge_list = [r, c]; 49 | for i = 1:size(edge_list, 1) 50 | pairwise_factors(i).var = edge_list(i, :); 51 | pairwise_factors(i).card = [2, 2]; 52 | pairwise_factors(i).val = [on_diag_weight, off_diag_weight, ... 53 | off_diag_weight, on_diag_weight]; 54 | 55 | end 56 | 57 | F = [singleton_factors, pairwise_factors]; 58 | G.var2factors = VariableToFactorCorrespondence(V, F); 59 | 60 | toy_network = G; 61 | toy_factors = [singleton_factors, pairwise_factors]; 62 | -------------------------------------------------------------------------------- /PA4/ComputeExactMarginalsBP.m: -------------------------------------------------------------------------------- 1 | %COMPUTEEXACTMARGINALSBP Runs exact inference and returns the marginals 2 | %over all the variables (if isMax == 0) or the max-marginals (if isMax == 1). 3 | % 4 | % M = COMPUTEEXACTMARGINALSBP(F, E, isMax) takes a list of factors F, 5 | % evidence E, and a flag isMax, runs exact inference and returns the 6 | % final marginals for the variables in the network. If isMax is 1, then 7 | % it runs exact MAP inference, otherwise exact inference (sum-prod). 8 | % It returns an array of size equal to the number of variables in the 9 | % network where M(i) represents the ith variable and M(i).val represents 10 | % the marginals of the ith variable. 11 | 12 | 13 | % CS228 Probabilistic Models in AI (Winter 2012) 14 | % Copyright (C) 2012, Stanford University 15 | 16 | function M = ComputeExactMarginalsBP(F, E, isMax) 17 | 18 | % Since we only need marginals at the end, you should M as: 19 | % 20 | % M = repmat(struct('var', 0, 'card', 0, 'val', []), length(N), 1); 21 | % 22 | % where N is the number of variables in the network, which can be determined 23 | % from the factors F. 24 | 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | % YOUR CODE HERE 27 | % 28 | % Implement Exact and MAP Inference. 29 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 | 31 | P = CreateCliqueTree(F, E); 32 | 33 | P = CliqueTreeCalibrate(P, isMax); 34 | 35 | N = length(F); 36 | vars = []; 37 | 38 | for i = 1:N 39 | vars = union(vars, F(i).var); 40 | end 41 | 42 | M = repmat(struct('var', 0, 'card', 0, 'val', []), length(vars), 1); 43 | 44 | for i = 1:length(vars) 45 | v = vars(i); 46 | for j = 1:length(P.cliqueList) 47 | if ismember(v, P.cliqueList(j).var) 48 | if isMax 49 | M(v) = FactorMaxMarginalization(P.cliqueList(j), setdiff(P.cliqueList(j).var, [v])); 50 | else 51 | M(v) = FactorMarginalization(P.cliqueList(j), setdiff(P.cliqueList(j).var, [v])); 52 | M(v).val = M(v).val ./ sum(M(v).val); % normalization 53 | end 54 | break; 55 | end 56 | end 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /PA4/FactorMaxMarginalization.m: -------------------------------------------------------------------------------- 1 | % FactorMaxMarginalization Max-marginalizes a factor 2 | % by taking the max over a given set variables. 3 | % 4 | % B = FactorMaxMarginalization(A,V) computes the factor with the variables 5 | % in V maxed out. The factor data structure has the following fields: 6 | % .var Vector of variables in the factor, e.g. [1 2 3] 7 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 8 | % .val Value table of size prod(.card) 9 | % 10 | % B.var will be A.var minus V. 11 | % For each assignment in B, its value is the maximum value in A 12 | % of all assignments in A consistent with that assignment in B. 13 | % 14 | % The resultant factor should have at least one variable remaining or this 15 | % function will throw an error. 16 | % 17 | % This is exactly the same as FactorMarginalization, 18 | % but with the sum replaced by a max. 19 | % 20 | % See also FactorMarginalization.m, IndexToAssignment.m, and AssignmentToIndex.m 21 | 22 | function B = FactorMaxMarginalization(A, V) 23 | 24 | % Check for empty factor or variable list 25 | if (isempty(A.var) || isempty(V)), B = A; return; end; 26 | 27 | % Construct the output factor over A.var \ V (the variables in A.var that are not in V) 28 | % and mapping between variables in A and B 29 | [B.var, mapB] = setdiff(A.var, V); 30 | 31 | % Check for empty resultant factor 32 | if isempty(B.var) 33 | error('Error: Resultant factor has empty scope'); 34 | end; 35 | 36 | % Initialize B.card and B.val 37 | B.card = A.card(mapB); 38 | B.val = ones(1, prod(B.card)) .* -inf; 39 | 40 | % Compute some helper indices 41 | % These will be very useful for calculating C.val 42 | % so make sure you understand what these lines are doing 43 | assignments = IndexToAssignment(1:length(A.val), A.card); 44 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 45 | 46 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47 | % YOUR CODE HERE 48 | % Correctly populate the factor values of B 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 | 51 | for i = 1:length(A.val) 52 | if A.val(i) > B.val(indxB(i)) 53 | B.val(indxB(i)) = A.val(i); 54 | end 55 | end 56 | 57 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 | end 59 | -------------------------------------------------------------------------------- /PA8/FitLinearGaussianParameters.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: FitLinearGaussianParameters.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function [Beta sigma] = FitLinearGaussianParameters(X, U) 7 | 8 | % Estimate parameters of the linear Gaussian model: 9 | % X|U ~ N(Beta(1)*U(1) + ... + Beta(n)*U(n) + Beta(n+1), sigma^2); 10 | 11 | % Note that Matlab/Octave index from 1, we can't write Beta(0). 12 | % So Beta(n+1) is essentially Beta(0) in the text book. 13 | 14 | % X: (M x 1), the child variable, M examples 15 | % U: (M x N), N parent variables, M examples 16 | 17 | M = size(U,1); 18 | N = size(U,2); 19 | 20 | Beta = zeros(N+1,1); 21 | sigma = 1; 22 | 23 | % collect expectations and solve the linear system 24 | % A = [ E[U(1)], E[U(2)], ... , E[U(n)], 1 ; 25 | % E[U(1)*U(1)], E[U(2)*U(1)], ... , E[U(n)*U(1)], E[U(1)]; 26 | % ... , ... , ... , ... , ... ; 27 | % E[U(1)*U(n)], E[U(2)*U(n)], ... , E[U(n)*U(n)], E[U(n)] ] 28 | 29 | % construct A 30 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 | % YOUR CODE HERE 32 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 | 34 | A = zeros(N+1); 35 | for i = 1:N 36 | A(1,i) = mean(U(:,i)); 37 | end 38 | A(1,N+1) = 1; 39 | A(2:N+1,N+1) = A(1,1:N)'; 40 | for i = 2:N+1 41 | for j = 1:N 42 | %E[U(j)*U(i-1)] 43 | A(i,j) = mean(U(:,j).*U(:,i-1)); 44 | end 45 | end 46 | 47 | % B = [ E[X]; E[X*U(1)]; ... ; E[X*U(n)] ] 48 | 49 | % construct B 50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | % YOUR CODE HERE 52 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 53 | 54 | B = zeros(N+1,1); 55 | B(1) = mean(X); 56 | for j = 2:N+1 57 | B(j) = mean(X.*U(:,j-1)); 58 | end 59 | 60 | % solve A*Beta = B 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | % YOUR CODE HERE 63 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 | 65 | Beta = A\B; 66 | 67 | % then compute sigma according to eq. (11) in PA description 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | % YOUR CODE HERE 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 | 72 | sigma = mean(X .^ 2) - mean(X) ^ 2; 73 | 74 | for i = 1:N 75 | for j = 1:N 76 | Cov = mean(U(:,i).*U(:,j))-mean(U(:,i))*mean(U(:,j)); 77 | sigma = sigma - Beta(i)*Beta(j)*Cov; 78 | end 79 | end 80 | 81 | sigma = sqrt(sigma); 82 | -------------------------------------------------------------------------------- /PA5/SmartGetNextClusters.m: -------------------------------------------------------------------------------- 1 | %GETNEXTCLUSTERS Takes in a cluster graph and returns the indices 2 | % of the nodes between which the next message should be passed. 3 | % 4 | % [i j] = SmartGetNextClusters(P,Messages,oldMessages,m) 5 | % 6 | % INPUT 7 | % P - our cluster graph 8 | % Messages - the current values of all messages in P 9 | % oldMessages - the previous values of all messages in P. Thus, 10 | % oldMessages(i,j) contains the value that Messages(i,j) contained 11 | % immediately before it was updated to its current value 12 | % m - the index of the message we are passing (ie, m=0 indicates we have 13 | % passed 0 messages prior to this one. m=5 means we've passed 5 messages 14 | % 15 | % Implement any message passing routine that will converge in cases that the 16 | % naive routine would also converge. You may also change the inputs to 17 | % this function, but note you may also have to change GetNextClusters.m as 18 | % well. 19 | 20 | 21 | function [i j] = SmartGetNextClusters(P,Messages,oldMessages,m) 22 | 23 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 24 | % YOUR CODE HERE 25 | % Find the indices between which to pass a cluster 26 | % The 'find' function may be useful 27 | % 28 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 29 | 30 | [lli, llj] = find(P.edges~=0, prod(size(P.edges))); 31 | numMessages = length(lli); 32 | 33 | % disp([ 'numMessages: ', int2str(numMessages), ' m: ', int2str(m) ]); % DEBUG 34 | 35 | maxdiff = 0; 36 | if (m-1) >= numMessages 37 | [ rows, cols ] = find(P.edges~=0, numMessages); 38 | maxdiff = 0; 39 | for x = 1:size(rows,1) 40 | d = MessageDelta( Messages(rows(x), cols(x)), oldMessages(rows(x), cols(x)) ); 41 | if d >= maxdiff 42 | maxdiff = d; 43 | i = rows(x); 44 | j = cols(x); 45 | end 46 | end 47 | else 48 | [i j] = NaiveGetNextClusters(P, m); 49 | end 50 | 51 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 52 | 53 | % disp([ 'getnext returning (', int2str(i), ', ', int2str(j), ') diff: ', num2str(maxdiff) ]); % DEBUG 54 | 55 | return; 56 | 57 | % Get the max difference between the marginal entries of 2 messages ------- 58 | function delta = MessageDelta(Mes1, Mes2) 59 | delta = max(abs(Mes1.val - Mes2.val)); 60 | return; 61 | -------------------------------------------------------------------------------- /PA5/CreateClusterGraph.m: -------------------------------------------------------------------------------- 1 | %CREATECLUSTERGRAPH Takes in a list of factors and returns a Bethe cluster 2 | % graph. It also returns an assignment of factors to cliques. 3 | % 4 | % C = CREATECLUSTERGRAPH(F) Takes a list of factors and creates a Bethe 5 | % cluster graph with nodes representing single variable clusters and 6 | % pairwise clusters. The value of the clusters should be initialized to 7 | % the initial potential. 8 | % It returns a cluster graph that has the following fields: 9 | % - .clusterList: a list of the cluster beliefs in this graph. These entries 10 | % have the following subfields: 11 | % - .var: indices of variables in the specified cluster 12 | % - .card: cardinality of variables in the specified cluster 13 | % - .val: the cluster's beliefs about these variables 14 | % - .edges: A cluster adjacency matrix where edges(i,j)=1 implies clusters i 15 | % and j share an edge. 16 | % 17 | % NOTE: The index of the cluster for each factor should be the same within the 18 | % clusterList as it is within the initial list of factors. Thus, the cluster 19 | % for factor F(i) should be found in P.clusterList(i) 20 | 21 | % CS228 Probabilistic Graphical Models(Winter 2012) 22 | % Copyright (C) 2012, Stanford University 23 | 24 | function P = CreateClusterGraph(F, Evidence) 25 | 26 | for j = 1:length(Evidence), 27 | if (Evidence(j) > 0), 28 | F = ObserveEvidence(F, [j, Evidence(j)]); 29 | end; 30 | end; 31 | 32 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 | % YOUR CODE HERE 34 | % 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | 37 | vars = []; 38 | for i = 1:length(F) 39 | vars = union(vars, F(i).var); 40 | end 41 | numVars = length(vars); 42 | 43 | P = struct('clusterList', [], 'edges', []); 44 | 45 | P.clusterList = repmat(struct('var', 0, 'card', 0, 'val', []), 1, length(F)); 46 | P.edges = zeros(length(F)); 47 | 48 | for i = 1:length(F) 49 | P.clusterList(i).var = F(i).var; 50 | P.clusterList(i).card = F(i).card; 51 | P.clusterList(i).val = F(i).val; 52 | if length(F(i).var) > 1 53 | for j = 1:length(F(i).var) 54 | ind = find(vars == F(i).var(j)); 55 | P.edges(i, ind) = 1; 56 | P.edges(ind, i) = 1; 57 | end 58 | end 59 | end 60 | 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | 63 | -------------------------------------------------------------------------------- /PA7/FactorProduct.m: -------------------------------------------------------------------------------- 1 | % FactorProduct Computes the product of two factors. 2 | % C = FactorProduct(A,B) computes the product between two factors, A and B, 3 | % where each factor is defined over a set of variables with given dimension. 4 | % The factor data structure has the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % 9 | % See also FactorMarginalization.m, IndexToAssignment.m, and 10 | % AssignmentToIndex.m 11 | 12 | function C = FactorProduct(A, B) 13 | 14 | % Check for empty factors 15 | if (isempty(A.var)), C = B; return; end; 16 | if (isempty(B.var)), C = A; return; end; 17 | 18 | % Check that variables in both A and B have the same cardinality 19 | [dummy iA iB] = intersect(A.var, B.var); 20 | if ~isempty(dummy) 21 | % A and B have at least 1 variable in common 22 | assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors'); 23 | end 24 | 25 | % Set the variables of C 26 | C.var = union(A.var, B.var); 27 | 28 | % Construct the mapping between variables in A and B and variables in C. 29 | % In the code below, we have that 30 | % 31 | % mapA(i) = j, if and only if, A.var(i) == C.var(j) 32 | % 33 | % and similarly 34 | % 35 | % mapB(i) = j, if and only if, B.var(i) == C.var(j) 36 | % 37 | % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5], 38 | % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3 39 | % and C.var(2) = 3, so A.var(1) == C.var(2). 40 | 41 | [dummy, mapA] = ismember(A.var, C.var); 42 | [dummy, mapB] = ismember(B.var, C.var); 43 | 44 | % Set the cardinality of variables in C 45 | C.card = zeros(1, length(C.var)); 46 | C.card(mapA) = A.card; 47 | C.card(mapB) = B.card; 48 | 49 | % Initialize the factor values of C: 50 | % prod(C.card) is the number of entries in C 51 | C.val = zeros(1,prod(C.card)); 52 | 53 | % Compute some helper indices 54 | % These will be very useful for calculating C.val 55 | % so make sure you understand what these lines are doing. 56 | assignments = IndexToAssignment(1:prod(C.card), C.card); 57 | indxA = AssignmentToIndex(assignments(:, mapA), A.card); 58 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 59 | 60 | C.val = A.val(indxA) .* B.val(indxB); 61 | 62 | 63 | end 64 | -------------------------------------------------------------------------------- /PA4/ObserveEvidence.m: -------------------------------------------------------------------------------- 1 | % ObserveEvidence Modify a vector of factors given some evidence. 2 | % F = ObserveEvidence(F, E) sets all entries in the vector of factors, F, 3 | % that are not consistent with the evidence, E, to zero. F is a vector of 4 | % factors, each a data structure with the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % E is an N-by-2 matrix, where each row consists of a variable/value pair. 9 | % Variables are in the first column and values are in the second column. 10 | 11 | function F = ObserveEvidence(F, E) 12 | 13 | % Iterate through all evidence 14 | 15 | for i = 1:size(E, 1), 16 | v = E(i, 1); % variable 17 | x = E(i, 2); % value 18 | 19 | % Check validity of evidence 20 | if (x == 0), 21 | warning(['Evidence not set for variable ', int2str(v)]); 22 | continue; 23 | end; 24 | 25 | for j = 1:length(F), 26 | % Does factor contain variable? 27 | indx = find(F(j).var == v); 28 | 29 | if (~isempty(indx)), 30 | 31 | % Check validity of evidence 32 | if (x > F(j).card(indx) || x < 0 ), 33 | error(['Invalid evidence, X_', int2str(v), ' = ', int2str(x)]); 34 | end; 35 | 36 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 | % YOUR CODE HERE 38 | % Adjust the factor F(j) to account for observed evidence 39 | % Hint: You might find it helpful to use IndexToAssignment 40 | % and SetValueOfAssignment 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | for k = 1:length(F(j).val), 43 | % get assignment for this index 44 | A = IndexToAssignment(k, F(j).card); 45 | if (A(indx) ~= x), 46 | F(j).val(k) = 0; 47 | end; 48 | end; 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 | 51 | % Check validity of evidence / resulting factor 52 | if (all(F(j).val == 0)), 53 | warning(['Factor ', int2str(j), ' makes variable assignment impossible']); 54 | end; 55 | 56 | end; 57 | end; 58 | end; 59 | 60 | end 61 | -------------------------------------------------------------------------------- /PA5/ObserveEvidence.m: -------------------------------------------------------------------------------- 1 | % ObserveEvidence Modify a vector of factors given some evidence. 2 | % F = ObserveEvidence(F, E) sets all entries in the vector of factors, F, 3 | % that are not consistent with the evidence, E, to zero. F is a vector of 4 | % factors, each a data structure with the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % E is an N-by-2 matrix, where each row consists of a variable/value pair. 9 | % Variables are in the first column and values are in the second column. 10 | 11 | function F = ObserveEvidence(F, E) 12 | 13 | % Iterate through all evidence 14 | 15 | for i = 1:size(E, 1), 16 | v = E(i, 1); % variable 17 | x = E(i, 2); % value 18 | 19 | % Check validity of evidence 20 | if (x == 0), 21 | warning(['Evidence not set for variable ', int2str(v)]); 22 | continue; 23 | end; 24 | 25 | for j = 1:length(F), 26 | % Does factor contain variable? 27 | indx = find(F(j).var == v); 28 | 29 | if (~isempty(indx)), 30 | 31 | % Check validity of evidence 32 | if (x > F(j).card(indx) || x < 0 ), 33 | error(['Invalid evidence, X_', int2str(v), ' = ', int2str(x)]); 34 | end; 35 | 36 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 37 | % YOUR CODE HERE 38 | % Adjust the factor F(j) to account for observed evidence 39 | % Hint: You might find it helpful to use IndexToAssignment 40 | % and SetValueOfAssignment 41 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 | for k = 1:length(F(j).val), 43 | % get assignment for this index 44 | A = IndexToAssignment(k, F(j).card); 45 | if (A(indx) ~= x), 46 | F(j).val(k) = 0; 47 | end; 48 | end; 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 | 51 | % Check validity of evidence / resulting factor 52 | if (all(F(j).val == 0)), 53 | warning(['Factor ', int2str(j), ' makes variable assignment impossible']); 54 | end; 55 | 56 | end; 57 | end; 58 | end; 59 | 60 | end 61 | -------------------------------------------------------------------------------- /PA7/FactorSum.m: -------------------------------------------------------------------------------- 1 | % FactorProduct Computes the product of two factors. 2 | % C = FactorSum(A,B) computes the sum of two factors, A and B, 3 | % where each factor is defined over a set of variables with given dimension. 4 | % The factor data structure has the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) -- values should be the 8 | % logs of the true values 9 | % 10 | % See also FactorMaxMarginalization.m, IndexToAssignment.m, and 11 | % AssignmentToIndex.m 12 | 13 | function C = FactorSum(A, B) 14 | 15 | % Check for empty factors 16 | if (isempty(A.var)), C = B; return; end; 17 | if (isempty(B.var)), C = A; return; end; 18 | 19 | % Check that variables in both A and B have the same cardinality 20 | [dummy iA iB] = intersect(A.var, B.var); 21 | if ~isempty(dummy) 22 | % A and B have at least 1 variable in common 23 | assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors'); 24 | end 25 | 26 | % Set the variables of C 27 | C.var = union(A.var, B.var); 28 | 29 | % Construct the mapping between variables in A and B and variables in C. 30 | % In the code below, we have that 31 | % 32 | % mapA(i) = j, if and only if, A.var(i) == C.var(j) 33 | % 34 | % and similarly 35 | % 36 | % mapB(i) = j, if and only if, B.var(i) == C.var(j) 37 | % 38 | % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5], 39 | % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3 40 | % and C.var(2) = 3, so A.var(1) == C.var(2). 41 | 42 | [dummy, mapA] = ismember(A.var, C.var); 43 | [dummy, mapB] = ismember(B.var, C.var); 44 | 45 | % Set the cardinality of variables in C 46 | C.card = zeros(1, length(C.var)); 47 | C.card(mapA) = A.card; 48 | C.card(mapB) = B.card; 49 | 50 | % Initialize the factor values of C: 51 | % prod(C.card) is the number of entries in C 52 | C.val = zeros(1,prod(C.card)); 53 | 54 | % Compute some helper indices 55 | % These will be very useful for calculating C.val 56 | % so make sure you understand what these lines are doing. 57 | assignments = IndexToAssignment(1:prod(C.card), C.card); 58 | indxA = AssignmentToIndex(assignments(:, mapA), A.card); 59 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 60 | 61 | C.val = A.val(indxA) + B.val(indxB); 62 | 63 | end 64 | -------------------------------------------------------------------------------- /PA8/MaxSpanningTree.m: -------------------------------------------------------------------------------- 1 | function adj = MaxSpanningTree (weights) 2 | % MAXSPANNINGTREE Maximum weight spanning tree 3 | % 4 | % adj = MaxSpanningTree(weights) takes an n-by-n weight matrix, which 5 | % should be symmetric, and returns an adjacency list representation of 6 | % the maximum weight spanning tree. The adjacency list will be directed, 7 | % i.e. not symmetric. 8 | % 9 | % Simply an implementation of Prim's MST algorithm 10 | 11 | % CS228 Probabilistic Models in AI (Winter 2007) 12 | % Copyright (C) 2007, Stanford University 13 | 14 | n = size(weights, 1); 15 | if (n ~= size(weights, 2)) 16 | help(mfilename); 17 | end 18 | % The keys are the weights of the edges 19 | keys = -inf*ones(n, 1); 20 | predecessors = -ones(n, 1); 21 | root = 1; 22 | keys(root) = 0; 23 | % Queue of vertices to put in the tree 24 | Q = 1:n; 25 | 26 | while (length(Q) ~= 0) 27 | [index, vertex] = MaxVertex(Q, keys); 28 | remover = [1:(index-1) (index+1):length(Q)]; 29 | % Remove the index of the maximum key vertex from Q 30 | Q = Q(remover); 31 | % Loop over all vertices adjacent to vertex 32 | for v = 1:n 33 | % If the vertex is still in the queue 34 | ind = find(Q == v); 35 | if (length(ind) == 1 && weights(vertex, v) > keys(v)) 36 | % If the v is still in the queue and the weight of the 37 | % edge is greater than its key, set the vertex to be v's 38 | % predecessor 39 | predecessors(v) = vertex; 40 | keys(v) = weights(vertex, v); 41 | end 42 | end 43 | end 44 | 45 | adj = AdjFromPreds(predecessors, n); 46 | 47 | 48 | % ---- MaxVertex ---- % 49 | function [index, vertex] = MaxVertex(Q, keys) 50 | % Returns the maximum weight vertex (maximum weight across the cut set) 51 | % given the keys. Returns the index into Q in index, return the actual 52 | % vertex in vertex. 53 | 54 | % We use keys(Q) to only consider the keys for vertices still in the queue 55 | [val, index] = max(keys(Q)); 56 | vertex = Q(index); 57 | 58 | 59 | % ---- AdjFromPreds ---- % 60 | function adj = AdjFromPreds(predecessors, n) 61 | % Constructs an adjacency matrix representation of the matrix from the list 62 | % of predecessors found by the MST algorithm. 63 | adj = zeros(n); 64 | for i = 1:n 65 | if (predecessors(i) ~= -1) 66 | adj(predecessors(i), i) = 1; 67 | end 68 | end 69 | % Make it symmetric (undirected) 70 | % adj = adj + adj'; 71 | -------------------------------------------------------------------------------- /PA3/ScorePredictions.m: -------------------------------------------------------------------------------- 1 | function [charAcc, wordAcc] = ScorePredictions (words, predictions, showOutput) 2 | % This function computes the character and word accuracies for a list of 3 | % words and the predictions for each of those words. 4 | % 5 | % Input: 6 | % words: A cell array of struct arrays such as the provided 'allWords'. 7 | % predictions: A cell array of arrays. predictions{i} should be an array 8 | % of the character values of word i. This will be the return value of 9 | % ComputeWordPredictions.m when correctly implemented. 10 | % showOutput [optional]: Boolean, default true. If true, this functional 11 | % will print diagnostic information to the console as it runs. 12 | % Otherwise, there is no printed output. 13 | % 14 | % Output: 15 | % charAcc: The percentage of all characters (across all words) correctly 16 | % identified. (Between 0 and 1) 17 | % wordAcc: The percentage of the words in which every character is 18 | % correctly identified. (Between 0 and 1) 19 | 20 | 21 | if (nargin < 3) 22 | showOutput = true; 23 | end 24 | 25 | numWords = length(words); 26 | if (numWords ~= length(predictions)) 27 | error('words and predictions must be same length'); 28 | end 29 | 30 | totalChars = 0; 31 | totalWords = 0; 32 | totalCharsRight = 0; 33 | totalWordsRight = 0; 34 | 35 | for i = 1:numWords 36 | totalChars = totalChars + length(predictions{i}); 37 | totalWords = totalWords + 1; 38 | charsRight = sum(predictions{i}(:) == vertcat(words{i}(:).groundTruth)); 39 | totalCharsRight = totalCharsRight + charsRight; 40 | if (charsRight == length(predictions{i})) 41 | totalWordsRight = totalWordsRight + 1; 42 | end 43 | 44 | if (showOutput) 45 | charsWrong = length(predictions{i}) - charsRight; 46 | rightWord = char(horzcat(words{i}(:).groundTruth) + 'a' - 1); 47 | predWord = char(horzcat(predictions{i}(:)) + 'a' - 1); 48 | 49 | fprintf('%d\n Correct: %s\n Predicted: %s\n (%d mistaken characters)\n', ... 50 | i, rightWord, predWord, charsWrong); 51 | end 52 | end 53 | 54 | charAcc = totalCharsRight / totalChars; 55 | wordAcc = totalWordsRight / totalWords; 56 | 57 | if (showOutput) 58 | fprintf('\n\n %d / %d characters (%.2f%% accuracy)\n %d / %d words (%.2f%% accuracy)\n\n', ... 59 | totalCharsRight, totalChars, charAcc * 100, totalWordsRight, totalWords, wordAcc * 100); 60 | end 61 | 62 | end 63 | 64 | -------------------------------------------------------------------------------- /PA4/ComputeInitialPotentials.m: -------------------------------------------------------------------------------- 1 | %COMPUTEINITIALPOTENTIALS Sets up the cliques in the clique tree that is 2 | %passed in as a parameter. 3 | % 4 | % P = COMPUTEINITIALPOTENTIALS(C) Takes the clique tree skeleton C which is a 5 | % struct with three fields: 6 | % - nodes: cell array representing the cliques in the tree. 7 | % - edges: represents the adjacency matrix of the tree. 8 | % - factorList: represents the list of factors that were used to build 9 | % the tree. 10 | % 11 | % It returns the standard form of a clique tree P that we will use through 12 | % the rest of the assigment. P is struct with two fields: 13 | % - cliqueList: represents an array of cliques with appropriate factors 14 | % from factorList assigned to each clique. Where the .val of each clique 15 | % is initialized to the initial potential of that clique. 16 | % - edges: represents the adjacency matrix of the tree. 17 | 18 | 19 | % CS228 Probabilistic Models in AI (Winter 2012) 20 | % Copyright (C) 2012, Stanford University 21 | 22 | function P = ComputeInitialPotentials(C) 23 | 24 | % number of cliques 25 | N = length(C.nodes); 26 | 27 | % initialize cluster potentials 28 | P.cliqueList = repmat(struct('var', [], 'card', [], 'val', []), N, 1); 29 | 30 | 31 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 | % YOUR CODE HERE 33 | % 34 | % First, compute an assignment of factors from factorList to cliques. 35 | % Then use that assignment to initialize the cliques in cliqueList to 36 | % their initial potentials. 37 | 38 | % Hint: C.nodes is a list of cliques. 39 | % P.cliqueList(i).var = C.nodes{i}; 40 | % Print out C to get a better understanding of its structure. 41 | % 42 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 | 44 | M = length(C.factorList); 45 | assigned = zeros(M, 1); 46 | 47 | for i = 1:N 48 | 49 | P.cliqueList(i).var = C.nodes{i}; 50 | 51 | for j = 1:M 52 | if (~assigned(j)) 53 | [tf, index] = ismember (C.factorList(j).var, P.cliqueList(i).var); 54 | if (all(tf)) 55 | P.cliqueList(i).card(index) = C.factorList(j).card; 56 | assigned(j) = i; 57 | end 58 | end 59 | end 60 | 61 | P.cliqueList(i).val = ones(1, prod(P.cliqueList(i).card)); 62 | 63 | end 64 | 65 | for j = 1:M 66 | product = FactorProduct(P.cliqueList(assigned(j)), C.factorList(j)); 67 | P.cliqueList(assigned(j)).val = product.val; 68 | end 69 | 70 | P.edges = C.edges; 71 | 72 | end 73 | 74 | -------------------------------------------------------------------------------- /PA7/CreateCliqueTree.m: -------------------------------------------------------------------------------- 1 | %CREATECLIQUETREE Takes in a list of factors F, Evidence and returns a 2 | %clique tree after calling ComputeInitialPotentials at the end. 3 | % 4 | % C = CREATECLIQUETREE(F) Takes a list of factors and creates a clique 5 | % tree . The value of the cliques should be initialized to 6 | % the initial potential. 7 | % It returns a clique tree that has the following fields: 8 | % - .edges: Contains indices of the nodes that have edges between them. 9 | % - .factorList: Contains the list of factors used to build the Clique 10 | % tree. 11 | % 12 | 13 | % CS228 Probabilistic Graphical Models(Winter 2012) 14 | % Copyright (C) 2012, Stanford University 15 | 16 | function P = CreateCliqueTree(F) 17 | 18 | 19 | C.nodes = {}; 20 | 21 | V = unique([F(:).var]); 22 | 23 | % Setting up the cardinality for the variables since we only get a list 24 | % of factors. 25 | C.card = zeros(1, length(V)); 26 | for i = 1 : length(V), 27 | 28 | for j = 1 : length(F) 29 | if (~isempty(find(F(j).var == i))) 30 | C.card(i) = F(j).card(find(F(j).var == i)); 31 | break; 32 | end 33 | end 34 | end 35 | 36 | C.factorList = F; 37 | 38 | % Setting up the adjaceny matrix. 39 | edges = zeros(length(V)); 40 | 41 | for i = 1:length(F) 42 | for j = 1:length(F(i).var) 43 | for k = 1:length(F(i).var) 44 | edges(F(i).var(j), F(i).var(k)) = 1; 45 | end 46 | end 47 | end 48 | 49 | cliquesConsidered = 0; 50 | 51 | while cliquesConsidered < length(V) 52 | 53 | % Using Min-Neighbors where you prefer to eliminate the variable that has 54 | % the smallest number of edges connected to it. 55 | % Everytime you enter the loop, you look at the state of the graph and 56 | % pick the variable to be eliminated. 57 | 58 | bestClique = 0; 59 | bestScore = inf; 60 | for i=1:size(edges,1) 61 | score = sum(edges(i,:)); 62 | if score > 0 && score < bestScore 63 | bestScore = score; 64 | bestClique = i; 65 | end 66 | end 67 | 68 | cliquesConsidered = cliquesConsidered + 1; 69 | [F, C, edges] = EliminateVar(F, C, edges, bestClique); 70 | 71 | end 72 | 73 | % Pruning the tree. 74 | C = PruneTree(C); 75 | 76 | % Assume that C now has correct cardinality, variables, nodes and edges. 77 | % Here we make the function call to assign factors to cliques and compute the 78 | % initial potentials for clusters. 79 | 80 | P = ComputeInitialPotentials(C); 81 | 82 | -------------------------------------------------------------------------------- /PA7/ComputeExactMarginalsBP.m: -------------------------------------------------------------------------------- 1 | %COMPUTEEXACTMARGINALSBP Runs exact inference and returns the marginals 2 | %over all the variables. 3 | 4 | % M = COMPUTEEXACTMARGINALSBP(F,E, isMax) Takes a list of factors F, 5 | % evidence E and a flag isMax and run exact inference and returns the 6 | % final marginals for the variables in the network. If isMax is 1, then 7 | % it runs exact MAP inference, otherwise exact inference (sum-prod). 8 | % It returns an array of size equal to the number of variables in the 9 | % network where M(i) represents the ith variable and M(i).val represents 10 | % the marginals of the ith variable. 11 | 12 | 13 | % CS228 Probabilistic Models in AI (Winter 2012) 14 | % Copyright (C) 2012, Stanford University 15 | 16 | function M = ComputeExactMarginalsBP(F, E, isMax) 17 | % Since we only need marginals at the end, you should M as: 18 | % 19 | % M = repmat(struct('var', 0, 'card', 0, 'val', []), length(N), 1); 20 | % 21 | % where N is the number of variables in the network, which can be determined 22 | % from the factors F. 23 | 24 | % Create a clique tree, compute the initial potentails, calibrate the 25 | % clique tree, and find the belief for each varaible at a clique that has 26 | % that variable in its scope 27 | compressedCliqueTree = CreateCliqueTree(F, E); 28 | PCalibrated = CliqueTreeCalibrate(compressedCliqueTree, isMax); 29 | varsList = unique([F(:).var]); 30 | M = repmat(struct('var', 0, 'card', 0, 'val', []), length(varsList), 1); 31 | for i = 1:length(varsList) 32 | % Iterate through variables and find the marginal for each 33 | clique = struct('var', 0, 'card', 0, 'val', []); 34 | currentVar = varsList(i); 35 | for j = 1:length(PCalibrated.cliqueList) 36 | % Find a clique with the variable of interest 37 | if ~isempty(find(ismember(PCalibrated.cliqueList(j).var, currentVar))) 38 | % A clique with the variable has been indentified 39 | clique = PCalibrated.cliqueList(j); 40 | break 41 | end 42 | end 43 | if isMax == 0 44 | % Do sum-product inference 45 | M(i) = FactorMarginalization(clique, setdiff(clique.var, currentVar)); 46 | if any(M(i).val ~= 0) 47 | % Normalize 48 | M(i).val = M(i).val/sum(M(i).val); 49 | end 50 | else 51 | % Do MAP inference by using FactorMaxMarginalization instead of 52 | % FactorMarginalization 53 | M(i) = FactorMaxMarginalization(clique, setdiff(clique.var, currentVar)); 54 | end 55 | end 56 | 57 | end 58 | -------------------------------------------------------------------------------- /PA5/ComputeInitialPotentials.m: -------------------------------------------------------------------------------- 1 | %COMPUTEINITIALPOTENTIALS Sets up the cliques in the clique tree that is 2 | %passed in as a parameter. 3 | 4 | % P = COMPUTEINITIALPOTENTIALS(C) Takes the clique tree C which is a 5 | % struct with three fields: 6 | % - nodes: represents the cliques in the tree. 7 | % - edges: represents the adjacency matrix of the tree. 8 | % - factorList: represents the list of factors that were used to build 9 | % the tree. 10 | % 11 | % It returns a compact form of a clique tree P that we will use through 12 | % the rest of the assigment. P is struct with two fields: 13 | % - cliqueList: represents a list of cliques with appropriate factors 14 | % from factorList assigned to each clique. 15 | % - edges: represents the adjacency matrix of the tree. 16 | 17 | 18 | % CS228 Probabilistic Models in AI (Winter 2012) 19 | % Copyright (C) 2012, Stanford University 20 | 21 | function P = ComputeInitialPotentials(C) 22 | 23 | P.cliqueList = C.factorList; 24 | 25 | % number of cliques 26 | N = length(C.nodes); 27 | 28 | % compute assignment of factors to cliques 29 | alpha = zeros(length(C.factorList),1); 30 | 31 | % Setting up the cardinality 32 | V = unique([C.factorList(:).var]); 33 | 34 | % Setting up the cardinality for the variables since we only get a list 35 | % of factors. 36 | C.card = zeros(1, length(V)); 37 | for i = 1 : length(V), 38 | 39 | for j = 1 : length(C.factorList) 40 | if (~isempty(find(C.factorList(j).var == i))) 41 | C.card(i) = C.factorList(j).card(find(C.factorList(j).var == i)); 42 | break; 43 | end 44 | end 45 | end 46 | 47 | for i = 1:length(C.factorList), 48 | for j = 1:N, 49 | 50 | % does clique contain all variables in factor 51 | if (isempty(setdiff(C.factorList(i).var, C.nodes{j}))), 52 | alpha(i) = j; 53 | break; 54 | end; 55 | end; 56 | end; 57 | 58 | if (any(alpha == 0)), 59 | warning('Clique Tree does not have family preserving property'); 60 | end; 61 | 62 | P.edges = C.edges; 63 | 64 | % initialize cluster potentials 65 | P.cliqueList = repmat(struct('var', [], 'card', [], 'val', []), N, 1); 66 | 67 | for i = 1:N, 68 | P.cliqueList(i).var = C.nodes{i}; 69 | P.cliqueList(i).card = C.card(P.cliqueList(i).var); 70 | P.cliqueList(i).val = ones(1,prod(P.cliqueList(i).card)); 71 | end; 72 | 73 | for i = 1:length(alpha), 74 | P.cliqueList(alpha(i)) = FactorProduct(P.cliqueList(alpha(i)), C.factorList(i)); 75 | end; 76 | 77 | 78 | end 79 | 80 | -------------------------------------------------------------------------------- /PA4/FactorProduct.m: -------------------------------------------------------------------------------- 1 | % FactorProduct Computes the product of two factors. 2 | % C = FactorProduct(A,B) computes the product between two factors, A and B, 3 | % where each factor is defined over a set of variables with given dimension. 4 | % The factor data structure has the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % 9 | % See also FactorMarginalization.m, IndexToAssignment.m, and 10 | % AssignmentToIndex.m 11 | 12 | function C = FactorProduct(A, B) 13 | 14 | % Check for empty factors 15 | if (isempty(A.var)), C = B; return; end; 16 | if (isempty(B.var)), C = A; return; end; 17 | 18 | % Check that variables in both A and B have the same cardinality 19 | [dummy iA iB] = intersect(A.var, B.var); 20 | if ~isempty(dummy) 21 | % A and B have at least 1 variable in common 22 | assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors'); 23 | end 24 | 25 | % Set the variables of C 26 | C.var = union(A.var, B.var); 27 | 28 | % Construct the mapping between variables in A and B and variables in C. 29 | % In the code below, we have that 30 | % 31 | % mapA(i) = j, if and only if, A.var(i) == C.var(j) 32 | % 33 | % and similarly 34 | % 35 | % mapB(i) = j, if and only if, B.var(i) == C.var(j) 36 | % 37 | % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5], 38 | % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3 39 | % and C.var(2) = 3, so A.var(1) == C.var(2). 40 | 41 | [dummy, mapA] = ismember(A.var, C.var); 42 | [dummy, mapB] = ismember(B.var, C.var); 43 | 44 | % Set the cardinality of variables in C 45 | C.card = zeros(1, length(C.var)); 46 | C.card(mapA) = A.card; 47 | C.card(mapB) = B.card; 48 | 49 | % Initialize the factor values of C: 50 | % prod(C.card) is the number of entries in C 51 | C.val = zeros(1,prod(C.card)); 52 | 53 | % Compute some helper indices 54 | % These will be very useful for calculating C.val 55 | % so make sure you understand what these lines are doing. 56 | assignments = IndexToAssignment(1:prod(C.card), C.card); 57 | indxA = AssignmentToIndex(assignments(:, mapA), A.card); 58 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % YOUR CODE HERE: 62 | % Correctly populate the factor values of C 63 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 | C.val = A.val(indxA) .* B.val(indxB); 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | end 68 | -------------------------------------------------------------------------------- /PA5/FactorProduct.m: -------------------------------------------------------------------------------- 1 | % FactorProduct Computes the product of two factors. 2 | % C = FactorProduct(A,B) computes the product between two factors, A and B, 3 | % where each factor is defined over a set of variables with given dimension. 4 | % The factor data structure has the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % 9 | % See also FactorMarginalization.m, IndexToAssignment.m, and 10 | % AssignmentToIndex.m 11 | 12 | function C = FactorProduct(A, B) 13 | 14 | % Check for empty factors 15 | if (isempty(A.var)), C = B; return; end; 16 | if (isempty(B.var)), C = A; return; end; 17 | 18 | % Check that variables in both A and B have the same cardinality 19 | [dummy iA iB] = intersect(A.var, B.var); 20 | if ~isempty(dummy) 21 | % A and B have at least 1 variable in common 22 | assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors'); 23 | end 24 | 25 | % Set the variables of C 26 | C.var = union(A.var, B.var); 27 | 28 | % Construct the mapping between variables in A and B and variables in C. 29 | % In the code below, we have that 30 | % 31 | % mapA(i) = j, if and only if, A.var(i) == C.var(j) 32 | % 33 | % and similarly 34 | % 35 | % mapB(i) = j, if and only if, B.var(i) == C.var(j) 36 | % 37 | % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5], 38 | % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3 39 | % and C.var(2) = 3, so A.var(1) == C.var(2). 40 | 41 | [dummy, mapA] = ismember(A.var, C.var); 42 | [dummy, mapB] = ismember(B.var, C.var); 43 | 44 | % Set the cardinality of variables in C 45 | C.card = zeros(1, length(C.var)); 46 | C.card(mapA) = A.card; 47 | C.card(mapB) = B.card; 48 | 49 | % Initialize the factor values of C: 50 | % prod(C.card) is the number of entries in C 51 | C.val = zeros(1,prod(C.card)); 52 | 53 | % Compute some helper indices 54 | % These will be very useful for calculating C.val 55 | % so make sure you understand what these lines are doing. 56 | assignments = IndexToAssignment(1:prod(C.card), C.card); 57 | indxA = AssignmentToIndex(assignments(:, mapA), A.card); 58 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % YOUR CODE HERE: 62 | % Correctly populate the factor values of C 63 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 | C.val = A.val(indxA) .* B.val(indxB); 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | end 68 | -------------------------------------------------------------------------------- /PA6/FactorProduct.m: -------------------------------------------------------------------------------- 1 | % FactorProduct Computes the product of two factors. 2 | % C = FactorProduct(A,B) computes the product between two factors, A and B, 3 | % where each factor is defined over a set of variables with given dimension. 4 | % The factor data structure has the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % 9 | % See also FactorMarginalization.m, IndexToAssignment.m, and 10 | % AssignmentToIndex.m 11 | 12 | function C = FactorProduct(A, B) 13 | 14 | % Check for empty factors 15 | if (isempty(A.var)), C = B; return; end; 16 | if (isempty(B.var)), C = A; return; end; 17 | 18 | % Check that variables in both A and B have the same cardinality 19 | [dummy iA iB] = intersect(A.var, B.var); 20 | if ~isempty(dummy) 21 | % A and B have at least 1 variable in common 22 | assert(all(A.card(iA) == B.card(iB)), 'Dimensionality mismatch in factors'); 23 | end 24 | 25 | % Set the variables of C 26 | C.var = union(A.var, B.var); 27 | 28 | % Construct the mapping between variables in A and B and variables in C. 29 | % In the code below, we have that 30 | % 31 | % mapA(i) = j, if and only if, A.var(i) == C.var(j) 32 | % 33 | % and similarly 34 | % 35 | % mapB(i) = j, if and only if, B.var(i) == C.var(j) 36 | % 37 | % For example, if A.var = [3 1 4], B.var = [4 5], and C.var = [1 3 4 5], 38 | % then, mapA = [2 1 3] and mapB = [3 4]; mapA(1) = 2 because A.var(1) = 3 39 | % and C.var(2) = 3, so A.var(1) == C.var(2). 40 | 41 | [dummy, mapA] = ismember(A.var, C.var); 42 | [dummy, mapB] = ismember(B.var, C.var); 43 | 44 | % Set the cardinality of variables in C 45 | C.card = zeros(1, length(C.var)); 46 | C.card(mapA) = A.card; 47 | C.card(mapB) = B.card; 48 | 49 | % Initialize the factor values of C: 50 | % prod(C.card) is the number of entries in C 51 | C.val = zeros(1,prod(C.card)); 52 | 53 | % Compute some helper indices 54 | % These will be very useful for calculating C.val 55 | % so make sure you understand what these lines are doing. 56 | assignments = IndexToAssignment(1:prod(C.card), C.card); 57 | indxA = AssignmentToIndex(assignments(:, mapA), A.card); 58 | indxB = AssignmentToIndex(assignments(:, mapB), B.card); 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % YOUR CODE HERE: 62 | % Correctly populate the factor values of C 63 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 | C.val = A.val(indxA) .* B.val(indxB); 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | 67 | end 68 | -------------------------------------------------------------------------------- /PA6/ObserveEvidence.m: -------------------------------------------------------------------------------- 1 | % ObserveEvidence Modify a vector of factors given some evidence. 2 | % F = ObserveEvidence(F, E) sets all entries in the vector of factors, F, 3 | % that are not consistent with the evidence, E, to zero. F is a vector of 4 | % factors, each a data structure with the following fields: 5 | % .var Vector of variables in the factor, e.g. [1 2 3] 6 | % .card Vector of cardinalities corresponding to .var, e.g. [2 2 2] 7 | % .val Value table of size prod(.card) 8 | % E is an N-by-2 matrix, where each row consists of a variable/value pair. 9 | % Variables are in the first column and values are in the second column. 10 | % NOTE - DOES NOT RENORMALIZE THE FACTOR VALUES 11 | 12 | function F = ObserveEvidence(F, E, normalize) 13 | 14 | % Iterate through all evidence 15 | for i = 1:size(E, 1), 16 | v = E(i, 1); % variable 17 | x = E(i, 2); % value 18 | 19 | % Check validity of evidence 20 | if (x == 0), 21 | warning(['Evidence not set for variable ', int2str(v)]); 22 | continue; 23 | end; 24 | 25 | % Iterate through the factors 26 | for j = 1:length(F), 27 | % Does factor contain variable? 28 | indx = find(F(j).var == v); 29 | 30 | if (~isempty(indx)), 31 | 32 | % Check validity of evidence 33 | if (x > F(j).card(indx) || x < 0 ), 34 | error(['Invalid evidence, X_', int2str(v), ' = ', int2str(x)]); 35 | end; 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | % YOUR CODE HERE 39 | % Adjust the factor F(j) to account for observed evidence 40 | % Hint: You might find it helpful to use IndexToAssignment 41 | % and SetValueOfAssignment 42 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 | % For each value (1-1 map between assignment and values) 44 | for k = 1:length(F(j).val), 45 | 46 | % get assignment for this index 47 | A = IndexToAssignment(k, F(j).card); 48 | 49 | % indx = index of evidence variable in this factor 50 | if (A(indx) ~= x), 51 | F(j).val(k) = 0; 52 | end; 53 | 54 | end; 55 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 56 | 57 | % Check validity of evidence / resulting factor 58 | if (all(F(j).val == 0)), 59 | warning(['Factor ', int2str(j), ' makes variable assignment impossible']); 60 | end; 61 | 62 | end % if (!isempty(index)) 63 | 64 | end % for j = 1:length(F), 65 | 66 | end % for i = 1:size(E, 1), 67 | 68 | if (nargin == 3) 69 | if (normalize) 70 | F = NormalizeCPDFactors(F); 71 | end 72 | end 73 | 74 | 75 | -------------------------------------------------------------------------------- /PA5/gaimc/sparse_to_csr.m: -------------------------------------------------------------------------------- 1 | function [rp ci ai ncol]=sparse_to_csr(A,varargin) 2 | % SPARSE_TO_CSR Convert a sparse matrix into compressed row storage arrays 3 | % 4 | % [rp ci ai] = sparse_to_csr(A) returns the row pointer (rp), column index 5 | % (ci) and value index (ai) arrays of a compressed sparse representation of 6 | % the matrix A. 7 | % 8 | % [rp ci ai] = sparse_to_csr(i,j,v,n) returns a csr representation of the 9 | % index sets i,j,v with n rows. 10 | % 11 | % Example: 12 | % A=sparse(6,6); A(1,1)=5; A(1,5)=2; A(2,3)=-1; A(4,1)=1; A(5,6)=1; 13 | % [rp ci ai]=sparse_to_csr(A) 14 | % 15 | % See also CSR_TO_SPARSE, SPARSE 16 | 17 | % David F. Gleich 18 | % Copyright, Stanford University, 2008-2009 19 | 20 | % History 21 | % 2008-04-07: Initial version 22 | % 2008-04-24: Added triple array input 23 | % 2009-05-01: Added ncol output 24 | % 2009-05-15: Fixed triplet input 25 | 26 | %error(nargchk(1, 5, nargin, 'struct')) 27 | retc = nargout>1; reta = nargout>2; 28 | 29 | if nargin>1 30 | if nargin>4, ncol = varargin{4}; end 31 | nzi = A; nzj = varargin{1}; 32 | if reta && length(varargin) > 2, nzv = varargin{2}; end 33 | if nargin<4, n=max(nzi); else n=varargin{3}; end 34 | nz = length(A); 35 | if length(nzi) ~= length(nzj), error('gaimc:invalidInput',... 36 | 'length of nzi (%i) not equal to length of nzj (%i)', nz, ... 37 | length(nzj)); 38 | end 39 | if reta && length(varargin) < 3, error('gaimc:invalidInput',... 40 | 'no value array passed for triplet input, see usage'); 41 | end 42 | if ~isscalar(n), error('gaimc:invalidInput',... 43 | ['the 4th input to sparse_to_csr with triple input was not ' ... 44 | 'a scalar']); 45 | end 46 | if nargin < 5, ncol = max(nzj); 47 | elseif ~isscalar(ncol), error('gaimc:invalidInput',... 48 | ['the 5th input to sparse_to_csr with triple input was not ' ... 49 | 'a scalar']); 50 | end 51 | else 52 | n = size(A,1); nz = nnz(A); ncol = size(A,2); 53 | retc = nargout>1; reta = nargout>2; 54 | if reta, [nzi nzj nzv] = find(A); 55 | else [nzi nzj] = find(A); 56 | end 57 | end 58 | if retc, ci = zeros(nz,1); end 59 | if reta, ai = zeros(nz,1); end 60 | rp = zeros(n+1,1); 61 | for i=1:nz 62 | rp(nzi(i)+1)=rp(nzi(i)+1)+1; 63 | end 64 | rp=cumsum(rp); 65 | if ~retc && ~reta, rp=rp+1; return; end 66 | for i=1:nz 67 | if reta, ai(rp(nzi(i))+1)=nzv(i); end 68 | ci(rp(nzi(i))+1)=nzj(i); 69 | rp(nzi(i))=rp(nzi(i))+1; 70 | end 71 | for i=n:-1:1 72 | rp(i+1)=rp(i); 73 | end 74 | rp(1)=0; 75 | rp=rp+1; 76 | 77 | -------------------------------------------------------------------------------- /PA5/VisualizeMCMCMarginals.m: -------------------------------------------------------------------------------- 1 | % VISUALIZEMCMCMARGINALS 2 | % 3 | % This function accepts a list of sample lists, each from a different MCMC run. It then visualizes 4 | % the estimated marginals for each variable in V over the lifetime of the MCMC run. 5 | % 6 | % samples_list - a list of sample lists; each sample list is a m-by-n matrix where m is the 7 | % number of samples and n is the number of variables in the state of the Markov chain 8 | % 9 | % V - an array of variables 10 | % D - the dimensions of the variables in V 11 | % F - a list of factors (used in computing likelihoods of each sample) 12 | % window_size - size of the window over which to aggregate samples to compute the estimated 13 | % marginal at a given time 14 | % ExactMarginals - the exact marginals of V (optional) 15 | 16 | function VisualizeMCMCMarginals(samples_list, V, D, F, window_size, ExactMarginals) 17 | 18 | for i = 1:length(V) 19 | figure; 20 | v = V(i); 21 | d = D(i); 22 | title(['Marginal for Variable ', num2str(v)]); 23 | if exist('ExactMarginals') == 1, M = ExactMarginals(i); end; 24 | for j = 1:length(samples_list) 25 | samples_v = samples_list{j}(:, v); 26 | indicators_over_time = zeros(length(samples_v), d); 27 | for k = 1:length(samples_v) 28 | indicators_over_time(k, samples_v(k)) = 1; 29 | end 30 | 31 | % estimated_marginal = cumsum(indicators_over_time, 1); 32 | estimated_marginal = []; 33 | for k = 1:size(indicators_over_time, 2) 34 | estimated_marginal = [estimated_marginal, smooth(indicators_over_time(:, k), window_size)]; 35 | end 36 | % Prune ends 37 | estimated_marginal = estimated_marginal(window_size/2:end - window_size/2, :); 38 | 39 | 40 | estimated_marginal = estimated_marginal ./ ... 41 | repmat(sum(estimated_marginal, 2), 1, size(estimated_marginal, 2)); 42 | hold on; 43 | plot(estimated_marginal, '-', 'LineWidth', 2); 44 | if exist('M') == 1 45 | plot([1; size(estimated_marginal, 1)], [M.val; M.val], '--', 'LineWidth', 3); 46 | end 47 | set(gcf,'DefaultAxesColorOrder', rand(d, 3)); 48 | end 49 | end 50 | 51 | % Visualize likelihood of sample at each time step 52 | all_likelihoods = []; 53 | for i = 1:length(samples_list) 54 | samples = samples_list{i}; 55 | likelihoods = []; 56 | for j = 1:size(samples, 1) 57 | likelihoods = [likelihoods; LogProbOfJointAssignment(F, samples(j, :))]; 58 | end 59 | all_likelihoods = [all_likelihoods, likelihoods]; 60 | end 61 | figure; 62 | plot(all_likelihoods, '-', 'LineWidth', 2); -------------------------------------------------------------------------------- /PA4/CreateCliqueTree.m: -------------------------------------------------------------------------------- 1 | %CREATECLIQUETREE Takes in a list of factors F, Evidence and returns a 2 | %clique tree after calling ComputeInitialPotentials at the end. 3 | % 4 | % P = CREATECLIQUETREE(F, Evidence) Takes a list of factors and creates a clique 5 | % tree. The value of the cliques should be initialized to 6 | % the initial potential. 7 | % It returns a clique tree that has the following fields: 8 | % - .edges: Contains indices of the nodes that have edges between them. 9 | % - .cliqueList: Contains the list of factors used to build the Clique 10 | % tree. 11 | % 12 | % CS228 Probabilistic Graphical Models(Winter 2012) 13 | % Copyright (C) 2012, Stanford University 14 | 15 | function P = CreateCliqueTree(F, Evidence) 16 | 17 | C.nodes = {}; 18 | 19 | V = unique([F(:).var]); 20 | 21 | % Setting up the cardinality for the variables since we only get a list 22 | % of factors. 23 | C.card = zeros(1, length(V)); 24 | for i = 1 : length(V), 25 | 26 | for j = 1 : length(F) 27 | if (~isempty(find(F(j).var == i))) 28 | C.card(i) = F(j).card(find(F(j).var == i)); 29 | break; 30 | end 31 | end 32 | end 33 | 34 | C.factorList = F; 35 | 36 | % Setting up the adjacency matrix. 37 | edges = zeros(length(V)); 38 | 39 | for i = 1:length(F) 40 | for j = 1:length(F(i).var) 41 | for k = 1:length(F(i).var) 42 | edges(F(i).var(j), F(i).var(k)) = 1; 43 | end 44 | end 45 | end 46 | 47 | cliquesConsidered = 0; 48 | 49 | while cliquesConsidered < length(V) 50 | 51 | % Using Min-Neighbors where you prefer to eliminate the variable that has 52 | % the smallest number of edges connected to it. 53 | % Everytime you enter the loop, you look at the state of the graph and 54 | % pick the variable to be eliminated. 55 | 56 | bestClique = 0; 57 | bestScore = inf; 58 | for i=1:size(edges,1) 59 | score = sum(edges(i,:)); 60 | if score > 0 && score < bestScore 61 | bestScore = score; 62 | bestClique = i; 63 | end 64 | end 65 | 66 | cliquesConsidered = cliquesConsidered + 1; 67 | [F, C, edges] = EliminateVar(F, C, edges, bestClique); 68 | end 69 | 70 | % Pruning the tree. 71 | C = PruneTree(C); 72 | 73 | % We are incorporating the effect of evidence in our factor list. 74 | for j = 1:length(Evidence), 75 | if (Evidence(j) > 0), 76 | C.factorList = ObserveEvidence(C.factorList, [j, Evidence(j)]); 77 | end; 78 | end; 79 | 80 | % Assume that C now has correct cardinality, variables, nodes and edges. 81 | % Here we make the function call to assign factors to cliques and compute the 82 | % initial potentials for clusters. 83 | 84 | P = ComputeInitialPotentials(C); 85 | 86 | return 87 | -------------------------------------------------------------------------------- /PA6/OptimizeMEU.m: -------------------------------------------------------------------------------- 1 | function [MEU OptimalDecisionRule] = OptimizeMEU( I ) 2 | 3 | % Inputs: An influence diagram I with a single decision node and a single utility node. 4 | % I.RandomFactors = list of factors for each random variable. These are CPDs, with 5 | % the child variable = D.var(1) 6 | % I.DecisionFactors = factor for the decision node. 7 | % I.UtilityFactors = list of factors representing conditional utilities. 8 | % Return value: the maximum expected utility of I and an optimal decision rule 9 | % (represented again as a factor) that yields that expected utility. 10 | 11 | % We assume I has a single decision node. 12 | % You may assume that there is a unique optimal decision. 13 | D = I.DecisionFactors(1); 14 | 15 | 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | % 18 | % YOUR CODE HERE... 19 | % 20 | % Some other information that might be useful for some implementations 21 | % (note that there are multiple ways to implement this): 22 | % 1. It is probably easiest to think of two cases - D has parents and D 23 | % has no parents. 24 | % 2. You may find the Matlab/Octave function setdiff useful. 25 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 26 | EUF = CalculateExpectedUtilityFactor(I); 27 | OptimalDecisionRule = struct('var', [], 'card', [], 'val', []); 28 | OptimalDecisionRule.var = EUF.var; 29 | OptimalDecisionRule.card = EUF.card; 30 | OptimalDecisionRule.val = zeros(prod(OptimalDecisionRule.card), 1); 31 | if length(EUF.var) < 2, 32 | [MEU myIndex] = max(EUF.val); 33 | OptimalDecisionRule.val(myIndex) = 1; 34 | else 35 | MEU = 0.0; 36 | fullAssignment = IndexToAssignment([1:prod(OptimalDecisionRule.card)],OptimalDecisionRule.card); 37 | for i = 1:prod(OptimalDecisionRule.card(2:end)) 38 | subAssignment = IndexToAssignment(i,OptimalDecisionRule.card(2:end)); 39 | myIndex = []; 40 | for j = 1:size(fullAssignment,1) 41 | if all(fullAssignment(j,2:size(fullAssignment,2))==subAssignment) 42 | myIndex = [myIndex;j]; 43 | end 44 | end 45 | Assignment = IndexToAssignment(myIndex,OptimalDecisionRule.card); 46 | myValue = GetValueOfAssignment(EUF,Assignment); 47 | [myMax mySubIndex] = max(myValue); 48 | OptimalDecisionRule.val(myIndex) = 0; 49 | OptimalDecisionRule.val(myIndex(mySubIndex)) = 1; 50 | MEU = MEU + EUF.val(myIndex(mySubIndex)); 51 | end 52 | end 53 | 54 | 55 | end 56 | -------------------------------------------------------------------------------- /PA7/GenerateAllFeatures.m: -------------------------------------------------------------------------------- 1 | % This function is called by InstanceNegLogLikelihood. 2 | % Its input/output is specified there. 3 | % If you're interested in the implementation details of CRFs, 4 | % feel free to read through this code! 5 | % For the purposes of this assignment, though, you don't 6 | % have to understand how this code works. 7 | 8 | function featureSet = GenerateAllFeatures(X, y, modelParams) 9 | 10 | unconditionedFFs = {@ComputeUnconditionedSingleFeatures, @ComputeUnconditionedPairFeatures}; 11 | conditionedFFs = {@ComputeConditionedSingletonFeatures}; 12 | 13 | numUnconditionedFFs = length(unconditionedFFs); 14 | numConditionedFFs = length(conditionedFFs); 15 | 16 | for i = 1:numUnconditionedFFs 17 | if (~isa(unconditionedFFs{i}, 'function_handle')) 18 | error('Non-function variable in unconditionedFFs argument to GenerateAllFeatures'); 19 | end 20 | end 21 | for i = 1:numConditionedFFs 22 | if (~isa(conditionedFFs{i}, 'function_handle')) 23 | error('Non-function variable in conditionedFFs argument to GenerateAllFeatures'); 24 | end 25 | 26 | end 27 | 28 | conditionedCell = cell(1, numConditionedFFs); 29 | for i = 1:numConditionedFFs 30 | fn = conditionedFFs{i}; 31 | conditionedCell{i} = fn(y, X, modelParams); 32 | end 33 | 34 | unconditionedCell = cell(1, numUnconditionedFFs); 35 | for i = 1:numUnconditionedFFs 36 | fn = unconditionedFFs{i}; 37 | unconditionedCell{i} = fn(y, modelParams); 38 | end 39 | 40 | if (numConditionedFFs > 0) 41 | prevMaxParam = NumParamsForConditionedFeatures(conditionedCell{1}, modelParams.numObservedStates); 42 | else 43 | prevMaxParam = 0; 44 | end 45 | 46 | for i = 2:1:numConditionedFFs 47 | conditionedCell{i} = IncrementFeatureParams(conditionedCell{i}, prevMaxParam); 48 | prevMaxParam = NumParamsForConditionedFeatures(conditionedCell{i}); 49 | end 50 | 51 | for i = 1:1:numUnconditionedFFs 52 | unconditionedCell{i} = IncrementFeatureParams(unconditionedCell{i}, prevMaxParam); 53 | prevMaxParam = NumParamsForUnconditionedFeatures(unconditionedCell{i}); 54 | end 55 | finalMaxParam = prevMaxParam; 56 | 57 | 58 | allFeatures = horzcat(conditionedCell{:}, unconditionedCell{:}); 59 | 60 | featureSet.numParams = finalMaxParam; 61 | featureSet.features = allFeatures; 62 | 63 | end 64 | 65 | % Helper function to increment the 'param' val of each entry in a feature 66 | % array. 67 | function features = IncrementFeatureParams(features, incr) 68 | 69 | for i = 1:length(features) 70 | features(i).paramIdx = features(i).paramIdx + incr; 71 | end 72 | 73 | end 74 | -------------------------------------------------------------------------------- /PA9/CreateCliqueTreeHMM.m: -------------------------------------------------------------------------------- 1 | % CreateCliqueTreeHMM Takes in a list of factors F and returns a clique 2 | % tree. Should only be called when F meets the following conditions: 3 | % 4 | % 1) Factors are over 1 or 2 variables 5 | % 2) All 2-variable factors are over variables (i,i+1) 6 | % 3) All variables have the same cardinality 7 | % 8 | % Roughly, these conditions mean that the factors of F define a standard 9 | % chain model such as an HMM. 10 | % 11 | % Function returns a clique tree that has the following fields: 12 | % - .edges: Contains indices of the nodes that have edges between them. 13 | % - .factorList: Contains the list of factors used to build the Clique 14 | % tree. 15 | 16 | % CS228 Probabilistic Graphical Models(Winter 2012) 17 | % Copyright (C) 2012, Stanford University 18 | 19 | function P = CreateCliqueTreeHMM (F) 20 | 21 | maxVar = max([F.var]); 22 | numNodes = maxVar - 1; 23 | card = F(1).card(1); 24 | 25 | P.cliqueList = repmat(struct('var', [], 'card', [], 'val', []), numNodes, 1); 26 | P.edges = zeros(numNodes); 27 | 28 | for i = 1:numNodes 29 | P.cliqueList(i).var = [i i+1]; 30 | P.cliqueList(i).card = [card card]; 31 | P.cliqueList(i).val = ones(1, card * card); 32 | 33 | if (i > 1) 34 | P.edges(i, i-1) = 1; 35 | P.edges(i-1, i) = 1; 36 | end 37 | if (i < numNodes) 38 | P.edges(i, i+1) = 1; 39 | P.edges(i+1, i) = 1; 40 | end 41 | end 42 | 43 | for i = 1:length(F) 44 | f = F(i); 45 | if (length(f.var) == 1) 46 | if (f.var > 1) 47 | cliqueIdx = f.var - 1; 48 | else 49 | cliqueIdx = 1; 50 | end 51 | 52 | for assignment = 1:card 53 | if (f.var == cliqueIdx) 54 | updateIdxs = AssignmentToIndex([(1:card)' assignment*ones(card,1)], [card card]); 55 | else 56 | updateIdxs = AssignmentToIndex([assignment*ones(card,1) (1:card)'], [card card]); 57 | end 58 | P.cliqueList(cliqueIdx).val(updateIdxs) = P.cliqueList(cliqueIdx).val(updateIdxs) + f.val; 59 | end 60 | else 61 | assert(length(f.var) == 2); 62 | cliqueIdx = min(f.var); 63 | if (f.var(1) > f.var(2)) 64 | % sort the factor val so it's in increasing var order 65 | [dummy, order] = sort(f.var); %#ok 66 | oldAssignments = IndexToAssignment(1:length(f.val), f.card); 67 | newAssignments = oldAssignments(:, order); 68 | f.card = f.card(order); 69 | f.var = f.var(order); 70 | f.val = f.val(AssignmentToIndex(newAssignments, f.card)); 71 | end 72 | P.cliqueList(cliqueIdx).val = P.cliqueList(cliqueIdx).val + f.val; 73 | end 74 | end 75 | 76 | end 77 | 78 | -------------------------------------------------------------------------------- /PA5/gaimc/scomponents.m: -------------------------------------------------------------------------------- 1 | function [sci sizes] = scomponents(A) 2 | % SCOMPONENTS Compute the strongly connected components of a graph 3 | % 4 | % ci=scomponents(A) returns an index for the component number of every 5 | % vertex in the graph A. The total number of components is max(ci). 6 | % If the input is undirected, then this algorithm outputs just the 7 | % connected components. Otherwise, it output the strongly connected 8 | % components. 9 | % 10 | % The implementation is from Tarjan's 1972 paper: Depth-first search and 11 | % linear graph algorithms. In SIAM's Journal of Computing, 1972, 1, 12 | % pp.146-160. 13 | % 14 | % See also DMPERM 15 | % 16 | % Example: 17 | % load_gaimc_graph('cores_example'); % the graph A has three components 18 | % ci = scomponents(A) 19 | % ncomp = max(ci) % should be 3 20 | % R = sparse(1:size(A,1),ci,1,size(A,1),ncomp); % create a restriction matrix 21 | % CG = R'*A*R; % create the graph with each component 22 | % % collapsed into a single node. 23 | 24 | % David F. Gleich 25 | % Copyright, Stanford University, 2008-2009 26 | 27 | % History 28 | % 2008-04-11: Initial coding 29 | 30 | if isstruct(A), rp=A.rp; ci=A.ci; %ofs=A.offset; 31 | else [rp ci]=sparse_to_csr(A); 32 | end 33 | 34 | n=length(rp)-1; sci=zeros(n,1); cn=1; 35 | root=zeros(n,1); dt=zeros(n,1); t=0; 36 | cs=zeros(n,1); css=0; % component stack 37 | rs=zeros(2*n,1); rss=0; % recursion stack holds two nums (v,ri) 38 | % start dfs at 1 39 | for sv=1:n 40 | v=sv; if root(v)>0, continue; end 41 | rss=rss+1; rs(2*rss-1)=v; rs(2*rss)=rp(v); % add v to the stack 42 | root(v)=v; sci(v)=-1; dt(v)=t; t=t+1; 43 | css=css+1; cs(css)=v; % add w to component stack 44 | while rss>0 45 | v=rs(2*rss-1); ri=rs(2*rss); rss=rss-1; % pop v from the stack 46 | while ridt(root(w)), root(v)=root(w); end 59 | end 60 | end 61 | if root(v)==v 62 | while css>0 63 | w=cs(css); css=css-1; sci(w)=cn; 64 | if w==v, break; end 65 | end 66 | cn=cn+1; 67 | end 68 | end 69 | end 70 | 71 | if nargout>1 72 | sizes=accumarray(sci,1,[max(sci) 1]); 73 | end 74 | -------------------------------------------------------------------------------- /PA8/ClassifyDataset.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: ClassifyDataset.m 3 | % Copyright (C) 2012, Stanford University 4 | 5 | function accuracy = ClassifyDataset(dataset, labels, P, G) 6 | % returns the accuracy of the model P and graph G on the dataset 7 | % 8 | % Inputs: 9 | % dataset: N x 10 x 3, N test instances represented by 10 parts 10 | % labels: N x 2 true class labels for the instances. 11 | % labels(i,j)=1 if the ith instance belongs to class j 12 | % P: struct array model parameters (explained in PA description) 13 | % G: graph structure and parameterization (explained in PA description) 14 | % 15 | % Outputs: 16 | % accuracy: percentage of correctly classified instances (scalar) 17 | 18 | N = size(dataset, 1); 19 | K = size(labels, 2); 20 | accuracy = 0; 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % YOUR CODE HERE 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | 26 | predictions = []; 27 | 28 | for i=1:N 29 | 30 | ll = []; 31 | 32 | for k=1:K 33 | 34 | lpk = log(P.c(k)); 35 | lpoi = 0; 36 | 37 | for part = 1:10 38 | 39 | parentpart = 0; 40 | if (length(size(G)) == 2 && G(part,1) == 1) 41 | parentpart = G(part, 2); 42 | elseif ( length(size(G)) == 3 && G(part,1, k) == 1) 43 | parentpart = G(part, 2, k); 44 | end 45 | 46 | if ( parentpart == 0 ) 47 | lpoi = lpoi + lognormpdf( dataset(i, part, 1), P.clg(part).mu_y(k), P.clg(part).sigma_y(k) ); 48 | lpoi = lpoi + lognormpdf( dataset(i, part, 2), P.clg(part).mu_x(k), P.clg(part).sigma_x(k) ); 49 | lpoi = lpoi + lognormpdf( dataset(i, part, 3), P.clg(part).mu_angle(k), P.clg(part).sigma_angle(k) ); 50 | else 51 | mu_y = P.clg(part).theta(k, 1) + P.clg(part).theta(k, 2) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 3) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 4) * dataset(i, parentpart, 3); 52 | mu_x = P.clg(part).theta(k, 5) + P.clg(part).theta(k, 6) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 7) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 8) * dataset(i, parentpart, 3); 53 | mu_angle = P.clg(part).theta(k, 9) + P.clg(part).theta(k, 10) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 11) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 12) * dataset(i, parentpart, 3); 54 | lpoi = lpoi + lognormpdf( dataset(i, part, 1), mu_y, P.clg(part).sigma_y(k) ); 55 | lpoi = lpoi + lognormpdf( dataset(i, part, 2), mu_x, P.clg(part).sigma_x(k) ); 56 | lpoi = lpoi + lognormpdf( dataset(i, part, 3), mu_angle, P.clg(part).sigma_angle(k) ); 57 | end 58 | end 59 | 60 | ll(k) = lpk + lpoi; 61 | end 62 | 63 | [maxv predictions(i)] = max(ll); 64 | end 65 | 66 | correct = 0; 67 | for i = 1:N 68 | if labels(i, predictions(i)) 69 | correct = correct + 1; 70 | end 71 | end 72 | 73 | accuracy = correct / N; 74 | 75 | fprintf('Accuracy: %.2f\n', accuracy); 76 | -------------------------------------------------------------------------------- /PA5/ComputeApproxMarginalsBP.m: -------------------------------------------------------------------------------- 1 | % COMPUTEAPPROXMARGINALSBP Computation of approximate marginals using Loopy BP 2 | % M = COMPUTEAPPROXMARGINALSBP(F,E ) returns the approximate marginals over 3 | % each variable in F given the evidence E. 4 | % . 5 | % The Factor list F has the following fields: 6 | % - .var: indices of variables in the specified cluster 7 | % - .card: cardinality of variables in the specified cluster 8 | % - .val: the cluster's beliefs about these variables 9 | % - .edges: Contains indices of the clusters that have edges between them. 10 | % 11 | % The Evidence E is a vector of length equal to the number of variables in the 12 | % factors where 0 stands for unobserved and other values are an observed 13 | % assignment to that variable. It can be left empty (E=[]) if there is no evidence 14 | % 15 | % M should be an array of factors with one factor for each variable and 16 | % M(i).val should be filled in with the marginal of variable i. 17 | % 18 | 19 | 20 | % CS228 Probabilistic Models in AI (Winter 2012) 21 | % Copyright (C) 2012, Stanford University 22 | 23 | function M = ComputeApproxMarginalsBP(F,E) 24 | 25 | % returning approximate marginals. 26 | 27 | clusterGraph = CreateClusterGraph(F,E); 28 | 29 | P = ClusterGraphCalibrate(clusterGraph, 1); 30 | 31 | vars = unique([P.clusterList(:).var]); 32 | 33 | % compute marginals on each variable 34 | M = repmat(struct('var', 0, 'card', 0, 'val', []), length(vars), 1); 35 | 36 | % Populate M so that M(i) contains the marginal probability over 37 | % variable i 38 | for i = 1:length(vars), 39 | 40 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41 | % YOUR CODE HERE 42 | % 43 | % Populate M(i) such that M(i) contains a factor representation of 44 | % the marginal proability over the variable with index i. 45 | % (ie. M(i).val is the actual marginal) 46 | % 47 | % You may want to use the helper function 'FindPotentialWithVariable' 48 | % which is defined at the bottom of this file. Read through it 49 | % to make sure you understand its functionality. 50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | 52 | indx = FindPotentialWithVariable(P, vars(i)); 53 | M(i) = FactorMarginalization(P.clusterList(indx), setdiff(P.clusterList(indx).var, [ vars(i) ]) ); 54 | M(i).val = M(i).val ./ sum(M(i).val); 55 | 56 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 57 | end 58 | 59 | 60 | 61 | return; 62 | 63 | % Helper function: 64 | function indx = FindPotentialWithVariable(P, V) 65 | 66 | indx = 0; 67 | for i = 1:length(P.clusterList), 68 | if (any(P.clusterList(i).var == V)), 69 | indx = i; 70 | return; 71 | end; 72 | end; 73 | 74 | return; 75 | -------------------------------------------------------------------------------- /PA8/ComputeLogLikelihood.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: ComputeLogLikelihood.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function loglikelihood = ComputeLogLikelihood(P, G, dataset) 7 | % returns the (natural) log-likelihood of data given the model and graph structure 8 | % 9 | % Inputs: 10 | % P: struct array parameters (explained in PA description) 11 | % G: graph structure and parameterization (explained in PA description) 12 | % 13 | % NOTICE that G could be either 10x2 (same graph shared by all classes) 14 | % or 10x2x2 (each class has its own graph). your code should compute 15 | % the log-likelihood using the right graph. 16 | % 17 | % dataset: N x 10 x 3, N poses represented by 10 parts in (y, x, alpha) 18 | % 19 | % Output: 20 | % loglikelihood: log-likelihood of the data (scalar) 21 | 22 | 23 | N = size(dataset,1); % number of examples 24 | K = length(P.c); % number of classes 25 | 26 | loglikelihood = 0; 27 | 28 | % You should compute the log likelihood of data as in eq. (12) and (13) 29 | % in the PA description 30 | % Hint: Use lognormpdf instead of log(normpdf) to prevent underflow. 31 | % You may use log(sum(exp(logProb))) to do addition in the original 32 | % space, sum(Prob). 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | % YOUR CODE HERE 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | 37 | for i=1:N 38 | 39 | ll = -Inf; 40 | for k=1:K 41 | lpk = log(P.c(k)); 42 | lpoi = 0; 43 | 44 | for part = 1:10 45 | 46 | parentpart = 0; 47 | if (length(size(G)) == 2 && G(part,1) == 1) 48 | parentpart = G(part, 2); 49 | elseif ( length(size(G)) == 3 && G(part,1, k) == 1) 50 | parentpart = G(part, 2, k); 51 | end 52 | 53 | if ( parentpart == 0 ) 54 | lpoi = lpoi + lognormpdf( dataset(i, part, 1), P.clg(part).mu_y(k), P.clg(part).sigma_y(k) ); 55 | lpoi = lpoi + lognormpdf( dataset(i, part, 2), P.clg(part).mu_x(k), P.clg(part).sigma_x(k) ); 56 | lpoi = lpoi + lognormpdf( dataset(i, part, 3), P.clg(part).mu_angle(k), P.clg(part).sigma_angle(k) ); 57 | else 58 | mu_y = P.clg(part).theta(k, 1) + P.clg(part).theta(k, 2) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 3) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 4) * dataset(i, parentpart, 3); 59 | mu_x = P.clg(part).theta(k, 5) + P.clg(part).theta(k, 6) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 7) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 8) * dataset(i, parentpart, 3); 60 | mu_angle = P.clg(part).theta(k, 9) + P.clg(part).theta(k, 10) * dataset(i, parentpart, 1) + P.clg(part).theta(k, 11) * dataset(i, parentpart, 2) + P.clg(part).theta(k, 12) * dataset(i, parentpart, 3); 61 | lpoi = lpoi + lognormpdf( dataset(i, part, 1), mu_y, P.clg(part).sigma_y(k) ); 62 | lpoi = lpoi + lognormpdf( dataset(i, part, 2), mu_x, P.clg(part).sigma_x(k) ); 63 | lpoi = lpoi + lognormpdf( dataset(i, part, 3), mu_angle, P.clg(part).sigma_angle(k) ); 64 | end 65 | end 66 | 67 | ll = log( exp(ll) + exp(lpk + lpoi) ); 68 | end 69 | 70 | loglikelihood = loglikelihood + ll; 71 | end 72 | -------------------------------------------------------------------------------- /PA8/LearnCPDsGivenGraph.m: -------------------------------------------------------------------------------- 1 | % CS228 Winter 2011-2012 2 | % File: LearnCPDsGivenGraph.m 3 | % Copyright (C) 2012, Stanford University 4 | % Huayan Wang 5 | 6 | function [P loglikelihood] = LearnCPDsGivenGraph(dataset, G, labels) 7 | % 8 | % Inputs: 9 | % dataset: N x 10 x 3, N poses represented by 10 parts in (y, x, alpha) 10 | % G: graph parameterization as explained in PA description 11 | % labels: N x 2 true class labels for the examples. labels(i,j)=1 if the 12 | % the ith example belongs to class j and 0 elsewhere 13 | % 14 | % Outputs: 15 | % P: struct array parameters (explained in PA description) 16 | % loglikelihood: log-likelihood of the data (scalar) 17 | 18 | N = size(dataset, 1); 19 | K = size(labels, 2); 20 | numparts = 10; 21 | 22 | loglikelihood = 0; 23 | P.c = zeros(1,K); 24 | 25 | % estimate parameters 26 | % fill in P.c, MLE for class probabilities 27 | % fill in P.clg for each body part and each class 28 | % choose the right parameterization based on G(i,1) 29 | % compute the likelihood - you may want to use ComputeLogLikelihood.m 30 | % you just implemented. 31 | %%%%%%%%%%%%%%%%%%%%%%%%% 32 | % YOUR CODE HERE 33 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 | 35 | nums = sum(labels, 1); 36 | 37 | P.c = nums ./ sum(nums); 38 | 39 | P.clg = repmat( struct('mu_y', [], 'sigma_y', [], 'mu_x', [], 'sigma_x', [], 'mu_angle', [], 'sigma_angle', [], 'theta', [] ), 1, numparts); 40 | 41 | for part = 1:numparts 42 | 43 | for k=1:K 44 | 45 | parentpart = 0; 46 | if (length(size(G)) == 2 && G(part, 1) == 1) 47 | parentpart = G(part, 2); 48 | elseif ( length(size(G)) == 3 && G(part, 1, k) == 1) 49 | parentpart = G(part, 2, k); 50 | end 51 | 52 | if parentpart == 0 53 | 54 | [mu, sigma] = FitGaussianParameters(dataset(labels(:,k) == 1, part, 1)); 55 | P.clg(part).mu_y(k) = mu; 56 | P.clg(part).sigma_y(k) = sigma; 57 | 58 | [mu, sigma] = FitGaussianParameters(dataset(labels(:,k) == 1, part, 2)); 59 | P.clg(part).mu_x(k) = mu; 60 | P.clg(part).sigma_x(k) = sigma; 61 | 62 | [mu, sigma] = FitGaussianParameters(dataset(labels(:,k) == 1, part, 3)); 63 | P.clg(part).mu_angle(k) = mu; 64 | P.clg(part).sigma_angle(k) = sigma; 65 | 66 | else 67 | 68 | U = []; 69 | U(:, 1) = dataset(labels(:,k) == 1, parentpart, 1); 70 | U(:, 2) = dataset(labels(:,k) == 1, parentpart, 2); 71 | U(:, 3) = dataset(labels(:,k) == 1, parentpart, 3); 72 | 73 | [Beta, sigma] = FitLinearGaussianParameters(dataset(labels(:,k) == 1, part, 1), U); 74 | P.clg(part).theta(k, 1) = Beta(4); 75 | P.clg(part).theta(k, 2:4) = Beta(1:3); 76 | P.clg(part).sigma_y(k) = sigma; 77 | 78 | [Beta, sigma] = FitLinearGaussianParameters(dataset(labels(:,k) == 1, part, 2), U); 79 | P.clg(part).theta(k, 5) = Beta(4); 80 | P.clg(part).theta(k, 6:8) = Beta(1:3); 81 | P.clg(part).sigma_x(k) = sigma; 82 | 83 | [Beta, sigma] = FitLinearGaussianParameters(dataset(labels(:,k) == 1, part, 3), U); 84 | P.clg(part).theta(k, 9) = Beta(4); 85 | P.clg(part).theta(k, 10:12) = Beta(1:3); 86 | P.clg(part).sigma_angle(k) = sigma; 87 | 88 | end 89 | 90 | end 91 | 92 | end 93 | 94 | loglikelihood = ComputeLogLikelihood(P, G, dataset); 95 | 96 | fprintf('log likelihood: %f\n', loglikelihood); 97 | --------------------------------------------------------------------------------