This is a static copy of a profile report

Home

tabularDimension>tabularDimension.tabularDimension (Calls: 2, Time: 0.000 s)
Generated 04-Jun-2021 04:11:24 using performance time.
class method in file C:\Program Files\MATLAB\R2020b\toolbox\matlab\datatypes\tabular\+matlab\+internal\+tabular\+private\tabularDimension.m
Copy to new window for comparing multiple runs

Parents (calling functions)

Function NameFunction TypeCalls
metaDim>metaDim.metaDimclass method2
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
4
?matlab.internal.tabular.priva...
20.000 s0.7%
All other lines  0.000 s99.3%
Totals  0.000 s100% 
Children (called functions)
No children
Code Analyzer results
No Code Analyzer messages.
Coverage results
Show coverage for parent directory
Total lines in function532
Non-code lines (comments, blank lines)240
Code lines (lines that can run)292
Code lines that did run1
Code lines that did not run291
Coverage (did run/can run)0.34 %
Function listing
time 
Calls 
 line
   1 
classdef (AllowedSubclasses = {?matlab.internal.tabular.private.rowNamesDim, ...
   2 
                               ?matlab.internal.tabular.private.rowTimesDim, ...
   3 
                               ?matlab.internal.tabular.private.varNamesDim, ...
      2 
   4
                               ?matlab.internal.tabular.private.metaDim}) tabularDimension 
   5 
%tabularDimension Internal abstract class to represent a tabular's dimension.
   6 

   7 
% This class is for internal use only and will change in a
   8 
% future release.  Do not use this class.
   9 

  10 
    %   Copyright 2016-2019 The MathWorks, Inc.
  11 
        
  12 
    properties(Abstract, Constant, GetAccess=public)
  13 
        propertyNames
  14 
        requireLabels
  15 
        requireUniqueLabels
  16 
        DuplicateLabelExceptionID
  17 
    end
  18 
    
  19 
    properties(GetAccess=public, SetAccess=protected)
  20 
        % SetAccess=protected because subclass lengthenTo methods write to these
  21 
        length
  22 
        
  23 
        % Distinguish between not having labels and a zero-length dimension with no labels.
  24 
        hasLabels = false
  25 
    end
  26 
    properties(Abstract, GetAccess=public, SetAccess=protected)
  27 
        % Abstract because one subclass doesn't store this explicitly. Assign
  28 
        % via the public setLabels method.
  29 
        labels
  30 
    end
  31 
    
  32 
    properties(Constant, GetAccess=public)
  33 
        subsType = struct('reference',0,'assignment',1,'deletion',2)
  34 
    end
  35 
    
  36 
    %===========================================================================
  37 
    methods        
  38 
        function obj = init(obj,dimLength,dimLabels)
  39 
        % INIT is called by both the dimension objects' constructor and
  40 
        % tabular objects' loadobj method. In the latter case, because 
  41 
        % a default dimension object is already constructed, it is faster
  42 
        % to 'initialize' through INIT rather reconstruct a new one
  43 
            obj.length = dimLength;
  44 
            if nargin == 3
  45 
                if isvector(dimLabels) && (numel(dimLabels) == dimLength)
  46 
                    obj.hasLabels = true;
  47 
                    obj.labels = obj.orientAs(dimLabels);
  48 
                else
  49 
                    obj.throwIncorrectNumberOfLabels();
  50 
                end
  51 
            end
  52 
        end
  53 
        
  54 
        %-----------------------------------------------------------------------
  55 
        function obj = createLike(obj,dimLength,dimLabels)
  56 
            %CREATELIKE Create a tabularDimension of the same kind as an existing one.
  57 
            obj.length = dimLength;
  58 
            if nargin < 3
  59 
                if obj.hasLabels
  60 
                    % These are invalid empty labels that must be filled in later.
  61 
                    obj.labels = obj.emptyLabels(dimLength); 
  62 
                else
  63 
                    obj.hasLabels = false;
  64 
                    obj.labels = obj.labels([]);
  65 
                end
  66 
            else
  67 
                obj = obj.setLabels(dimLabels,[]);
  68 
            end
  69 
        end
  70 
                
  71 
        
  72 
        %-----------------------------------------------------------------------
  73 
        function obj = removeLabels(obj)
  74 
            if obj.requireLabels
  75 
                obj.throwRequiresLabels();
  76 
            else
  77 
                obj.labels = {}; % optional labels is usually names
  78 
                obj.hasLabels = false;
  79 
            end
  80 
        end
  81 
        
  82 
        %-----------------------------------------------------------------------
  83 
        function labels = emptyLabels(obj,num)
  84 
            % EMPTYLABELS Return a vector of empty labels of the right kind.
  85 
            
  86 
            % Default behavior assumes the labels are names, subclasses with
  87 
            % non-name labels need to overload.
  88 
            labels = obj.orientAs(repmat({''},num,1));
  89 
        end
  90 
        
  91 
        %-----------------------------------------------------------------------
  92 
        function labels = textLabels(obj,indices)
  93 
            % TEXTLABELS Return the labels converted to text.
  94 
            
  95 
            % Default behavior assumes the labels are names, subclasses with
  96 
            % non-name labels need to overload.
  97 
            if nargin < 2
  98 
                labels = obj.labels;
  99 
            else
 100 
                labels = obj.labels(indices);
 101 
            end
 102 
        end
 103 
        
 104 
        %-----------------------------------------------------------------------
 105 
        function obj = selectFrom(obj,toSelect)
 106 
            %SELECTFROM Return a subset of a tableDimimension for the specified indices.
 107 
            % The indices might be out of order, that's OK or repeated, that's handled.
 108 
            import matlab.internal.datatypes.isUniqueNumeric
 109 
            import matlab.internal.datatypes.isColon
 110 
            
 111 
            if obj.hasLabels
 112 
                obj.labels = obj.orientAs(obj.labels(toSelect));
 113 
                
 114 
                % Only numeric subscripts can lead to repeated rows (thus labels), no
 115 
                % need to check otherwise.
 116 
                if isnumeric(toSelect) && ~isUniqueNumeric(toSelect)
 117 
                    obj = obj.makeUniqueForRepeatedIndices(toSelect);
 118 
                end
 119 
                
 120 
                obj.length = numel(obj.labels);
 121 
            elseif isnumeric(toSelect)
 122 
                obj.length = numel(toSelect);
 123 
            elseif islogical(toSelect)
 124 
                obj.length = sum(toSelect);
 125 
            elseif isColon(toSelect)
 126 
                % leave obj.length alone
 127 
            elseif isa(toSelect,'matlab.internal.ColonDescriptor')
 128 
                obj.length = toSelect.length;
 129 
            else
 130 
                assert(false);
 131 
            end
 132 
        end
 133 
                        
 134 
        %-----------------------------------------------------------------------
 135 
        function obj = shortenTo(obj,maxIndex)
 136 
            if obj.hasLabels
 137 
                obj.labels = obj.labels(1:maxIndex);
 138 
            end
 139 
            obj.length = maxIndex;
 140 
        end
 141 
        
 142 
        %-----------------------------------------------------------------------
 143 
        function obj = deleteFrom(obj,toDelete)
 144 
            if obj.hasLabels
 145 
                obj.labels(toDelete) = [];
 146 
                obj.labels = obj.orientAs(obj.labels);
 147 
            end
 148 
            keepIndices = 1:obj.length;
 149 
            keepIndices(toDelete) = [];
 150 
            obj.length = numel(keepIndices);
 151 
        end        
 152 
        
 153 
        %-----------------------------------------------------------------------
 154 
        function obj = assignInto(obj,obj2,assignInto)
 155 
            if obj.hasLabels && obj2.hasLabels
 156 
                obj.labels(assignInto) = obj2.labels;
 157 
            elseif obj.hasLabels % && ~obj2.hasLabels
 158 
                % These are invalid empty labels that must be filled in later.
 159 
                obj.labels(assignInto) = obj2.emptyLabels(obj2.length);
 160 
            elseif obj2.hasLabels % && ~obj.hasLabels
 161 
                obj.labels = obj.emptyLabels(obj.length);
 162 
                obj.labels(assignInto) = obj2.labels;
 163 
                obj.hasLabels = true;
 164 
            end
 165 
        end
 166 
        
 167 
        %-----------------------------------------------------------------------
 168 
        function target = moveProps(target,source,fromLocs,toLocs) %#ok<INUSD>
 169 
            % MOVEPROPS Assign values from a tableDimension's properties into another's.
 170 
            % Replace property values in the target with values from the source,
 171 
            % across all properties that this dimension manages. If a property
 172 
            % that exists in the source doesn't exist in the target, first create
 173 
            % it in the target filled with default values. If a property that
 174 
            % exists in the target doesn't exist in the source, replace the target
 175 
            % values with default values. If a property doesn't exist in either,
 176 
            % do nothing for that property.
 177 
            %
 178 
            % Labels are not replaced.
 179 
            
 180 
            % By default, there are no properties (other than labels).
 181 
        end
 182 
        
 183 
        %-----------------------------------------------------------------------
 184 
        function target = mergeProps(target,source,fromLocs) %#ok<INUSD>
 185 
            % MERGEPROPS Merge a tableDimension's properties into another's.
 186 
            % Create properties that don't exist in the target using the
 187 
            % corresponding properties from the source (if the latter exist).
 188 
            % Properties that are already present in the target are left alone.
 189 
            % Labels are left alone.
 190 
            
 191 
            % By default, there are no properties (other than labels).
 192 
        end
 193 
        
 194 
        %-----------------------------------------------------------------------
 195 
        function obj = setLabels(obj,newLabels,subscripts,fixDups,fixEmpties,fixIllegal)
 196 
            %SETLABELS Modify, overwrite, or remove a tabularDimension's labels.
 197 
            if isstring(newLabels)
 198 
                % cannot use convertStringsToChars because scalar string
 199 
                % must convert to cellstr, not char vector.
 200 
                newLabels = cellstr(newLabels);
 201 
            end
 202 
            if nargin < 6
 203 
                % Should illegal labels be modified to make them legal?
 204 
                fixIllegal = false;
 205 
                if nargin < 5
 206 
                    % Should empty labels be filled in wth default labels?
 207 
                    fixEmpties = false;
 208 
                    if nargin < 4
 209 
                        % Should duplicate labels be made unique?
 210 
                        fixDups = false;
 211 
                    end
 212 
                end
 213 
            end
 214 
                        
 215 
            % Subscripts equal to [] denotes a full assignment while the edge case of a
 216 
            % partial assignment to zero labels requires a 1x0 or 0x1 empty.
 217 
            fullAssignment = (nargin == 2) || isequal(subscripts,[]);
 218 
            if fullAssignment % replacing all labels
 219 
                indices = 1:obj.length;
 220 
            elseif obj.hasLabels % replacing some labels
 221 
                indices = obj.subs2inds(subscripts);
 222 
                if islogical(indices)
 223 
                    % subs2inds leaves logical untouched, validateAndAssignLabels requires indices
 224 
                    indices = find(indices);
 225 
                end
 226 
            else % don't allow a subscripted assignment to an empty label property
 227 
                assert(false,'Partial/Subscripted assignment to empty label is not supported');
 228 
            end
 229 
            
 230 
            % Check the type of the new labels, and convert them to the canonical type as
 231 
            % necessary (and allowed). If this is a full assignment of a 0x0, and removing
 232 
            % the labels is allowed, validateLabels leaves the shape alone, otherwise it
 233 
            % reshapes to a vector of the appropriate orientation.
 234 
            obj = obj.validateAndAssignLabels(newLabels,indices,fullAssignment,fixDups,fixEmpties,fixIllegal);
 235 
        end
 236 
        
 237 
        %-----------------------------------------------------------------------
 238 
        function [indices,numIndices,maxIndex,isLiteralColon,isLabels,updatedObj] ...
 239 
                     = subs2inds(obj,subscripts,subsType)
 240 
            %SUBS2INDS Convert table subscripts (labels, logical, numeric) to indices.
 241 
            
 242 
            import matlab.internal.datatypes.isColon
 243 
            
 244 
            try
 245 
                if nargin < 3, subsType = obj.subsType.reference; end
 246 
                
 247 
                % Translate a table subscript object into actual subscripts,
 248 
                % take note of a colon object. The concrete dim class may have
 249 
                % already translated some kinds of subscript objects that need
 250 
                % dim-specific infomration to do the translation.
 251 
                isColonObj = false;
 252 
                if isobject(subscripts)
 253 
                    if isa(subscripts,'matlab.internal.tabular.private.subscripter')
 254 
                        subscripts = subscripts.getSubscripts(obj);
 255 
                    end
 256 
                    % The subscript may be a colonobj, or a timerange subscripter may return one.
 257 
                    if isa(subscripts,'matlab.internal.ColonDescriptor')
 258 
                        isColonObj = true;
 259 
                    end
 260 
                end
 261 
                
 262 
                if isnumeric(subscripts) || islogical(subscripts) || isColonObj
 263 
                    isLiteralColon = false;
 264 
                    isLabels = false;
 265 
                    
 266 
                    % Leave numeric and logical indices alone.
 267 
                    if isnumeric(subscripts)
 268 
                        indices = subscripts(:);
 269 
                        if any(isnan(indices))
 270 
                            error(message('MATLAB:badsubscript',getString(message('MATLAB:badsubscriptTextRange'))));
 271 
                        end
 272 
                        numIndices = numel(indices);
 273 
                        maxIndex = max(indices);
 274 
                    elseif islogical(subscripts)
 275 
                        indices = subscripts(:);
 276 
                        numIndices = sum(indices);
 277 
                        maxIndex = find(indices,1,'last');
 278 
                    else % isColonObj
 279 
                        indices = subscripts; % unexpanded
 280 
                        numIndices = length(subscripts); %#ok<CPROPLC>
 281 
                        maxIndex = double(subscripts.Stop);
 282 
                    end
 283 
                    
 284 
                    subsTypes = obj.subsType;
 285 
                    switch subsType
 286 
                    case subsTypes.reference
 287 
                        if maxIndex > obj.length
 288 
                            obj.throwIndexOutOfRange();
 289 
                        elseif nargout > 4
 290 
                            updatedObj = obj.selectFrom(indices);
 291 
                        end
 292 
                    case subsTypes.assignment
 293 
                        if nargout > 4
 294 
                            if maxIndex > obj.length
 295 
                                % Grow the dimension with default labels.
 296 
                                updatedObj = obj.lengthenTo(maxIndex);
 297 
                            else
 298 
                                updatedObj = obj;
 299 
                            end
 300 
                        end
 301 
                    case subsTypes.deletion
 302 
                        if maxIndex > obj.length
 303 
                            obj.throwIndexOutOfRange();
 304 
                        elseif nargout > 4
 305 
                            updatedObj = obj.deleteFrom(indices);
 306 
                        end
 307 
                    otherwise
 308 
                        assert(false);
 309 
                    end
 310 
                    
 311 
                elseif isColon(subscripts)
 312 
                    % Leave ':' alone. The : is evaluated with respect to the existing
 313 
                    % dimension. Cases where : needs to be evaluated with respect to the
 314 
                    % RHS of an assignment (i.e. assigning to a 0x0) need to be handled
 315 
                    % elsewhere.
 316 
                    isLiteralColon = true;
 317 
                    isLabels = false;
 318 
                    indices = subscripts;
 319 
                    numIndices = obj.length;
 320 
                    maxIndex = obj.length;
 321 
                    
 322 
                    if nargout > 4
 323 
                        updatedObj = obj;
 324 
                    end
 325 
                    
 326 
                else % "native" subscripts, i.e. names or times
 327 
                    isLiteralColon = false;
 328 
                    isLabels = true;
 329 
                    
 330 
                    % Translate labels into indices.
 331 
                    [subscripts,indices] = obj.validateNativeSubscripts(subscripts);
 332 
                    numIndices = numel(indices);
 333 
                    maxIndex = max(indices(:));
 334 
                    
 335 
                    subsTypes = obj.subsType;
 336 
                    switch subsType
 337 
                    case subsTypes.reference
 338 
                        if nnz(indices) < numIndices
 339 
                            if obj.requireUniqueLabels
 340 
                                newLabels = unique(subscripts(~indices),'stable');
 341 
                                obj.throwUnrecognizedLabel(newLabels(1));
 342 
                            end
 343 
                            indices = indices(indices>0);
 344 
                        end
 345 
                        if nargout > 4
 346 
                            updatedObj = obj.selectFrom(indices);
 347 
                        end
 348 
                    case subsTypes.assignment
 349 
                        if nnz(indices) < numIndices
 350 
                            [newLabels,~,newIndices] = unique(subscripts(~indices),'stable');
 351 
                            indices(~indices) = obj.length + newIndices;
 352 
                            maxIndex = max(indices(:));
 353 
                            if nargout > 4
 354 
                                % The new labels are guaranteed be distinct from the existing
 355 
                                % labels, otherwise the assignment would not need to
 356 
                                % lengthen the dimension.
 357 
                                updatedObj = obj.lengthenTo(maxIndex,newLabels);
 358 
                            end
 359 
                        elseif nargout > 4
 360 
                            updatedObj = obj;
 361 
                        end
 362 
                    case subsTypes.deletion
 363 
                        if nnz(indices) < numIndices
 364 
                            newLabels = unique(subscripts(~indices),'stable');
 365 
                            obj.throwUnrecognizedLabel(newLabels(1));
 366 
                        elseif nargout > 4
 367 
                            updatedObj = obj.deleteFrom(indices);
 368 
                        end
 369 
                    otherwise
 370 
                        assert(false);
 371 
                    end
 372 
                end
 373 
                if ~isColonObj
 374 
                    indices = obj.orientAs(indices);                
 375 
                end
 376 
            catch ME
 377 
                throwAsCaller(ME)
 378 
            end
 379 
        end
 380 
    end
 381 
       
 382 
    %===========================================================================
 383 
    methods (Access=protected)
 384 
        function obj = assignLabels(obj,newLabels,fullAssignment,indices)
 385 
            if fullAssignment
 386 
                if isvector(newLabels)
 387 
                    % The number of new labels has to match what's being assigned to.
 388 
                    if numel(newLabels) ~= obj.length
 389 
                        obj.throwIncorrectNumberOfLabels();
 390 
                    end
 391 
                    obj.hasLabels = true;
 392 
                    obj.labels = newLabels;
 393 
                else % a 0x0
 394 
                    % Full assignment of a 0x0 clears out the existing labels, if allowed above by
 395 
                    % the subclass's validateLabels.
 396 
                    obj.labels = newLabels([]); % force a 0x0, for cosmetics
 397 
                    obj.hasLabels = false;
 398 
                end
 399 
            else % subscripted assignment
 400 
                % The number of new labels has to match what's being assigned to.
 401 
                if numel(newLabels) ~= numel(indices)
 402 
                    obj.throwIncorrectNumberOfLabelsPartial();
 403 
                end
 404 
                obj.labels(indices) = newLabels;
 405 
            end
 406 
        end
 407 
        
 408 
        %-----------------------------------------------------------------------
 409 
        function [subscripts,indices] = validateNativeSubscripts(obj,subscripts)
 410 
            import matlab.internal.datatypes.isText
 411 

 412 
            subscripts = convertStringsToChars(subscripts);
 413 
            
 414 
            % Default behavior assumes the labels are names, subclasses with
 415 
            % non-name labels need to overload.
 416 
            if ischar(subscripts) % already weeded out ':'
 417 
                if isrow(subscripts)
 418 
                    subscripts = { subscripts };
 419 
                else
 420 
                    obj.throwInvalidLabel();
 421 
                end
 422 
            elseif isText(subscripts,true) % require a cell array or string array, don't allow empty character vectors in it
 423 
                % Don't allow scalar missing string or "", and handle it the
 424 
                % same as ''.
 425 
                if isstring(subscripts) && isscalar(subscripts) && strlength(subscripts) < 1 
 426 
                    obj.throwInvalidLabel();
 427 
                end
 428 
            else
 429 
                obj.throwInvalidSubscripts();
 430 
            end
 431 
            
 432 
            indices = zeros(size(subscripts));
 433 
            labs = obj.labels;
 434 
            for i = 1:numel(indices)
 435 
                indFirstMatch = find(strcmp(subscripts{i},labs), 1);
 436 
                if indFirstMatch
 437 
                    indices(i) = indFirstMatch;
 438 
                end
 439 
            end
 440 
        end
 441 
    end
 442 
    
 443 
    %===========================================================================
 444 
    methods (Access={?matlab.internal.tabular.private.tabularDimension, ?matlab.unittest.TestCase})
 445 
        function [tf,duplicated] = checkDuplicateLabels(obj,labels1,labels2,okLocs)
 446 
            %CHECKDUPLICATELABELS Check for duplicated names.
 447 
            
 448 
            % Check for any duplicate names in names1            
 449 
            if nargin == 2 % checkDuplicateLabels(obj,labels1)
 450 
                % names1 is always a cellstr
 451 
                duplicated = false(size(labels1));
 452 
                [labels1Sorted,lids] = sort(labels1);
 453 
                duplicated(2:end) = strcmp(labels1Sorted(1:end-1),labels1Sorted(2:end));
 454 
                % Put duplicated back in the original order.
 455 
                duplicated(lids) = duplicated; 
 456 
                
 457 
            % Check if any name in names1 is already in names2, except that
 458 
            % names1(i) may be at names2(okLocs(i)).  This does not check if
 459 
            % names1 contains duplicates within itself
 460 
            elseif nargin == 4 % checkDuplicateLabels(obj,labels1,labels2,okLocs)
 461 
                % names2 is always a cellstr
 462 
                if ischar(labels1) % names1 is either a single character vector ...
 463 
                    tmp = strcmp(labels1, labels2); tmp(okLocs) = false;
 464 
                    duplicated = any(tmp);
 465 
                else             % ... or a cell array of character vectors
 466 
                    duplicated = false(size(labels1));
 467 
                    for i = 1:length(labels1) %#ok<CPROPLC>
 468 
                        tmp = strcmp(labels1{i}, labels2); tmp(okLocs(i)) = false;
 469 
                        duplicated(i) = any(tmp);
 470 
                    end
 471 
                end
 472 
                
 473 
            % Check if any name in names1 is already in names2.  This does not check if
 474 
            % names1 contains duplicates within itself
 475 
            else % nargin==3, checkDuplicateLabels(obj,labels1,labels2) - least frequent syntax
 476 
                % names2 is always a cellstr
 477 
                if ischar(labels1) % names1 is either a single character vector ...
 478 
                    duplicated = any(strcmp(labels1, labels2));
 479 
                else             % ... or a cell array of character vectors
 480 
                    duplicated = false(size(labels1));
 481 
                    for i = 1:length(labels1) %#ok<CPROPLC>
 482 
                        duplicated(i) = any(strcmp(labels1{i}, labels2));
 483 
                    end
 484 
                end
 485 
                
 486 
            
 487 
            end
 488 
            
 489 
            tf = any(duplicated);
 490 
            
 491 
            if tf && obj.requireUniqueLabels && (nargout == 0)
 492 
                allDups = labels1(duplicated); 
 493 
                throwAsCaller(MException(message(obj.DuplicateLabelExceptionID,allDups{1}))); % Report the first dup in the message
 494 
            end
 495 
        end
 496 
    end
 497 

 498 
    %===========================================================================
 499 
    methods (Static)
 500 
        function conflicts = checkReservedNamesImpl(labels,reservedNames)
 501 
            %CHECKRESERVEDNAMES Check if variable names conflict with reserved names.
 502 
            conflicts = matches(labels,reservedNames);                
 503 
        end
 504 
    end
 505 
    
 506 
    %===========================================================================
 507 
    methods (Abstract)
 508 
        labels = defaultLabels(indices);
 509 
        obj = lengthenTo(obj,maxIndex,newLabels)
 510 
        s = getProperties(obj)
 511 
    end
 512 
    
 513 
    %===========================================================================
 514 
    methods (Abstract, Access=protected)
 515 
        obj = validateAndAssignLabels(obj,newLabels,indices,fullAssignment,fixDups,fixEmpties,fixIllegal)
 516 
        obj = makeUniqueForRepeatedIndices(obj,indices)
 517 
        
 518 
        throwRequiresLabels(obj)
 519 
        throwIncorrectNumberOfLabels(obj)
 520 
        throwIncorrectNumberOfLabelsPartial(obj)
 521 
        throwIndexOutOfRange(obj)
 522 
        throwUnrecognizedLabel(obj,label)
 523 
        throwInvalidLabel(obj)
 524 
        throwInvalidSubscripts(obj)
 525 
    end
 526 
   
 527 
    %===========================================================================
 528 
    methods (Abstract, Static, Access=protected)
 529 
        x = orientAs(x); % Reshape x as a vector in the specified orientation
 530 
    end
 531 
end
 532