MatrixBerryCore
absrelcompare.m
Go to the documentation of this file.
1 function [isEqual, absDiff, isRelDiffTriggered, relDiff, absMRelDiff, reportStr] = absrelcompare(leftArr, rightArr, absTol, relTol, fNormOp)
2 
3 import mxberry.core.checkvar;
4 import mxberry.core.checkmultvar;
5 import mxberry.core.throwerror;
6 %
7 FORMAT_SPEC='%.17g';
8 %
9 if ~(isequal(size(leftArr),size(rightArr))&&...
10  isnumeric(leftArr)&&isnumeric(rightArr))
11  throwerror('wrongInput:wrongArgs',['leftArr and rightArr must be ',...
12  'numeric arrays with the same size']);
13 end
14 if ~(isnumeric(absTol)&&isscalar(absTol)&&(absTol>=0))
15  throwerror('wrongInput:wrongAbsTol',['absTol', ...
16  ' must be a nonnegative scalar']);
17 end
18 if ~(isempty(relTol)||(isscalar(relTol)&&(relTol>=0)))&&isnumeric(relTol)
19  throwerror('wrongInput:wrongRelTol',['relTol', ...
20  ' must be a nonnegative scalar']);
21 end
22 if ~mxberry.core.check.lib.isfunction(fNormOp)
23  throwerror('wrongInput:wrongNormOp',['fNormOp must be ', ...
24  'a function handle']);
25 end
26 %
27 diffArr = fNormOp(leftArr - rightArr);
28 absDiff = max(diffArr(:));
29 if isempty(absDiff)
30  absDiff = [];
31 end
32 absRDiff = absDiff;
33 %
34 relDiff = [];
35 absMRelDiff = [];
36 %
37 isRelDiffTriggeredArr = (diffArr > absTol) & ~isempty(relTol);
38 isRelDiffTriggered = any(isRelDiffTriggeredArr(:));
39 if isRelDiffTriggered
40  argSumNormArr = fNormOp(leftArr) + fNormOp(rightArr);
41  isRelDiffTriggeredArr = isRelDiffTriggeredArr & ...
42  (argSumNormArr > absTol);
43  isRelDiffTriggered = any(isRelDiffTriggeredArr(:));
44  if isRelDiffTriggered
45  tempArr = zeros(size(diffArr));
46  temp2Arr = tempArr;
47  tempArr(isRelDiffTriggeredArr) = ...
48  2 .* diffArr(isRelDiffTriggeredArr) ./ ...
49  argSumNormArr(isRelDiffTriggeredArr);
50  relDiff = max(tempArr(:));
51  temp2Arr(tempArr == relDiff) = diffArr(tempArr == relDiff);
52  absMRelDiff = max(temp2Arr(:));
53  tempArr = zeros(size(diffArr));
54  tempArr(~isRelDiffTriggeredArr) = diffArr(~isRelDiffTriggeredArr);
55  absRDiff = max(tempArr(:));
56  end
57 end
58 isEqual = all([absRDiff <= absTol, relDiff <= relTol]);
59 %
60 if nargout > 5
61  if isEqual
62  reportStr = '';
63  else
64  if isRelDiffTriggered
65  reportStr = sprintf(strrep(['relative difference (FORMAT_SPEC) is greater', ...
66  ' than the specified tolerance (FORMAT_SPEC); absolute', ...
67  ' difference (FORMAT_SPEC), absolute tolerance (FORMAT_SPEC)'],...
68  'FORMAT_SPEC',FORMAT_SPEC), relDiff, ...
69  relTol, absMRelDiff, absTol);
70  else
71  reportStr = sprintf(strrep(['absolute difference (FORMAT_SPEC) is greater', ...
72  ' than the specified tolerance (FORMAT_SPEC)'],...
73  'FORMAT_SPEC',FORMAT_SPEC),...
74  absDiff, absTol);
75  end
76  end
77 end
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
function absrelcompare(in leftArr, in rightArr, in absTol, in relTol, in fNormOp)
ABSRELCOMPARE - compares two numerical arrays by user defined norm. For each two corresponding fNormO...