]> Creatis software - CreaPhase.git/blob - octave_packages/dataframe-0.9.1/@dataframe/private/df_func.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / dataframe-0.9.1 / @dataframe / private / df_func.m
1 function resu = df_func(func, A, B, itercol=true, whole=logical([0 0]));
2
3   %# function resu = df_func(func, A, B, whole)
4   %# Implements an iterator to apply some func when at
5   %# least one argument is a dataframe. The output is a dataframe with
6   %# the same metadata, types may be altered, like f.i. double=>logical.
7   %# When itercol is 'true', the default, LHS is iterated by columns,
8   %# otherwise by rows. 'Whole' is a two-elements logical vector with
9   %# the meaning that LHS and or RHS must be iterated at once or not
10
11   %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
12   %%
13   %% This file is part of Octave.
14   %%
15   %% Octave is free software; you can redistribute it and/or
16   %% modify it under the terms of the GNU General Public
17   %% License as published by the Free Software Foundation;
18   %% either version 2, or (at your option) any later version.
19   %%
20   %% Octave is distributed in the hope that it will be useful,
21   %% but WITHOUT ANY WARRANTY; without even the implied
22   %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
23   %% PURPOSE.  See the GNU General Public License for more
24   %% details.
25   %%
26   %% You should have received a copy of the GNU General Public
27   %% License along with Octave; see the file COPYING.  If not,
28   %% write to the Free Software Foundation, 51 Franklin Street -
29   %% Fifth Floor, Boston, MA 02110-1301, USA.
30   
31   %#
32   %# $Id: df_func.m 9585 2012-02-05 15:32:46Z cdemills $
33   %#
34
35   [A, B, resu] = df_basecomp(A, B, itercol, func);
36   itercol = itercol(1); %# drop second value
37
38   if (isa(B, 'dataframe'))
39     if (!isa(A, 'dataframe')),
40       if (isscalar(A)),
41         for indi = resu._cnt(2):-1:1,
42           switch resu._type{indi}
43             case "char"
44               resu._data{indi} = feval(func, A, char(B._data{indi}));
45             otherwise
46               resu._data{indi} = feval(func, A, B._data{indi});
47           endswitch
48         endfor
49         resu._rep = B._rep;
50       else
51         if (whole(1) && !whole(2)),
52           for indi = resu._cnt(2):-1:1,
53             switch resu._type{indi}
54               case "char"
55                 resu._data{indi} = feval(func, A, \
56                                          char(B._data{indi}(:, B._rep{indi})));
57               otherwise
58                 resu._data{indi} = feval(func, A, \
59                                          B._data{indi}(:, B._rep{indi}));
60             endswitch
61             resu._rep{indi} = 1:size(resu._data{indi}, 2);
62           endfor
63         elseif (itercol && !whole(2)),
64           for indi = resu._cnt(2):-1:1,
65             switch resu._type{indi}
66               case "char"
67                 resu._data{indi} = feval(func, squeeze(A(:, indi, :)), \
68                                          char(B._data{indi}(:, B._rep{indi})));
69               otherwise
70                 resu._data{indi} = feval(func, squeeze(A(:, indi, :)), \
71                                          B._data{indi}(:, B._rep{indi}));
72             endswitch
73             resu._rep{indi} = 1:size(resu._data{indi}, 2);
74           endfor
75         elseif (!whole(2)),
76           warning("no 3D yet");
77           for indi = resu._cnt(2):-1:1,
78             switch resu._type{indi}
79               case "char"
80                 resu._data{indi} = feval(func, A(indi, :), char(B._data{indi}));
81               otherwise
82                 resu._data{indi} = feval(func, A(indi, :), B._data{indi});
83             endswitch
84           endfor
85         else
86           dummy = feval(func, A, df_whole(B));
87           for indi = resu._cnt(2):-1:1, %# store column-wise
88             resu._data{indi} = squeeze(dummy(:, indi, :));
89             resu._rep{indi} = 1:size(resu._data{indi}, 2);
90             resu._type{indi} = class(dummy);
91           endfor
92         endif
93       endif
94     else
95       if (itercol),
96         for indi = resu._cnt(2):-1:1,
97           switch resu._type{indi}
98             case "char"
99               resu._data{indi} = feval\
100                   (func, char(A._data{indi}(:, A._rep{indi})), \
101                    char(B._data{indi}(B._rep{indi})));
102             otherwise
103               resu._data{indi} = feval\
104                   (func, A._data{indi}(:, A._rep{indi}), \
105                    B._data{indi}(:, B._rep{indi}));
106           endswitch
107           resu._rep{indi} = 1:size(resu._data{indi}, 2);
108         endfor
109       else %# itercol is false
110         dummy = df_whole(A);
111         if whole(1),
112           for indi = resu._cnt(2):-1:1,
113             switch resu._type{indi}
114               case "char"
115                 resu._data{indi} = feval(func, dummy, \
116                                          char(B._data{indi}(:, B._rep{indi})));
117               otherwise
118                 resu._data{indi} = feval(func, dummy, \
119                                          B._data{indi}(:, B._rep{indi}));
120             endswitch
121             resu._rep{indi} = 1:size(resu._data{indi}, 2);
122           endfor
123         elseif (!whole(2)),
124           for indi = resu._cnt(2):-1:1,
125             switch resu._type{indi}
126               case "char"
127                 resu._data{indi} = squeeze\
128                     (feval(func, dummy(indi, :, :),\
129                            char(B._data{indi}(:, B._rep{indi}))));
130               otherwise
131                 resu._data{indi} = squeeze\
132                      (feval(func, dummy(indi, :, :), \
133                             B._data{indi}(:, B._rep{indi})));
134             endswitch
135             resu._rep{indi} = 1:size(resu._data{indi}, 2);
136           endfor
137         else
138           dummy = feval(func, dummy, df_whole(B));
139           for indi = resu._cnt(2):-1:1, %# store column-wise
140             resu._data{indi} = squeeze(dummy(:, indi, :));
141             resu._rep{indi} = 1:size(resu._data{indi}, 2);
142             resu._type{indi} = class(dummy);
143           endfor
144         endif
145       endif
146     endif  
147   else %# B is not a dataframe
148     if (isscalar(B)),
149       for indi = resu._cnt(2):-1:1,
150         switch resu._type{indi}
151           case "char"
152             resu._data{indi} = feval(func, char(A._data{indi}), B);
153           otherwise
154             resu._data{indi} = feval(func, A._data{indi}, B);
155         endswitch
156       endfor
157       resu._rep = A._rep;
158     else
159       if (itercol),
160         if (whole(2)),
161           for indi = resu._cnt(2):-1:1,
162             switch resu._type{indi}
163               case "char"
164                 unfolded = char(A._data{indi}(:, A._rep{indi}));
165               otherwise
166                 unfolded = A._data{indi}(:, A._rep{indi});
167             endswitch
168             resu._data{indi} = squeeze(feval(func, unfolded, B));
169             resu._rep{indi} = 1:size(resu._data{indi}, 2);
170           endfor
171         else
172           for indi = resu._cnt(2):-1:1,
173             switch resu._type{indi}
174               case "char"
175                 unfolded = char(A._data{indi}(:, A._rep{indi}));
176               otherwise
177                 unfolded = A._data{indi}(:, A._rep{indi});
178             endswitch
179             resu._data{indi} = feval(func, unfolded, \
180                                      squeeze(B(:, indi, :)));
181             resu._rep{indi} = 1:size(resu._data{indi}, 2);
182           endfor
183         endif 
184       else
185         dummy = df_whole(A);
186         if whole(1),
187           for indi = columns(B):-1:1,
188             resu._data{indi} = squeeze(feval(func, dummy, B(:, indi, :)));
189             resu._rep{indi} = 1:size(resu._data{indi}, 2);
190           endfor
191         else
192           if !whole(2),
193             for indi = resu._cnt(1):-1:1,
194               resu._data{indi} = squeeze(feval(func, dummy(indi, :, :), \
195                                                B(:, indi, :)));
196               resu._rep{indi} = 1:size(resu._data{indi}, 2);
197             endfor
198           else
199             for indi = resu._cnt(1):-1:1, %# in place computation
200               dummy(indi, :, :) = feval(func, dummy(indi, :, :), B);
201             endfor
202             for indi = resu._cnt(2):-1:1, %# store column-wise
203               resu._data{indi} = squeeze(dummy(:, indi, :));
204               resu._rep{indi} = 1:size(resu._data{indi}, 2);
205             endfor
206           endif
207         endif
208         %# verify that sizes match, this is required for "\"
209         resu._cnt(2) = length(resu._data);
210         resu._cnt(1) = max(cellfun('size', resu._data, 1));
211         if (length(resu._ridx) < resu._cnt(1)),
212           if (1 == length(resu._ridx)),
213             resu._ridx(end+1:resu._cnt(1), 1) = resu._ridx(1);
214           else
215             resu._ridx(end+1:resu._cnt(1), 1) = NA;
216           endif
217         endif
218         if (length(resu._name{2}) < resu._cnt(2)),
219           if (1 == length(resu._name{2})),
220             resu._name{2}(end+1:resu._cnt(2), 1) = resu._name{2};
221             resu._over{2}(end+1:resu._cnt(2), 1) = resu._over{2};
222           else
223             resu._name{2}(end+1:resu._cnt(2), 1) = '_';
224             resu._over{2}(end+1:resu._cnt(2), 1) = true;
225           endif
226         endif
227       endif
228     endif
229   endif
230
231   resu._type = cellfun(@class, resu._data, "UniformOutput", false); 
232
233   resu = df_thirddim(resu);
234
235 endfunction