-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
280 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
../../../../../lib/mp_table_subclass.m |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
docs/sphinx/source/ref-manual/classes/mp_table_subclass.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.. automodule:: matpower | ||
|
||
:raw-html:`<div style="float: right"><a href="https://github.com/MATPOWER/matpower/blob/master/lib/mp_table_subclass.m" target=_blank><svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github v-align-middle color-fg-default"><path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path></svg></a></div>` | ||
|
||
mp_table_subclass | ||
----------------- | ||
|
||
.. autoclass:: mp_table_subclass | ||
:show-inheritance: | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
classdef mp_table_subclass | ||
% mp_table_subclass - Class that acts like a table but isn't one. | ||
% | ||
% Addresses two issues with inheriting from **table** classes (:class:`table`) | ||
% or mp_table). | ||
% | ||
% 1. In MATLAB, :class:`table` is a sealed class, so you cannot inherit | ||
% from it. You can, however, use a subclass of mp_table, but that can | ||
% result in the next issue under Octave. | ||
% 2. While nesting of tables works just fine in general, when using mp_table | ||
% in Octave (at least up through 8.4.0), you cannot nest a subclass of | ||
% mp_table inside another mp_table object because of this bug: | ||
% https://savannah.gnu.org/bugs/index.php?65037. | ||
% | ||
% To work around these issues, your "table subclass" can inherit from **this** | ||
% class. An object of this class **isn't** a :class:`table` or mp_table object, | ||
% but rather it **contains** one and attempts to act like one. That is, it | ||
% delegates method calls (currently only those available in mp_table, listed | ||
% below) to the contained table object. | ||
% | ||
% The class of the contained table object is either :class:`table` or mp_table | ||
% and is determined by mp_table_class. | ||
% | ||
% .. admonition:: Limitation | ||
% | ||
% In MATLAB, when nesting an mp_table_subclass object within another | ||
% mp_table_subclass object, one cannot use multi-level indexing directly. | ||
% E.g. If ``T2`` is a variable in ``T1`` and ``x`` is a variable in ``T2``, | ||
% attempting ``x = T1.T2.x`` will result in an error. The indexing must | ||
% be done in multiple steps ``T2 = T1.T2; x = T2.x``. Note: This only | ||
% applies to MATLAB, where the contained table is a :class:`table`. It works | ||
% just fine in Octave, where the contained table is an :class:`mp_table`. | ||
% | ||
% .. important:: | ||
% | ||
% Since the dot syntax ``T.<var_name>`` is used to access table variables, | ||
% you must use a functional syntax ``<method>(T,...)``, as opposed to | ||
% the object-oriented ``T.<method>(...)``, to call methods of this class | ||
% or subclasses, as with mp_table. | ||
% | ||
% mp.mp_table_subclass Properties: | ||
% * tab - *(table or mp_table)* contained table object this class emulates | ||
% | ||
% mp.cost_table Methods: | ||
% * mp_table_subclass - construct object | ||
% * get_table - return the table stored in :attr:`tab` | ||
% * set_table - assign a table to :attr:`tab` | ||
% * istable - true for mp_table objects | ||
% * size - dimensions of table | ||
% * isempty - true if table has no columns or no rows | ||
% * end - used to index last row or variable/column | ||
% * subsref - indexing a table to retrieve data | ||
% * subsasgn - indexing a table to assign data | ||
% * horzcat - concatenate tables horizontally | ||
% * vertcat - concatenate tables vertically | ||
% * display - display table contents | ||
% | ||
% See also mp_table, mp_table_class. | ||
|
||
% MATPOWER | ||
% Copyright (c) 2023, Power Systems Engineering Research Center (PSERC) | ||
% by Ray Zimmerman, PSERC Cornell | ||
% | ||
% This file is part of MATPOWER. | ||
% Covered by the 3-clause BSD License (see LICENSE file for details). | ||
% See https://matpower.org for more info. | ||
|
||
properties | ||
tab | ||
end %% properties | ||
|
||
%% delegate all mp_table methods to obj.tab | ||
methods | ||
function obj = mp_table_subclass(varargin) | ||
|
||
args = varargin; | ||
if nargin | ||
%% extract named arguments | ||
[var_names, row_names, dim_names, args] = ... | ||
mp_table.extract_named_args(args); | ||
|
||
%% set default variable names | ||
nv = length(args); %% number of variables | ||
if length(var_names) < nv | ||
for k = nv:-1:length(var_names)+1 | ||
var_names{k} = inputname(k); | ||
if isempty(var_names{k}) | ||
var_names{k} = sprintf('Var%d', k); | ||
end | ||
end | ||
end | ||
args(end+1:end+2) = {'VariableNames', var_names}; | ||
if ~isempty(row_names) | ||
args(end+1:end+2) = {'RowNames', row_names}; | ||
end | ||
if ~isempty(dim_names) | ||
args(end+1:end+2) = {'DimensionNames', dim_names}; | ||
end | ||
end | ||
|
||
table_class = mp_table_class(); | ||
obj.tab = table_class(args{:}); | ||
end | ||
|
||
function tab = get_table(obj) | ||
% | ||
% :: | ||
% | ||
% T = get_table(obj) | ||
tab = obj.tab; | ||
end | ||
|
||
function obj = set_table(obj, T) | ||
% | ||
% :: | ||
% | ||
% set_table(obj, T) | ||
obj.tab = T; | ||
end | ||
|
||
function TorF = istable(obj) | ||
TorF = istable(obj.tab); | ||
end | ||
|
||
function varargout = size(obj, varargin) | ||
[varargout{1:nargout}] = size(obj.tab, varargin{:}); | ||
end | ||
|
||
function TorF = isempty(obj) | ||
TorF = isempty(obj.tab); | ||
end | ||
|
||
function N = end(obj, k, n) | ||
N = size(obj.tab, k); | ||
end | ||
|
||
function n = numArgumentsFromSubscript(obj, varargin) | ||
n = numArgumentsFromSubscript(obj.tab, varargin{:}); | ||
end | ||
|
||
function n = numel(obj, varargin) | ||
n = numel(obj.tab, varargin{:}); | ||
end | ||
|
||
function b = subsref(obj, varargin) | ||
b = subsref(obj.tab, varargin{:}); | ||
if varargin{1}(1).type(1) == '(' && ... | ||
(isa(b, 'table') || isa(b, 'mp_table')) | ||
o = feval(class(obj)); | ||
b = set_table(o, b); | ||
end | ||
end | ||
|
||
function obj = subsasgn(obj, varargin) | ||
for k = 2:length(varargin) | ||
if isa(varargin{k}, 'mp_table_subclass') | ||
varargin{k} = get_table(varargin{k}); | ||
end | ||
end | ||
obj.tab = subsasgn(obj.tab, varargin{:}); | ||
end | ||
|
||
function obj = horzcat(obj, varargin) | ||
args = varargin; | ||
for k = 1:length(args) | ||
if isa(args{k}, 'mp_table_subclass') | ||
args{k} = args{k}.tab; | ||
end | ||
end | ||
obj.tab = horzcat(obj.tab, args{:}); | ||
end | ||
|
||
function obj = vertcat(obj, varargin) | ||
args = varargin; | ||
for k = 1:length(args) | ||
if isa(args{k}, 'mp_table_subclass') | ||
args{k} = args{k}.tab; | ||
end | ||
end | ||
obj.tab = vertcat(obj.tab, args{:}); | ||
end | ||
|
||
function display(obj) | ||
obj.tab | ||
end | ||
end %% methods | ||
end %% classdef |
Oops, something went wrong.