www.gusucode.com > mbctools 工具箱 matlab 源码程序 > mbctools/+xregbdrygui/BdryPairwiseData.m
classdef BdryPairwiseData < mbcgui.widget.ScrollTableData %xregbdrygui.BdryPairwiseData class % xregbdrygui.BdryPairwiseData extends mbcgui.widget.ScrollTableData % % xregbdrygui.BdryPairwiseData properties: % MessageService - Property is of type 'handle' % NPoints - Property is of type 'int' % NBins - Property is of type 'int' % Primes - Property is of type 'MATLAB array' % Points - Property is of type 'MATLAB array' % Values - Property is of type 'MATLAB array' % Bins - Property is of type 'MATLAB array' % MidPoints - Property is of type 'MATLAB array' % MainContours - Property is of type 'MATLAB array' % HighlightContours - Property is of type 'MATLAB array' % HighlightData - Property is of type 'MATLAB array' % % xregbdrygui.BdryPairwiseData methods: % getBlackDotXData - Get the XData required for the black dots % getBlackDotYData - Get the YData required for the black dots % getColumnCount - Return the number of columns in the data model. % getEvaluationPoints - Access for evaluation points % getHighlightContours - A short description of the function. % getHighlightIndices - Get the indices of factors that are highlighted. % getHighlightLineXData - Get the XData required for the highlight line % getHighlightLineYData - Get the YData required for the highlight line. % getMainContours - A short description of the function. % getRedRingXData - Get the XData required for the red rings % getRedRingYData - Get the YData required for the red rings % getRowCount - Return the number of rows in the data model. % getValidationXData - Get the XData required for the green dots % getValidationYData - Get the YData required for the green dots % setHighlight - Set a new highlight rectangle. % Copyright 2005-2015 The MathWorks, Inc. and Ford Global Technologies, Inc. properties (AbortSet) %MESSAGESERVICE Property is of type 'handle' MessageService = []; %NPOINTS Property is of type 'int' NPoints = 29791; %NBINS Property is of type 'int' NBins = 21; %PRIMES Property is of type 'MATLAB array' Primes = []; %POINTS Property is of type 'MATLAB array' Points = []; %VALUES Property is of type 'MATLAB array' Values = []; %BINS Property is of type 'MATLAB array' Bins = []; %MIDPOINTS Property is of type 'MATLAB array' MidPoints = []; %MAINCONTOURS Property is of type 'MATLAB array' MainContours = []; %HIGHLIGHTCONTOURS Property is of type 'MATLAB array' HighlightContours = []; %HIGHLIGHTDATA Property is of type 'MATLAB array' HighlightData = []; end methods % constructor block function obj = BdryPairwiseData( varargin ) % XREGBDRYGUI.BDRYPAIRWISEDATA class constructor % Get oursleves some prime numbers obj.Primes = primes( 100 ); end % BdryPairwiseData end % constructor block methods end % set and get functions methods % public methods %---------------------------------------- function X = getBlackDotXData(obj, R, C) %GETBLACKDOTXDATA Get the XData required for the black dots % GETBLACKDOTXDATA(OBJ, R, C) BMS = obj.MessageService; data = BMS.getDataPoints; X = data(:,C); end % getBlackDotXData %---------------------------------------- function Y = getBlackDotYData(obj, R, C) %GETBLACKDOTYDATA Get the YData required for the black dots % GETBLACKDOTYDATA(OBJ, R, C) BMS = obj.MessageService; data = BMS.getDataPoints; Y = data(:,R+1); end % getBlackDotYData %---------------------------------------- function nC = getColumnCount(obj) %GETCOLUMNCOUNT Return the number of columns in the data model. % NC = GETCOLUMNCOUNT(OBJ) returns the number of columns in the data model. nC = obj.getRowCount; end % getColumnCount %---------------------------------------- function X = getEvaluationPoints(obj) %GETEVALUATIONPOINTS Access for evaluation points % X = GETEVALUATIONPOINTS(OBJ) % The points stored by the object are just a design on [0, 1]^d. This % method provides access to points scalled on the correct domain for the % current constraint. % We need to get some information about the current constraint from the % BMS. bms = obj.MessageService; cif = bms.getInputFactors; nf = length( cif ); pUpdateEvaluationPoints( obj, obj.NPoints, nf ); X = obj.Points(1:obj.NPoints,1:nf); % The evaluation points are then scaled on to the appropriate domain X = repmat( cif.Min, obj.NPoints, 1 ) + X * diag( cif.Max - cif.Min ); end % getEvaluationPoints %---------------------------------------- function HC = getHighlightContours(obj, R, C) %GETHIGHLIGHTCONTOURS A short description of the function. % GETHIGHLIGHTCONTOURS(OBJ, R, C) % Returns a matrix of the form % C = [level1 x1 x2 x3 ... level2 x2 x2 x3 ...; % pairs1 y1 y2 y3 ... pairs2 y2 y2 y3 ...] % % See also XREGCONTOURS2PATCHES. if isempty( obj.HighlightContours ), HC = []; else HC = obj.HighlightContours{C,R+1}; end end % getHighlightContours %---------------------------------------- function [R, C] = getHighlightIndices(obj) %GETHIGHLIGHTINDICES Get the indices of factors that are highlighted. % [R, C] = GETHIGHLIGHTINDICES(OBJ) returns the indices of the input % factors on the row and column that are currently highlighted. R = 0; C = 0; HLData = obj.HighlightData; if ~isempty(HLData) bms = obj.MessageService; con = bms.getConstraint; if ~isempty(con) cif = getInputFactors(con); R = find(HLData.YFactor, cif); C = find(HLData.XFactor, cif); end end end % getHighlightIndices %---------------------------------------- function X = getHighlightLineXData(obj, R, C) %GETHIGHLIGHTLINEXDATA Get the XData required for the highlight line % X = GETHIGHLIGHTLINEXDATA(OBJ, R, C) X = []; if ~isempty( obj.HighlightData ) bms = obj.MessageService; con = bms.getConstraint; if ~isempty(con) cif = getInputFactors(con); if isequal(obj.HighlightData.XFactor, cif(C)) ... && isequal(obj.HighlightData.YFactor, cif(R+1)) ... X = obj.HighlightData.Rectangle([1,1,2,2,1],1); end end end end % getHighlightLineXData %---------------------------------------- function Y = getHighlightLineYData(obj, R, C) %GETHIGHLIGHTLINEYDATA Get the YData required for the highlight line. % Y = GETHIGHLIGHTLINEYDATA(OBJ, R, C) Y = []; if ~isempty( obj.HighlightData ) bms = obj.MessageService; con = bms.getConstraint; if ~isempty(con) cif = getInputFactors(con); if isequal(obj.HighlightData.XFactor, cif(C)) ... && isequal(obj.HighlightData.YFactor, cif(R+1)) Y = obj.HighlightData.Rectangle([1,2,2,1,1],2); end end end end % getHighlightLineYData %---------------------------------------- function HC = getMainContours(obj, R, C) %GETMAINCONTOURS A short description of the function. % GETMAINCONTOURS(OBJ, R, C) % Returns a matrix of the form % C = [level1 x1 x2 x3 ... level2 x2 x2 x3 ...; % pairs1 y1 y2 y3 ... pairs2 y2 y2 y3 ...] % % See also XREGCONTOURS2PATCHES. if isempty( obj.MainContours ), HC = []; else HC = obj.MainContours{C,R+1}; end end % getMainContours %---------------------------------------- function X = getRedRingXData(obj, R, C) %GETREDRINGXDATA Get the XData required for the red rings % GETREDRINGXDATA(OBJ, R, C) BMS = obj.MessageService; data = BMS.getDataPoints; bp = BMS.getBoundaryPoints; X = data(bp,C); end % getRedRingXData %---------------------------------------- function Y = getRedRingYData(obj, R, C) %GETREDRINGYDATA Get the YData required for the red rings % GETREDRINGYDATA(OBJ, R, C) BMS = obj.MessageService; data = BMS.getDataPoints; bp = BMS.getBoundaryPoints; Y = data(bp,R+1); end % getRedRingYData %---------------------------------------- function nR = getRowCount(obj) %GETROWCOUNT Return the number of rows in the data model. % NR = GETROWCOUNT(OBJ) returns the number of rows in the data model. bms = obj.MessageService; if isempty( bms ) nR = 0; else nR = max(0,length( bms.getInputFactors ) - 1); end end % getRowCount %---------------------------------------- function [dotXs, crossXs] = getValidationXData(obj, R, C) %GETVALIDATIONXDATA Get the XData required for the green dots % GETVALIDATIONXDATA(OBJ, R, C) BMS = obj.MessageService; [data, inside] = BMS.getValidationPoints; if ~isempty(data) crossXs = data(~inside,C); dotXs = data(inside,C); else crossXs = []; dotXs = []; end end % getValidationXData %---------------------------------------- function [dotYs, crossYs] = getValidationYData(obj, R, C) %GETVALIDATIONYDATA Get the YData required for the green dots % GETVALIDATIONYDATA(OBJ, R, C) BMS = obj.MessageService; [data, inside] = BMS.getValidationPoints; if ~isempty(data) crossYs = data(~inside,R+1); dotYs = data(inside,R+1); else crossYs = []; dotYs = []; end end % getValidationYData %---------------------------------------- function contourData = pComputeContourData( obj, values ) %PCOMPUTECONTOURDATA Compute the projection contours. % CONTOURDATA = PCOMPUTECONTOURDATA( OBJ, VALUES ) % Note that this method requires that the distance values be passed in % and that it returns the contour data. This allows this method to be % used to compute both main and the highligh contours. % We need to get some information about the current constraint from the % BMS. bms = obj.MessageService; con = bms.getConstraint; cif = bms.getInputFactors; nf = length( cif ); ai = getActiveIndices( con ); % And some information from the object nBins = obj.NBins; bins = obj.Bins; midPoints = obj.MidPoints; midPoints = repmat( cif.Min, obj.NBins, 1 ) + ... repmat( midPoints(:), 1, nf ) * diag( cif.Max - cif.Min ); % Initialize the cell array into which the contour data will be put contourData = cell( nf, nf ); % It is not uncommon to get some edges that don't look quite right. To % "fix" this, we convolve the resulting projection surface against the % following "mask". This smoothes out the edges a little. mask = [ 0 1 0 1 2 1 0 1 0 ]; effectiveInf = max( 1.0, 2 * max( values ) ); nPoints = size( values, 1 ); for i = 1:(nf-1), for j = (i+1):nf, D = repmat( effectiveInf, nBins, nBins ); if any( ai == i ), if any( ai == j ), % Both i and j are active for k = 1:nPoints, ii = bins(k,i); jj = bins(k,j); % We want to do something like: % >> D(ii,jj) = min( D(ii,jj), values(k) ); % but it is probably quicker to do: if values(k) < D(ii,jj), D(ii,jj) = values(k); end end D = conv2( D, mask, 'same' ); else % i is active but j is not for k = 1:nPoints, ii = bins(k,i); % We want to do something like: % >> D(ii,:) = min( D(ii,:), values(k) ); % but it is probably quicker to do: if values(k) < D(ii,1), D(ii,:) = values(k); end end end else if any( ai == j ), % j is active but i is not for k = 1:nPoints, jj = bins(k,j); % We want to do something like: % >> D(:,jj) = min( D(:,jj), values(k) ); % but it is probably quicker to do: if values(k) < D(1,jj), D(:,jj) = values(k); end end else % neither is active D(:) = -1; end end if any( D(:) > 0 ), contourData{i,j} = i_FindContours( midPoints(:,i), midPoints(:,j), D.', 0 ); %>> [xi, yi] = ndgrid( 0.5:obj.NBins+0.5 ); %>> D = interp2( D, 0.5:obj.NBins+0.5, (0.5:obj.NBins+0.5).' ); %>> obj.MainContours{i,j} = i_FindContours( edges(:,i), edges(:,j), D.', 0 ); else % C = [level1 x1 x2 x3 ... level2 x2 x2 x3 ...; % pairs1 y1 y2 y3 ... pairs2 y2 y2 y3 ...] contourData{i,j} = [ 0, cif(i).Min, cif(i).Min, cif(i).Max, cif(i).Max, cif(i).Min 5, cif(j).Min, cif(j).Max, cif(j).Max, cif(j).Min, cif(j).Min ]; end end end end % pComputeContourData %---------------------------------------- function pPostConstraintChange(obj) %PPOSTCONSTRAINTCHANGE Respond to a change in the constraint % PPOSTCONSTRAINTCHANGE(OBJ) % We need to get some information about the current constraint from the % BMS. bms = obj.MessageService; con = bms.getConstraint; % If there is no constraint then there is nothing to do. We just leave all % the contours as empty. if isempty( con ), obj.MainContours = []; obj.HighlightContours = []; return end % Get evaluation points X = obj.getEvaluationPoints; % With the evaluation points all nicely set-up, the evaluation is easy: d = constraintDistance( con, X ); obj.Values = d; % Find Contours obj.MainContours = obj.pComputeContourData( d ); obj.pSelectHighlight; end % pPostConstraintChange %---------------------------------------- function pSelectHighlight(obj, RFactor, CFactor) %PSELECTHIGHLIGHT Respond to the highlight region being selected. % PSELECTHIGHLIGHT(OBJ) redraws the highlight contour. highlightData = obj.HighlightData; if nargin==1 % Derive R and C from the saved input factors [RFactor, CFactor] = obj.getHighlightIndices; end if isempty( highlightData ) || RFactor==0 || CFactor==0 obj.HighlightContours = []; return end % We should already have all the constraint evaluations inside the data % object (obj). If not, we'll have to fire the "pPostConstraintChange" % method. % % We need to compare the evaluation points with the ranges of the % highlight window. We can then set to +Inf the distance values for all % points outside the region. % % As the data has already been binned, we then just need to loops over all % the combinations of input factors computing the new contour data. % Check for appropriate data if isempty( obj.Points ) || isempty( obj.Values ) || isempty( obj.Bins ), obj.pPostConstraintChange; end % Check also the main contours. If these are all empty then there is % nothing for us to highlight and we should stop if isempty( obj.MainContours ) || all( cellfun( 'isempty', obj.MainContours(:) ) ), obj.HighlightContours = obj.MainContours; return end % Now the fun starts. bms = obj.MessageService; cif = bms.getInputFactors; X = obj.getEvaluationPoints; ai = highlightData.MinPoint(1); bi = highlightData.MaxPoint(1); ri = cif(CFactor).Max - cif(CFactor).Min; aj = highlightData.MinPoint(2); bj = highlightData.MaxPoint(2); rj = cif(RFactor).Max - cif(RFactor).Min; distances = max( [ obj.Values, (ai - X(:,CFactor))/ri, (X(:,CFactor) - bi)/ri, ... (aj - X(:,RFactor))/rj, (X(:,RFactor) - bj)/rj ], [], 2 ); % We now use the existing bins and edges to compute the highlight contours. obj.HighlightContours = obj.pComputeContourData( distances ); end % pSelectHighlight %---------------------------------------- function pUpdateEvaluationPoints(obj, nPoints, nFactors) %PUPDATEEVALUATIONPOINTS Add more evaluation points as required. % PUPDATEEVALUATIONPOINTS(OBJ, NPOINTS, NFACTORS) adds points to the list % of evaluation points to ensure that there are at least NPOINTS points % for at least NFACTORS input factors. doMakeNewBins = false; [np, nf] = size( obj.Points ); if nf > 0, if np < nPoints, doMakeNewBins = true; % Add more rows % -- just add "Halton sequence" points to the end obj.Points = [ obj.Points i_Halton( obj.Primes(1:nf), np, nPoints ) ]; else nPoints = np; end end if nf < nFactors, doMakeNewBins = true; % Add more columns % -- need to add the corners to the beginning (rows) and "Halton % sequence" points to end (columns) corners = cell( 1, nFactors ); [corners{:}] = ndgrid( [0, 1] ); corners = cell2mat( cellfun( @(x){x(:)}, corners ) ); nOldCorners = 2^nf; obj.Points = [ corners obj.Points((nOldCorners+1):end,:), ... i_Halton( obj.Primes((nf+1):nFactors), 0, nPoints - nOldCorners ) ]; end if doMakeNewBins, % Need to update the bin data nBins = obj.NBins; edges = linspace( 0, 1, nBins+1 ); edges(end) = edges(end) + eps( 1 ); % -- This last line ensure that points are inside the bins, i.e., all % points will be less than edges(end). The small change also means % that the last edge is numrically close enough to where the edge of % the last bin and this will help us latter with the contour % computation. [~, bins] = histc( obj.Points, edges ); obj.Bins = bins; obj.MidPoints = 0.5 * (edges(1:end-1) + edges(2:end)); end end % pUpdateEvaluationPoints %---------------------------------------- function setHighlight(obj, R, C, HLData) %SETHIGHLIGHT Set a new highlight rectangle. % SETHIGHLIGHT(OBJ, R, C, HLDATA) set the rectangle defined by the data % structure HLDATA in cell (R, C) of the view as the current highlight. % HLDATA must be a structure containing the fields Rectangle, MinPoint % and MaxPoint. % Convert (R, C) to the current input factors and save these along with the % rectangle information. bms = obj.MessageService; con = bms.getConstraint; if ~isempty(con) % Don't accept highlight data if there is no constraint being viewed cif = getInputFactors(con); HLData.XFactor = cif(C); HLData.YFactor = cif(R); obj.HighlightData = HLData; obj.pSelectHighlight(R, C); end end % setHighlight end % public methods methods (Hidden) % possibly private or hidden %---------------------------------------- function Changed = guiEditResolution(obj) %GUIEDITRESOLUTION % Changed = guiEditResolution(obj) d= mbcgui.container.Dialog('Name', 'Pairwise Projections Resolution',... 'InfoHeight', 35, ... 'InfoString',['To increase the resolution of the plot at the expense of greater calculation time, ',... 'increase the number of evaluation points and bins.'],... 'Size', [360 200], ... 'ContentBorder',[0 0 0 0],... 'Buttons', 'OK_CANCEL', ... 'DefaultAction', 'OK', ... 'CloseAction', 'CANCEL'); figh = d.Figure; hNPoints = mbcgui.widget.Spinner( ... 'Parent', figh, ... 'Rule', 'int', ... 'Min', 0, ... 'Max', 2^31, ... 'Value', obj.NPoints, ... 'ClickIncrementMode', 'auto'); hNPointsLabel = xregGui.labelcontrol('parent', figh, ... 'String', 'Number of evaluation points:', ... 'LabelSizeMode', 'absolute', ... 'ControlSizeMode', 'absolute', ... 'LabelSize', 150, ... 'ControlSize', 70, ... 'Control', hNPoints); hNBins = mbcgui.widget.Spinner( ... 'Parent', figh, ... 'Rule', 'int', ... 'Min', 2, ... 'Max', 2^8, ... 'Value', obj.NBins, ... 'ClickIncrementMode', 'auto'); hNBinsLabel = xregGui.labelcontrol('parent', figh, ... 'String', 'Number of bins per axes:', ... 'LabelSizeMode', 'absolute', ... 'ControlSizeMode', 'absolute', ... 'LabelSize', 150, ... 'ControlSize', 70, ... 'Control', hNBins); hGrid = xreggridbaglayout(figh,... 'Dimension',[2 1],... 'RowSizes',[20 20],... 'Gap', 5, ... 'Border',[7 0 7 7],... 'Elements',{hNPointsLabel,hNBinsLabel}); d.Content = hGrid; closeMode = d.showDialog(); Changed = false; if strcmp(closeMode,'OK') if hNBins.Value~=obj.NBins || hNPoints.Value~=obj.NPoints; obj.NBins = hNBins.Value; obj.NPoints = hNPoints.Value; obj.Points = []; Changed = true; end end delete(d); end % guiEditResolution end % possibly private or hidden end % classdef function C = i_FindContours( x, y, z, v ) z = -z; [m, n] = size( z ); ii = isfinite( z ); if ~any( ii(:) ), C = []; return end % pading with a very large negative value is an easy way of getting the % caps from contours minz = min( z(ii) ); maxz = max( z(ii) ); pad = minz - 1e4*(maxz - minz); if ~isfinite( pad ), pad = -realmax; end z(~ii) = pad; z = [ repmat( pad, 1, m + 2 ); repmat( pad, n, 1 ), z, repmat( pad, n, 1 ); repmat( pad, 1, m + 2 ); ]; x = [2*x(1)-x(2), x(:).', 2*x(end)-x(end-1)]; y = [2*y(1)-y(2), y(:).', 2*y(end)-y(end-1)]; % find the contours C = contours( x, y, z, [v, v] ); end % i_FindContours %-------------------------------------------------------------------------- function X = i_Halton( p, start, finish ) %HALTON Simple Halton sequence. np = finish - start; % We want P as a row p = p(:).'; % Initialize memory of X X = zeros( np, numel( p ) ); L = ceil( log( finish )/log( min( p ) ) ); for j = 1:numel( p ), pp = p(j).^(0:L); for i = 1:np, thisN = start + i; for k = L:-1:1, d = floor( thisN/pp(k) ); thisN = thisN - d * pp(k); % rem( thisN, pp(k) ); X(i,j) = X(i,j) + d/(pp(k+1)); end end end end % i_Halton