]> Creatis software - CreaPhase.git/blob - octave_packages/dataframe-0.9.1/@dataframe/private/df_basecomp.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / dataframe-0.9.1 / @dataframe / private / df_basecomp.m
1 function [A, B, C] = df_basecomp(A, B, itercol=true, func=@plus);
2
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.
8
9   %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
10   %%
11   %% This file is part of Octave.
12   %%
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.
17   %%
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
22   %% details.
23   %%
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.
28   
29   %#
30   %# $Id: df_basecomp.m 9585 2012-02-05 15:32:46Z cdemills $
31   %#
32
33   if 1 == length(itercol), 
34     strict = false;
35   else
36     strict = itercol(2); itercol = itercol(1);
37   endif
38
39   if (iscell(A)), A = dataframe(A); endif
40   if (iscell(B)), B = dataframe(B); endif  
41
42   switch (func2str(func)),
43     case 'bsxfun'
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');
50         else
51           Csize = max([size(A)(1:2); size(B)(1:2)]);
52         endif
53       else
54         Csize = size(A)(1:2);
55       endif
56     case 'mldivide'
57       if (isscalar(A)), 
58         Csize = size(B)(1:2);
59       else
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));
63         endif
64         Csize = [size(A, 2) size(B, 2)];
65       endif
66     otherwise
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
70           Csize = size(A)(1:2);
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)",\
74                   Csize, size(B));
75           endif
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));
80           endif
81           Csize = [size(A, 1) size(B, 2)];
82         endif
83       endif
84   endswitch
85
86   if !(isscalar(A) || isscalar(B))
87     C = [];
88     if (isa(A, 'dataframe'))
89       if (nargout > 2 && all(Csize == size(A)(1:2))),
90         C = df_allmeta(A, Csize);
91       endif         
92       if (isa(B, 'dataframe'))
93         if (nargout > 2 && isempty(C) && all(Csize == size(B)(1:2))),
94           C = df_allmeta(B, Csize);
95         endif
96         if (strict),
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");
102               endif
103             endif
104           else
105             if (nargout > 2 && itercol), C._ridx = B._ridx; endif
106           endif
107           
108           if (itercol),
109             idxB = 1; %# row-row comparison
110           else
111             idxB = 2; %# row-col comparsion
112           endif
113           
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}(:)));
118               if (any(dummy)),
119                 if (itercol),
120                   error("Incompatible row names");
121                 else
122                   error("Incompatible row vs. column names");
123                 endif
124               endif
125               dummy = A._over{1} > B._over{idxB};
126               if (any(dummy)),
127                 C._name{1}(dummy) = B._name{idxB}(dummy);
128                 C._over{1}(dummy) = B._over{idxB}(dummy);
129               endif
130             endif
131           else
132             if (nargout > 2), 
133               C._name{1} = B._name{idxB}; C._over{1} = B._over{idxB};
134             endif
135           endif
136           
137           idxB = 3-idxB;
138           
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}(:)));
143               if (any(dummy)),
144                 if (itercol),
145                   error("Incompatible column vs row names");
146                 else
147                   error("Incompatible column names");
148                 endif
149               endif
150               dummy = A._over{2} > B._over{idxB};
151               if (any(dummy)),
152                 C._name{2}(dummy) = B._name{idxB}(dummy);
153                 C._over{2}(dummy) = B._over{idxB}(dummy);
154               endif
155             endif
156           else
157             if (nargout > 2 && !isempty(B._name{idxB})),
158               C._name{2} = B._name{idxB}; C._over{2} = B._over{idxB}; 
159             endif
160           endif
161         endif
162
163         if (isempty(A._src) && nargout > 2 && !isempty(B._src)), 
164           C._src = B._src;
165         endif
166         if (isempty(A._cmt) && nargout > 2 && !isempty(B._cmt)), 
167           C._cmt = B._cmt;
168         endif
169       else %# B is not a df
170         if (nargout > 2 && isempty(C)),
171           C = df_allmeta(A);
172         endif
173       endif
174     else %# A is not a df
175       if (nargout > 2), 
176         if (all(Csize==size(B)(1:2))),
177           C = df_allmeta(B, Csize); 
178         else
179           C = df_allmeta(B); 
180         endif         
181       endif
182     endif
183   else %# both arg are  scalar
184     if (nargout > 2),
185       if (isa(A, 'dataframe')) 
186         C = df_allmeta(A);     
187       else
188         C = df_allmeta(B); 
189       endif
190     endif
191   endif
192   
193 endfunction