Mercurial > hg > ltpda
view m-toolbox/classes/@plist/eq.m @ 38:3aef676a1b20 database-connection-manager
Keep backtrace on error
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Mon, 05 Dec 2011 16:20:06 +0100 |
parents | f0afece42f48 |
children |
line wrap: on
line source
% EQ overloads the == operator for ltpda plist objects. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % DESCRIPTION: EQ overloads the == operator for ltpda plist objects. % % Two plists are considered equal if each has the same name, % created time, version, creator and parameter objects. The % order of the param-objects doesn't matter. % % CALL: result = eq(u1,u2) % % With a PLIST % % r = eq(obj1, obj2, plist('Exceptions', {'prop1', 'prop2'})) % r = eq(obj1, obj2, plist('Tol', eps(1))) % r = eq(obj1, obj2, plist('Exceptions', 'prop', 'Tol', 1e-14)) % % INPUTS: pl1, pl2 - Input objects % % OUTPUTS: If the two objects are considered equal, result == true, % otherwise, result == false. % % <a href="matlab:utils.helper.displayMethodInfo('plist', 'eq')">Parameters Description</a> % % VERSION: $Id: eq.m,v 1.27 2011/04/08 08:56:21 hewitson Exp $ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function result = eq(obj1, obj2, varargin) % Check if this is a call for parameters hh = [{obj1}, {obj2}, varargin]; if utils.helper.isinfocall(hh{:}) result = getInfo(varargin{1}); return end import utils.const.* %%%%% Check class if ~strcmp(class(obj1), class(obj2)) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The objects are not from the same class. [%s] <-> [%s]', class(obj1), class(obj2)); result = false; return end %%%%% Check length of obj1 and obj2 if numel(obj1) ~= numel(obj2) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The size of the %s-object''s. [%d] <-> [%d]', class(obj1), numel(obj1), numel(obj2)); result = false; return end plin = []; exception_list = varargin; if ~isempty(varargin) && isa(varargin{1}, 'plist') plin = varargin{1}; end %%%%% Get the tolerance from a potential existing plist if ~isempty(plin) && plin.isparam('tol') tol = plin.find('tol'); else dpl = getDefaultPlist(); tol = dpl.find('tol'); end %%%%% Convert a potential existing plist into a exception if ~isempty(plin) && plin.isparam('exceptions') exception_list = find(plin, 'Exceptions'); if isempty(exception_list) exception_list = cell(0); elseif ~iscell(exception_list) exception_list = cellstr(exception_list); end end result = true; %%%%% for each element in obj1 and obj2 for jj = 1:numel(obj1) if isa(obj1, 'ltpda_uoh') utils.helper.msg(msg.PROC1, 'testing %s against %s', obj1.name, obj2.name); end fields = fieldnames(obj1(jj)); for ii = 1:length(fields) field = fields{ii}; %%%%% Creates the exception list for the current field. %%%%% For example: {'name', 'ao/name'} ck_field = {field, sprintf('%s/%s', class(obj1), field)}; % Special case (for the ao- and history-class): % Is the field = 'hist', 'inhists' then add 'history' to the exception list. %%%%% For example: {'history', 'ao/history'} if utils.helper.ismember(field, {'hist', 'inhists'}) ck_field{end+1} = 'history'; ck_field{end+1} = sprintf('%s/history', class(obj1)); elseif strcmp(field, 'val') ck_field{end+1} = 'value'; ck_field{end+1} = sprintf('%s/value', class(obj1)); end %%%%% Check field if it is not in the exception list if ~(any(utils.helper.ismember(ck_field, exception_list))) if isa(obj1(jj).(field), 'sym') %%%%%%%%%% The property is a sym-object %%%%%%%%%% if ~eq(obj1(jj).(field), obj2(jj).(field)) result = false; disaply_msg(obj1, jj, field) return end elseif isa(obj1(jj).(field), 'ltpda_obj') %%%%%%%%%% The property is a ltpda-object %%%%%%%%%% %%%%% Check the length of the property if length(obj1(jj).(field)) ~= length(obj2(jj).(field)) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The property [%s] of the object [%s] have not the same size %d <-> %d.', field, class(obj1), length(obj1(jj).(field)), length(obj2(jj).(field))); result = false; return end %%%%% Special case for param-objects because the order shouldn't matter if isa(obj1(jj).(field), 'param') if ~eqparam(obj1(jj).(field), obj2(jj).(field), exception_list, tol) result = false; disaply_msg(obj1, jj, field) return end else %%%%% For each element of the property for kk = 1:numel(obj1(jj).(field)) if isempty(plin) % Command with a list of exceptions res = eq(obj1(jj).(field)(kk), obj2(jj).(field)(kk), exception_list{:}); else % Command with a PLIST res = eq(obj1(jj).(field)(kk), obj2(jj).(field)(kk), plin); end if ~res result = false; disaply_msg(obj1, jj, field) return end end end elseif isstruct(obj1(jj).(field)) %%%%%%%%%% The property is a structure %%%%%%%%%% if ~eqstruct(obj1(jj).(field), obj2(jj).(field), exception_list, tol) result = false; disaply_msg(obj1, jj, field) return end elseif iscell(obj1(jj).(field)) %%%%%%%%%% The property is a cell array %%%%%%%%%% if ~eqcell(obj1(jj).(field), obj2(jj).(field), exception_list, tol) result = false; disaply_msg(obj1, jj, field) return end elseif isnumeric(obj1(jj).(field)) %%%%%%%%%% The property is an elemental MATLAB datatype %%%%%%%%%% if ~utils.math.isequal(obj1(jj).(field), obj2(jj).(field), tol) result = false; disaply_msg(obj1, jj, field) return end else %%%%%%%%%% The property is an elemental MATLAB datatype %%%%%%%%%% if ~isequal(obj1(jj).(field), obj2(jj).(field)) result = false; disaply_msg(obj1, jj, field) return end end end end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Local Functions % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: disaply_msg % % DESCRIPTION: Diesplay a message if the objects are not equal % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function disaply_msg(obj, obj_no, field) import utils.const.* if numel(obj) > 1 utils.helper.msg(msg.PROC1, 'NOT EQUAL: %s.%s (%d. object)', class(obj(obj_no)), field, obj_no); else utils.helper.msg(msg.PROC1, 'NOT EQUAL: %s.%s', class(obj(obj_no)), field); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: eqstruct % % DESCRIPTION: Equal method to compare structures % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function result = eqstruct(obj1, obj2, exception_list, tol) import utils.const.* %%%%% Check class if ~strcmp(class(obj1), class(obj2)) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The objects are not from the same class. [%s] <-> [%s]', class(obj1), class(obj2)); result = false; return end %%%%% Check length of obj1 and obj2 fieldsA = fieldnames(obj1); fieldsB = fieldnames(obj2); if numel(fieldsA) ~= numel(fieldsB) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The size of the %s-object''s. [%d] <-> [%d]', class(obj1), numel(obj1), numel(obj2)); result = false; return end result = true; for oo = 1:numel(obj1) for ii = 1:numel(fieldsA) if isa(obj1(oo).(fieldsA{ii}), 'ltpda_obj') %%%%%%%%%%%%% LTPDA objects if ~eq(obj1(oo).(fieldsA{ii}), obj2(oo).(fieldsA{ii}), plist('exceptions', exception_list, 'tol', tol)) result = false; disaply_msg(obj1, oo, fieldsA{ii}) return end elseif isstruct(obj1(oo).(fieldsA{ii})) %%%%%%%%%%%%% STRUCTURE if ~eqstruct(obj1(oo).(fieldsA{ii}), obj2(oo).(fieldsA{ii}), exception_list, tol) result = false; disaply_msg(obj1, oo, fieldsA{ii}) return end elseif iscell(obj1(oo).(fieldsA{ii})) %%%%%%%%%%%%% STRUCTURE if ~eqcell(obj1(oo).(fieldsA{ii}), obj2(oo).(fieldsA{ii}), exception_list, tol) result = false; disaply_msg(obj1, oo, fieldsA{ii}) return end elseif isnumeric(obj1(oo).(fieldsA{ii})) if ~utils.math.isequal(obj1(oo).(fieldsA{ii}), obj2(oo).(fieldsA{ii}), tol) result = false; disaply_msg(obj1, oo, fieldsA{ii}) return end else if ~isequal(obj1(oo).(fieldsA{ii}), obj2(oo).(fieldsA{ii})) result = false; disaply_msg(obj1, oo, fieldsA{ii}) return end end end % over all fields end % over all objects end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: eqcell % % DESCRIPTION: Equal method to compare structures % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function result = eqcell(obj1, obj2, exception_list, tol) import utils.const.* %%%%% Check class if ~strcmp(class(obj1), class(obj2)) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The objects are not from the same class. [%s] <-> [%s]', class(obj1), class(obj2)); result = false; return end %%%%% Check length of obj1 and obj2 if numel(obj1) ~= numel(obj2) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The size of the %s-object''s. [%d] <-> [%d]', class(obj1), numel(obj1), numel(obj2)); result = false; return end result = true; for ii = 1:numel(obj1) if isa(obj1{ii}, 'ltpda_obj') %%%%%%%%%%%%% LTPDA objects if ~eq(obj1{ii}, obj2{ii}, plist('exceptions', exception_list, 'tol', tol)) result = false; disaply_msg(obj1, ii, 'cell-object') return end elseif isstruct(obj1{ii}) %%%%%%%%%%%%% STRUCTURE if ~eqstruct(obj1{ii}, obj2{ii}, exception_list, tol) result = false; disaply_msg(obj1, ii, 'cell-object') return end elseif iscell(obj1{ii}) %%%%%%%%%%%%% CELL if ~eqcell(obj1{ii}, obj2{ii}, exception_list, tol) result = false; disaply_msg(obj1, ii, 'cell-object') return end elseif isnumeric(obj1{ii}) %%%%%%%%%%%%% Numberic if ~utils.math.isequal(obj1{ii}, obj2{ii}, tol) result = false; disaply_msg(obj1, ii, 'cell-object') return end else if ~isequal(obj1{ii}, obj2{ii}) result = false; disaply_msg(obj1, ii, 'cell-object') return end end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: eqparam % % DESCRIPTION: Equal method to compare param-objects. The order of the % param-objects doesn't matter. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function result = eqparam(obj1, obj2, exception_list, tol) import utils.const.* %%%%% Check class if ~strcmp(class(obj1), class(obj2)) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The objects are not from the same class. [%s] <-> [%s]', class(obj1), class(obj2)); result = false; return end %%%%% Check length of obj1 and obj2 if numel(obj1) ~= numel(obj2) utils.helper.msg(msg.PROC1, 'NOT EQUAL: The size of the %s-object''s. [%d] <-> [%d]', class(obj1), numel(obj1), numel(obj2)); result = false; return end result = true; for oo = 1:numel(obj1) found = false; for ii = 1:numel(obj2) if strcmp(obj1(oo).key, obj2(ii).key) allparts = true; fields = fieldnames(obj1(oo)); for ff = 1:numel(fields) field = fields{ff}; ck_field = {field, sprintf('%s/%s', class(obj1), field)}; if ~(any(utils.helper.ismember(ck_field, exception_list))) if strcmp(field, 'val') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Compare only the current value val1 = obj1(oo).getVal(); val2 = obj2(ii).getVal(); if isa(val1, 'ltpda_obj') %%%%%%%%%%%%% LTPDA objects allparts = allparts && eq(val1, val2, plist('exceptions', exception_list, 'tol', tol)); elseif isstruct(val1) %%%%%%%%%%%%% STRUCTURE allparts = allparts && eqstruct(val1, val2, exception_list, tol); elseif iscell(val1) %%%%%%%%%%%%% CELL allparts = allparts && eqcell(val1, val2, exception_list, tol); elseif isnumeric(val1) %%%%%%%%%%%%% Numeric allparts = allparts && utils.math.isequal(val1, val2, tol); else allparts = allparts && isequal(val1, val2); end %%%%% Check the properties of the paramValue Object if isa(obj1(oo).val, 'paramValue') allparts = allparts && eqstruct(obj1(oo).val.property, obj2(ii).val.property, exception_list, tol); end continue; end if isa(obj1(oo).(field), 'ltpda_obj') %%%%%%%%%%%%% LTPDA objects allparts = allparts && eq(obj1(oo).(field), obj2(ii).(field), plist('exceptions', exception_list, 'tol', tol)); elseif isstruct(obj1(oo).(field)) %%%%%%%%%%%%% STRUCTURE allparts = allparts && eqstruct(obj1(oo).(field), obj2(ii).(field), exception_list, tol); elseif iscell(obj1(oo).(field)) %%%%%%%%%%%%% CELL allparts = allparts && eqcell(obj1(oo).(field), obj2(ii).(field), exception_list, tol); elseif isnumeric(obj1(oo).(field)) %%%%%%%%%%%%% Numeric allparts = allparts && utils.math.isequal(obj1(oo).(field), obj2(ii).(field), tol); else allparts = allparts && isequal(obj1(oo).(field), obj2(ii).(field)); end end end if allparts found = true; end end end % inner-loop if ~found result = false; disaply_msg(obj1, oo, ['key: ''' obj1(oo).key '''']) return end end % outer-loop end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: getInfo % % DESCRIPTION: Get Info Object % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ii = getInfo(varargin) if nargin == 1 && strcmpi(varargin{1}, 'None') sets = {}; pl = []; else sets = {'Default'}; pl = getDefaultPlist; end % Build info object ii = minfo(mfilename, 'plist', 'ltpda', utils.const.categories.relop, '$Id: eq.m,v 1.27 2011/04/08 08:56:21 hewitson Exp $', sets, pl); ii.setModifier(false); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FUNCTION: getDefaultPlist % % DESCRIPTION: Get Default Plist % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function plo = getDefaultPlist() plo = plist(); % Exceptions p = param({'Exceptions', 'Test the objects without the given property names'}, paramValue.EMPTY_CELL); plo.append(p); % Tolerance p = param({'Tol', 'Test double values with the given tolerance'}, paramValue.DOUBLE_VALUE(eps(1))); plo.append(p); end