Thursday, November 28, 2013

Merging or joining cell arrays in matlab.

Array operators in Matlab...I cannot figure them out with cells. You get all sorts of funny behavior. What I wanted to do was JOIN two cell structures, so if you had: x.a=1, x.b=2, and then y.c='dogfish', you could get z.a=1, z.b=2, z.c='dogfish'. I tried about everything, but this is what I ended up with:
function result=merge_cells(p_cells1, p_cells2)
    a_names =fieldnames(p_cells1);
    for i=1:length(a_names)
        str_fieldname=a_names{i};
        str_fieldval =  p_cells1.(genvarname(str_fieldname));
        data.(genvarname(str_fieldname)) = str_fieldval;
    end
    a_names =fieldnames(p_cells2);
    for i=1:length(a_names)
        str_fieldname=a_names{i};
        str_fieldval =  p_cells2.(genvarname(str_fieldname));
        data.(genvarname(str_fieldname)) = str_fieldval;
    end
    
   result =data;
end
I dynamically make cells by reading Excel XLS files, and then I merge the sheets with this function, and then I export them back to XLS.

Saturday, November 23, 2013

Read a row of an Excel CSV file in Matlab

The only issue with CSV files in matlab is that they sometimes have commas between quotes. I wrote this function that parses the CSV file into an array of cells, but leaves the text with commas. It also figures which entries are numbers and converts those.
function result=xlscsvlineparse(p_line)
%the p_line is just a character array, we loop to find the beginning and
%end of the commas unless there are quotes around them.
    i_comma=1;
    i_counter=0;
    i_linelength=length(p_line);
    for i=1:i_linelength      
        if(p_line(i)==',')
            if(i_comma==1)
                i_counter=i_counter+1;
                a_comma(i_counter) = i;
            end
        elseif(p_line(i)=='"')
            if(i_comma==1)
                i_comma=0;
            else
               i_comma=1; 
            end
        end  
    end
    %now that I have a line, make a cell array based upon what was there
    i_cellc=1;
    i_start=1;
    for i_counter=1:length(a_comma)
       i_end=a_comma(i_counter);
       %fprintf('%s\n',p_line(i_start:i_end)); 
       a_cell{i_cellc}=sprintf('%s',p_line(i_start:i_end));
       i_cellc=i_cellc+1;
       i_start=i_end;
    end
   
    % there still should be one more here, but it's missing because of 
    % the fact that the last ,EOL is not parsed.  
    if(a_comma(length(a_comma))==i_linelength)
        a_cell{i_cellc}=',,';
    else
        a_cell{i_cellc}=sprintf('%s',p_line(i_start:i_linelength));
    end
    %strip out the , if it starts or ends the cell string.
    for i_counter=1:length(a_cell)
        tmp_cell = a_cell{i_counter};
        if(tmp_cell(1)==',')
            tmp_cell=tmp_cell(2:end);
        end
        if(tmp_cell(end)==',')
            tmp_cell=tmp_cell(1:end-1);
        end
       %convert numbers to numbers
        if(valid_number(tmp_cell)==1)
            tmp_cell=str2num(tmp_cell);
        end
        a_cell{i_counter}=tmp_cell;
       % fprintf('%i: %s\n',i_counter,a_cell{i_counter});
    end
    result=a_cell;
end

function result=valid_number(s_str)
%this function return if s_str is a valid number
i_tick=1;  %default to valid.
a_int=char(s_str);  %to ASCII
    for i_counter=1:length(a_int);
        c_tmp=a_int(i_counter);
        if((c_tmp>=48)&&(c_tmp<=57))
            %nothing
        elseif(c_tmp==46)
            %nothing    
        else
           i_tick = i_tick -1; 
        end;        
    end
    result=i_tick;
end

Monday, November 11, 2013

numbers to strings in matlab sometimes truncate?

MATLAB is great because I generally have portable code. This is not always the case. Today, I found that for values greater than 31-bits, things went odd. 2000000000 was 2000000000 as a string, but 3000000000 was 3.00e9, which played havoc on some post-operation parsing. This behavior was computer dependent!
The issue was this line:
r=sprintf('%i',num);
The integer changes form over 2^31 bits in length. The fix was:
r=num2str(num);