1 function [A, B, C] = df_basecomp(A, B, itercol=true, func=@plus);
3 %# function [A, B, C] = df_basecomp(A, B, itercol)
4 %# Basic size and metadata compatibility verifications for
5 %# two-arguments operations on dataframe. Returns a scalar, a matrix,
6 %# or a dataframe. Cell arrays are converted to df. Third output
7 %# contains a merge of the metadata.
9 %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
11 %% This file is part of Octave.
13 %% Octave is free software; you can redistribute it and/or
14 %% modify it under the terms of the GNU General Public
15 %% License as published by the Free Software Foundation;
16 %% either version 2, or (at your option) any later version.
18 %% Octave is distributed in the hope that it will be useful,
19 %% but WITHOUT ANY WARRANTY; without even the implied
20 %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21 %% PURPOSE. See the GNU General Public License for more
24 %% You should have received a copy of the GNU General Public
25 %% License along with Octave; see the file COPYING. If not,
26 %% write to the Free Software Foundation, 51 Franklin Street -
27 %% Fifth Floor, Boston, MA 02110-1301, USA.
30 %# $Id: df_basecomp.m 9585 2012-02-05 15:32:46Z cdemills $
33 if 1 == length(itercol),
36 strict = itercol(2); itercol = itercol(1);
39 if (iscell(A)), A = dataframe(A); endif
40 if (iscell(B)), B = dataframe(B); endif
42 switch (func2str(func)),
44 %# bsxfun compatibility rule: if there is at least one singleton
45 %# dim, the smallest is repeated to reach the size of the
46 %# greatest. Otherwise, all dims must be equal.
47 if (any(size(A)(1:2) != size(B)(1:2)))
48 if (!any (1 == [size(A) size(B)]))
49 error('bsxfun: both arguments must have the same dim, of one of them must have at least one singleton dim');
51 Csize = max([size(A)(1:2); size(B)(1:2)]);
60 if (size(A, 1) != size(B, 1)),
61 error("Non compatible row sizes (op1 is %dx%d, op2 is %dx%d)",\
62 size(A), size(B)(1:2));
64 Csize = [size(A, 2) size(B, 2)];
67 %# if strict is set, B may not be non-scalar vs scalar
68 if ((!(isscalar(A) || isscalar(B)))||(strict && isscalar(A))),
69 if (itercol), %# requires full compatibility
71 if (any(Csize - size(B)(1:2))),
72 %# disp([size(A) size(B)])
73 error("Non compatible row and columns sizes (op1 is %dx%d, op2 is %dx%d)",\
76 else %# compatibility with matrix product
77 if (size(A, 2) - size(B, 1)),
78 error("Non compatible columns vs. rows size (op1 is %dx%d, op2 is %dx%d)",\
79 size(A)(1:2), size(B)(1:2));
81 Csize = [size(A, 1) size(B, 2)];
86 if !(isscalar(A) || isscalar(B))
88 if (isa(A, 'dataframe'))
89 if (nargout > 2 && all(Csize == size(A)(1:2))),
90 C = df_allmeta(A, Csize);
92 if (isa(B, 'dataframe'))
93 if (nargout > 2 && isempty(C) && all(Csize == size(B)(1:2))),
94 C = df_allmeta(B, Csize);
97 %# compare indexes if both exist
98 if (!isempty(A._ridx))
99 if (!isempty(B._ridx) && itercol),
100 if (any(A._ridx-B._ridx)),
101 error("Non compatible indexes");
105 if (nargout > 2 && itercol), C._ridx = B._ridx; endif
109 idxB = 1; %# row-row comparison
111 idxB = 2; %# row-col comparsion
114 if (!isempty(A._name{1}))
115 if (!isempty(B._name{idxB}))
116 dummy = !(strcmp(cellstr(A._name{1}), cellstr(B._name{idxB}))\
117 | (A._over{1}(:)) | (B._over{idxB}(:)));
120 error("Incompatible row names");
122 error("Incompatible row vs. column names");
125 dummy = A._over{1} > B._over{idxB};
127 C._name{1}(dummy) = B._name{idxB}(dummy);
128 C._over{1}(dummy) = B._over{idxB}(dummy);
133 C._name{1} = B._name{idxB}; C._over{1} = B._over{idxB};
139 if (!isempty(A._name{2}))
140 if (!isempty(B._name{idxB}))
141 dummy = !(strcmp(cellstr(A._name{2}), cellstr(B._name{2}))\
142 | (A._over{2}(:)) | (B._over{2}(:)));
145 error("Incompatible column vs row names");
147 error("Incompatible column names");
150 dummy = A._over{2} > B._over{idxB};
152 C._name{2}(dummy) = B._name{idxB}(dummy);
153 C._over{2}(dummy) = B._over{idxB}(dummy);
157 if (nargout > 2 && !isempty(B._name{idxB})),
158 C._name{2} = B._name{idxB}; C._over{2} = B._over{idxB};
163 if (isempty(A._src) && nargout > 2 && !isempty(B._src)),
166 if (isempty(A._cmt) && nargout > 2 && !isempty(B._cmt)),
169 else %# B is not a df
170 if (nargout > 2 && isempty(C)),
174 else %# A is not a df
176 if (all(Csize==size(B)(1:2))),
177 C = df_allmeta(B, Csize);
183 else %# both arg are scalar
185 if (isa(A, 'dataframe'))