]> Creatis software - CreaPhase.git/blobdiff - 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
diff --git a/octave_packages/dataframe-0.9.1/@dataframe/private/df_func.m b/octave_packages/dataframe-0.9.1/@dataframe/private/df_func.m
new file mode 100644 (file)
index 0000000..3bc91e7
--- /dev/null
@@ -0,0 +1,235 @@
+function resu = df_func(func, A, B, itercol=true, whole=logical([0 0]));
+
+  %# function resu = df_func(func, A, B, whole)
+  %# Implements an iterator to apply some func when at
+  %# least one argument is a dataframe. The output is a dataframe with
+  %# the same metadata, types may be altered, like f.i. double=>logical.
+  %# When itercol is 'true', the default, LHS is iterated by columns,
+  %# otherwise by rows. 'Whole' is a two-elements logical vector with
+  %# the meaning that LHS and or RHS must be iterated at once or not
+
+  %% Copyright (C) 2009-2012 Pascal Dupuis <Pascal.Dupuis@uclouvain.be>
+  %%
+  %% This file is part of Octave.
+  %%
+  %% Octave is free software; you can redistribute it and/or
+  %% modify it under the terms of the GNU General Public
+  %% License as published by the Free Software Foundation;
+  %% either version 2, or (at your option) any later version.
+  %%
+  %% Octave is distributed in the hope that it will be useful,
+  %% but WITHOUT ANY WARRANTY; without even the implied
+  %% warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  %% PURPOSE.  See the GNU General Public License for more
+  %% details.
+  %%
+  %% You should have received a copy of the GNU General Public
+  %% License along with Octave; see the file COPYING.  If not,
+  %% write to the Free Software Foundation, 51 Franklin Street -
+  %% Fifth Floor, Boston, MA 02110-1301, USA.
+  
+  %#
+  %# $Id: df_func.m 9585 2012-02-05 15:32:46Z cdemills $
+  %#
+
+  [A, B, resu] = df_basecomp(A, B, itercol, func);
+  itercol = itercol(1); %# drop second value
+
+  if (isa(B, 'dataframe'))
+    if (!isa(A, 'dataframe')),
+      if (isscalar(A)),
+        for indi = resu._cnt(2):-1:1,
+          switch resu._type{indi}
+            case "char"
+              resu._data{indi} = feval(func, A, char(B._data{indi}));
+            otherwise
+              resu._data{indi} = feval(func, A, B._data{indi});
+          endswitch
+        endfor
+        resu._rep = B._rep;
+      else
+        if (whole(1) && !whole(2)),
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                resu._data{indi} = feval(func, A, \
+                                         char(B._data{indi}(:, B._rep{indi})));
+              otherwise
+                resu._data{indi} = feval(func, A, \
+                                         B._data{indi}(:, B._rep{indi}));
+            endswitch
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        elseif (itercol && !whole(2)),
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                resu._data{indi} = feval(func, squeeze(A(:, indi, :)), \
+                                         char(B._data{indi}(:, B._rep{indi})));
+              otherwise
+                resu._data{indi} = feval(func, squeeze(A(:, indi, :)), \
+                                         B._data{indi}(:, B._rep{indi}));
+            endswitch
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        elseif (!whole(2)),
+          warning("no 3D yet");
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                resu._data{indi} = feval(func, A(indi, :), char(B._data{indi}));
+              otherwise
+                resu._data{indi} = feval(func, A(indi, :), B._data{indi});
+            endswitch
+          endfor
+        else
+          dummy = feval(func, A, df_whole(B));
+          for indi = resu._cnt(2):-1:1, %# store column-wise
+            resu._data{indi} = squeeze(dummy(:, indi, :));
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+            resu._type{indi} = class(dummy);
+          endfor
+        endif
+      endif
+    else
+      if (itercol),
+        for indi = resu._cnt(2):-1:1,
+          switch resu._type{indi}
+            case "char"
+              resu._data{indi} = feval\
+                  (func, char(A._data{indi}(:, A._rep{indi})), \
+                   char(B._data{indi}(B._rep{indi})));
+            otherwise
+              resu._data{indi} = feval\
+                  (func, A._data{indi}(:, A._rep{indi}), \
+                   B._data{indi}(:, B._rep{indi}));
+          endswitch
+          resu._rep{indi} = 1:size(resu._data{indi}, 2);
+        endfor
+      else %# itercol is false
+        dummy = df_whole(A);
+        if whole(1),
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                resu._data{indi} = feval(func, dummy, \
+                                         char(B._data{indi}(:, B._rep{indi})));
+              otherwise
+                resu._data{indi} = feval(func, dummy, \
+                                         B._data{indi}(:, B._rep{indi}));
+            endswitch
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        elseif (!whole(2)),
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                resu._data{indi} = squeeze\
+                    (feval(func, dummy(indi, :, :),\
+                           char(B._data{indi}(:, B._rep{indi}))));
+              otherwise
+                resu._data{indi} = squeeze\
+                     (feval(func, dummy(indi, :, :), \
+                            B._data{indi}(:, B._rep{indi})));
+            endswitch
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        else
+          dummy = feval(func, dummy, df_whole(B));
+          for indi = resu._cnt(2):-1:1, %# store column-wise
+            resu._data{indi} = squeeze(dummy(:, indi, :));
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+            resu._type{indi} = class(dummy);
+          endfor
+        endif
+      endif
+    endif  
+  else %# B is not a dataframe
+    if (isscalar(B)),
+      for indi = resu._cnt(2):-1:1,
+        switch resu._type{indi}
+          case "char"
+            resu._data{indi} = feval(func, char(A._data{indi}), B);
+          otherwise
+            resu._data{indi} = feval(func, A._data{indi}, B);
+        endswitch
+      endfor
+      resu._rep = A._rep;
+    else
+      if (itercol),
+        if (whole(2)),
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                unfolded = char(A._data{indi}(:, A._rep{indi}));
+              otherwise
+                unfolded = A._data{indi}(:, A._rep{indi});
+            endswitch
+            resu._data{indi} = squeeze(feval(func, unfolded, B));
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        else
+          for indi = resu._cnt(2):-1:1,
+            switch resu._type{indi}
+              case "char"
+                unfolded = char(A._data{indi}(:, A._rep{indi}));
+              otherwise
+                unfolded = A._data{indi}(:, A._rep{indi});
+            endswitch
+            resu._data{indi} = feval(func, unfolded, \
+                                     squeeze(B(:, indi, :)));
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        endif 
+      else
+        dummy = df_whole(A);
+        if whole(1),
+          for indi = columns(B):-1:1,
+            resu._data{indi} = squeeze(feval(func, dummy, B(:, indi, :)));
+            resu._rep{indi} = 1:size(resu._data{indi}, 2);
+          endfor
+        else
+          if !whole(2),
+            for indi = resu._cnt(1):-1:1,
+              resu._data{indi} = squeeze(feval(func, dummy(indi, :, :), \
+                                               B(:, indi, :)));
+              resu._rep{indi} = 1:size(resu._data{indi}, 2);
+            endfor
+          else
+            for indi = resu._cnt(1):-1:1, %# in place computation
+              dummy(indi, :, :) = feval(func, dummy(indi, :, :), B);
+            endfor
+            for indi = resu._cnt(2):-1:1, %# store column-wise
+              resu._data{indi} = squeeze(dummy(:, indi, :));
+              resu._rep{indi} = 1:size(resu._data{indi}, 2);
+            endfor
+          endif
+        endif
+        %# verify that sizes match, this is required for "\"
+        resu._cnt(2) = length(resu._data);
+        resu._cnt(1) = max(cellfun('size', resu._data, 1));
+        if (length(resu._ridx) < resu._cnt(1)),
+          if (1 == length(resu._ridx)),
+            resu._ridx(end+1:resu._cnt(1), 1) = resu._ridx(1);
+          else
+            resu._ridx(end+1:resu._cnt(1), 1) = NA;
+          endif
+        endif
+        if (length(resu._name{2}) < resu._cnt(2)),
+          if (1 == length(resu._name{2})),
+            resu._name{2}(end+1:resu._cnt(2), 1) = resu._name{2};
+            resu._over{2}(end+1:resu._cnt(2), 1) = resu._over{2};
+          else
+            resu._name{2}(end+1:resu._cnt(2), 1) = '_';
+            resu._over{2}(end+1:resu._cnt(2), 1) = true;
+          endif
+        endif
+      endif
+    endif
+  endif
+
+  resu._type = cellfun(@class, resu._data, "UniformOutput", false); 
+
+  resu = df_thirddim(resu);
+
+endfunction