Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Commit

Permalink
Add completed version
Browse files Browse the repository at this point in the history
  • Loading branch information
cartermak committed Sep 18, 2020
1 parent 8b85543 commit ee71546
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.asv
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# MATLAB-General-Method
# MATLAB Error Analysis: General Method

Implementation of the "general method" of error analysis based on partial derivatives. The function reads in an anonymous function handle and input values with uncertainties and returns output values with uncertainties.

---

*Source:*
*An Introduction to Error Analysis: the Study of the Uncertainties in Physical Measurements*, by John Robert. Taylor, 2nd ed., University Science Books, 1997, pp. 73–76.
110 changes: 110 additions & 0 deletions generalMethod.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
function [val,err] = generalMethod(f,inVals,inErrs)
% function [val,err] = generalMethod(f,inVals,inErrs)
% -------------------------------------------------------------------------
% Carter Mak
% -------------------------------------------------------------------------
% Description:
% Pass an anonymous function handle and cell arrays of input values with
% errors. Returns output value with error estimated using the general
% method based on partial derivatives.
% -------------------------------------------------------------------------
% Inputs:
% f: function handle
% inVals: cell array of input values to f, in order
% inErrs: Cell array of uncertainties associated with each input value,
% in order. If no uncertainty, use 0.
%
% Outputs:
% val: Vector of output values
% err: Vector of uncertainties in output values
% -------------------------------------------------------------------------

%% Initialization
% Convert f to a symbolic function
g = sym(f);

% Get list of input variables
symVars = symvar(g);

% Number of input variables
nVars = length(symVars);

% Check for correct number of input variables and errors
if (nVars ~= length(inVals) || nVars ~= length(inErrs))
error('Incorrect number of input values and/or errors.')
end

% Number of samples is length of longest input variable list
nSamples = 0;
for i = 1:length(inVals)
if length(inVals{i})>nSamples
nSamples = length(inVals{i});
end
end

% Check that all variables and errors have the same length. Inputs should
% either have length Nsamples or 1 (implies same value for all samples)
for i = 1:length(inVals)

% Check all variables. Extend if necessary.
if length(inVals{i})==1
inVals{i} = repmat(inVals{i},nSamples);
end

% Check all error values. Extend if necessary.
if length(inErrs{i})==1
inErrs{i} = repmat(inErrs{i},nSamples);
end

% If the length of any inputs or error values isn't gucci, throw error
if nSamples~=length(inVals{i}) || nSamples~=length(inErrs{i})
error('Inconsistent number of samples')
end

end

% Preallocate outputs
val = zeros(nSamples,1);
err = val;

%% Calculus

% Preallocate (ish. They're cell arrays. It doesn't really matter.)
derivs = cell(nVars,1);
derivInputs = derivs;

% Calculate all partials
for i = 1:nVars
currVar = symVars(i);
currDiff = diff(g,currVar);
derivs{i} = matlabFunction(currDiff);
[~,derivInputs{i}] = intersect(symVars,symvar(currDiff),'stable');
end

%% Calculations

% Preallocate array of intermediate error terms
intermedErrs = zeros(nVars,1);
sampleVals = zeros(nVars,1);

% Loop over samples
for i = 1:nSamples

% Store input variables to a temporary vector, sampleVals
for j = 1:nVars
sampleVals(j) = inVals{j}(i);
end

% Calculate output value for sample i
tmpCell = num2cell(sampleVals);
val(i) = f(tmpCell{:});

% Loop over input variables for error calculation
for j = 1:nVars
currInputs = sampleVals(derivInputs{j});
tmpCell = num2cell(currInputs);
currFunc = derivs{j};
intermedErrs(j) = currFunc(tmpCell{:})*inErrs{j}(i);
end
err(i) = sqrt(sum(intermedErrs.^2,'omitnan'));
end

0 comments on commit ee71546

Please sign in to comment.