-->name = input ("What is your name?")
What is your name?
-->"Jesus"
name =
Jesus
We can do the same much more attractive by using
-->name = x_dialog ("What is your name?","")
name =
Jesus
It appears a window containing the question as well as the default value which in this case was adjusted to ``''.
To output values we have the command `printf'
-->printf ("1. Dog\n2. Cat\n3. Mouse\n\n");
1. Dog
2. Cat
3. Mouse
`printf' admits different formats as in `C' and has two variants `sprintf' (that writes to a string) and `fprintf' (that writes to a file).
There is a form to present information in a message box without asking for an answer
-->x_message(["1. Dog","2. Cat","3. Mouse"])`input', `printf' and its counterparts `x_dialog' and `x_message' are very useful commands to introduce data at runtime. Sometimes we need to stop the program (for instance to see a plot): `halt()' stops the execution until something is entered by the keyboard.
Scilab dispose of commands to branch the code similar to the ones found in other languages. As an example we can type the next commands in `evalneg.sce'
value = input('introduce a value')
if (value<0) then
printf('negative value')
else
printf('non negative value')
end
And we can execute the file from inside Scilab
-->exec('evalneg.sce',-1)
introduce a value
-->12
non negative value
-->exec('evalneg.sce',-1)
introduce a value
-->-1
negative value
Notice that exec with the optional parameter `-1' executes the file without echoing the commands.
There is also a `select case' command to select different options.
For-next loops have some particularities in Scilab. They can be used as in other languages
-->for i=1:5; printf('%d',i); end
1
2
3
4
5
-->for i=1:2:10; printf('%d',i); end
1
3
5
7
9
-->for i=10:-2:1; printf('%d',i); end
10
8
6
4
2
But since the expression that controls the loop is a vector, some more elaborated expressions are possible
-->randvec = rand (1,10)
randvec =
column 1 to 5
! .9329616 .2146008 .312642 .3616361 .2922267 !
column 6 to 10
! .5664249 .4826472 .3321719 .5935095 .5015342 !
-->for k=[1,3,10:-1:8], randvec(k), end
ans =
.9329616
ans =
.312642
ans =
.5015342
ans =
.5935095
ans =
.3321719
Notice that k takes different values ( 1, 3, 10, 9, 8) following the index contained in a vector. We could even give a name to this vector
-->ndx = [10,3,1]; for k=ndx, randvec(k), end
ans =
.5015342
ans =
.312642
ans =
.9329616
We choose some indexes (10, 3 and 1) and create with them a vector. This vector was employed to control the loop.
While-end loops can also be employed.
It is important to emphasize that loops are generally much slower than vectorial instructions. To evaluate the efficiency of code, we have the command `timer' that returns the time employed between successive calls. `timer()' can be used to compare the time employed in a task carried out by different methods.
-->timer();for k=100000:-1:1; end; timer()
ans =
0.35
-->k=100000; timer(); while(k>0); k=k-1; end; timer()
ans =
5.05
In Scilab, very different degrees of efficiency can be obtained with vectorial and non-vectorial commands. Imagine that we have a sinusoid of 100 seconds sampled at 1000 Hz. Its frequency is 0.1 Hz.
-->t = 0:0.001:100; -->s = sin (2 * %pi * .1 * t);We want to calculate the difference between each sample and the previous one. We prepare a vector with the same dimension and use a for loop to calculate it. We can check the time
-->s2 = zeros(s); l=length(s);
-->timer(); for k=2:l; s2(k)=s(k)-s(k-1); end; timer()
ans =
11.06
Now we are going to try a `vectorial' command
-->timer(); s3 = s(2:l) - s(1:l-1); timer()
ans =
0.1
Vectorial commands are much more efficient but this advantage is only important when we face many data. If we have a matrix of 10 rows and 10000 columns it is much more important that we vectorize the operating on rows
-->r = rand (10,10000); // a random matrix
-->su = 0; timer();... // init timer
-->for k=1: size(r,1);... // row by row
->su = su + sum (r (k,:));... // sum columns
-->end;... // closes loop
-->timer() // checks time
ans =
0.04
-->su // result
su =
50048.59
The addition iterates ten times and uses internally a vectorial command. If we choose the iteration on columns (10000), we have
-->su = 0; timer();... // init timer
-->for k=1: size(r,2);... // column by column
-->su = su + sum (r (:,k));... // sum rows
-->end;... // closes loop
-->timer() // checks time
ans =
0.96
-->su // result
su =
50048.59
Obviously, the use of a vectorial command is critical unless we are calculating on a small number of data.
The most usual structure to store data in Scilab is a matrix . This structure can be quite non flexible. On one side, data included in the matrix must be of the same type. We can not combine characters with numeric values, for instance. On the other side, matrices are rectangular. Let us consider a case. We have a sleep recording where we have recognized different `patterns' such as `arousals' `K-complexes' or `spindles'. Each time we recognize the pattern, we store the index at which this pattern occurs. Evidently, we have not the same number for the different events and we would like to store the different events all together. A flexible structure implemented in Scilab to face this difficulty is `list'. We are going to treat an imaginary sleep recording where we have identified 3 `K-complex', 7 `spindles' and 5 `arousals'
-->kcomplexes = [17, 197, 350];
-->spindles = [60, 350, 570, 690, 880, 890, 991];
-->arousals = [50, 250, 315, 514, 710];
-->events = list (kcomplexes, spindles, arousals)
events =
events(1)
! 17. 197. 350. !
events(2)
! 60. 350. 570. 690. 880. 890. 991. !
events(3)
! 50. 250. 315. 514. 710. !
We did not use semicolon at `events' definitions to see the results. The whole output is something similar to a matrix but it has a difference: each length is different. We can access any value
-->events(1)(2)
ans =
197.
-->events(2)($-1)
ans =
890.
-->events($)($-1)
ans =
514.
Even we can use a variant of the list that identifies the content
-->events2 = tlist (["ndx","K","S","A"],kcomplexes, spindles, arousals)
events2 =
events2(1)
!ndx K S A !
events2(2)
! 17. 197. 350. !
events2(3)
! 60. 350. 570. 690. 880. 890. 991. !
events2(4)
! 50. 250. 315. 514. 710. !
This structure can be accessed in a very flexible way
-->events2("S")(3)
ans =
570.
-->events2("A")($:-1:4)
ans =
! 710. 514. !
In `list' or `tlist' we can even mix different types of data
-->record = tlist(["patient","name","age"],"John Smith",34)
record =
record(1)
!patient name age !
record(2)
John Smith
record(3)
34.
-->record("age")
ans =
34.
The structures considered and the flow control commands allow to build very complex programs.