Session 14: Data Structures


In this session you will learn the following:

  1. User defined data structures in Scilab
  2. Creating and using struct, cell, list, tlist and mlist

Function Used

struct(), fieldnames(), list(), lstcat()tlist(), definedfields(), mlist(), cell()


User defined data structures offer the programmer the facility to tailor data suited to represent and program solutions to specific problems. Most data structures are an agglomeration of basic data types and previously defined user defined data types.

Scilab Data Types

Data types available in Scilab can be listed through the online help on type() and typeof(). The data types available in Scilab are:

Data Type Object Type Description
1 constant real or complex constant matrix
2 polynomial polynomial matrix
4 boolean boolean matrix
5 sparse sparse matrix
6 boolean sparse sparse boolean matrix
8 int8, int16 or int32 matrix of integers stored in 1, 2 or 4 bytes
9 handle matrix of graphic handles
10 string matrix of character strings
11   un-compiled function (Scilab code)
13 function compiled function (Scilab code)
14 library function library
15 list list
16 tlist typed list (tlist)
17 st or mlist structure or matrix oriented typed list (mlist)
128 pointer pointer
129 size implicit size implicit polynomial used for indexing
130 fptr Scilab intrinsic (C or Fortran code)

The following functions are used to determine data types:

  1. Function type(x) returns the type of a Scilab variable x.
  2. Function typeof(x) returns a string indicating the type of Scilab object x.

Data Structure - struct

struct is a user defined data structure. Programmer can define fields within the structure and each field can be any valid Scilab data type. Each field can thus contain any valid Scilab data and data in any field can be accessed using the dot convention, namely, object.field accesses field from object. Let us see an example:

-->s = struct('name', 'John Doe', 'courses', ['MA102', 'HS108', 'CV102'], 'marks', [85, 92, 79]);
-->type(s) // enquire data type
 ans  =
-->typeof(s) // enquire object type
 ans  =
-->fieldnames(s) // list field names
 ans  =
!name    !
!courses !
!marks   !
-->s // display data
  name: "John Doe"
  courses: ["MA102", "HS108", "CV102"]
  marks: [85, 92, 79]
--> // display field "name" of object "s"
 ans  =
  John Doe
--> // display field "course" of object "s"
 ans  =
  !MA102  HS108  CV102  !
-->s.marks // display field "marks" of object "s"
 ans  =
   85.  92.  79.

This is what happened:

  1. We created a struct object with the name s using the struct() function. While creating this object, we defined the following fieldnames and assigned them initial values:

    1. name - assigned the value "John Doe"
    2. courses - assigned a vector of string elements
    3. marks - assigned a vector of numerical elements
  2. We enquired the type of the object using type() and typeof() functions.
  3. We displayed the field names in the object s using function fieldnames()
  4. We displayed the data contained in object s
  5. We displayed the individual fields in the object s using the object.fieldname syntax

The exact same result could also be achieved in a simpler and direct manner with the following statements:

--> = "John Doe";
--> = ["MA102", "HS108", "CV102"];
-->s.marks = [85, 92, 71];

In fact, a new field could be added any time with equal ease:

--> = sum(s.marks)
 s  =
name: "John Doe"
courses: ["MA102", "HS108", "CV102"]
marks: [85, 92, 71]
total: 248

Being a weakly type language, Scilab does not require that variables be declared before being used. Thususer defined types can be constructed and altered dynamically. Each field can contain any valid Scilab data type.

Data Structure - list

A list is similar to a struct, but uses indexing to access its components instead of field names. In addition, operations such as insert/append new nodes, delete existing nodes is possible. Let us use a list to represent the same information used in the struct example above:

-->l = list("John Doe", ["MA102", "HS108", "CV102"], [85, 92, 71])
 l  =
John Doe
["MA102", "HS108", "CV102"]
  85.  92.  71.
 ans  =
 ans  =

To insert a new node after the last node, do the following:

-->l($+1) = sum(l(3));
 ans  =

To insert a node before the first node use l(0). To insert a new node at position i, use l(i). You can concatenate lists with the function lstcat().

Data Structures - tlist

A tlist is a typed list. It has characteristics that are a combination of a struct and a list. Like a struct, it uses field names, but the fields can also be accessed using indexing. Its data type is 16 and its object type is user definable. Like a list, nodes can be inserted and appended. Let us create a tlist to represent the same information above, and let us choose to call this data type student.

-->t = tlist(["student", "name", "courses", "marks'], "John Doe", ["MAT102", "HS108", "CV102"]);
 ans  =
 ans  =
 ans  =
!name    !
!courses !
!marks   !
 ans  =
    1.   2.   3.
 ans  =
John Doe
 ans  =
 ans  =
!student  name  courses  marks  !
 ans  =
John Doe
 ans  =
!MA102  HS108  CV102  !

From the above, we can understand the following:

  1. Data type of tlist is 16. Object type of tlist must be defined by user. If the first input argument to tlist() is a string, it is the object type of the tlist. If the first input argument to tlist() is a vector of strings, the fist element of the vector is the object type and the rest represent field names of the object.
  2. Field names of a tlist can also referred to by their index. Thus t(2) is the same as, t(3) is the same as and t(4) is the same as t.marks.
  3. Values may be assigned to the various fields at the time of creating the object or later. Fields which have been assigned values can be listed with the function definedfields(). It lists the indices of the fields, not their field names. t(1) is always defined because object type must be defined at the time of creating the tlist object.
  4. Fieldnames can be defined in advance or inserted later. Values can be assigned at the time of creating the object or assigned later.

To assign values to t.marks, do the following:

-->t.marks = [85 92 71];

To create a new field total and assign it a value, do the following:

-->t(1) = [t(1), 'total'];
--> = sum(t.marks)
 ans  =

One advantage of a tlist over a list is that it is possible to overload some of its default functions, such as the display function disp(). Here we overload the disp function of the tlist with object type student:

-->// Display using default disp()
!student  name  courses  marks  !
John Doe
!MA102  HS108  CV102  !
   85.   92.   71.
function %student_p(mytlist)
-->  f = fieldnames(mytlist);
-->  [m, n] = size(f);
-->  mprintf("tlist type: %s\n", typeof(mytlist));
-->  for i = 1:m
-->    mprintf("%7s: %s\n", f(i), sci2exp(mytlist(f(i))});
-->  end
-->// Display using overloaded disp()
tlist type: student
   name: John Doe
courses: ["MA102", "HS108", "CV102"]
  marks: [85, 92, 71]

Function sci2exp() converts an expression to a string so that it can be output using the %s format specifier. For details about overloading functions, see online help:

-->help overloading

Data Structure - cell

A cell is an array of matrices. That is, like a matrix, it has elements arranged as rows and columns. Individual elements of a cell can be addressed in the same way as we address elements of a matrix, by referring to their row and column position within the matrix. Each element of a cell can be any valid Scilab data, including string, polynomial, or even another matrix. But when assigning values to an element of a cell, the syntax must use cell(index).entries = value, as shown in the example below:

-->b = cell(3, 1) // Create an empty cell of size 3x1
 b  =
!{} !
!{} !
!{} !
-->b(1).entries = [1:3]; b(2).entries = 'Scilab'; b(3).entries = poly(1:3, 's')
 b  =
![1, 2, 3]         !
!"Scilab"          !
!-6+11*s-6*s^2+s^3 !
-->x = cell(3, 2); x(:,1) = b
![1, 2, 3]           {} !
!"Scilab"            {} !
!-6+11*s-6*s^2+s^3   {} !
-->// Element extraction
-->x(1, 1) // return value is a cell
 ans  =
[1, 2, 3]
-->x(1, 1).entries // return value is a matrix
   1.   2.   3.
-->// Cell dimensions
-->b.dims // Dimensions of the cell, as int32
 ans  =
   3   1
-->size(b) // Size of the cell, as a double
 ans  =
   3.  1.


Task Discussion