[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2 Cell Arrays

It can be both necessary and convenient to store several variables of different size or type in one variable. A cell array is a container class able to do just that. In general cell arrays work just like N-dimensional arrays, with the exception of the use of `{' and `}' as allocation and indexing operators.

As an example, the following code creates a cell array containing a string and a 2-by-2 random matrix

 
c = {"a string", rand(2, 2)};

And a cell array can be indexed with the { and } operators, so the variable created in the previous example can be indexed like this

 
c{1}
     ⇒ ans = a string

As with numerical arrays several elements of a cell array can be extracted by indexing with a vector of indexes

 
c{1:2}
     ⇒ ans =
          
          (,
            [1] = a string
            [2] =
          
               0.593993   0.627732
               0.377037   0.033643
          
          ,)

The indexing operators can also be used to insert or overwrite elements of a cell array. The following code inserts the scalar 3 on the third place of the previously created cell array

 
c{3} = 3
     ⇒ c =
         
         {
           [1,1] = a string
           [1,2] =
         
              0.593993   0.627732
              0.377037   0.033643
         
           [1,3] =  3
         }

In general nested cell arrays are displayed hierarchically as above. In some circumstances it makes sense to reference them by their index, and this can be performed by the celldisp function.

Function File: celldisp (c, name)

Recursively display the contents of a cell array. By default the values are displayed with the name of the variable c. However, this name can be replaced with the variable name.
See also: disp.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.1 Creating Cell Array

The introductory example showed how to create a cell array containing currently available variables. In many situations, however, it is useful to create a cell array and then fill it with data.

The cell function returns a cell array of a given size, containing empty matrices. This function works very similar to the zeros function for creating new numerical arrays. The following example creates a 2-by-2 cell array containing empty matrices

 
c = cell(2,2)
     ⇒ c =
         
         {
           [1,1] = [](0x0)
           [2,1] = [](0x0)
           [1,2] = [](0x0)
           [2,2] = [](0x0)
         }

Just like numerical arrays, cell arrays can be multidimensional. The cell function accepts any number of positive integers to describe the size of the returned cell array. It is also possible to set the size of the cell array through a vector of positive integers. In the following example two cell arrays of equal size is created, and the size of the first one is displayed

 
c1 = cell(3, 4, 5);
c2 = cell( [3, 4, 5] );
size(c1)
     ⇒ ans =
         3   4   5

As can be seen, the size function also works for cell arrays. As do the other functions describing the size of an object, such as length, numel, rows, and columns.

An alternative to creating empty cell arrays, and then filling them, it is possible to convert numerical arrays into cell arrays using the num2cell and mat2cell functions.

Built-in Function: cell (x)
Built-in Function: cell (n, m)

Create a new cell array object. If invoked with a single scalar argument, cell returns a square cell array with the dimension specified. If you supply two scalar arguments, cell takes them to be the number of rows and columns. If given a vector with two elements, cell uses the values of the elements as the number of rows and columns, respectively.

Built-in Function: iscell (x)

Return true if x is a cell array object. Otherwise, return false.

Loadable Function: c = num2cell (m)
Loadable Function: c = num2cell (m, d)

Convert to matrix m into a cell array. If d is defined the value c is of dimension 1 in this dimension and the elements of m are placed in slices in c.
See also: mat2cell.

Loadable Function: b = mat2cell (a, m, n)
Loadable Function: b = mat2cell (a, d1, d2, …)
Loadable Function: b = mat2cell (a, r)

Converts the matrix a to a cell array If a is 2-D, then it is required that sum (m) == size (a, 1) and sum (n) == size (a, 2). Similarly, if a is a multi-dimensional and the number of dimensional arguments is equal to the dimensions of a, then it is required that sum (di) == size (a, i).

Given a single dimensional argument r, the other dimensional arguments are assumed to equal size (a,i).

An example of the use of mat2cell is

 
mat2cell (reshape(1:16,4,4),[3,1],[3,1])
⇒ {
  [1,1] =

     1   5   9
     2   6  10
     3   7  11

  [2,1] =

     4   8  12

  [1,2] =

    13
    14
    15

  [2,2] = 16
}

See also: num2cell, cell2mat.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.2 Indexing Cell Arrays

As shown in the introductory example elements can be inserted from cell arrays using the `{' and `}' operators. Besides the change of operators, indexing works for cell arrays like for multidimensional arrays. As an example, all the rows of the first and third column of a cell array can be set to 0 with the following code

 
c{:, [1, 3]} = 0;

Accessing values in a cell array is, however, different from the same operation for numerical arrays. Accessing a single element of a cell array is very similar to numerical arrays, for example

 
element = c{1, 2};

This will, however, not work when accessing multiple elements of a cell array, because it might not be possible to represent all elements with a single variable as is the case with numerical arrays.

Accessing multiple elements of a cell array with the `{' and `}' operators will result in a comma-separated list (see section Comma Separated Lists) of all the requested elements as discussed later.

One distinction between `{' and `(' to index cell arrays is in the deletion of elements from the cell array. In a similar manner to a numerical array the `()' operator can be used to delete elements from the cell array. The `{}' operator however will remove the elements of the cell array, but not delete the space for them. For example

 
x = {"1", "2"; "3", "4"};
x{1, :} = []
⇒ x =
      {
        [1,1] = [](0x0)
        [2,1] = 3
        [1,2] = [](0x0)
        [2,2] = 4
      }

x(1, :) = []
⇒ x =
      {
        [1,1] = 3
        [1,2] = 4
      }

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.3 Cell Arrays of Strings

One common use of cell arrays is to store multiple strings in the same variable. It is possible to store multiple strings in a character matrix by letting each row be a string. This, however, introduces the problem that all strings must be of equal length. Therefore it is recommended to use cell arrays to store multiple strings. If, however, the character matrix representation is required for an operation, it can be converted to a cell array of strings using the cellstr function

 
a = ["hello"; "world"];
c = cellstr (a)
     ⇒ c =
         {
           [1,1] = hello
           [2,1] = world
         }

One further advantage of using cell arrays to store multiple strings, is that most functions for string manipulations included with Octave support this representation. As an example, it is possible to compare one string with many others using the strcmp function. If one of the arguments to this function is a string and the other is a cell array of strings, each element of the cell array will be compared the string argument,

 
c = {"hello", "world"};
strcmp ("hello", c)
     ⇒ ans =
        1   0

The following functions for string manipulation support cell arrays of strings, strcmp, strcmpi, strncmp, strncmpi, str2double, str2mat, strappend, strtrunc, strvcat, strfind, and strmatch.

Built-in Function: cellstr (string)

Create a new cell array object from the elements of the string array string.

Built-in Function: iscellstr (cell)

Return true if every element of the cell array cell is a character string

Function File: [idxvec, errmsg] = cellidx (listvar, strlist)

Return indices of string entries in listvar that match strings in strlist.

Both listvar and strlist may be passed as strings or string matrices. If they are passed as string matrices, each entry is processed by deblank prior to searching for the entries.

The first output is the vector of indices in listvar.

If strlist contains a string not in listvar, then an error message is returned in errmsg. If only one output argument is requested, then cellidx prints errmsg to the screen and exits with an error.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.4 Processing Data in Cell Arrays

Data that is stored in a cell array can be processed in several ways depending on the actual data. The most simple way to process that data is to iterate through it using one or more for loops. The same idea can be implemented easier through the use of the cellfun function that calls a user specified function on all elements of a cell array.

Loadable Function: cellfun (name, c)
Loadable Function: cellfun ("size", c, k)
Loadable Function: cellfun ("isclass", c, class)
Loadable Function: cellfun (func, c)
Loadable Function: cellfun (func, c, d)
Loadable Function: [a, b] = cellfun (…)
Loadable Function: cellfun (…, 'ErrorHandler', errfunc)
Loadable Function: cellfun (…, 'UniformOutput', val)

Evaluate the function named name on the elements of the cell array c. Elements in c are passed on to the named function individually. The function name can be one of the functions

isempty

Return 1 for empty elements.

islogical

Return 1 for logical elements.

isreal

Return 1 for real elements.

length

Return a vector of the lengths of cell elements.

ndims

Return the number of dimensions of each element.

prodofsize

Return the product of dimensions of each element.

size

Return the size along the k-th dimension.

isclass

Return 1 for elements of class.

Additionally, cellfun accepts an arbitrary function func in the form of an inline function, function handle, or the name of a function (in a character string). In the case of a character string argument, the function must accept a single argument named x, and it must return a string value. The function can take one or more arguments, with the inputs args given by c, d, etc. Equally the function can return one or more output arguments. For example

 
cellfun (@atan2, {1, 0}, {0, 1})
⇒ans = [1.57080   0.00000]

Note that the default output argument is an array of the same size as the input arguments.

If the param 'UniformOutput' is set to true (the default), then the function must return either a single element which will be concatenated into the return value. If 'UniformOutput is false, the outputs are concatenated in a cell array. For example

 
cellfun ("tolower(x)", {"Foo", "Bar", "FooBar"},
         "UniformOutput",false)
⇒ ans = {"foo", "bar", "foobar"}

Given the parameter 'ErrorHandler', then errfunc defines a function to call in case func generates an error. The form of the function is

 
function […] = errfunc (s, …)

where there is an additional input argument to errfunc relative to func, given by s. This is a structure with the elements 'identifier', 'message' and 'index', giving respectively the error identifier, the error message, and the index into the input arguments of the element that caused the error. For example

 
function y = foo (s, x), y = NaN; endfunction
cellfun (@factorial, {-1,2},'ErrorHandler',@foo)
⇒ ans = [NaN 2]

See also: isempty, islogical, isreal, length, ndims, numel, size, isclass.

An alternative is to convert the data to a different container, such as a matrix or a data structure. Depending on the data this is possible using the cell2mat and cell2struct functions.

Function File: m = cell2mat (c)

Convert the cell array c into a matrix by concatenating all elements of c into a hyperrectangle. Elements of c must be numeric, logical or char, and cat must be able to concatenate them together.
See also: mat2cell, num2cell.

Built-in Function: cell2struct (cell, fields, dim)

Convert cell to a structure. The number of fields in fields must match the number of elements in cell along dimension dim, that is numel (fields) == size (cell, dim).

 
A = cell2struct ({'Peter', 'Hannah', 'Robert';
                   185, 170, 168},
                 {'Name','Height'}, 1);
A(1)
⇒ ans =
      {
        Height = 185
        Name   = Peter
      }


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated on December, 26 2007 using texi2html 1.76.