From: <cde...@us...> - 2010-11-30 21:58:15
|
Revision: 7965 http://octave.svn.sourceforge.net/octave/?rev=7965&view=rev Author: cdemills Date: 2010-11-30 21:58:08 +0000 (Tue, 30 Nov 2010) Log Message: ----------- Mostly implemented a 3rd dim with column-compressed data Modified Paths: -------------- trunk/octave-forge/extra/dataframe/inst/@dataframe/cat.m trunk/octave-forge/extra/dataframe/inst/@dataframe/dataframe.m trunk/octave-forge/extra/dataframe/inst/@dataframe/display.m trunk/octave-forge/extra/dataframe/inst/@dataframe/end.m trunk/octave-forge/extra/dataframe/inst/@dataframe/fold.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_allmeta.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_basecomp.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_colmeta.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_func.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper2.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_pad.m trunk/octave-forge/extra/dataframe/inst/@dataframe/repmat.m trunk/octave-forge/extra/dataframe/inst/@dataframe/size.m trunk/octave-forge/extra/dataframe/inst/@dataframe/sort.m trunk/octave-forge/extra/dataframe/inst/@dataframe/subsasgn.m trunk/octave-forge/extra/dataframe/inst/@dataframe/subsref.m Added Paths: ----------- trunk/octave-forge/extra/dataframe/inst/@dataframe/ndims.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_cow.m trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_whole.m Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/cat.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/cat.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/cat.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -28,7 +28,7 @@ %# %# $Id$ %# - +disp('@dataframe/cat.m'); disp(dim) switch dim case 1 resu = A; @@ -57,17 +57,22 @@ resu._over{1} = [resu._over{1} B._over{1}]; endif resu._cnt(1) = resu._cnt(1) + B._cnt(1); - resu._ridx = [resu._ridx(:); B._ridx(:)]; + if size(resu._ridx, 2) < size(B._ridx, 2), + resu._ridx(:, end+1:size(B._ridx, 2)) = NA; + elseif size(resu._ridx, 2) > size(B._ridx, 2), + B._ridx(:, end+1:size(resu._ridx, 2)) = NA; + endif + resu._ridx = [resu._ridx; B._ridx]; %# find data with same column names dummy = A._over{2} & B._over{2}; - indA = logical(ones(1, resu._cnt(2))); - indB = logical(ones(1, resu._cnt(2))); + indA = true(1, resu._cnt(2)); + indB = true(1, resu._cnt(2)); for indj = 1:resu._cnt(2), if (dummy(indj)), - indk = strmatch(resu._name{2}(indi), B. _name{2}, 'exact'); + indk = strmatch(resu._name{2}(indj), B._name{2}, 'exact'); if (~isempty(indk)), indk = indk(1); - if ~strcmp(resu._type{indi}, B._type{indk}), + if ~strcmp(resu._type{indj}, B._type{indk}), error("Trying to mix columns of different types"); endif endif @@ -114,59 +119,75 @@ for indi = 1:length(varargin), B = varargin{indi}; - if !isa(B, 'dataframe'), - if iscell(B) && 2 == length(B), + if (!isa(B, 'dataframe')), + if (iscell(B) && 2 == length(B)), B = dataframe(B{2}, 'rownames', B{1}); else - B = dataframe(B, 'colnames', inputname(2+indi)); + B = dataframe(B, 'colnames', inputname(indi+2)); endif endif - if resu._cnt(1) != B._cnt(1), - disp('line 124 '); keyboard + if (resu._cnt(1) != B._cnt(1)), error('Different number of rows in dataframes'); endif - if resu._cnt(2) != B._cnt(2), + if (resu._cnt(2) != B._cnt(2)), error('Different number of columns in dataframes'); endif %# to be merged against 3rd dim, rownames must be equals, if %# non-empty. Columns are merged based upon their name; columns %# with identic content are kept. - resu._ridx = [resu._ridx B._ridx(:)]; + if size(resu._ridx, 2) < size(B._ridx, 2), + resu._ridx(:, end+1:size(B._ridx, 2)) = NA; + elseif size(resu._ridx, 2) > size(B._ridx, 2), + B._ridx(:, end+1:size(resu._ridx, 2)) = NA; + endif + resu._ridx = cat(3, resu._ridx, B._ridx); %# find data with same column names - indr = logical(ones(1, resu._cnt(2))); - indb = logical(ones(1, resu._cnt(2))); - indi = 1; - while indi <= resu._cnt(2), - indj = strmatch(resu._name{2}(indi), B. _name{2}, 'exact'); - if ~isempty(indj), - indj = indj(1); - if ~strcmp(resu._type{indi}, B._type{indj}), - error("Trying to mix columns of different types"); + indA = true(1, resu._cnt(2)); + indB = true(1, resu._cnt(2)); + dummy = A._over{2} & B._over{2}; + for indj = 1:resu._cnt(2), + if (dummy(indj)), + indk = strmatch(resu._name{2}(indj), B._name{2}, 'exact'); + if (~isempty(indk)), + indk = indk(1); + if (~strcmp(resu._type{indj}, B._type{indk})), + error("Trying to mix columns of different types"); + endif endif - if all([isnumeric(resu._data{indi}) isnumeric(B._data{indj})]), - try - dummy = all(abs(resu._data{indi} - B._data{indj}) <= eps); - if dummy, - %# two numeric columns with same content -- skip - indr(indi) = false; indb(indj) = false; - indi = indi+1; continue; + else + indk = indj; + endif + if (all([isnumeric(resu._data{indj}) isnumeric(B._data{indk})])), + %# iterate over the columns of resu and B + op1 = resu._data{indj}; op2 = B._data{indk}; + for ind2=1:columns(op2), + indr = false; + for ind1=1:columns(op1), + if (all(abs(op1(:, ind1) - op2(:, ind2)) <= eps)), + resu._rep{indj} = [resu._rep{indj} ind1]; + indr = true; + break; endif - catch - %# things are not substractible - end_try_catch - endif - %# pad - resu._data{indi} = [resu._data{indi} B._data{indj}]; - indr(indi) = false; indb(indj) = false; + endfor + if (!indr), + %# pad in the second dim + resu._data{indj} = [resu._data{indj}, B._data{indk}]; + resu._rep{indj} = [resu._rep{indj} 1+length(resu._rep{indj})]; + endif + endfor + else + resu._data{indj} = [resu._data{indj} B._data{indk}]; + resu._rep{indj} = [resu._rep{indj} 1+length(resu._rep({indj}))]; endif - indi = indi + 1; - endwhile - if any(indr) || any(indb) + indA(indj) = false; indB(indk) = false; + endfor + if (any(indA) || any(indB)), error('Different number/names of columns in dataframe'); endif endfor - dummy = sum(cellfun('size', resu._data, 2)); + + dummy = sum(cellfun(@length, resu._rep)); if dummy != resu._cnt(2), resu._cnt(3) = dummy; else Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/dataframe.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/dataframe.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/dataframe.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -69,8 +69,9 @@ df._name = {cell(0, 1), cell(1, 0)}; %# rows - cols df._over = cell(1, 2); df._ridx = []; - df._data = cell(0, 0); - df._type = cell(0, 0); + df._data = cell(0, 0); + df._rep = cell(0, 0); %# a repetition index + df._type = cell(0, 0); %# the type of each column df._src = cell(0, 0); df = class(df, 'dataframe'); return @@ -312,6 +313,7 @@ if !isempty(indj), idx.subs = {'', indj}; %# use direct assignement + if ndims(x) > 2, idx.subs{3} = 1:size(x, 3); endif df = subsasgn(df, idx, x); else df._cnt(2) = length(df._name{2}); Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/display.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/display.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/display.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -42,26 +42,25 @@ endif if all(df._cnt > 0), %# stop for empty df - vspace = repmat(' ', df._cnt(1), 1); + dummy=[]; vspace = repmat(' ', df._cnt(1), 1); indi = 1; %# the real, unfolded index %# loop over columns where the corresponding _data really exists for indc = 1:min(df._cnt(2), size(df._data, 2)), %# emit column names and type - if 1 == size(df._data{indc}, 2), + if 1 == length(df._rep{indc}), dummy{1, 2+indi} = deblank(disp(df._name{2}{indc})); dummy{2, 2+indi} = deblank(df._type{indc}); else %# append a dot and the third-dimension index to column name tmp_str = [deblank(disp(df._name{2}{indc})) "."]; tmp_str = arrayfun(@(x) horzcat(tmp_str, num2str(x)), ... - (1:size(df._data{indc}, 2)), 'UniformOutput', false); + (1:length(df._rep{indc})), 'UniformOutput', false); dummy{1, 2+indi} = tmp_str{1}; dummy{2, 2+indi} = deblank(df._type{indc}); - indk = 1; while indk < size(df._data{indc}, 2), - dummy{1, 2+indi+indk} = tmp_str{1+indk}; - dummy{2, 2+indi+indk} = dummy{2, 2+indi}; - indk = indk + 1; - endwhile + for indk = 2:length(tmp_str), + dummy{1, 1+indi+indk} = tmp_str{indk}; + dummy{2, 1+indi+indk} = dummy{2, 2+indi}; + endfor endif %# "print" each column switch df._type{indc} @@ -88,8 +87,9 @@ endwhile otherwise %# keep only one horizontal space per line - indk = 1; while indk <= size(df._data{indc}, 2), - dummy{3, 2+indi} = disp(df._data{indc}(:, indk)); + unfolded = df._data{indc}(:, df._rep{indc}); + indk = 1; while indk <= size(unfolded, 2), + dummy{3, 2+indi} = disp(unfolded(:, indk)); tmp_str = char(regexp(dummy{3, 2+indi}, \ '[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?(\s??[-+]\s??[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?i)?', \ 'match', 'dotexceptnewline')); @@ -105,27 +105,35 @@ %# put everything together vspace = [' '; ' '; vspace]; %# second line content - if !isempty(df._ridx), - if 1 == size(df._ridx, 2), - dummy{2, 1} = ["_"; "Nr"]; - dummy{3, 1} = disp(df._ridx(:)); - indi = regexp(dummy{3, 1}, '\b.*\b', 'match', 'dotexceptnewline'); - resu = strjust(char(dummy{2, 1}, indi), 'right'); - else - resu = []; - for indi = 1:size(df._ridx, 2)-1, - dummy{2, 1} = [["_." num2str(indi)]; "Nr"]; - dummy{3, 1} = disp(df._ridx(:, indi)); - indj = regexp(dummy{3, 1}, '\b.*\b', 'match', 'dotexceptnewline'); - resu = horzcat(resu, strjust(char(dummy{2, 1}, indj), 'right'), vspace); - endfor - dummy{2, 1} = [["_." num2str(indi+1)]; "Nr"]; - dummy{3, 1} = disp(df._ridx(:, end)); - indj = regexp(dummy{3, 1}, '\b.*\b', 'match', 'dotexceptnewline'); - resu = horzcat(resu, strjust(char(dummy{2, 1}, indj), 'right')); - endif - else - resu = []; + resu = []; + if (!isempty(df._ridx)), + for ind1 = 1:size(df._ridx, 2), + if (1 == size(df._ridx, 3)) && (any(!isna(df._ridx(:, ind1)))), + dummy{2, 1} = [sprintf("_%d", ind1) ; "Nr"]; + dummy{3, 1} = disp(df._ridx(:, ind1)); + indi = regexp(dummy{3, 1}, '\b.*\b', 'match', 'dotexceptnewline'); + if isempty(resu), + resu = strjust(char(dummy{2, 1}, indi), 'right'); + else + resu = horzcat(resu, vspace, strjust(char(dummy{2, 1}, indi), \ + 'right'), vspace); + endif + else + for ind2 = 1:size(df._ridx, 3), + if (any(!isna(df._ridx(:, ind1, ind2)))), + dummy{2, 1} = [sprintf("_%d.%d", ind1, ind2) ; "Nr"]; + dummy{3, 1} = disp(df._ridx(:, ind1, ind2)); + indi = regexp(dummy{3, 1}, '\b.*\b', 'match', 'dotexceptnewline'); + if isempty(resu), + resu = strjust(char(dummy{2, 1}, indi), 'right'); + else + resu = horzcat(resu, vspace, strjust(char(dummy{2, 1}, indi), \ + 'right'), vspace); + endif + endif + endfor + endif + endfor endif %# emit row names @@ -140,17 +148,17 @@ if !isempty(dummy{3, 2}), indi = ~cellfun('isempty', dummy{3, 2}); if any(indi), - resu = horzcat(resu, vspace); - resu = horzcat(resu, strjust(char(dummy{2, 2}, dummy{3,2}), 'right')); + resu = horzcat(resu, vspace, strjust(char(dummy{2, 2}, dummy{3, 2}),\ + 'right')); endif endif %# emit each colum - for indi = 1: size(dummy, 2) - 2, + for indi = 1:size(dummy, 2) - 2, %# was max(df._cnt(2:end)), try %# avoid this column touching the previous one - if any(cellfun('size', dummy(1:2, 2+indi), 2) >= ... + if any(cellfun('size', dummy(1:2, 2+indi), 2) >= \ size(dummy{3, 2+indi}, 2)), resu = horzcat(resu, vspace); endif @@ -158,6 +166,7 @@ catch tmp_str = sprintf("Emitting %d lines, expecting %d", ... size(dummy{3, 2+indi}, 1), df._cnt(1)); + keyboard error(tmp_str); end_try_catch endfor Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/end.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/end.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/end.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -31,7 +31,7 @@ if k < 3, resu = df._cnt(k); else - resu = max(cellfun('size', df._data, 2)); + resu = max(cellfun(@length, df._rep)); endif catch error("incorrect call to end, index greater than number of dimensions"); Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/fold.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/fold.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/fold.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -35,7 +35,7 @@ [indr, nrow] = df_name2idx(df._name{1}, indr, df._cnt(1), 'row'); [indc, ncol] = df_name2idx(df._name{2}, indc, df._cnt(2), 'column'); - if indr(1) > 1, + if (indr(1) > 1), slice_size = indr(1) - 1; %# we can't use directly resu = df(1:slice_size, :, :) S.type = '()'; @@ -43,10 +43,10 @@ resu = subsref(df, S); %# how many columns for each slice - targets = cellfun('size', df._data, 2); + targets = cellfun(@length, df._rep); %# a test function to determine if the location is free for indj = 1:df._cnt(2), - if any(indj == indc), + if (any(indj == indc)), continue; endif switch df._type{indj} @@ -63,19 +63,20 @@ %# where does this line go ? where = find(df._data{indc}(1:slice_size, 1) ... == df._data{indc}(indi, 1)); - if !isempty(where), + if (!isempty(where)), %# transfering one line -- loop over columns for indj = 1:df._cnt(2), if any(indj == indc), continue; endif - if testfunc{indj}(resu._data{indj}, where, targets(indj)) + if (testfunc{indj}(resu._data{indj}, where, targets(indj))), %# add one more sheet resu = df_pad(resu, 3, 1, indj); targets(indj) = targets(indj) + 1; endif %# transfer field + stop resu._data{indj}(where, targets(indj)) = ... df._data{indj}(indi, 1); endfor Added: trunk/octave-forge/extra/dataframe/inst/@dataframe/ndims.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/ndims.m (rev 0) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/ndims.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -0,0 +1,12 @@ +function resu = ndims(df) + %# -*- texinfo -*- + %# @deftypefn {Function File} ndims(@var{df}) + %# overloaded function implementing ndims for a dataframe + %# @end deftypefn + + resu = 2; + nseq = max(cellfun(@length, df._rep)); + + if nseq > 1, resu = 3; endif + +endfunction Property changes on: trunk/octave-forge/extra/dataframe/inst/@dataframe/ndims.m ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_allmeta.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_allmeta.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_allmeta.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -1,7 +1,7 @@ function resu = df_allmeta(df, dim = []) %# function resu = df_allmeta(df) - %# Returns a new dataframe, initalised with the allthe + %# Returns a new dataframe, initalised with the all the %# meta-information but with empty data %% Copyright (C) 2009-2010 Pascal Dupuis <Pas...@uc...> @@ -30,7 +30,11 @@ resu = dataframe([]); - if isempty(dim), dim = df._cnt(1:2); endif + if (isempty(dim)), + dim = df._cnt(1:2); + else + dim = dim(1:2); %# ignore third dim, if any + endif resu._cnt(1:2) = min(dim, df._cnt(1:2)); if (!isempty(df._name{1})), @@ -42,11 +46,16 @@ resu._over{2} = df._over{2}(1:resu._cnt(2)); endif if (!isempty(df._ridx)), - resu._ridx = df._ridx(1:resu._cnt(1)); + if (size(df._ridx, 2) >= resu._cnt(2)), + resu._ridx = df._ridx(1:resu._cnt(1), :, :); + else + resu._ridx = df._ridx(1:resu._cnt(1), 1, :); + endif endif - resu._type = df._type(1:resu._cnt(2)); %# init it with the right orientation resu._data = cell(size(df._data)); + resu._rep = cell(size(df._rep)); + resu._type = df._type(1:resu._cnt(2)); resu._src = df._src; endfunction Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_basecomp.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_basecomp.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_basecomp.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -58,7 +58,7 @@ if (isscalar(A)), Csize = size(B); else - if (size(A, 1) != size(B, 1)), + if (size(A, 1) != size(B, 1)), error("Non compatible row sizes (op1 is %dx%d, op2 is %dx%d)",\ size(A), size(B)); endif @@ -77,6 +77,7 @@ if (!isempty(A._ridx)) if (!isempty(B._ridx) && itercol), if (any(A._ridx-B._ridx)), + keyboard error("Non compatible indexes"); endif endif Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_colmeta.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_colmeta.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_colmeta.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -36,6 +36,7 @@ resu._type = df._type; %# init it with the right orientation resu._data = cell(size(df._data)); + resu._rep = cell(size(df._rep)); resu._src = df._src; endfunction Added: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_cow.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_cow.m (rev 0) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_cow.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -0,0 +1,62 @@ +function [df, S] = df_cow(df, S, col, inds) + + %# function [resu, S] = df_cow(df, S, col, inds) + %# Implements Copy-On-Write on dataframe. If one or more columns + %# specified in inds is aliased to another one, duplicate it and + %# adjust the repetition index to remove the aliasing + + %% Copyright (C) 2009-2010 Pascal Dupuis <Pas...@uc...> + %% + %% 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, 59 Temple Place - + %% Suite 330, Boston, MA 02111-1307, USA. + + %# + %# $Id$ + %# + + if length(col) > 1, + error("df_cow must work on a column-by-column basis"); + endif + + if isempty(inds), inds = 1; endif + + for indi = inds, + dummy = df._rep{col}; dummy(indi)=[]; + [t1, t2] = ismember(df._rep{col}(indi)(:), dummy); + for indj = t2(find(t2)), %# Copy-On-Write + %# determines the index for the next column + t1 = 1+max(df._rep{col}); + %# update repetition index aliasing this one + df._rep{col}(find(df._rep{col} == indj)(2:end)) = t1; + %# duplicate the touched column + df._data{col} = horzcat(df._data{col}, df._data{col}(:, indj)); + if (length(S.subs) > 1), + %# adapt the sheet index accordingly + indk = find(S.subs{2} == indj); + S.subs{2}(indk(2:end)) = t1; + endif + endfor + endfor + + %# sanity check + dummy = sum(cellfun(@length, df._rep)); + if dummy != df._cnt(2), + df._cnt(3) = dummy; + endif + +endfunction Property changes on: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_cow.m ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_func.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_func.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_func.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -33,7 +33,8 @@ %# [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)), @@ -45,26 +46,34 @@ 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})); + resu._data{indi} = feval(func, A, \ + char(B._data{indi}(:, B._rep{indi}))); otherwise - resu._data{indi} = feval(func, A, B._data{indi}); + 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, A(:, indi), char(B._data{indi})); + resu._data{indi} = feval(func, A(:, indi, :), \ + char(B._data{indi}(:, B._rep{indi}))); otherwise - resu._data{indi} = feval(func, A(:, indi), B._data{indi}); + resu._data{indi} = feval(func, 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" @@ -74,9 +83,10 @@ endswitch endfor else - dummy = feval(func, A, horzcat(B._data {:})); + dummy = feval(func, A, df_whole(B)); for indi = resu._cnt(2):-1:1, %# store column-wise - resu._data{indi} = dummy(:, indi); + resu._data{indi} = squeeze(dummy(:, indi, :)); + resu._rep{indi} = 1:size(resu._data{indi}, 2); resu._type{indi} = class(dummy); endfor endif @@ -86,35 +96,49 @@ for indi = resu._cnt(2):-1:1, switch resu._type{indi} case "char" - resu._data{indi} = feval(func, char(A._data{indi}), char(B._data{indi})); + 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}, B._data{indi}); + 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 - dummy = horzcat(A._data {:}); + 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})); + resu._data{indi} = feval(func, dummy, \ + char(B._data{indi}(:, B._rep{indi}))); otherwise - resu._data{indi} = feval(func, dummy, B._data{indi}); + 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} = feval(func, dummy(indi, :), char(B._data{indi})); + resu._data{indi} = squeeze\ + (feval(func, dummy(indi, :, :),\ + char(B._data{indi}(:, B._rep{indi})))); otherwise - resu._data{indi} = feval(func, dummy(indi, :), B._data{indi}); + 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, horzcat(B._data{:})); + dummy = feval(func, dummy, df_whole(B)); for indi = resu._cnt(2):-1:1, %# store column-wise - resu._data{indi} = dummy(:, indi); + resu._data{indi} = squeeze(dummy(:, indi, :)); + resu._rep{indi} = 1:size(resu._data{indi}, 2); resu._type{indi} = class(dummy); endfor endif @@ -130,45 +154,54 @@ 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" - resu._data{indi} = feval(func, char(A._data{indi}), B); + unfolded = char(A._data{indi}(:, A._rep{indi})); otherwise - resu._data{indi} = feval(func, A._data{indi}, B); + 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" - resu._data{indi} = feval(func, char(A._data{indi}), \ - B(:, indi)); + unfolded = char(A._data{indi}(:, A._rep{indi})); otherwise - resu._data{indi} = feval(func, A._data{indi}, B(:, indi)); + unfolded = A._data{indi}(:, A._rep{indi}); endswitch + resu._data{indi} = squeeze(feval(func, unfolded, \ + B(:, indi, :))); + resu._rep{indi} = 1:size(resu._data{indi}, 2); endfor - endif + endif else - dummy = horzcat(A._data {:}); + dummy = df_whole(A); if whole(1), for indi = columns(B):-1:1, - resu._data{indi} = feval(func, dummy, B(:, indi)); + 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} = feval(func, dummy(indi, :), B(:, indi)); + 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); + dummy(indi, :, :) = feval(func, dummy(indi, :, :), B); endfor for indi = resu._cnt(2):-1:1, %# store column-wise - resu._data{indi} = dummy(:, indi); + resu._data{indi} = squeeze(dummy(:, indi, :)); + resu._rep{indi} = 1:size(resu._data{indi}, 2); endfor endif endif @@ -197,7 +230,7 @@ resu._type = cellfun(@class, resu._data, "UniformOutput", false); %# sanity check - dummy = sum(cellfun('size', resu._data, 2)); + dummy = sum(cellfun(@length, resu._rep)); if dummy != resu._cnt(2), resu._cnt(3) = dummy; endif Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -27,11 +27,13 @@ %# resu = df_allmeta(df); - resu._data = cellfun(@(x) feval(func, x, varargin{:}), df._data, "UniformOutput", false); + resu._data = cellfun(@(x) feval(func, x, varargin{:}), df._data, \ + "UniformOutput", false); + resu._rep = df._rep; %# things didn't change resu._type = cellfun(@(x) class(x(1)), resu._data, "UniformOutput", false); %# sanity check - dummy = sum(cellfun('size', resu._data, 2)); + dummy = sum(cellfun(@length, resu._rep)); if dummy != resu._cnt(2), resu._cnt(3) = dummy; endif Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper2.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper2.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_mapper2.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -39,9 +39,12 @@ switch(dim) case {1}, resu = df_colmeta(df); - resu._data = cellfun(@(x) feval(func, x, vout{:}), df._data, \ - "UniformOutput", false); - resu._cnt(1) = max(cellfun('size', resu._data, 2)); + for indi = 1:df._cnt(2), + resu._data{indi} = feval(func, df._data{indi}(:, df._rep{indi}), \ + vout{:}); + resu._rep{indi} = 1:size(resu._data{indi}, 2); + endfor + resu._cnt(1) = max(cellfun('size', resu._data, 1)); if (resu._cnt(1) == df._cnt(1)), %# the func was not contracting resu._ridx = df._ridx; @@ -50,15 +53,18 @@ case {2}, error('Operation not implemented'); case {3}, - resu = df_allmeta(df); - resu._data = cellfun(@(x) feval(func, x, vout{:}), df._data, \ - "UniformOutput", false); + resu = df_allmeta(df); + for indi = 1:df._cnt(2), + resu._data{indi} = feval(func, df._data{indi}(:, df._rep{indi}), \ + vout{:}); + resu._rep{indi} = 1:size(resu._data{indi}, 2); + endfor otherwise error("Invalid dimension %d", dim); endswitch %# sanity check - dummy = sum(cellfun('size', resu._data, 2)); + dummy = sum(cellfun(@length, resu._rep)); if dummy != resu._cnt(2), resu._cnt(3) = dummy; endif Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_pad.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_pad.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_pad.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -49,7 +49,7 @@ df._ridx = dummy; %# pad every line for indi = 1:min(size(df._data, 2), df._cnt(2)), - neff = n - size(df._data{indi}, 1); + neff = n + df._cnt(1) - size(df._data{indi}, 1); if neff > 0, m = size(df._data{indi}, 2); switch df._type{indi} @@ -85,7 +85,9 @@ df._type(n+(indc+1:end)) = df._type(indc+1:end); df._type(indc + (1:n)) = NA; df._data(n + (indc+1:end)) = df._data(indc+1:end); + df._rep(n + (indc+1:end)) = df._rep(indc+1:end); df._data(indc + (1:n)) = NA; + df._rep(indc + (1:n)) = 1; endif else %# add new values after the last column @@ -106,6 +108,7 @@ dummy = cast(repmat(NA, df._cnt(1), 1), coltype{indi}); endswitch df._data{indc+indi} = dummy; + df._rep{indc+indi} = 1; df._type{indc+indi} = coltype{indi}; endfor @@ -118,14 +121,14 @@ strjust(num2str(indc + (1:n).'), 'left')); df._name{2}(indc + (1:n)) = cellstr(dummy); df._over{2}(1, indc + (1:n)) = true; - endif - + endif case 3 - if isempty(coltype), + if (n <= 0), return; endif + if (isempty(coltype)), coltype = 1:df._cnt(2); endif - dummy = max(n+cellfun('size', df._data(coltype), 2)); + dummy = max(n+cellfun(@length, df._rep(coltype))); if size(df._ridx, 2) < dummy, df._ridx(:, end+1:dummy) = NA; endif @@ -133,19 +136,23 @@ switch df._type{indi} case {'char'} if isa(df._data{indi}, 'char'), - dummy = horzcat(df._data{indi}, {repmat(NA, df._cnt(1), n)}); + dummy = horzcat(df._data{indi}(:, df._rep{indi}), \ + {repmat(NA, df._cnt(1), 1)}); else dummy = df._data{indi}; endif case { 'double' } - dummy = horzcat(df._data{indi}, repmat(NA, df._cnt(1), n)); + dummy = horzcat(df._data{indi}(:, df._rep{indi}), \ + repmat(NA, df._cnt(1), 1)); otherwise - dummy = cast(horzcat(df._data{indi}, repmat(NA, df._cnt(1), n)), ... + dummy = cast(horizcat(df._data{indi}(:, df._rep{indi}), \ + repmat(NA, df._cnt(1), 1)), \ df._type{indi}); endswitch df._data{indi} = dummy; + df._rep{indi} = [df._rep{indi} length(df._rep{indi})+ones(1, n)]; endfor - df._cnt(3) = sum(cellfun('size', df._data, 2)); + df._cnt(3) = sum(cellfun(@length, df._rep)); otherwise error('Invalid dimension in df_pad'); endswitch Added: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_whole.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_whole.m (rev 0) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_whole.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -0,0 +1,54 @@ +function resu = df_whole(df); + + %# function resu = df_whole(df) + %# Generate a full matrix from a column-compressed version of a dataframe. + + %% Copyright (C) 2009-2010 Pascal Dupuis <Pas...@uc...> + %% + %% 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, 59 Temple Place - + %% Suite 330, Boston, MA 02111-1307, USA. + + %# + %# $Id$ + %# + + inds = max(cellfun(@length, df._rep)); + + resu = df._data{1}(:, df._rep{1}); + if (inds > 1), + resu = reshape(resu, df._cnt(1), 1, []); + if (1 == size(resu, 3)), + resu = repmat(resu, [1 1 inds]); + endif + endif + + if df._cnt(2) > 1, + resu = repmat(resu, [1 df._cnt(2)]); + for indi = 2:df._cnt(2), + dummy = df._data{indi}(:, df._rep{indi}); + if (inds > 1), + dummy = reshape(dummy, df._cnt(1), 1, []); + if (1 == size(dummy, 3)), + dummy = repmat(dummy, [1 1 inds]); + endif + endif + resu(:, indi, :) = dummy; + endfor + endif + +endfunction Property changes on: trunk/octave-forge/extra/dataframe/inst/@dataframe/private/df_whole.m ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/repmat.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/repmat.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/repmat.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -32,9 +32,9 @@ else dummy(2) = 1; endif - %# operate on first and third dim first - if (idx(1) > 1 || length(idx) > 2) - resu = df_mapper(@repmat, df, dummy); + %# operate on first dim + if (idx(1) > 1), + resu = df_mapper(@repmat, df, [idx(1) 1]); if (!isempty(df._name{1})), resu._name{1} = feval(@repmat, df._name{1}, [idx(1) 1]); resu._over{1} = feval(@repmat, df._over{1}, [idx(1) 1]); @@ -42,8 +42,14 @@ resu._cnt(1) = resu._cnt(1) * idx(1); endif + if (dummy(2) > 1), + for indi = 1:resu._cnt(2), + resu._rep{indi} = feval(@repmat, resu._rep{indi}, [1 dummy(2)]); + endfor + endif + %# operate on ridx - resu._ridx = feval(@repmat, resu._ridx, dummy); + resu._ridx = feval(@repmat, resu._ridx, idx); %# operate on second dim if (length(idx) > 1 && idx(2) > 1), @@ -55,7 +61,7 @@ endif if (any([length(resu._cnt) length(idx)] > 2)), - resu._cnt(3) = sum(cellfun('size', resu._data, 2)); + resu._cnt(3) = sum(cellfun(@length, resu._rep)); endif endfunction Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/size.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/size.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/size.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -29,10 +29,22 @@ switch nargin case 1 switch nargout - case {0 1} + case {0, 1} varargout{1} = df._cnt; case {2} - varargout{1} = df._cnt(1); varargout{2} = df._cnt(2); + varargout{1} = df._cnt(1); + if (1 == df._cnt(2) && length(df._cnt) > 2), + varargout{2} = df._cnt(3); + else + varargout{2} = df._cnt(2); + endif + case {3} + varargout{1:2} = df._cnt(1:2); + if 2==length(df._cnt), + varargout{3} = 1; + else + varargout{3} = df._cnt(3); + endif otherwise error(print_usage()); endswitch @@ -48,6 +60,22 @@ otherwise error(print_usage()); endswitch + case 3 + switch nargout + case {0 1} + if (length(df._cnt) < 3), + varargout{1} = 1; + else + varargout{1} = df._cnt; + endif + try + varargout{1} = varargout{1}(varargin{1}); + catch + error(print_usage()); + end_try_catch + otherwise + error(print_usage()); + endswitch otherwise error(print_usage()); endswitch Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/sort.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/sort.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/sort.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -112,15 +112,19 @@ switch(dim) case {1}, for indi = 1:resu._cnt(2), - [resu._data{1, indi}, idx(:, indi)] = sort(resu._data{1, indi}, varargin{:}); + [resu._data{indi}, idx(:, indi, :)] = sort\ + (resu._data{indi}(:, resu._rep{indi}), varargin{:}); + resu._data{indi} = squeeze(resu._data{indi}); + resu._rep{indi} = 1:size(resu._data{indi}, 2); endfor - if 1 == size(idx, 2), + if all([1 == size(idx, 2) 1 == size(idx, 3)]), resu._ridx = resu._ridx(idx, :); resu._name{1, 1} = resu._name{1, 1}(idx); resu._over{1, 1} = resu._over{1, 1}(idx); else %# data where mixed - resu._ridx = idx; resu._name{1, 1} = []; resu._over{1, 1} = []; + resu._ridx = idx; + resu._name{1, 1} = []; resu._over{1, 1} = []; endif case {2}, Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/subsasgn.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/subsasgn.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/subsasgn.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -154,8 +154,14 @@ if strcmp(S.subs(1), ':'), %# removing column/matrix RHS = S; RHS.subs(2) = []; - df._data(indc) = cellfun(@(x) feval(@subsasgn, x, RHS, []), - df._data(indc), "UniformOutput", false); + for indi = indc, + unfolded = df._data{indi}(:, df._rep{indi}); + unfolded = feval(@subsasgn, unfolded, RHS, []); + df._data{indi} = unfolded; + if (!isempty(unfolded)), + df._rep(indi) = 1:size(unfolded, 2); + endif + endfor %# remove empty elements indi = cellfun('isempty', df._data); if any(indi), %# nothing left, remove this column @@ -165,6 +171,7 @@ df._over{2} = df._over{2}(indi); df._type = df._type(indi); df._data = df._data(indi); + df._rep = df._rep(indi); endif endif if strcmp(S.subs(2), ':'), %# removing rows @@ -183,7 +190,8 @@ df._cnt(1) = df._cnt(1) - length(indr); endif endif - dummy = sum(cellfun('size', df._data, 2)); + %# ici + dummy = sum(cellfun(@length, df._rep)); if dummy != df._cnt(2), df._cnt(3) = dummy; else @@ -196,6 +204,7 @@ if ~indc_was_set, %# initial dataframe was empty ncol = size(RHS, 2); indc = 1:ncol; endif + indr = S.subs{1, 1}; indr_was_set = ~isempty(indr); %# initial dataframe was empty ? @@ -218,6 +227,12 @@ elseif !isempty(indr) && isnumeric(indr), nrow = length(indr); endif + if (length(S.subs) > 2), + inds = S.subs{1, 3}; + else + inds = []; + endif + rname = cell(0, 0); rname_width = max(1, size(df._name{2}, 2)); ridx = []; cname = rname; ctype = rname; @@ -407,6 +422,7 @@ endif else %# partial assignement -- extract actual data and update + keyboard dummy = df._data{indc(indi)}; try switch df._type{indc(indi)} @@ -424,42 +440,56 @@ error(dummy); end_try_catch endif - df._data{indc(indi)} = dummy; indj = indj + 1; + df._data{indc(indi)} = dummy; df._rep{indc(indi)} = 1:size(dummy, 2); + indj = indj + 1; endfor else %# RHS is either a numeric, either a df - if any(indc > min(size(df._data, 2), df._cnt(2))), + if (any(indc > min(size(df._data, 2), df._cnt(2)))), df = df_pad(df, 2, max(indc-min(size(df._data, 2), df._cnt(2))),\ class(RHS)); endif - if isa(RHS, 'dataframe'), + if (!isempty(inds) && any(inds > 1)), + for indi=1:length(indc), + if (max(inds) > length(df._rep{indc(indi)})), + df = df_pad(df, 3, max(inds)-length(df._rep{indc(indi)}), \ + indc(indi)); + endif + endfor + endif + + if (isa(RHS, 'dataframe')), + %# block-copy index + S.subs(2) = 1; + df._ridx = feval(@subsasgn, df._ridx, S, RHS._ridx); + %# skip second dim and copy data + S.subs(2) = []; for indi = 1:length(indc), - if 1 == size(RHS._data{indi}, 2), - if strcmp(df._type(indc(indi)), \ - RHS._type(indi)), + if (1 == length(RHS._rep{indi})), + df = df_cow(df, S, indc(indi), inds); + if (strcmp(df._type(indc(indi)), \ + RHS._type(indi))), df._data{indc(indi)}(indr, 1) = RHS._data{indi}; else df._data{indc(indi)}(indr, 1) = cast(RHS._data{indi}, \ df._type(indc(indi))); endif else - dummy = 1:size(RHS._data{indi}, 2); - if strcmp(df._type(indc(indi)), RHS._type(indi)), - df._data{indc(indi)}(indr, dummy) = RHS._data{indi}; + unfolded = df._data{indc(indi)}(:, df._rep{indc(indi)}); + if (strcmp(df._type(indc(indi)), RHS._type(indi))), + truc = RHS._data{indi}(:, RHS._rep{indi}); + unfolded = feval(@subsasgn, unfolded, S, \ + RHS._data{indi}(:, RHS._rep{indi})); else - df._data{indc(indi)}(indr, dummy) = cast(RHS._data{indi}, \ - df._type(indc(indi))); + unfolded = feval(@subsasgn, unfolded, S, \ + cast(RHS._data{indi}(:, RHS._rep{indi}), \ + df._type(indc(indi)))); endif + df._data{indc(indi)} = unfolded; + df._rep{indc(indi)} = 1:size(unfolded, 2); endif endfor - if (1 == size(RHS._ridx, 2)) - df._ridx(indr, :) = NA; - df._ridx(indr, 1) = RHS._ridx; - else - dummy = 1:size(RHS._ridx, 2); - df._ridx(indr, dummy) = RHS._ridx; - endif if (!isempty(RHS._name{1})), df._name{1}(indr) = RHS._name{1}(indr); df._over{1}(indr) = RHS._over{1}(indr); @@ -478,19 +508,24 @@ else %# ignore 'column' dimension -- force colum vectors -- use a %# third dim just in case - if isempty(S.subs{1}), S.subs{1} = ':'; endif + if (isempty(S.subs{1})), S.subs{1} = ':'; endif S.subs(2) = []; - if length(S.subs) < 2, S.subs{2} = 1; endif - if length(indc) > 1 && length(RHS) > 1, + if (length(S.subs) < 2), + S.subs{2} = 1; + endif + if (length(indc) > 1 && length(RHS) > 1), %# set a row from a vector - fillfunc = @(x, y) feval(@subsasgn, x, S, RHS(y)); + fillfunc = @(x, S, y) feval(@subsasgn, x, S, RHS(y)); else - fillfunc = @(x, y) feval(@subsasgn, x, S, RHS); + fillfunc = @(x, S, y) feval(@subsasgn, x, S, RHS); endif endif + Sorig = S; for indi = 1:length(indc), try - df._data{indc(indi)} = fillfunc(df._data{indc(indi)}, indi); + [df, S] = df_cow(df, S, indc(indi), inds); + df._data{indc(indi)} = fillfunc(df._data{indc(indi)}, S, indi); + S = Sorig; catch disp('line 470 '); keyboard end_try_catch @@ -508,14 +543,16 @@ else %# 2D - 3D matrix S.subs(2) = []; %# ignore 'column' dimension %# rotate slices in dim 1-3 to slices in dim 1-2 - if isempty(S.subs{1}), - fillfunc = @(x, y) squeeze(RHS(:, y, :)); + if (isempty(S.subs{1})), + fillfunc = @(x, S, y) squeeze(RHS(:, y, :)); else - fillfunc = @(x, y) feval(@subsasgn, x, S, squeeze(RHS(:, y, :))); + fillfunc = @(x, S, y) feval(@subsasgn, x, S, squeeze(RHS(:, y, :))); endif + Sorig = S; for indi = 1:length(indc), - %# disp('line 454 '); keyboard - df._data{indc(indi)} = fillfunc(df._data{indc(indi)}, indi); + [df, S] = df_cow(df, S, indc(indi), inds); + df._data{indc(indi)} = fillfunc(df._data{indc(indi)}, S, indi); + S = Sorig; endfor endif if indi < size(RHS, 2) && !isa(RHS, 'char'), @@ -528,6 +565,7 @@ if !isempty(indr) && isnumeric(indr), if max(indr) > df._cnt(1) && size(df._data, 2) < df._cnt(2), df = df_pad(df, 1, max(indr)-df._cnt(1), rname_width); + keyboard endif endif @@ -558,7 +596,7 @@ endif %# adjust cnt(3) if required - dummy = sum(cellfun('size', df._data, 2)); + dummy = sum(cellfun(@length, df._rep)); if (dummy > df._cnt(2)) || length(df._cnt) > 2, df._cnt(3) = dummy; endif Modified: trunk/octave-forge/extra/dataframe/inst/@dataframe/subsref.m =================================================================== --- trunk/octave-forge/extra/dataframe/inst/@dataframe/subsref.m 2010-11-30 17:22:36 UTC (rev 7964) +++ trunk/octave-forge/extra/dataframe/inst/@dataframe/subsref.m 2010-11-30 21:58:08 UTC (rev 7965) @@ -55,7 +55,7 @@ indi = strmatch(S(1).subs, char('df', class(df))); if (~isempty(indi)), %# requiring a dataframe - if 1 == indi, %# 'df' = short for 'dataframe' + if (1 == indi), %# 'df' = short for 'dataframe' asked_output_type = 'dataframe'; else asked_output_type = S(1).subs; @@ -300,18 +300,18 @@ inds = 1; indt(1, 1:df._cnt(2)) = inds; nseq = 1; if (isempty(S) || all(cellfun('isclass', S(1).subs, 'char'))) inds = ':'; indt(1, 1:df._cnt(2)) = inds; - nseq = max(cellfun('size', df._data(indc), 2)); + nseq = max(cellfun(@length, df._rep(indc))); else if (length(S(1).subs) > 1), %# access-as-matrix if (length(S(1).subs) > 2), inds = S(1).subs{3}; - if isa(inds, 'char'), - nseq = max(cellfun('size', df._data(indc), 2)); + if (isa(inds, 'char')), + nseq = max(cellfun(@length, df._rep(indc))); indt(1, 1:df._cnt(2)) = inds; else %# generate a specific index for each column nseq = length(inds); - dummy = cellfun('size', df._data(indc), 2); + dummy = cellfun(@length, df._rep(indc)); indt(1, 1:df._cnt(2)) = inds; indt(1==dummy) = 1; endif @@ -327,10 +327,12 @@ for indi = 1:ncol, resu._data{indi} = df._data{indc(indi)}\ (indr, indt{indc(indi)}); + resu._rep{indi} = df._rep{indc(indi)}(indt{indc(indi)}); resu._name{2}(indi, 1) = df._name{2}(indc(indi)); resu._over{2}(1, indi) = df._over{2}(indc(indi)); resu._type{indi} = df._type{indc(indi)}; endfor + %# to be verified : keyboard if (!isempty(df._ridx) && size(df._ridx, 2) >= inds), resu._ridx = df._ridx(indr, inds); endif @@ -339,7 +341,7 @@ resu._over{1}(1, 1:nrow) = df._over{1}(indr); endif resu._src = df._src; - dummy = sum(cellfun('size', resu._data, 2)); + dummy = sum(cellfun(@length, resu._rep)); if (dummy > resu._cnt(2)), resu._cnt(3) = dummy; else @@ -456,56 +458,54 @@ df = struct(df); if (~isempty(asked_output_format)), %# force a conversion if (strmatch(asked_output_format, 'cell')), - extractfunc = @(x) mat2cell(df._data{indc(x)}, \ - ones(df._cnt(1), 1)); + extractfunc = @(x) mat2cell\ + (df._data{indc(x)}(indr, df._rep{indc(x)}(inds)), \ + ones(nrow, 1)); else - extractfunc = @(x) cast(df._data{indc(x)}, asked_output_format); + extractfunc = @(x) cast(df._data{indc(x)}\ + (indr, df._rep{indc(x)}(inds)),\ + asked_output_format); endif else %# let the usual downclassing occur - extractfunc = @(x) df._data{indc(x)}; + extractfunc = @(x) df._data{indc(x)}(indr, df._rep{indc(x)}(inds)); endif try - dummy = extractfunc(1); + if (nseq > 1), + dummy = reshape(extractfunc(1), nrow, 1, []); + if (size(dummy, 3) < nseq), + dummy = repmat(dummy, [1 1 nseq]); + endif + else + dummy = extractfunc(1); + endif catch error("Column %d format (%s) can't be converted to %s", \ indc(1), df._type{indc(1)}, asked_output_format); end_try_catch if (ncol > 1), %# dynamic allocation with the final type - if (size(dummy, 2) > 1), - resu = repmat(dummy(indr, inds(1)), [1 ncol nseq]); - %# "turn" the extracted matrix - resu(:, 1, :) = dummy(indr, inds); - else - resu = repmat(dummy(indr(:)), [1 ncol nseq]); - endif + resu = repmat(dummy, [1 ncol]); for indi = 2:ncol, try - dummy = extractfunc(indi); + if (nseq > 1), + dummy = reshape(extractfunc(indi), nrow, 1, []); + if (size(dummy, 3) < nseq), + dummy = repmat(dummy, [1 1 nseq]); + endif + else + dummy = extractfunc(indi); + endif catch error("Column %d format (%s) can't be converted to %s", \ indc(indi), df._type{indc(indi)}, asked_output_format); end_try_catch - if (1 == size(dummy, 2)), - try - if (1 == nseq), - resu(:, indi) = dummy(indr)(:); - else - resu(:, indi, :) = repmat(dummy(indr), [1 1 nseq]); - endif - catch - disp('line 458 '); keyboard - end_try_catch - else - %# "turn" the extracted matrix - resu(:, indi, :) = dummy(indr, inds); - endif + resu(:, indi, :) = dummy; endfor else if (strcmp(df._type{indc(1)}, 'char')), - resu = char(dummy(indr, inds)); + resu = char(dummy); else - resu = dummy(indr, inds); + resu = dummy; endif endif if (!isempty(S) && 2 == length(S(1).subs) \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |