Scilab
Scilab
EW
Johnny Heikell
Johnny Heikell
"It is a mistake often made in this country to measure things by the amount of money
they cost." Albert Einstein
Johnny Heikell
www.heikell.fi
LinkedIn
The best Scilab tutorials are non-English. The following are the ones
that I have consulted most for this work:
Timo Mkels Scilab/Xcos tutorials (3 parts) in Finnish <http://sites.
Why I did it
the way I did it
Why PowerPoint?
3.
4.
5.
6.
Why simulate?
Contents
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Introduction
A first peek at Scilab
The Console & Editor
Examples, Set 1
Matrices, functions &
operators
Examples, Set 2
Graphics & plotting
Examples, Set 3
Converting Matlab files
Subroutines
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
Flow control
Examples, Set 4
Doing math on Scilab
Examples, Set 5
Working with GUIs
File handling
Animation
Miscellaneous
Examples, Set 6
Adieu
Dr.EW
Johnny Heikell
1. Introduction
What is and why use Scilab?
Return to Contents
Matlab 6.5 (R13) was not compatible with my new Windows Vista
laptop. MatWorks, Inc., recommended to buy a new version
I refused to pay another license fee for Matlab and went looking for
open-source alternatives:
Sage felt bulky, immature, and focused on pure mathematics
Python is not optimized for scientific and engineering tasks
Python(x,y) messed up my PC when I installed it. Maybe I should I
have tried SciPy instead?
I grew tired of GNU Octave before I figured out how to download
and install it (I want a tool to use, not to fight against)
Scilab was the fifth alternative that I looked at. It gave no immediate
problems, so I stuck to it. Later I have come across bugs and
crashes/lockupsand become frustrated with its poor documentation
Would I still select Scilab? Yes, I am impressed by Scilab and believe that the
competitors cause you gray hair as wellone way or another.
Scilab advantages
Scilab disadvantages
Terminology: function
The C programming language brought confusion with its
unrestricted use of the term function and this is repeated in
Scilab. The term refers to (at least):
Mathematical functions in general
Scilabs built-in functions
User defined functions (UDF)
With Scilab 5.2 came a problem that I did not experience with
version 5.1.1: Copy-pasting from Scilabs Editor to PowerPoint
frequently caused the latter to crash. The bug has been fixed
With Scilab 5.3.0 I found that the paths File/Open file in... and
File/Save file in... on the Editor were unresponsive
Some scripts that I originally wrote using Scilab 5.1.1 did not work
with Scilab 5.3.0, and GUIs on 5.3.2 are a real pain down there
Typically larger updates come with bugs and are quickly followed by
minor bug fix updates (a.k.a. patches). Scilab 5.3.1 emerged within
three months of 5.3.0. This is universal in the software business
It is wise to keep an old Scilab version until you know that the new
release can be trusted (I was happy I had kept version 5.1.1 when
GUIs on 5.3.1 & 5.3.2 gave me problems)
*) Various Scilab versions are mentioned. I have worked with Scilab 5.1.1 5.3.2. Scilab 5.3.3 came too late to be considered.
Embedded information
Books
There is not a single good textbook in English on Scilab like you find in
abundance on Matlab. These are the books that I am familiar with:
Beater, P.: Regelungstechnik und Simulationstechnik mit Scilab und
*) Scilab is released under the French CeCILL license. The question is, is it
really a Free and Open-Source license that allows you to release a Scilab copy
under a new name, the way OpenOffice was turned into LibreOffice?
Dr.EW
Johnny Heikell
4. Double-click on the
file to install Scilab,
follow the prompts
Linux installation
This discussion is valid for Ubuntu
10.04 LTS with the GNOME
desktop*
Click: Applications/Ubuntu
Software Center/Science &
Engineering and scroll down to
Scilab; then just Click Install
Only Scilab 5.3.0 beta-2 is
available at the repository
For the latest version you must
go to Scilab's web site and
download Linux binaries. The
installation, however, is a
trickier question and I do not
cover it here (have not tried it)
The Console
Click on Scilabs shortcut
icon to open the Console
(Command Window in
Matlab*):
Menu bar
Toolbar
Command prompt
If no shortcut icon has been
created: Click: Start\All
Programs\scilab\scilab (do
not select Scilab Console)
*) The Console has other names as well: Workspace, Startup/Main Window, etc.
Folks:
Scilab in 15 minutes
(1/3): write a script
Recall how Jim taught me MathCAD in 15 minutes? Now well repeat
that lesson in Scilab. We do it by using the Editor (SciNotes):
Step 1: On the Console, Click
the leftmost icon on the
toolbar. The Editor pops up
Step 2: Define whatever
variables your function needs
(row 1). Note comment (// )
Step 3: Next, define the (sine)
function in case (row 2)
Scilab in 15 minutes
(2/3): save and plot
Step 5: Save the script by
Clicking on the Save icon
and name it e.g. foo.sce
Scilab in 15 minutes
(3/3): discussion
This exercise showed the essentials of Scilab in engineering
applications:
The recipe for using Scilab is the one that Jim taught me:
First you declare the variables that are needed
Then you define the function that you want to plot
And finally, plug in the plot instruction
Scilab Web
resources
Editor toolbar
New... Opens a second
tab for a new script to
be edited (the same
command can be found
under File)
The Save icon looks like the
Dutch tricolor, but youll get
used to it. The next one is
Save as...
The Undo/Redo arrows
are quite normal
The Paste icon is a
bit unusual (French?)
Ready to go
Console (command window)
Your desktop
should now look
something like
the one here. As
we have seen,
both the Editor
and the Console
are needed since
when the
scriptscreated
on the Editor
are executed
numeric outputs
is returned to the
Console
Editor (SciNotes)
Built-in functions
Below is a list of common math functions in Scilab. A full list of built-in
functions can be found under Help\Elementary Functions, which also
explains requirements on arguments (there are both mandatory and
optional arguments).
sin(), cos(), tan(), cotg()
Arc functions
Hyperbolic functions
sqrt(), exp()
sum()
Sum
min(), max()
abs(), sign()
real(f), imag(f)
i = -1
Imaginary unit
%pi
= 3.1415927.
Pi
%e
e = 2.7182818.
Napiers constant e
%eps
= 2.22 10-16
%inf
%nan
Not a Number
%s
Polynomial variable
%z
Polynomial variable
%t, %T
true
Boolean variable
%f, %F
false
Boolean variable
'
.'
Non-conjugate transpose
[] , [] '
()
+, -
Addition, subtraction
* , .*
*) Both simple (') and double (") quotes are allowed to define character strings
\ , .\
^ or ** , .^
.*.
./. , .\.
Kronecker product
Kronecker right and left division
Logical OR
&
Logical AND
Logical NOT
Computing terminology:
a brief introduction
On handles
You will often see Scilabs Help Browser refer to a handle, but
Help does not provide a helpful explanation of the term. Here is a
brief account:
Check handles
with gcf()
f =
Handle of type "Figure" with properties:
========================================
children: "Axes
figure_position = [567,485]
figure_size = [628,592]
axes_size = [610,460]
auto_resize = "on
viewport = [0,0]
figure_name = "Graphic window number %d
figure_id = 0
info_message = "
color_map= matrix 32x3
pixmap = "off
pixel_drawing_mode = "copy
anti_aliasing = "off
immediate_drawing = "on
background = -2
visible = "on
rotation_style = "unary
event_handler = "
event_handler_enable = "off
user_data = []
tag = ""
foo
Dr.EW
Johnny Heikell
Return to Contents
Console keyboard
shortcuts
Keyboard shortcuts allow
speedier execution of
commands, but require
frequent use to stay
memorized
In the Help Browser, Click:
Console/console for a list
of keyboard shortcuts
The simplest ones to
memorize are:
F1 = Open Help Browser
F2 = Clear Console
Simple calculations
Entering numbers
ans =
0.1
ans =
0.1
ans =
Computing precision
(1/2)
Look at the two examples to the
left. In both cases we are
computing 1-5*0.2, but in two
different ways
-->a = 1 - 5*0.2
a =
0.
-->b = 1 - .2 - .2 - .2 - .2 - .2
b =
5.551D-17
Computing precision
(2/2)
Here are two more cases where finite precision
shows up. The answers should be 0 (zero) and T
(True) respectively (Note that 1.225D-15,
1.225e-16, 1.225*10^-16 and 1.225*10-16
express the same thing)
Assume that the mentioned variable a is part of
a script with an if...then...else...end structure
(conditional branching will be covered in Chapter
11). The result is that alternative 1 is never
executed because a is never exactly zero
We must test a with some finite bounds, e.g.:
if abs (a ) < 1e- 6 then
......
-->a = sin(%pi)
a =
1.225D-16
Displaying graphics
-->x = linspace(-%pi,%pi,40);
-->y = linspace(-%pi,%pi,40);
-->a = 2; b = sqt(a)
!--error 4
-->a = 2; b = sqt(a)
-->a = 2; b = sqrt(a)
b =
^
|
Press up
arrow
Correct
Editing demo
-->s=.5; log(s^2-2*s*cos(%pi/5)+1)
ans =
- 0.8187489
-->s=.95; log(s^2-2*s*cos(%pi/5)+1)
ans =
- 1.006851
-->s=1; log(s^2-2*s*cos(%pi/5)+1)
ans =
- 0.9624237
Complex numbers
-->x = 2 + 3*%i;
-->abs(x)
ans =
3.6055513
-->real(x)
ans =
2.
-->imag(x)
ans =
5. + i
-->z3 = x / y
z3 =
- 0.5 + 2.5i
Vectorized functions
-->t = [0:5]'
t =
0.
2.
1.
3.
4.
t = [0:5]; y = sin(0.2*t)
5.
-->p=1+2+3+4+5+6+7+8+9+10+11+12+...
-->13+14+15+16+17+18+18+19+21+22+23+24+25
p =
323.
-->q = 1/2 + 1/3 + 1/4 + 1/5 + 1/6 + ...
-->1/7 + 1/8 + 1/9 + 1/10 + 1/11 + 1/12
q =
2.1032107
-->A = [1 2 3 4 5
-->6 7 8 9 10
-->11 12 13 14 15]
A =
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Polynomials
-->s=%s;
-->num = poly([0,-1,-2],'s')
num =
2 3
2s + 3s + s
-->den=poly([-.5,-1.5,-2.5,-3.5],'s')
den =
2 3 4
6.5625 + 22s + 21.5s + 8s + s
-->fr=num/den
fr =
2 3
2s + 3s + s
---------------------------------------2
3 4
6.5625 + 22s + 21.5s + 8s + s
Roots of polynomials
-->s=%s;
-->x=roots(2*s+3*s^2+s^3)
x =
-->s=%s;
0
- 1.
-->z=roots(6.5625+22*s+21.5*s^2+8*s^3+s^4)
z =
- 0.5
- 1.5
- 2.
-->s=%s;
-->sys=syslin('c',((1+2*s)*(1+3*s))/(s*(s*s+s+1)));
-->plzr(sys)
-->calendar(2013,6)
ans =
ans(1)
Jun 2013
ans(2)
M
Tu
Th
Sat
Sun
ans(3)
0.
3.
10.
17.
24.
0.
0.
4.
11.
18.
25.
0.
0.
5.
12.
19.
26.
0.
0.
6.
13.
20.
27.
0.
0.
1.
7.
8.
14. 15.
21. 22.
28. 29.
0.
0.
2.
9.
16.
23.
30.
0.
Sorry,
I could not copy-paste an extract because
PowerPoint crashed repeatedly (it happens
to Bill Gates as well Often.)
Dr.EW
Johnny Heikell
4. Examples, Set 1
Demonstration of basic Scilab
programs
Return to Contents
// plot1.sce
//
//
//
//
x = [0:.1:10];
A = 0.5*x;
y = A.*sin(2*x);
plot(y)
// plot1.sce
//
//
//
//
x = [0:.1:10];
A = 0.5*x;
y = A.*sin(2*x);
plot(y)
/
/
/
/
clf;
x = [0:.1:10];
A = 0.5*x;
y = A.*sin(5*x);
plot(y)
// plot1.sce
//
//
//
//
*) Careful with clear, it may cause havoc in some cases (there will be a demo on
this later)
// f-modulation1.sce
//
//
//
//
/
/
/
/
/
Ex 1-2: plot
The plot looks as
expectedincluding
the initial phase
shiftbut it lacks a
grid, title, and axis
labels
plot2d() is a more
versatile function
than plot(), which
is similar to the plot
function in Matlab
// f-modulation2.sce
//
//
//
//
/
/
/
/
Ex 1-2:
printing
Ex 1-2: checking
// f-modulation3.sce
//
//
//
//
//
/
/
/
/
/
/
Ex 1-2: discussion
dt=getdate() returns
dd-mm-yyyy
rand(seed,n) sets
the random generator seed to n
dt(9) returns a
number between 00
and 59, dt(10)
returns milliseconds
000999
The while...end
construct will be
covered under the
discussion below
function lotto
//-----------------------------------------------------------------/
// The function draws 7 Lotto numbers [1,39] by first /
// creating a seed using current date and time
/
// (second, millisecond) information
/
//----------------------------------------------------------------/
dt=getdate();
// Pick current date
rand('seed',1000*dt(9)+dt(10));
// Initialize random generator
numbers=floor(1+39*rand(1,7));
// Draw Lotto row
while(length(unique(numbers))<7) // If number repeats in row,
numbers=floor(1+39*rand(1,7)); // then drawn a new row
end
numbers=gsort(numbers); // Sort numbers in decreasing order
disp(numbers(7:-1:1));
// Display in increasing order
endfunction
Why the hassle with the seed? Without it Scilab generates the same sequence for
each session. The 1000*t(9)+ dt(10) argument improves randomness.
-->
-->help funcprot
-->lotto
3.
5.
13.
15.
33.
37.
39.
length(unique(numbers)) < 7
// lotto2.sce
//-----------------------------------------------------------------------/
// The script asks for the number of Lotto draws that we /
// wish to do, using a separate dialog box. It then calls
/
// the local UDF lottodraw()) that generates a row of N
/
// random Lotto numbers in the range [1,39]. It sorts the /
// numbers into a vector by adding one (1) to the relevant /
// vector element for each corresponding hit. The result
/
// is plotted after the entered number of draws.
/
//-----------------------------------------------------------------------/
clear,clc,clf;
// (SUBROUTINE) function lottodraw():
//----------------------------------------------------// The function draws N Lotto numbers [1,39], with
// N being defined through the input argument in.
// It delivers the drawn row to the calling script
// command through the output argument out. The
// randomness of the drawn numbers is improved by
// first creating a seed using current date and
// time (second, millisecond) information.
/
/
/
/
/
/
/
function out=lottodraw(in)
dt=getdate(); // Pick current date
rand('seed',1000*dt(9)+dt(10)); // Initialize random generator
out = floor(1+39*rand(1,in));
// Draw Lotto row (out variable)
while(length(unique(out))<in) // If number repeats in row,
out = floor(1+39*rand(1,in)); // then a new row is drawn
end
endfunction
// (MAIN) Call subroutine, update histogram, plot:
//------------------------------------------------------------------M = evstr(x_dialog('Enter # of...
// Open dialog box
lotto draws ',''));
N = 7;
// Lotto numbers to draw
columns = zeros(1,39);
// Initiate collecting vector
for k = 1:M
numbers = lottodraw(N);
// Call to subroutine
columns(numbers)=columns(numbers)+1;
// Add 1 for drawn number
end
x = linspace(1,39,39);
// Define x axis
plot2d2(x,columns,style=2)
// Plot as step functions
xtitle('RESULT OF LOTTO DRAWS') // Add title & labels
xlabel('Lotto numbers [1,39]')
ylabel('Hits')
Examples 1-1 1-3 were also intended to stress the fact that
we are forced to think matrix-wise when working with
Scilab. For instance, Scilab immediately generates an error
message if we attempt to do ordinary multiplication (*) when
a parameter is in matrix form and requires Dot multiplication
(.*) (Recall Example 1-1?)
fix() or
int()
floor()
rounds down
ceil()
rounds up
-->round(-2.7), round(2.7)
ans =
- 3.
ans =
3.
-->fix(-2.7), fix(2.7)
ans =
- 2.
ans =
2.
-->floor(-2.7), floor(2.7)
ans =
- 3.
ans =
2.
-->ceil(-2.7), ceil(2.7)
ans =
- 2.
ans =
3.
Dr.EW
Johnny Heikell
Introduction
11.
12.
13.
21.
22.
23.
-->A = [11, 12, 13; 21, 22, 23; 31, 32, 33]
31. 32. 33.
A =
11.
12.
13.
21.
22.
23.
31.
32.
33.
-->row=[0:0.2:1]
row =
0.8
1.
-->C=eye(3,3)
C =
3x2 matrix
of ones
2x3 zero
matrix
1.
0.
0.
0.
1.
0.
0.
0.
1.
0.2312237
0.2164633
0.8833888
0.6525135
-->rand(4,4,'normal')
ans =
-->D=ones(3,2)
D =
- 1.3772844
0.7915156
- 0.1728369
0.7629083
C =
C =
Addition
2. 4. 6.
8. 10. 12.
-->A=[1 2 3; 4 5 6]; B=[A]; C=A/B
C =
1.
1.518D-16
3.795D-15 1.
Multiplication
(note transpose!)
14. 32.
32.
77.
Inverse
- 2.5 1.5matrix
2. - 1.
Note 1: Rules for matrix operations must of course
be observed!
Note 2: Scilab returns D, not e, for the exponent (1.518D-16); the exact
value is 0 but here we have a case of limited computing accuracy
16. 3.
5. 10.
9. 6.
4. 15.
-->sum(M)
ans =
136.
2. 13.
11. 8.
7. 12.
14. 1.
-->M
ans =
16. 5.
3. 10.
2. 11.
13. 8.
-->diag(M)
ans =
16.
10.
7.
1.
9. 4.
6. 15.
7. 14.
12. 1.
-->A = [1 2 3; 4 5 6; 7 8 9]
A =
1.
2.
3.
4.
5.
6.
7.
8.
9.
-->B = sum(A,'r')
B =
12.
15.
18.
prod()
-->A=[1 2 3; 4 5 6; 7 8 9]
A =
1.
4.
7.
2.
5.
8.
3.
6.
9.
-->prod(A, 'r')
ans =
28.
80.
-->prod(A, 'c')
ans =
6.
120.
504.
-->prod(A)
ans =
362880.
162.
min(), max()
-->A=[3 0 1; 2 2 7; 5 9 4]
A =
3.
2.
5.
0.
2.
9.
1.
7.
4.
-->min(A)
ans =
0.
-->max(A)
ans =
9.
-->min(A, 'r')
ans =
2.
0.
1.
-->max(A, 'c')
ans =
3.
7.
9.
-->A = [5 3 1; 2 4 6];
1.
3.
min_val =
1.
mean()
-->A=[1 2 3; 4 5 6]
A =
1.
2.
3.
4.
5.
6.
-->mean(A)
ans =
3.5
-->mean(A, 'r')
size()
-->v1 = [1 2 3 4];
-->A = [1 2 3 4; 5 6 7 8];
-->v2 = v1';
-->size(A)
-->size(v1)
ans =
ans =
-->[n,m]
2. 4.= size([1 2 3; 4 5 6])
1.
4.
m =
-->size(v2)
3.
ans =
n =
-->size(['You' 'Me'; 'Alpha' 'Beta'; 'Two' 'Three'])
4. 1.
2.
ans =
length()
3.
-->length(['Hello world' 'SCILAB'; 'Alpha' 'Beta'])
ans =
11.
6.
5.
4.
find(condition)
-->X = [9 1 8; 2 7 3; 6 3 5];
-->find(X<5)
ans =
2.
4.
6.
8.
-->find(X==3)
ans =
6.
8.
-->find(X=3)
ans =
1.
-->find(X~=3)
ans =
1.
2.
3.
4.
5.
7.
9.
gsort()
4. - 2. 2.
0. - 3. 3.
5. 0. - 5.
-->s_matr = gsort(matr)
s_matr =
5.
4.
3.
2. 0. - 3.
1. - 1. - 4.
0. - 2. - 5.
- 4.
0. - 3.
-5.
testmatrix()
-->testmatrix('magi',4)
ans =
16.
5.
9.
4.
2.
11.
7.
14.
3.
10.
6.
15.
13.
8.
12.
1.
-->testmatrix('magi',5)
ans =
17.
23.
4.
10.
11.
24. 1.
5. 7.
6. 13.
12. 19.
18. 25.
8. 15.
14. 16.
20. 22.
21. 3.
2.
9.
-->M = testmatrix('magi',4)
M =
16.
2.
3.
13.
5.
11.
10.
8.
9.
7.
6.
12.
4.
14.
15.
1.
-->det(M)
ans =
delete
13.
8.
12.
1.
-->m(2,:) = []
m =
16. 3. 13.
9.
6. 12.
4. 15. 1.
delete
m =
16.
9.
4.
3.
6.
15.
13.
12.
1.
-->m(2,:)=[0 0 0]
m =
16. 3. 13.
0. 0.
0.
4. 15. 1.
-->m(:,3)=[1 1 1]'
m =
16. 3.
1.
0. 0.
1.
4. 15. 1.
-->M=testmatrix('magi',4)
M =
16.
2.
3.
-->M(14)
5. 11. 10.
9.
7.
6.
ans =
4.
8.
14.
15.
13.
8.
12.
1.
-->M([1 6 11 16])
ans =
-->M([4 7 10 13]) = [0 0 0 0]
M =
16.
11.
6.
16.
2.
3.
0.
5.
11.
0.
8.
Concatenation (1/2)
4.
5.
6.
C =
-->A = [1 2 3]'; B = [4 5 6]'; C = [A,B]
1. 2.
C =
1.
4.
2.
5.
3.
6.
3.
4.
5.
6.
Concatenation (2/2)
22
32
23
33
-->E = [A B; C D]
E =
11.
21.
12.
22.
13.
23.
14.
24.
31.
41.
32.
42.
33.
43.
34.
44.
Operators (1/4):
the Colon Operator (:)
-->1:8
ans =
1. 2. 3. 4. 5. 6. 7.
-->M = testmatrix('magi',4)
M =
16.
2.
3.
13.
5.
11.
10.
8.
9.
7.
6.
12.
4.
14.
15.
1.
8.
Operators (2/4):
more examples with (:)
-->M = testmatrix('magi',4);
-->M = testmatrix('magi',4);
-->M = testmatrix('magi',4);
-->A = M(2:3,2:3)
-->B = M(:,3)
-->C = M(3:4,:)
A =
B =
C =
11.
10.
3.
9.
7.
6.
7.
6.
10.
4.
14.
15.
12.
1.
Operators (3/4):
the $ Operator
-->M = testmatrix('magi',4)
M =
16. 2.
5. 11.
9. 7.
4. 14.
-->M($)
ans =
1.
-->M(1:$-1,$)
ans =
-->v = [3 4 5 6 7 8 9];
-->v($:-1:1)
ans =
13.
8.
12.
3. 13.
10. 8.
6. 12.
15. 1.
-->x = A\b
Warning :
matrix is close to singular or badly scaled. rcond =
computing least squares solution. (see lsq).
x =
4.1895D-18
Duplicating an mx1
vector to an mxn matrix
-->m = (2:2:6)';
-->n = 4;
2.
4.
6.
2.
4.
6.
2.
4.
6.
6 2
= 63 25 = 8 , it is therefore nonsingular
5 3
6 3
= 61 32 = 0 , meaning that it is singular
2 1
-->a = 125;
-->b = 521;
!Was it 125 that you said? !
LIFO
This is
LIFO
-->mprintf(\nThis is \nFIFO \nin action')
in action
This is
FIFO
in action
-->find(cars=='Saab')
ans =
4.
-->find(cars=='Volvo')
ans =
[]
-->gsort(cars)
ans =
!Xantia Fiat Audi !
!
!
!Saab BMW 343 !
Symbolic computing
!
!
v+w !
-->tsc = trianfml(sc)
tsc =
!z
!
!0
v+w
!
!
z*y-x*(v+w) !
Arrays: general
addition
subtraction
.*
multiplication
./
right division
.\
left division
.^
power
-->n = (0:9)';
-->powers = [n n.^2 2.^n]
powers =
0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
0.
1.
4.
9.
16.
25.
36.
49.
64.
81.
1.
2.
4.
8.
16.
32.
64.
128.
256.
512.
-->p = powers(4:5,1:2)
p =
3.
4.
9.
16.
-->q = powers(3,2)*powers(4,3)
q =
32.
Element-by-element
multiplication and division
Element-by-element
multiplication with the use of
the Dot Operator can also be
performed on two-dimensional
matrices
In the first example we multiply,
element-by-element, two 2x2
matrices to form a 2x2 product
matrix C
Note the different result with
ordinary matrix multiplication
And here we divide the same
matrices element-by-element to
form a 2x2 matrix of quotients
22.
50.
-->E = A./B
E =
0.2
0.3333333
0.4285714 0.5
-->A = [1 2; 3 4]
A =
1.
3.
2.
4.
-->B = [5 6; 2 -3]
B =
5. 6.
2. - 3.
-->A.\B
ans =
5.
3.
0.6666667 - 0.75
-->A./B
ans =
0.2
0.3333333
1.5 - 1.3333333
-->A = [1 2 3 4];
-->B = 1./A
B =
0.0333333
0.0666667
0.1
0.1333333
-->C = (1)./A
C =
1.
0.5
0.3333333
-->D = 2.*A
D =
2.
4.
6.
8.
-->E = (2).*A
E =
2.
4.
6.
8.
0.25
-->modulo(3,2)
ans =
-->modulo(n,m)
1.
ans =
1. 0.
x=input('Give a number :');
if modulo(x,2)==0
1. then
0.
disp('Number is even');
else
disp('Number is odd');
end
Number is even
Number is odd
-->xp=getdate();
-->xp(1),xp(2),xp(3),xp(4),xp(5),xp(6),xp(7)
ans =
2011.
ans =
3.
ans =
12.
ans =
83.
ans =
5.
ans =
24.
ans =
11.
-->M=round(5*rand(5,1))'
round() was
up in Ex. 1-3
M =
5.
2.
1.
5.
4.
0 and 3
are absent
-->unique(M)
A = [0 0 1 1;
ans =
0 1 1 1;
2 0 1 1;
0 2 2 2;
2 0 1 1;
1. 2. 4. 5.
0 0 1 1 ];
disp(['Unique rows are:'])
disp(unique(A,'r'))
0.
0.
1.
1.
0.
1.
1.
1.
0.
2.
2.
2.
// rand_demo1.sce
clear,clc,clf;
u_fun=rand(1,2000);
subplot(121);
histplot([-4:0.1:4],u_fun,2,'073',' ',[-4,0,4,1.2],[3,3,2,3]);
xtitle('Uniform')
G_fun=rand(1,2000,'n');
subplot(122);
histplot([-4:0.1:4],G_fun,2,'073',' ',[-4,0,4,1.2],[3,3,2,3]);
xtitle('Gaussian')
Dr.EW
Johnny Heikell
6. Examples, Set 2
Adds to what we have learned
so far
Return to Contents
1
-2
-1
2
6
3
1
4
3
b =
1
-2
1
// algebra1.sce
// Find the solution to x in /
// Ax = b
/
A = [1 2 -1; -2 -6 4; -1 -3 3];
b = [1; -2; 1];
x = A\b
The solution:
x1
x2
x3
-1
= 2
2
algebra1.sce has to be
run from the Console
since the script contains
no disp() command
-->exec algebra1.sce
-->// algebra1.sce
/
-->//
-->// Find the solution x in /
-->// Ax = b
/
-->//
-->A = [1 2 -1; -2 -6 4; -1 -3 3];
-->b = [1; -2; 1];
-->x = A\b
x =
- 1.
2.
2.
// algebra1.sce
// Find the solution x in /
// Ax = b
/
A = [1 2 -1; -2 -6 4; -1 -3 3];
b = [1; -2; 1];
x = A\b
// algebra1_check.sce
/
// Make sure that b - Ax = 0 /
x =
residual = b - A*x
- 1.
2.
2.
residual =
-->det(A)
ans =
- 2.
E3 = 4 V
i3
R3 = 12
Loop 3
i1
R1 = 2
R2 = 4
i2
i4
E1 = 5 V
Loop 1
R4 = 8
Loop 2
E2 = 3 V
Ex 2-2: mesh-currents
Instead, superposition of
currents with meshcurrent equations can be
used. Along the current
loops the diagonal term
resistances are:
R11 = 10
R22 = 12
R33 = 18
E3 = 4 V
R3 = 12
i_3
R1 = 2
E1 = 5 V
i_1
R2 = 4
R4 = 8
i_2
E2 = 3 V
Ex 2-2: solution
These values allow us to write the
following mesh-current equations:
10
-8
-2
-8
12
-4
-2
-4
18
i_1
i_2
i_3
// circuit1.sce
5
3
4
2.5
i1
i2
i3
i4
=
=
=
=
2.25
1.
residual =
Ex 2-2: comments
x'
1
s
where
A = system matrix
B = input matrix
C = output matrix
D = feedforward matrix
x = state vector
x= dx/dt
u = input vector
y = output vector
0
-1
C =
1
0.5
0
B =
D =
Ex 2-3: script
// state_space.sce
// System matrices
// Initial state
// Create cont.-time ('c') system model
// Time vector
// Create constant input signal
Ex 2-3: plots
Note the use of the function scf(number) (set current figure) to produce
two plots
State-space
External description
Internal description
Input/Output descriptions
State descriptions
Laplace transform
Matrix
In common are block diagrams and their manipulations, poles and zeros
These functions are needed e.g. when discretizing continuoustime models, for which Scilab has the function dscr() but
which is valid only for state-space models
// conv_seconds.sce
//
//
//
//
/
/
/
/
clear,clc;
time = input("Give time in seconds: ");
if time < 0
// Check if time >= 0
disp("ERROR, negative number")
// Display error message
abort
// and abort execution
else
minut = floor(time/60);
// Convert to minutes
seconds = modulo(time,60);
// Remaining seconds
hours = floor(minut/60);
// Convert to hours
minutes = modulo(minut,60);
// Remaining minutes
disp(string(hours)+" hour(s) "...
// Display answer
+string(minutes)+" minute(s)
+string(seconds)+" second(s) ")
end
Dr.EW
Johnny Heikell
Return to Contents
getcolor()
grayplot()
errbar()
plot3d()
fplot3d1()
Axes Editor
The most useful
editing objects are
Axes() and
Polyline(). Here
the Axes window is
open
There are seven
object properties
that can be played
with, the one for
the x-axis is shown
-->plot2d(t,[sin(t),cos(t)])
Graphics Window
commands
for figures:
show_window()
and the obsolete:**
xset()
*) Single plots can be created
without the scf() command.
**) Obsolete functions can be seen
in most Scilab tutorials, but they
should be avoided.
Windows-related clear/
delete commands are e.g.:
clf()
xdel()
delete()
obsolete are:
xclear()
xselect()
xbasc()
(Removed)
// multiple_plot.sce
// Demonstrates one alternative offered /
// by the plot2d() function
/
clear,clc,clf;
x = [0:0.01:2*%pi]';
plot2d(x,[sin(x) sin(2^x) sin(3*x)],rect=[0,0,6,1])
legend('sin(x)','sin(2^x)','sin(3*x)')
plot2d(): syntax
The plot2d() syntax can be used as a guide for some other plot
commands, e.g. for fplot2d()and histplot()
plot2d() has the following arguments:
plot2d(logflag,x,y,optional arguments)
// x axis definition
// Function 1
// Function 2
style1 = 5;
// style for sin
strf1 = '174';
// strf
rect = [0,-1.2,2*%pi,1.2];
// rect
nax = [4,%pi,4,7];
// nax
plot2d(x,y1,style1,strf1,' ',rect,nax)
style2 = -9;
// style for cos
strf2 = 000;
// No axes changes
leg = sin@cos;
// Legend definition
plot2d(x,y2,style2,strf2,leg)
Color codes are those that can be found with the getcolor()
command on the Console. The most important ones are 1=black,
2=blue (9=dark blue), 3=green (13=dark green), 5=red, 8=white,
and 25=brown
On the previous slide we saw that the code -9 creates circles. Plug
in getmark() on the Console to see the whole list, including codes
for mark sizes that you can use with handle commands. There are in
all 15 of these marks (always black):
-1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-12
-13
-14
-->plot2d(x,y, style=1)
-->scf();
fplot2d()
-->fplot2d(linspace(-10,10,100),sinc,style=5)
opt arg
// plot()_demo.sce
// Demonstration of plot() syntax /
clf();
t=0:0.1:2*%pi;
plot(t,sin(t),'o',..
// Plot with 'o'
t,cos(t),'x',..
// Plot with 'x'
t,abs(sin(t+%pi/4)),'<') // Plot with '<
Cross
--
Dashed line
'square' or 's'
Square
Dotted line
'diamond' or 'd'
Diamond
-.
Dash-dotted line
Upward-pointing triangle
Plus sign
Downward-pointing triangle
Circle
>
Right-pointing triangle
Asterisk
<
Left-pointing triangle
Point
'pentagram'
Five-armed star
3D graphs: plot3d()
r = (x2 y2)
3D graphs: plot3d(),
script & plot for 3D sinc()
Pay attention to [X,Y] = ndgrid(x,y)
& use of the Dot Operator in Z
// sinc3D.sce
// Plot the sinc function (sin(x)/x) using plot3d() /
// with surface definition arguments
/
clear,clc,clf;
x = linspace(-10,10,50);
y = linspace(-10,10,50);
[X,Y] = ndgrid(x,y);
//Create array for xy grid
Z = 50*sin(sqrt(X.^2 + Y.^2))./sqrt(X.^2 + Y.^2);
plot3d(x,y,Z,leg=X@Y@Z",flag=[4,2,4])
3D graphs: surf(),
task & script
// surf_ex1.sce
//
//
//
//
/
/
/
/
clear,clc,clf;
x=linspace(-2,2,30); // Linear spacing
y=linspace(-3,3,30);
[X,Y]=meshgrid(x,y); // Surface mesh
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
surf(X,Y,Z)
// Plot 3D surface
If you click on the display button for surf() in the Help Browser, Scilab
first displays a number of alternatives and then crashes.
// contour.sce
//
//
//
//
//
clear,clc,clf;
x=linspace(-2,2,30);
y=linspace(-3,3,30);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
contour(x,y,Z,10)
/
/
/
/
/
// vector_field.sce
//
//
//
//
clear,clc,clf;
x=linspace(-2,2,10);
y=linspace(-3,3,10);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
champ(x,y,X,Y)
Vector fields are not very informative per se, but the situation
improves when they are fused with contours
In the previous case, just insert the champ() and contour()
commands into the same script and you get them in one plot:
// contour-vector.sce
//
//
//
//
clf;
x=linspace(-2,2,15);
y=linspace(-3,3,15);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
champ(x,y,X,Y)
contour(x,y,Z,10)
/
/
/
/
Cutting a 3D surface
We can see the outline of the 3D surface z = (2*x2 y2)exp(-x2 0.5*y2) at a certain plane by defining the plane in case (below y =
-1) and by returning to 2D plotting:
// cutting.sce
// Cut the the function
/
// z=(2*x^2 - y^2)exp(-x^2 - 0.5*y^2) /
// along the plane y = -1
/
clf;
x=linspace(-2,2,50);
y=linspace(-1,-1,0);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
plot2d(X,Z,5)
// plot3d-contour.sce
//
//
//
//
/
/
/
/
clear,clc,clf;
x=linspace(-2,2,30);
y=linspace(-3,3,30);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2); // Same as before
contour(x,y,Z,10,flag=[0,0,0]);
// First flag[] argument
plot3d(x,y,Z,theta=60,alpha=80); // Turn 60 and 80 deg
subplot()
p=1
p=2
p=3
p=4
/
/
/
/
x=linspace(-2,2,10);
y=linspace(-3,3,10);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
subplot(223)
champ(x,y,X,Y)
clear,clc,clf;
x=linspace(-2,2,30);
y=linspace(-3,3,30);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
subplot(221)
surf(X,Y,Z)
x=linspace(-2,2,50);
y=linspace(-1,1,0);
[X,Y]=meshgrid(x,y);
Z=(2*X.^2-Y.^2).*exp(-X.^2-0.5*Y.^2);
subplot(224)
plot2d(X,Z,5)
subplot(222)
contour(x,y,Z,10)
There is
another
function for
subplots:
xsetech().
Check with
Help for
details
plot2d2(), plot2d3(),
plot2d4(): demo, script
// plot2dx.sce
subplot(222);
plot2d2(x,sinc(x),style=2) // Plot with steps
xtitle('plot2d2')
subplot(223);
plot2d3(x,sinc(x),style=2) // Plot vertical bars
xtitle('plot2d3')
subplot(224);
plot2d4(x,sinc(x),style=2) // Plot arrow style
xtitle('plot2d4')
plot2d2(), plot2d3(),
plot2d4(): demo, plot
Note: You
can still see
the obsolete
plot2d1() in
manuals.
plot2d()
should be
used instead
(In contrast,
plot3d1() is
not declared
obsolete)
Histograms: functions to
create them with
subplot(223)
hist3d(5*rand(8,4)) // 3D histogram
subplot(224)
z=10*rand(3,4);
x=[1 3 5 6];
y=[1 2 7 11 20];
hist3d(list(z,x,y))
// multiple_plots2.sce
//
//
//
//
clear,clc,clf;
x1 = linspace(0,1,61);
x2 = linspace(0,1,31);
x3 = linspace(0.1,0.9,12);
y1 = x1.*(1-x1).*cos(2*%pi*x1);
// First graph
y2 = x2.*(1-x2);
// Second graph
y3 = x3.*(1-x3) + 0.1*(rand(x3)-0.5); // Third, as y2 with disturbance
ymin = min([y1,y2,y3]);
// Select minimum to define frame bottom
ymax = max([y1,y2,y3]); // Select maximum to define frame top
dy = (ymax - ymin)*0.1;
// Border for min/max
rect = [0,ymin - dy,1,ymax+dy];
// Frame limits, start at 0
plot2d(x1,y1,5,"011"," ",rect)
// First call with frame definitions
plot2d(x2,y2,2,"000")
// Second call, only type/color (2) definition
plot2d(x3,y3,-1,"000")
// Third call, defines marks(-1)
xtitle("THREE GRAPHS PLOTTED IN THE SAME FRAME","Abscissa","Ordinate")
y3
y2
y1
Rotation surfaces
// rotation_surface.sce
The rotation
surface is
created by
multiplying
the original
function,
which is
redefined as
2+sin(T), by
.*sin(PHI)
and
.*cos(PHI)
Logarithmic scale:
task & script
// log_plot.sce
//
//
//
//
clear,clc,clf;
w = logspace(-1,3,100);
// Define log scale for w
s = %i*w;
// Define imaginary s
G = 100../((s-10).*(s-90)); // Define G(s)
y = 20*log10(abs(G));
// Define dB scale for y
plot2d(w,y,5,logflag='ln') // Plot y=f(w)
xtitle("Bode plot for G(s)=100/((s-10)(s-90))","w,...
log scale","y, dB scale")
xgrid()
// Add grid
Logarithmic scale:
the plot
The graph has been
edited after plotting
We have not before
mentioned the argument
logflag ln in plot2d().
Change ln to nn (ll is
not possible here) and see
how the plot changes
(n=normal, l=logarithmic)
Note: Scilab has a special
function for Bode plots,
bode(). See Example 3-1
Polar coordinates
//cardioid.sce
Exporting plots
export to PNG
export to PDF
export to SVG
export to EPS
export to Postscript
export to EMF (Windows)
xs2fig()
xs2gif()
xs2jpg()
xs2bmp()
xs2ppm()
export to FIG
export to GIF
export to JPG
export to BMP
export to PPM
Handles (1/12):
introduction*
Handles (2/12):
introduction*
x = a.x_label
y_label
y = a.y_label
z_label
title
t = a.title
compound
etc.
Object Browser
that we have used
to edit plots
c = a.children
legend
polyline
Lessons learned:
1) You have to be systematic when working with handles
2) The existing literature is not always correct. For instance, the
method suggested by Steer for changing axes ticks & marks simply
does not work (took me hours to figure out)
=================================
parent: Figure
children: "Compound
A check with
gce() reveals
that Compound in turn has a
child, Polyline. This matches
the hierarchy that we have
seen on the Figure Editor
-->gce()
ans =
// handles_demo1.sce
// Basic script to demonstrate handles /
clear,clc,clf;
x = linspace(0, 4*%pi, 100);
plot2d(x, 0.5*cos(x))
f=gcf(); // Get Figure (window) handle
f.figure_size = [500,400]; // Adjust window size
f.background = 12;
// Add background color
f.figure_name= "cosine"; // Name window
a=gca();
// Get Axes handle
a.background = 9; // Change background
c=a.children;
// Get compound handle
p1=c.children; // Get polyline (plot) handle
p1.foreground = 8; // Change line color
p1.line_style = 7;
// Change line style
p1.thickness = 3;
// Line thickness
xtitle('COSINE PLOT',...
'X-axis','Y-axis');
t=a.title;
t.font_style = 5;
t.font_size = 3;
xL=a.x_label;
xL.font_style = 5;
xL.font_size = 2;
yL=a.y_label;
yL.font_style = 5;
yL.font_size = 2;
xgrid(5);
// Add grid
a.x_ticks = tlist(['ticks','locations','labels'],...
[0,%pi,2*%pi,3*%pi,4*%pi,14],...
['0','pi','2*pi3','3*pi','4*pi','14']);
a.y_ticks = tlist(['ticks','locations','labels'],...
[-0.5,-0.25,0,0.25,0.5],...
['-0.5','-0.25','0','0.25','0.5']);
Handles (11/12):
comments (1/2)
a=gca();
a.children(1).foreground=5;
!--error 15
Submatrix incorrectly defined.
at line
6 of function %h_get called by :
at line
16 of function generic_i_h called by :
at line
2 of function %s_i_h called by :
children(1).foreground = 5; // Sum pattern re
at line
68 of exec file called by :
opulse_a-pattern.sce', -1
Handles (12/12):
comments (2/2)
!--error 999
This object has no auto_clear property.
at line
4 of function generic_i_h called by :
at line
2 of function %c_i_h called by :
e2.auto_clear = "on";at line
71 of exec file called by :
examples\planet_moon1.sce', -1
// xpoly.sce
// Attempt to plot a hexagon with xpoly() & edit
// with handles. Causes erroneous behavior in
// Scilab. The script must be closed to get rid of
// the grey background color
/
/
/
/
clear,clc,clf;
x = sin(2*%pi*(0:5)/6);
y = cos(2*%pi*(0:5)/6);
xpoly(x,y,'lines',1);
// Define hexagon
// - "
// Draw polygone
e=gca();
// Get Axes handle
e.parent.background =...
// Get Figure handle
color('grey');
// & set background
e.box='on';
// Switch frame on
e.foreground=5;
// Red frame color
e.data_bounds=[-2,-2;2,2]; // Frame size
e.children.foreground = 2; // Blue graph color
It is left open if we do a
small change to the x/y
arguments:
x = sin(2*%pi*(0:5)/6);
y = cos(2*%pi*(0:5)/6);
plot2d(x,y,strf='011',rect=[-2,-2,2,2])
Programming pitfalls:
dont forget clf;
// ptifalls_1.sce
// Clear commands /
Change
and
rerun
K = 100; a = 0; b = 0;
x = zeros(1,K); y = zeros(1,K);
for k = 1:K
x(k) = a+k;
y(k) = b+k^(0.5);
end
plot2d3(x,y,style=-1)
// ptifalls_1.sce
// Clear commands /
K = 10; a = 0; b = 0;
x = zeros(1,K); y = zeros(1,K);
for k = 1:K
x(k) = a+k;
y(k) = b-k^(0.5);
end
plot2d3(x,y,style=-1)
Plots are
superposed
without the
clf command
1. Initial script
with xset()
x=-1:0.1:2.6
plot2d(x,sin(2*x),5,rect=[-2,-2,3.6,2])
xset("color",2)
2. Modified script
with Axes handle
command
x=-1:0.1:2.6
plot2d(x,sin(2*x),5,rect=[-2,-2,3.6,2])
a=gca();
a.foreground=2
3. Modified script
with set() and
handle argument
x=-1:0.1:2.6
plot2d(x,sin(2*x),5,rect=[-2,-2,3.6,2])
a=gca();
set(a,"foreground",2)
xset(background,1)
black
h.background = 1
xset(color,2)
blue fill
h.foreground = 2
xset(thickness,3)
line thickness
h.thickness = 3
xset(color,5)
red border
h.foreground = 5
But frankly, it can be a pain and you want to throw the computer out
the window. If so, check if the gca() handle has any children at all...
plot2d(x1,y1,style=5) // Function
!--error 999 plot2d:
first and second arguments have incompatible dimensions.
at line
16 of exec file called by :
exec("H:/Dr.EW/Writings/Scilab examples/derviative_2.sce");
while executing a callback
clc();
!--error 13
Redefining permanent variable.
Dr.EW
Johnny Heikell
8. Examples, Set 3
On plotting, handles, control
engineering, and user defined
functions
Return to Contents
Example 2-3 and the log scale demo were typical control engineering
tasks. Recall also the pages on polynomials in Chapter 3
Here well look at examples with Bode and Nyquist plots, Nichols
chart (Blacks diagram), and an Evans root locus plot
The first cases use the second-order transfer functions
G2(s) =
s2 + 20s + 100
s2
+ 6s + 100
s2 + 3s + 220
s2 + 25s + 225
5+s
2000s2 + 200s3 + 25s4 + s5
Ex 3-1:
script
// control_eng.sce
// Plot Bode, Nyquist, Nichols & Black's, /
// and Evans for defined equations
/
clear,clc,clf;
// Definition of systems:
//------------------------------s = poly(0,'s'); // Polynomial seed
Gain1 = syslin('c',(s^2+20*s+100)/(s^2+6*s+100));
Gain2 = Gain1*syslin('c',(s^2+3*s+220)/(s^2+25*s+225));
Gain3 = poly(-5,'s')/poly([0,0,2000,200,25,1],'s','c');
Gain4 = syslin('c',352*Gain3);
// Bode plot:
//--------------subplot(221)
gainplot([Gain2;Gain1],0.01,100) // Magnitude plot
// Nyquist plot:
//------------------subplot(222)
nyquist([Gain2;Gain1]) // Plot with Re and Im axes
Ex 3-1: plot
The plot has not
been edited,
everything shown
is the result of the
script. Note the
red iso-curves on
the Bode-Nichols
subplot
Ex 3-1: comments
The script was modified after being copied from the Scilab Group
Users Manual and pasted into Editor. When copy-pasting, Editor
tends to interpret citation marks (c,s, etc.) wrongly and they have
to be corrected manually
Scilab is strict with the arguments for polynomial expressions. If, for
instance, the c is left out from the expression
poly([0,0,2000,200,25,1],s,c), it will be translated into 10000000s2
- 10455000s3 + 455225s4 - 2226s5 + s6. Be careful!
There is an advantage in using self-documenting expressions, here
exemplified by naming the polynomials Gain1, Gain2, etc.
The separate Bode plot demo showed that the bode() function has
an advantage in providing also the phase of the system of interest
The difference between Blacks diagram and Nichols chart will be
demonstrated in Example 3-2
// black_nichols.sce
// Demonstration of black() and /
// chart() functions
/
clear,clc,clf;
s = %s;
Gain = (2+3*s+s^2)/(1+3*s+2.5*s^2+s^3);
system = syslin('c',Gain);
black(system,.01,100) // Plot Black's diagram
chart([-8,-2,.5,3,6,12],[5,25,60,120],list(1,1,2,5))
// chart() adds iso-graphs
Ex 3-2: plots
black(sl,.01,100)
black(sl,.01,100)
chart ([-8,-2,.5,3,6,12],[5,25,60,120],list(1,1,2,5))
Example 3-3: an RC
circuit
R = 1 k
uin
uout
C = 0.1 F
G=
uout
uin
1
1 + i2 f RC
Ex 3-3: script
The logspace(1,6,60)
command means starting
point 101, end point 106,
in 60 steps and
logarithmic scale
Trigonometric phase
definition and conversion
to degrees
The logflag = ln
argument defines a
logarithmic x-scale and
linear (normal) y-scale
Different styles and
xgrid() arguments have
been used to
demonstrate their effect
// bode_RC.sce
// Bode diagram for an RC circuit /
// (first-order low-pass filter)
/
clear,clc,clf;
R = 1e+3;
// Resistance in ohm
C = 1e-7;
// Capacitance in farad
freq = logspace(1,6,60); // Frequency range, logarithmic
G = 1 ./ (1 + %i*2*%pi*freq*R*C); // Transfer function
G_dB = 20*log10(abs(G));
// Logarithmic scale
phase = ((atan(imag(G),real(G)))/(%pi))*180; // Phase
subplot(211);
// Amplitude plot
plot2d(freq,G_dB,logflag='ln',style=5)
xgrid(2)
// Blue grid
xtitle('Amplitude','Frequency (Hz)','Gain (dB)')
subplot(212)
// Phase plot
plot2d(freq,phase,logflag='ln',style=2)
xgrid(3)
// Green grid
xtitle('Phase','Frequency (Hz)','Phase (deg)')
Ex 3-3: plot
Note that the xaxis label is
missing for the
phase plot,
although it was
specified. Scilab
does not repeat it
since it is the
same as the top
one. Change the
subplot
declarations to
(121) and (122)
and the x-axis
label is given for
both parts
Radiating
elements
Amplitude
weights
Phase
shifters
1
d
wN
wn
w3
w2
w1
......
(n-1)dsin
......
N
En
| AF | =
sin [ N ( d ) sin ]
sin [ ( d ) sin ]
Scan angle
| AF | =
d
sin [ ( ) (sin - sin o)]
Scan angle
Ex 3-4:
script
// array_factor.sce
// ---------------------------------------------------------------------------------/
// Plots the array factor of a linear antenna array with N elemnts,
/
// spaced at d wavelengths, and main beam scanned at +60 degrees /
// ---------------------------------------------------------------------------------/
clear,clc,clf;
// Variables:
N = 10;
// Number of radiating elements
d1 = 0.45;
// Element spacing in wavelengths
d2 = 0.55;
// Ditto
theta = [-%pi/2:0.01:%pi/2]'; // Half space, +/-90 deg
theta_z = %pi/3;
// Scan angle
AF_norm2 = abs((sin(N*f_phase2)./sin(f_phase2))/N);
// Plot functions:
subplot(211
// Linear plot (d=0.45,0.55)
plot2d(theta,[AF_norm1,AF_norm2], style=[2,5],...
leg="d = 0.55@d = 0.45")
xtitle("ANTENNA ARRAY FACTOR, N = 10, Beam angle = 60 deg",...
"Theta (radians)","Normalized amplitude")
subplot(212)
// Polar diagram (d=0.55)
polarplot(theta,AF_norm2, style=5)
xtitle('POLAR DIAGRAM FOR d = 0.55:')
Ex 3-4: plot
Grating lobe
Main lobe
Main lobe
Grating lobe
Main lobe
Grating lobe
Example 3-5:
3D sinc
// sinc_colormap.sce
// Define and plot 3D sic funtion, graphic /
// adjust properties with handles /
clear,clc,clf;
x=linspace(-10,10,50); // Linear space of x
y=x; // Ditto for y
function [z]=sincf(x, y)
r=sqrt(x.^2+y.^2)+%eps; // Auxiliary computation
z=sin(r)./r;
// Amplitude
endfunction
For comparison we first do a basic plot with plot2d() and then modify
the figure with handles
//
//
//
//
handles_demo2-1.sce
Two Lissajous figures, sin(t) & cos(3t) and
/
sin(1.5t) & 0.5*cos(1.5t), with plot definitions /
given by arguments of the plot2d() function
/
clear,clc,clf;
// Plot Lissajous figures:
//------------------------------t=linspace(0,6,100)';
sines = [sin(t) sin(1.5*t)];
cosines = [cos(3*t) 0.5*cos(1.5*t)];
plot2d(sines, cosines, [2,5], ...
leg='sin(t), cos(3t)@sin(1.5t), 0.5*cos(1.5t)',...
nax=[1,9,1,9], rect=[-1.1,-1.1,1.1,1.1])
# of linspace() steps is
lowered to 40 to better
show the arrows that are
used below
// handles_demo2-3.sce
clear,clc,clf;
f=gcf();
// Get Figure handle
f.background=color('grey'); // Grey background color
a.x_ticks = tlist(['ticks','locations','labels'],...
[-1.1,-.825,-.55,-.275,0,.275,.55,.827,1.1],...
['-1.1','-.825','-.55','-.275','0','.275','.55',...
'.825','1.1']);
a.y_ticks = tlist(['ticks','locations','labels'],...
[-1.1,-.825,-.55,-.275,0,.275,.55,.827,1.1],...
['-1.1','-.825','-.55','-.275','0','.275','.55',...
'.825','1.1']);
a.labels_font_color=13; // Change label color
a.labels_font_size=2;
// Increase label size
set(gca(),'grid',[1 1]);
// Matlab's "grid on"
a.grid(1)=color('green'); // Vertical line color
a.grid(2)=color('green'); // Horizontal line color
There were huge problems when I first tried to include the gce(), get
current Entity, command in the script. The background color did not come
up after Scilab was reloaded, I could not define ticks, etc.
Lessons learned: Be sure that you now what you do with gce()!
And a final check on
the next slide
plot2d(sines,cosines,rect=[-1.1,-1.1,1.1,1.1])
Dr.EW
Johnny Heikell
9. Converting Matlab
files
The embedded Matlab-to-Scilab
translator seems to work and
manual conversion is an option
Return to Contents
*) It used to be possible to import Matlab files directly, but this option does not
exist any more.
M-to-S translator:
messages on the Console
Scilab presents a
list of translation
conditions and
also warnings of
possible errors
on the Console.
The warnings
are repeated as
comments in the
script (and on
one of the text
documents)
Next, open the
translated script
in the Editor
// Display mode
mode(0);
// Display warning for floating point exception
ieee(1);
// Monopulse Antenna Pattern
// -------------------------------------clear,clc,// !! L.4: All children will be deleted, no
HandleVisibility property in Scilab graphics.
clf;
// Normalized Aperture Width
na = 4;
// Sampling Frequeny=Number elements per norm aperture
fs = 8;
// Illumination Function
wxna(1,1:N/2) = ones(1,N/2);
wxna = mtlb_i(wxna,N/2+1:N,-ones(1,N/2));
wxnb(1,1:N/2) = ones(1,N/2);
wxnb = mtlb_i(wxnb,N/2+1:N,ones(1,N/2));
// Fill with M/2 zeros front and back
M = 1024;
xna = na*(-1/2:1/N+M-1:1/2);
wxna = [zeros(1,M/2),wxna,zeros(1,M/2)];
wxnb = [zeros(1,M/2),wxnb,zeros(1,M/2)];
// Beam Functions from -fs/2 to fs/2 in sine space
Nfft = max(size(wxna));
Esine = mtlb_fft(wxna,Nfft);
Esine = fftshift(Esine);
plot(fi,Gfi,fi,Gfs);mtlb_grid;
set(gca(),"data_bounds",matrix([-0.25,0.25,-0.8,1],2,-1));
ylabel("Amplitude");
xlabel("Angle - radians");
title("Monopulse Antenna Patterns");
// !! L.63: Matlab function text not yet converted,
original calling sequence used.
text(0.04,0.8,"Sum Pattern");
// !! L.64: Matlab function text not yet converted,
original calling sequence used.
text(-0.22,0.6,"Difference Pattern");
Yeees, it comes,
labels and all!
But the legends are
missing, which
means that Scilab
cannot cope with
Matlabs text()
function
M-to-S translator:
comments
Based on this example one could say that the embedded Matlab-toScilab translator is adequate
A legend has to be added manually to compensate for the missing
text() information*
The example demonstrates partly good programming practice by
declaring each logical entity. However, informative explanations
could be added
Another improvement is to use expressive variable names. Why not
talk about sampl_freq instead of fs, and what does wxna() stand
for?
Help sheds no light over the meaning of the second .sci files that the
conversion produces
*) A paper by Sharma & Gobbert (2010) reports that the translator cannot
cope with Matlabs xlim() function. In their case the plot() function had to
be manually changed to plot2d() to correct the problem.
The pie() function has not been discussed before, but below is a
short Matlab script that draws a pie graph*
The pie() function also exists in Scilab, the difference is that Scilab
does not support Matlabs pielabel() function
revenues = [31 36 18 8 7];
h = pie(revenues);
pielabel(h,{'Income Tax: ';'Sales Tax: ';'Borrowing: ';
'Corporate Taxes: ';'Misc: '});
// M-to-S_2-pie.sce
// Draw a pie graph with labels /
clear,clc,clf;
revenues = [31 36 18 8 7];
pie(revenues,['Income Tax';'Sales Tax';'Borrowing';
'Corporate Taxes';'Misc']);
// M-to-S_3polarplot.sce
// Polar plot of 1+sin(x)/x /
clear,clc,clf;
x = -(5*2*%pi):.1:(5*2*%pi);
th = linspace(-%pi,%pi,length(x));
rho = 1+sin(x)./x;
polarplot(th,rho)
Linear plot
// M-to-S_3polarplot.sce
// Polar plot of 1+sin(x)/x
clear,clc,clf;
x = -(5*2*%pi):.1:(5*2*%pi);
th = linspace(-%pi,%pi,length(x));
rho = 10*log10((1+sin(x)./x));
subplot(211);
plot2d(th,rho)
subplot(212);
polarplot(th,rho)
Polar plot
Dr.EW
Johnny Heikell
10. Subroutines
This discussion on subroutines is
a prelude to flow control that will
be discussed in Chapter 11
Return to Contents
Terminology
Recall from Chapter 1 that Scilab does not recognize the term
subroutine, which belongs to the group of varied constructs that
Scilab calls function. More exact, we are talking about user defined
functions (UDFs), an expression that Scilab also does not know
Regardless of official Scilab terminology, I willwhen possibleuse
the traditional term subroutine since it is an elegant way of pointing
to specific entities in computer programs
An introductory demo
function A = triangle_area(a,b,c)
funcprot(0)
p = (a+b+c)/2 // p = half perimeter
A = sqrt(p*(p-a)*(p-b)*(p-c))
endfunction
-->function A = triangle_area(a,b,c)
-->// The function 'triangle_area' calculates the /
-->// area of a triangle with side lengths a, b, c. /
-->funcprot(0)
-->p = (a+b+c)/2 // p = half perimeter
-->A = sqrt(p*(p-a)*(p-b)*(p-c))
-->endfunction
-->triangle_area(4,5,6)
ans =
9.9215674
Local functions are embedded in a script and valid for it alone, global
functions are saved separately and accessible to any script
Local function
(local subroutine)
.....
.....
Call 1
Call
Result 1
Result
.....
.....
Call 2
.....
.....
Scilab script 1
Global function
(global subroutine)
.....
.....
Call
Result
Result 2
Scilab script
Scilab script 2
You will run into the terms local and global variables and they
need a short clarification:
As with functions, Scilab has two types of function variables,
local and global:
Subroutines, more
formally
endfunction
On output arguments
The example to the
right highlights the
basic way in which
Scilab manages output
arguments of
subroutines
-->y2 = myfunc(4,7)
y2 =
-->myfunc(4,7)
ans =
12.
12.
3x4=12
3x4=12
-->[y1,y2] = myfunc(4,7)
y2 =
37.
5x7+2=37
y1 =
12.
3x4=12
With no output
argument defined,
the first output
argument is returned
in the ans variable
The same answer is
returned when only
one output argument
is defined
With both output
arguments defined,
the result of the
computation is
returned in full
Vector arguments
x(1)=5*(-5)-8*(-13)
x(2)=8*7-(-2)*(-5)
x(3)=-2*(-13)-5*7
*) Here I use the term function since the code is independent and not called
by a main program.
Demo (1/2):
script
Task: Compute & plot a
parabola, find its
positive root
Here the subroutine is
called for the first time
using the input
argument x
// subroutine1.sce
// Compute & plot the function y = x^2-x+1 in the /
// range [-5,5] and determine its positive root.
/
// Assume we know the root lies in the range [1,2] /
clear, clc, clf;
// SUBROUTINE para():
//-----------------------------function y=para(x);
// Subroutine declaration
y = x^2-x-1
// Equation (parabola))
endfunction
// MAIN script:
//------------------x = linspace(-5,5,100); // Range of interest
plot(x,para)
// Call subroutine and plot
xgrid;
// Add grid
a=1; b=2;
while b-a > 10^(-4)
c = (a+b)/2;
if para(a)*para(c)>0
// Search limits
// Accuracy for searching root
// Midpoint of limits
then // IF (lower)*(midpoint)
// is positive
// THEN change lower limit
a=c;
else
b=c;
// ELSE change upper limit
end
end
disp("The root lies between "... // Output root limits
+string(a)+" and "+string(b))
Nested subroutines
-->function y = nested(x)
--> a = sin(x) + 2*%pi;
-->
function y = inner(x);
-->
y = x^2 -sqrt(x);
-->
endfunction
--> y = inner(a) + 3^2;
-->endfunction
-->value = nested(%pi/3)
value =
57.437413
-->f(2), f(-5)
-->g(2), g(-5)
ans =
ans =
5.
5.
Note the
semicolon!
(Scilab
understands
if you skip it
after the
second y
expression)
Global subroutines:
window demo (1/4)
Global subroutines:
window demo (2/4)
Global subroutines:
window demo (3/4)
// reuse_function.sce
// Reusing graphics function,
/
// defenitions with handle commands /
Figure saved.
So it is as a subroutine. I called
it window_demo.scg . Note the
ending .scg. Not .sce or .sci.
Its g for graphic
Then we need a main script
that uses global subroutine
Note that I call the Entity
handle e=gce(). It simplifies
compared to the path needed if
calling the Axes handle, as was
done in Chapter 7
clear,clc;
Global subroutines:
window demo (4/4), plot
y1 = 2*sin(x) - 2;
y2 = 2*cos(2*x) + 6;
plot2d(x,[y1',y2'])
e=gce();
e.children.thickness=5;
// First equation
// Second equation
// Plot both
// Get Entity handle
// Polyline size
Dr.EW
Johnny Heikell
Introduction
We have now come to the line that separates boys from men
Some examples using flow control (also known as conditional
branching and programming) have come up in the preceding
chapters, but the nature of conditional branch commands like if ...
then ... else has not been discussed*
Flow control together with subroutines are needed for serious
practical simulations
We shall therefore take a good look at the most important aspects of
flow control
Note, however, that loop operations are slow. We should aim for
vectorized operations if a task requires a lot of loop iterations (there
is a brief discussion on the subject in Chapter 18)
*) Historical note: Konrad Zuse, the German who built the first real computer
during WW II (using over 2000 relays because he did not trust vacuum tubes),
got everything right except for conditional branches.
Logical operators:
Comparison operators:
==
equal to
<
smaller than
>
greater than
<=
smaller or equal to
>=
greater or equal to
<> or ~=
not equal to
Logical/Boolean constants:
&
and
| or /
or
%t or %T
true
not
%f or %F
false
*) Rumor has it that Scilab will see select ... case renamed switch ... case
in line with Matlab.
for end
No semicolon!
As seen here:
// for-end_demo.sce
// Compute the square root and square /
// of odd integers from 1 to 8
/
square cannot
be used as
variable name
since square() is
a Scilab function
n = 8;
for k = 1:2:n
root = sqrt(k);
quadrat = k^2;
disp([k, root, quadrat])
end
1.
1.
1.
3.
1.7320508
9.
5.
2.236068
25.
for ... end can be nested with if/else conditions to allow for
execution of alternate statements:
for variable = initial_value:step:final_value
if condition
// foo
else
// foo
end
end
--------------------------------------------------------------------------- /
The script generates Gaussian noise around a fixed signal.
/
Each sample ("signal") is sorted according to whether it
/
is within, above or below default variance limits (+/-1). The /
result is reported verbally with strings and is also plotted
/
--------------------------------------------------------------------------- /
clear,clc,clf;
// Define variables:
// -----------------------n = 500;
// # of forend loops
above = 0;
// Signals above upper variance limit
below = 0;
// Signals below lower variance limit
within = 0;
// Signals within variance limits
ave = 3;
// Mean (average)
x = [];
// x axis vector
// Generate signal:
// ---------------------dt = getdate();
// Get date
rand('seed',(531+n)*dt(9)+dt(10)); // Initialize random generator
signal= ave + rand(1,n,'normal');
// Shifted Gaussian signal
// Sort signal:
// ---------------for j = 1:1:n
if signal(1,j) > ave+1 then
above = above + 1;
elseif signal(1,j) < ave-1
below = below +1;
else
within = within + 1;
end
end
// Display result:
// -------------------disp(['Result from generating', string(n), 'Gaussian distributed samples'])
disp(['(signals) with mean =' string(ave) 'and variance = 1:'])
disp([' -' string(within) ' samples were inside variance limits,'])
disp([' -' string(above) 'above upper variance limit, and'])
disp([' -' string(below) 'below lower limit'])
// Plot result:
// --------------x = [1:1:n];
// Array for x axis
y1 = ave*ones(1,n);
// Array for mean value
y2 = (ave+1)*ones(1,n);
// Array for upper variance limit
y3 = (ave-1)*ones(1,n);
// Array for lower variance limit
rect = [0,ave-4,n+1,ave+4];
// Set pot window
plot2d(x,signal,2,"011"," ",rect) // Plot samples
plot2d(x,y1,5,"000")
// Plot mean value
plot2d(x,y2,3,"000")
// Plot upper variance limit
plot2d(x,y3,3,"000")
// Plot upper variance limit
legend('signal','average','variance');
xtitle('GAUSSIAN RANDOM SAMPLES','Sample #','Sample value')
It can be seen
that there are one
! - 77 below lower limit !
or
two samples
outside the 3
limit, as should be
while end
-->k
k =
52.
while if /then/else
end
The while ... end condition can be nested with an optional if ...
then ... else instruction:
while condition_1
if condition_2 then
// foo
else
// foo
end
// foo
end
The function on the next slide is for a game in which the user should
guess a random number that the computer draws. The game finishes
only with the correct guess
while if /then/else
end: demo
// game.sci
// The function draws a random number in the /
// range [1,M] that the user should guess.
/
// Game finishes when correct number is found /
clear,clc;
Loop
M=30;
// Upper limit of numbers
number=floor(1+M*rand());
// Draw a random number
disp('Guess a positive integer in the range ');
disp([1,M]);
// State range of random numbers
guess=input('You guess: ');
// User's guess
while (guess~=number)
// Start while condition
if guess>number then
// Start if-then-else
disp('Number is too big');
else
disp('Number is too small');
end
// End if-then-else
guess=input('You guess: '); // User's next guess
end
// End while condition
disp('Correct!');
Comments on
interactivity
To the user the input() prompt is not very clear since the text string
only pops upit should at least blink. One must therefore try to find
expressive text messages. Perhaps the following would be better in
the previous case:
guess = input(Now, Sir/Madame, type your guess: )
foo do end
-->n = 9;
-->k = 1;
-->k = 1;
-->n = n - 3
-->while k <= 3 do
-->end
-->n = n -3
-->n = n-3
n =
-->k = k + 1;
-->k = k + 1;
-->end
-->end
n =
n =
-->n = 9;
-->for k = 1:1:3 do
6.
if (elseif/else) end
else
// foo
end
if elseif/else end:
demo
The following function computes the n:th term of the Fibonacci sequence
when n is given:
// fibonacci.sci
// Gives the n-th term of the Fibonacci /
// sequence 0,1,1,2,3,5,8,13,...
/
funcprot(0)
// Suppress redefenition warning
function [K] = fibonacci(n)
if n==1
// Begin if-elseif-else-end
K = 0;
elseif n==2
// Condition to proceed, n > 2
K = 1;
elseif n>2 & int(n)==n
// Check if n is an integer >2
K = fibonacci(n-1) + fibonacci(n-2);
// Compute Fibonacci #
else
// Previous conditions not met
disp('error! -- input is not a positive integer'); // Error message
end
// End of if-elseif-else-end
endfunction
-->fibonacci(8)
ans =
Check what
happens
for n < 1
13.
The select ... case ... else ... end construct executes the first case
that matches the stated condition
If no match is found it executes the else statement
The advantage of select ... case ... else ... end is that it allows us
to avoid multiple if statements
select condition
case 1
// foo
case 2
// foo
else
// foo
end
// randomwalk.sce
//-----------------------------------------------------------------/
// Creates a track of marks that proceed randomly
/
// in the x,y plane. The walk starts at the origin
/
// and proceeds for a predetermined number of steps /
// either up, down, right, or left
/
//-----------------------------------------------------------------/
clear,clc,clf;
funcprot(0);
function randwalk(steps)
x=zeros(1,steps+1);
// Counter for x track
y=zeros(1,steps+1);
// Counter for y track
for k=1:steps
direction=floor(4*rand()); // Draw random move
select direction
case 0 then
x(k+1)=x(k)+1;
// Move right
y(k+1)=y(k);
case 1 then
x(k+1)=x(k)-1;
// Move left
y(k+1)=y(k);
-->randwalk(1000)
case 2 then
x(k+1)=x(k);
y(k+1)=y(k)+1;
case 3 then
x(k+1)=x(k);
y(k+1)=y(k)-1;
end
end
clf
plot(x,y,'o-');
endfunction
// Move up
// Move down
// Plot marks
-->while 1 == 1,
-->k = k + 1;
-->disp(k);
-->if k > 6 then
-->for j = 1:2
-->break
-->x = [];
-->end;
-->for k = 1:10
-->end
-->if k>j+1 & k<=8 then
-->continue
1.
-->end
-->x = [x,k];
2.
-->end
-->x
break: demo
Give amount of numbers to sum_3
// break.sce
clear,clc;
wrong-----negative value!
Give amount of numbers to sum_ 4
Give next number_ 18
!Accumulated error-free sum is: 19 !
Give next number_ 3.3
Dr.EW
Johnny Heikell
Unit step:
1
0
t0
y(t) =
t
0, t < t0
1, t > t0
rect = [-5.2,-0.2,5.2,1.2];
plot2d(x,u(x),5,'011',' ',rect)
xgrid()
a=gca();
// Get axes handle
a.title.text="UNITY STEP";
// Add title
a.children.children.thickness=3; // Increase line thickness
Rectangular pulse:
y
A
0
t0
y(t) =
t1
A, t0 t < t1
0, otherwise
clear,clc,clf;
t = 0:0.01:10;
deff('y=u(t)','y=1*(t>=0)');
// Define u(t)
y = 2*(u(t-3) - u(t-5));
// Define pulse
plot2d(t,y,5,rect=[0,0,8,2.5]) // Plot
xgrid()
// Add grid
f=gcf();
// Figure handle
f.children.thickness=2;
// Figure lines
a=gca();
c=a.children;
// Compound handle
c.children.thickness=3;
// Line thickness
In the first case (unit step) the handle command for line thickness is
a.children.children.thickness=3;
In the second case (rectangular pulse) Scilab did not accept this
form and it had to be rewritten as
c=a.children;
c.children.thickness=3;
I have no idea why this is the case and Help certainly is of no help
In the latter case I happened to write the script without the deff()
function, and for a while everything came out all right. But when I
added handle commands Scilab decided that the variable u is
undefined. The KISS principle (Keep It Simple, Stupid) did not apply
in this case
//
//
//
//
//
//
********************************************** //
The script generates and plots a cone with its
//
tip at the origin. It plots two copies of the
//
cone, one shifted and one shifted & rotated
//
//
********************************************** //
clear,clc,clf;
// Vertical reach of 3D object:
vertical=[0,1.0,1.6,2.5,2.2,2,1.6,0.9,0.5,0.3,0.3,0.4,0.6,1,1.4,...
1.7,0,0,0.1,0.4,0.8,1.1,1.4,1.7,1.9,2.2,2.4,2.7,3,3.3,3.7,3.9]/2;
// SUBROUTINE 1: Generation of 3D object:
//---------------------------------------------------------function [x,y,z]=cone(reach,Z) // Generation of a 3D object
x=vertical(1,Z).*cos(reach)
// Extension along x axis
y=vertical(1,Z).*sin(reach)
// Extension along y axis
z=vertical(1,Z).*ones(reach)
// Vertical (z) axis
endfunction
eval3dp() transforms
the smooth surface that
cone() creates into a
composition of
quadrangular facets
Here we plot the basic
cone, which has its tip
in the origin. The
exterior and interior of
the cone should have
different shades
Objects are manipulated
by vectors created by
the earlier user defined
functions
Ex 4-2: plot
Ex 4-2: comments
// cone_creation.sce
[xv,yv,zv]=eval3dp(cone,linspace(-%pi/1.5,%pi,20),1:5);
Ex 4-3: plot
Dark gray interior (e1.hiddencolor = 30)
Z5 = 3
Box alignment
defined by theta
and alpha in
plot3d()
Z4 = 2.3
Z3 = 2
Z2 = 1
Z1 = 0
Light gray exterior (e1.color_mode = 24)
Ex 4-3: discussion
If you change the first element in vertical[] from 0 to 0.5, youll see
that the tip of the cone is cut off
There are six elements in the vector vertical[]. The last one (4) is
never used since the third argument in eval3dp() is 1:5, meaning
that only the first five vector elements are needed. Hence the z axis
of the plot is [0,3]
I left a gap in the perimeter of the cone to demonstrate the role of
the second argument in eval3dp()
This example has correct shading of the object. The surface pattern
in Ex 4-2 is no artistic creation but messed up due to overlapping Zn
values
// vase_creation.sce
// A bare-bone eval3dp() script for plotting a 3D vase /
clear,clc,clf;
vertical=[0,1,2,2.3,3,4];
// Vertical reach of 3D object
R_factor=[1,1,0,-1.5,-1,0];
// Correction matrix
function [x,y,z]=cone(reach,Z)
R=vertical+R_factor;
x=R(1,Z).*cos(reach)
y=R(1,Z).*sin(reach)
z=vertical(1,Z).*ones(reach)
endfunction
// Generation of a 3D object
// Radius of vase, R=f(Z)
// Extension along x axis
// Extension along y axis
// Vertical (z) extension
[xv,yv,zv]=eval3dp(cone,linspace(-%pi,%pi,20),1:5);
plot3d(xv,yv,zv,theta=60,alpha=70) // Plot object
e1=gce();
// Get Current Entity handle
e1.color_mode = 24;
// Object exterior: light grey
e1.hiddencolor = 30;
// Object interior: dark grey
-->voting
Give number of issues to vote on_5
yes
no
yes -->voting
Give number of issues to vote on_-2.2
//
//
//
//
function voting
/
/
/
/
clear,clc;
funcprot(0)
Generation of random
numbers in the similar
manner to Ex 1-3
Then a select ... case
... end construct that
transforms the
random numbers to
text strings
Ex 4-4: comments
if ... end
// conditional.sce
//
//
//
//
scale = [1 2 3 4 5 6 7 8 9]';
// Define scale to climb
i = 1;
// Preset counter
strg = ' ';
// strg = empty string
while strg ~= 'e'
// Until the "e" key is hit
disp(scale(i,:));
// Display location on scale
strg = input('Exit(e), Up(u), Down(d)?','string')
if strg == 'u' then
// If "u" is hit
i = min(i+1, size(scale,1)); // One step up, until highest
elseif strg == 'd' then
// But if "d" is hit
i = max(i-1, 1);
// One step down, until lowest
elseif strg == 'e' then
// If "e" is hit
break;
// Jump out of the loop
else
// Whatever else is hit
disp('---incorrect input---') // Present error message
end
// End of if statement
end
// End of while statement
disp('you hit e=Exit')
// Exit message
Example 4-5:
execution
The scale counter i is preset to
1 and increases/decreases
depending on the entered data
Any input parameter except u,
d, or e give an error message
The break command works well
in this case
Homework: Modify the script by using the
select ... case ... else ... end structure
instead of if ... elseif ... else ... end.
Which solution is simpler?
1.
Exit(e), Up(u), Down(d)?u
strg =
u
2.
Exit(e), Up(u), Down(d)?u
strg =
u
3.
Exit(e), Up(u), Down(d)?d
strg =
d
2.
Exit(e), Up(u), Down(d)?6
strg =
6
---incorrect input--2.
Exit(e), Up(u), Down(d)?u
strg =
u
3.
Exit(e), Up(u), Down(d)?e
strg =
e
you hit e=Exit
Dr.EW
Johnny Heikell
// optim_list.sce
// Investigation of minima and maxima of the function /
// sin(x)/((x-0.1)^2+0.1)
/
clear,clc,clf;
// SUBROUTINES
//----------------------
deff('[fun1,grad,ind]=cost1(x,ind)',...
// Function
'fun1=sin(x)/((x-0.1)^2+0.1),grad=0');
deff('[fun2,grad,ind]=cost2(x,ind)',...
// Inverse function,
'fun2=-sin(x)/((x-0.1)^2+0.1),grad=0'); // note minus sign
// Plot function
min
- 1.1381166
max
2.1199214
max
roots
min
As said on the previous slide, approximate values for the roots are:
x1 -3, x2 0, x3 3
With the script is loaded into Scilab, we find the solutions on the
Console using the command x = fsolve(x0,f):
-->x1 = fsolve(-3,cost1)
x1
x1 =
x2
- 3.1415927
x3
-->x2 = fsolve(0,cost1)
x2 =
fsolve(): limitation
The script below demonstrates that for values of point close to peak of
the sin curve, e.g. 4.6 or 8, Scilab cannot solve the root correctly
// fsolve.sce
// Solves, for the equation sin(a*x)-x*exp(-x),
// the root closest to a defined point.
// Note: The selected point must not be too
// close to the midpoint between two roots
/
/
/
/
clear,clc,clf;
function y=myfunc(x)
a=1;
y=sin(a*x)-x.*exp(-x);
endfunction
x1=linspace(0,10,300);
plot2d(x1,myfunc(x1),5)
plot2d(x1,zeros(x1),2)
point = 8;
[x,y]=fsolve(point,myfunc)
plot2d(x,y,-3)
// Plot function
// Add y=0 graph
// Point of interest
// Def root closest to point
// Add mark for root location
Complex numbers:
demo, task
C = -j20
Complex numbers
have not been
discussed at any
length before, so lets
look at a practical
problem
The task is to solve
the steady-state
currents i1, i2, and i3
in the shown circuit
i3
L = j12
u1 =
100 -90o V
[Z] =
i1
R2+jL
-R2
-jL
R1 = 20
R2 = 80
-R2
R1+R2
-R1
i2
u2 =
500 0o V
-jL
-R1
R1+jL-jC
Complex numbers:
demo, equations
80+j12
-80
-j12
-80
100
-20
-1 0-j100
-j12
-20
-500-j0
20-j8
0+j0
Note that u2 was selected opposite to u1, hence the minus sign
Scilab has no problems with doing inverse matrices but, as mentioned
before, left hand division (\) typically gives better accuracy
Complex numbers:
demo, script (1/3)
// circuit3.sce
//
//
//
//
/
/
/
/
clear,clc;
// Compute complex currents:
//--------------------------------------Z = [80+12*%i, -80, -12*%i;
-80, 100, -20;
-12*%i, -20, 20-8*%i]; // Impedance matrix
u = [-100*%i; -500; 0];
// Voltage matrix
i_n = Z\u;
// Compute i = Z\u
// Calculate magnitude and phase:
//--------------------------------------------magn_i = [];
// Define empty current matrix
phase_i = [];
// Define empty phase matrix
for j = 1:1:3
// Compute for three currents
magn_i(j) = sqrt(real(i_n(j))^2 + imag(i_n(j))^2);
// Computes magnitude
Complex numbers:
demo, script (2/3)
// Calculate phase:
//-----------------------if clean(real(i_n(j))) > 0 then
// In 1st or 4th quadrant
phase_i(j) = atan(imag(i_n(j))/real(i_n(j)))*(180/%pi);
elseif clean(real(i_n(j))) < 0
// In 2nd or 3rd quadrant
if clean(imag(i_n(j))) > 0 then // In 2nd quadrant
phase_i(j) = atan(imag(i_n(j))/real(i_n(j)))*(180/%pi) + 180;
elseif clean(imag(i_n(j))) < 0 then
// In 3rd quadrant
phase_i(j) = atan(imag(i_n(j))/real(i_n(j)))*(180/%pi) - 180;
else
// On negative Re-axis
phase_i(j) = 180;
end
elseif clean(imag(i_n(j))) > 0
// On positive Im-axis
phase_i(j) = 90;
elseif clean(imag(i_n(j))) < 0
// On negative Im-axis
phase_i(j) = -90;
else
// Origin: imag(i_n(j)) = real(i_n(j)) = 0
phase_i(j) = 0;
end
result(j,:) = [i_n(j), magn_i(j), phase_i(j)];
// Matrix collects computed data
j = j+1;
end
Complex numbers:
demo, script (3/3) & print
In plain English:
i1 = 22.0 cos(t - 129.5) A
i2 = 24.0 cos(t - 129,3) A
i3 = 25.5 cos(t - 78.7) A
// Display summary:
//-------------------------currents = ['i1 = ', 'i2 = ', 'i3 = ']';
// String matrix
statement = [' equals: ',' equals: ',' equals: ']';
// String matrix
disp(['CURRENTS IN COMPLEX AND POLAR FORM:']) // Headline
disp([currents, string(result(:,1)), statement,...
// Display result
string(result(1:3,2)), string(result(1:3,3))])
// Check residual:
//---------------------residual = clean(u - Z*i_n)'
// derivative_1.sce
// Derivative of sin(x)/((x-0.1)^2+0.1) /
// calculated at selected points
/
clear,clc;
funcprot(0);
deff('y=f(x)','y=sin(x)./((x-0.1)^2 + 0.1)');
x = [-2 -1 0 1 2]';
// Points of interest
disp(["Point", "Derivative"])
disp([x, diag(derivative(f,x))])
!Point Derivative !
- 2. - 0.2800316
- 1. - 0.6663016
0.
9.0909091
/
/
clear,clc,clf;
funcprot(0)
x = -5:0.01:5;
d = 0.001;
// Area of interest
// Step size
deff('y1=f(x)','y1=sin(x)./((x-0.1)^2 + 0.1)');
// f(x)
deff('y2=g(x)','y2=((sin(x+d)./(((x+d)-0.1)^2 + 0.1))...
-(sin(x)./((x-0.1)^2 + 0.1)))/d');
// f'(x)
fplot2d(x,f,5,"011"," ",rect)
// Plot function
fplot2d(x,g,2,"000")
// Plot derivative
xgrid
// Add grid to plot
xtitle('f(x) = sin(x)/((x-0.1)^2+0.1 AND ITS DERIVATIVE')
legend('Function f(x)','Derivative of f(x)')
a=gca();
a.children.children(2).thickness=2
// f'(x)) thickness
a.children.children(3).thickness=2
// f(x) thickness
Pay attention to the legend command in the script. It comes before the
related handle statements, but Scilab does not complain. Beats me...
-->deff('y=f(x)', 'y=6*x^2');
A = f(x) dx
a
-->A = intg(-2,1,f)
-->deff('y=f(x)', 'y=sin(x)');
A =
18.
A = intg(a,b,f)
*) The function
integrate() can be more
useful in some cases.
Check with Help
-->A=intg(0, 2*%pi, f)
!--error 24
Convergence problem...
Change the
integration limits to
0 and 2*%pi, and
this is what you get
L = {1 + [f (x)]2}1/2 dx
-->deff('y=g(x)','y=sqrt(1+(x^2/8-2*x^(-2))^2)');
-->L=intg(2,3,g)
L =
a
1.125
-->L=intg(3,4,g)
L =
1.7083333
y
d
f(x,y) dx
I=
dy
D=a,d
C=b,d
ACD
ABC
A=a,c
B=b,c
a a
X= b b ,
b a
ABC ACD
c c
Y= c d
d d
ABC ACD
I=
(y cos(x) + x sin(y)) dx
/2
-->deff('z=f(x,y)', 'z=y*cos(x)+x*sin(y)');
/2 /2
Y = /2 2
2
2
dy
0.
3.1415927
3.1415927
0.
3.1415927
0.
1.5707963
1.5707963
6.2831853
1.5707963
6.2831853
6.2831853
-->[I,err] = int2d(X,Y,f)
err =
9.805D-11
I =
- 4.9348022
// double_integral_plot.sce
// Plot the function z = y*sin(x) + x*sin(y)
/
// over the rectangle 0<x<%pi, %pi/2<y<2*%pi /
clear,clc,clf;
x=linspace(0,%pi,30);
// Linear x axis
y=linspace(%pi/2,2*%pi,30); // Ditto y axis
[X,Y]=meshgrid(x,y);
// Surface mesh
Z=(Y.*cos(X)+X.*sin(Y));
// 3D surface equation
surf(X,Y,Z)
// Plot 3D surface
xtitle('f(x,y) = y*cos(x) + x*sin(y),
// Add title
with 0<x<%pi, %pi/2<y<2*%pi')
y
d
D=a,d
C=b,d
BCD
ABD
A=a,c
B=b,c
a b
X= b b ,
a a
c c
Y= c d
d d
Ordinary differential
equations (ODEs): ode()*
This simplest call for solving ODEs is ode() that has the
general form:
y = ode(y0,t0,t,f(t,y))
where
y0 = initial condition (normally a column vector)
t0 = initial time (normally 0)
t = vector of instances for which the solution has to be
computed, e.g. t = [0:0.01:10]
f(t,y) = function for which the solution has to be found, often
stated as [ydot] = f(t,y). Here t is a scalar, y a column vector,
and [ydot] a column vector with values of the derivative
Second-order ODEs:
introduction
Problem expressed as
second-order ODE
Substitute state
variables with zerothorder variables
Rewrite problem as
first-order state-space
equation system
Solve using Scilabs
ode() function
Second-order ODEs:
RLC circuit (1/5), the task
U = 5V
switch closes at t = 1
R = 0.3
L = 0.5 H
C = 0.8 F
v1(t)
i(t)
d2v2(t)
dt2
+
-
LC
dv2(t)
+ RC
dt
+ v2(t) = v1(t)
v2(t)
Second-order ODEs:
RLC circuit (2/5), reduce
1
RC
x1
x2 +
1
LC
RC
x1
0
+
x2
1
LC
Second-order ODEs:
RLC circuit (3/5), script
Recall the discussion
in connection with Ex
2-3: We are working
with a matrix
expression of the type
x = Ax + bu
All of these factors
can be seen here,
with x being denoted
ss and x substituted
by y
// RLC_ODE.sce
// Simulation of a series RCL circuit with /
// 5V step input voltage at t = 1s
/
clear,clc,clf;
Second-order ODEs:
RLC circuit (4/5), script
The ode() function
computes our
differential equation by
using the RLC statespace expression of the
second deff() function.
Calling parameters are
y0 and t0
Note the plot command
(new way of doing
plot2d())
// Edit plot:
//--------------
a=gca();
a.children.children.thickness=2
Second-order ODEs:
RLC circuit (5/5), plot
The plot shows that the
circuit is undercritically
damped. Change the
resistor value to 1.5 ,
and it becomes critical. It
is overcritical for still
higher values of R
Handle commands could
be used to edit the figure
further. I did not do it
because the main point
with this demo is to solve
a second-order ODE
odeoptions()
The command
%ODEOPTIONS = odeoptions()
opens the GUI shown right. With
the help of it you can change
parameters for solving differential
equations. Examples:
h0 = size of first step
Dr.EW
Johnny Heikell
Example 5-1:
solving an equation (1/3)
-->x = (0.01:0.01:8)';
ln(x) = x2-7x+10
-->plot2d(x,[log(x), x.^2-7*x+10])
Ex 5-1: solving an
equation (2/3)
The zoom function gives more precise values for the roots:
x1 = 1.81 and x2 = 5.49
To improve the accuracy even more we can calculate the roots with
the fsolve() function (next slide)
Ex 5-1: solving an
equation (3/3)
-->deff('y=f(x)', 'y=log(x)-(x^2-7*x+10)');
-->x1=fsolve(1.8,f)
x1 =
-->x2=fsolve(5.5,f)
x2 =
1.8132512
5.4881107
-->f(x1),f(x2)
ans =
- 7.772D-16
ans =
- 4.441D-16
Check
u(t)
i(t)
di(t)
L
1
+ Ri(t) +
dt
q(t) = u(t)
C
where
t
q=
i(t) dt
or:
dq
dt
q +
= i
R = 0.3
L = 0.5 H
C = 0.8 F
u(t) = sin(5t)
1
LC
i +
q
=
i
LC
Remember: x = Ax + Bu
0
+
1
L
//
//
//
//
/
/
/
/
clear;clc,clf;
// Define circuit components:
//-------------------------------------R = 0.3;
// Resistance (Ohm)
L = 0.5;
// Inductance (Henry)
C = 0.8;
// Capacitance (Farad)
// Define state-space equations & input signal:
//-------------------------------------------------------------A = [0 1; -1/(L*C) -R/L];
// SS system matrix
B = [0; 1/L];
// SS input matrix
deff('[ut]=u(t)','ut=sin(5*t)');
// Sinusoidal input
deff('[ss]=RLC(t,y)',ss=A*y+B*u(t)'); // SS expression
This example is modified from Povy (pp. 66-67, Povy also has an
animation version on pp. 67-68, but it causes Scilab to crash). The
example finishes with and interesting plot2d() command
The task is to plot the slope (vector) field for the following system of
first-order ODEs :
x = y
y = -x y
x
0
=
y
-1
1
-1
x
y
together with a single phase portrait with the initial trajectory x(0) =
1 and y(0) = 1
The script can utilize either the ODE system (as Povy has done) or
the state-space representation. Well select the latter, in line with
earlier examples
Ex 5-3:
script
The state-space function
is named firstorder()
// ode_phase_plane_m.sce
//
//
//
//
/
/
/
/
clear,clc,clf;
funcprot(0);
// First order transformation:
//-------------------------------------A = [0 1;-1 -1];
// State vector
deff('[ss]=firstorder(t,x)',ss=A*x');
// Create & draw slope (vector) field:
//------------------------------------------------z = linspace(-1.5,1.5,10);
fchamp(firstorder,0,z,z)
// Draw vector field
// Create phase portrait:
//------------------------------x0 = [1;1];
// Initial condition
t = linspace(0,30,300);
[x] = ode(x0,0,t,firstorder); // [x]=state variable vector
// with x=x(1), y=x(2)
// Plot phase portrait on slope field:
//----------------------------------------------plot2d(x(1,:),x(2,:),5,'004')
xtitle('Phase plane of dx/dt=y, dy/dt=-x-y')
Ex 5-3: plot
Full plot
Phase portrait
with initial
condition [1,1]
Zoomed center
area
I =
(y cos(x) + x sin(y)) dx dy ,
/2 0
I=
ij
i=2
j=2
i = i+2 j = j+2
b-a
n
y =
d-c
m
Furthermore:
Si j = fi-1 j-1 + fi-1 j+1 + fi+1 j-1 + fi+1 j+1 +
4(fi-1 j + fi j-1 + fi+1 j + fi j+1 ) + 16 fi j
// double_integration_simpson.sce
1. Overall headline
comments for the
program
//-----------------------------------------------------------------/
// The program calculates the double integral of the /
2. UDF declaration
followed by clarifying
comments
clear,clc;
endfunction
Dr.EW
Johnny Heikell
Introduction
Scilabs GUI interface was updated with version 5. Old tutorials (e.g.
Campbell et al.) are therefore of limited value
Brief discussions of GUIs can be found in Kubitzki and in Antonelli &
Chiaverini (you can read Scilab scripts in German and Italian even if
you dont speak the language)
Although the GUI interface has improved, the Scilab team still cannot
be proud of their achievement
GUIs is a large subject; the Help Browser identifies about 50 GUIrelated functions. Well be able to cover only a part of them (as
always)
We have earlier seen cases with the dialogue box (x_dialog() in Ex.
1-3) and the messagebox (messagebox() in Ex. 5-4)
The first discussion below is about how to tailor Scilabs windows
Following that we shall look at some user defined dialog windows. A
real GUI is presented in Example 6-1
setmenu()
unsetmenu()
This is not the whole truth. The book by Das, which is a collection of
Scilabs Help function texts, contains more hints
You can convince yourself that the added Console menu works by
clicking on New window to open the Graphics Window and click on
Close window to close it again
As the following steps we can deactivate the created menu by the
command unsetmenu() and delete it with delmenu():
xclick ()
xgetmouse ()
seteventhandler ()
// rectangle_selection.sce
// The script demonstrates the use of the mouse-related
// commands xclick(), xgetmouse() and xrect() when they
// are used to draw a rectangle in the Graphics Window
/
/
/
clear,clc,clf;
// Initialize drawing process:
//-------------------------------------a = gca();
// Get current Axes
a.data_bounds = [0 0;100 100]; // Boundaries for x & y coordinates
xtitle('Click left mouse button & drag to create a rectangle. ...
Click a second time to freeze')
// Display instruction
show_window();
// Put Graphics Window on top
// Start drawing rectangle in the Graphics Window:
//-------------------------------------------------------------------[button,x_coord,y_coord] = xclick(); // Point of mouse button click
xrect(x_coord,y_coord,0,0)
// Start rectangle at mouse pointer x & y coordinates
rectangle = gce();
// Get rectangle handle
mouse = [x_coord,y_coord,-1];
// Mouse pointer 1x3 matrix
Command
Feature
messagebox()
x_choose()
x_choices()
x_dialog()
x_mdialog()
x_matrix()
list()*
GUIs: messagebox()
The syntax of the messagebox() function is the following:
messagebox (message, title, icon, [buttons], modal )
Default title
Case 2:
Default icon
-->m = messagebox('Division by 0: Continue?','WARNING',['Yes' 'No'])
m =
Case
4: x_dialog() with input transformed
2.
from string to matrix
9.
8.
7.
1.
Change
2.
3.
Case 5: x_choices()
with four alternatives
for three cases
Pick your
choices, click
OK, and
Scilab returns
the answer as
a vector*
-->answer
answer =
3.
2.
1.
// x-matrix_demo.sce
// Demonstrates the use of x_matrix()
clear,clc;
ans =
- 1.450D-12
ans =
-->bew = ['Beer','Wine','Brandy','Gin','Water'];
-->m
m =
3.
2.
-->get(0,"screensize_px")
ans =
1.
1.
1280.
800.
-->get(0,"screensize_pt")
ans =
0.
0.
960.
600.
-->get(0,"screensize_norm")
ans =
0.
0.
1.
1.
-->get(0,"screendepth")
ans =
24.
GUI shortcomings
Dr.EW
Johnny Heikell
Return to Contents
File handling:
introduction
mfprint, fprintMat()
mfscanf(), fscanMat()
mseek()
menf()
size()
*) The full set of i/o functions (~60 in all) can be found under Help/Files:
Input/Output functions. Recall the related load() function in Chapter 10.
// file_exercise1.sce
//
//
//
//
//
/
/
/
/
/
clear,clc;
// Create and open a text file for the exercise:
//------------------------------------------------------------fd = mopen('H:\Dr.EW\Writings\Scilab examples\file_exercise1.txt','w');
// Create data and write into the exercise file:
//------------------------------------------------------------t = (1:1:18)';
// Integers from 1 to 18
mfprintf(fd,'%6.3f\n',t);
-->contents
five_data =
contents =
1.
2.
3.
1.
2.
-->three_data
3.
three_data =
4.
5.
6.
7.
6.
-->data_11
7.
data_11 =
8.
9.
8.
4.
5.
The variables
five_data ,
three_data , and
data_11 were
defined in the
script
n is the # of
elements (-1) in
the vector it
belongs to (4-1)
We can also
address specific
elements in the
column vector
and get the
answer as a row
vector
-->M = fscanfMat('I:\file_spreadsheet_demo5.csv')
M =
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
- 7.3
- 7.8
- 8.3
- 7.6
- 5.
- 3.3
- 1.9
0.1
1.2
0.4
- 2.1
- 3.6
20.1
19.8
19.5
19.5
19.7
20.
20.2
20.6
21.1
21.3
21.
20.7
M = fscanfMat()
-->[G,text] = fscanfMat('I:\file_spreadsheet_demo5.csv')
text =
Reading
Outdoor
Indoor
G =
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
- 7.3
- 7.8
- 8.3
- 7.6
- 5.
- 3.3
- 1.9
0.1
1.2
0.4
- 2.1
- 3.6
20.1
19.8
19.5
19.5
19.7
20.
20.2
20.6
21.1
21.3
21.
20.7
// spreadsheet_data_plot.sce
The size(name,r)
function is used to
determine the number
of matrix rows
mopen()
The mopen() function is of course more intricate than what one can
understand from the discussion above. Forgetting binary and text
files, the general structure of mopen() is:
[fd <,err>] = mopen(file_name <,mode>)
where
file_name is the entire path of the file, including its name
mode defines what to do with the data, e.g.:
It can be a good idea to check the err parameter after a file has
been opened (has not been done in Demo 1)
mclose()
A file that has been opened with mopen() should be closed with the
mclose(fd) command even if it is automatically closed when Scilab
closes. However, pay attention to the following ambiguous statement
in Scilabs Help Browser:
mclose must be used to close a file opened by mopen. If fd is
omitted mclose closes the last opened file.
Be careful with the use of [mclose(all)] ... because when it is used
inside a Scilab script file, it also closes the script and Scilab will not
execute commands written after mclose(all).
mfprintf(), fprintfMat()
Which means that each value that we want to print is declared with
an optional text, the format to be printed in (both within a single pair
of quotation marks), and the value to be printed
Format declarations are given on the next slide
The format demo two slides down should give a better grasp of what
it all means. If you ask me, it looks really messy...
The fprintfMat() command is used to write a matrix in a file. See
Help for details
Format definitions
\n go to a new line
\t use a horizontal tabulator
Format demo:
script (1/2)
This demo aims at clarifying the use of format declarations:
// file_format_demo.sce
//
//
//
//
/
/
/
/
clear,clc;
Format demo:
script (2/2) & text file
// Several outputs to be demonstrated:
//-------------------------------------------mfprintf(fd,'%d\n %10d\n %20d\n %8.4f\t %8.4f\n %5.2f\t %5.2f\t %5.2f\n',...
A,A,A,A,A,A,A,A);
mfprintf(fd,'%d\n %f\t %e\n %10.3f\t %6.2f\n complex = %3.4f + i%3.4f\n\n',...
A,A,A,A,A, real(c), imag(c));
mfprintf(fd,'%e\t %5.2e\n %s\n %5s\t %10s\t %15s\t %20s\t\n',...
A,A, text, text, text, text, text);
// Close the opened file:
//-------------------------mclose(fd);
Remember
to close!
No optional
text is used
in any of
the cases
mfscanf(), fscanfMat()
Dr.EW
Johnny Heikell
17. Animation
A brief introduction to creating
dynamic graphics
Return to Contents
Introduction
The script uses the xfarcs() function to fill the moving pie. Related
Scilab functions are xfarc(), xarcs(), and xarc()
xfarcs() is used instead of xfarc() because the latter has no
provision for defining plot color by arguments, and its Axes handle
gca() does not recognize any children that would allow colors to be
defined
*) Also called double buffer mode because the picture is first created in one
buffer before being pushed to the second (the Graphics Window).
/
/
/
/
clear,clc;
steps = 250; // # of animation steps
r1 = 0.5;
// Pie size
r2 = 0.5;
// Loop size
f = gcf();
// Figure handle
f.pixmap = "on";
// Create before display
for i=1:steps
clf();
// Erase pie after each step
plot2d (%nan,%nan,frameflag=3,.. // Define figure
rect=[-2,-2,2,2],axesflag=1)
xtitle('MOVING PIE');
theta1 = i*2*%pi/steps;
theta2 = i*10*%pi/steps;
c = [cos(theta1)+r2*cos(theta2),.. // Define pie..
sin(theta1)+r2*sin(theta2)];
// position
xfarcs([c(1)-r1, c(2)+r1, 2*r1,...
// Plot pie,..
2*r1, 0, 360*48]', 2);
// color=2
f.background = color('grey');
show_pixmap();
// Display created graphics
end
f.pixmap = 'off';
// Exit pixmap mode
clear,clc,clf();
f=gcf();
f.pixmap='on';
// Double buffer mode
f.pixel_drawing_mode='nor';
// NOR mode
f.background=color("lightblue");
ax=gca();
ax.data_bounds=[0,-4;14,10];
// Plot limits
ax.margins=[.1 .1 .1 .1];
// Plot framed
ax.background=color("lightgrey");
max_pos = 10;
// Max position of rectangles
k=%nan;
// Auxiliary parameter
xfrect(k,k,4,4);
// First black rectangle
e1 = gce();
xfrect(max_pos-k,max_pos-k,4,4); // Second rectangle
e2=gce();
for k=linspace(1,10,200)
// Animation loop
e1.data(1:2)=k;
e2.data(1:2)=max_pos-k;
show_pixmap()
//Show double buffer
end
Demo 3 (1/3): a 3D
object, script (1/2)
// rotating_surface.sce
// Initialize:
//--------------
f=gcf();
f.pixmap="on";
clear_pixmap();
t=%pi/20*(-20:20); // Bounds & mesh resolution
plot3d1(t,t,sin(t)'*cos(t),%nan,%nan,..
'x_axis@y_axis@z_axis');
Demo 3 (2/3): a 3D
object, script (2/2)
Demo 3 (3/3): a 3D
object, plot
The surface has reached
its destination: rotated to
100 (azimuth) and tilted
to 80 (elevation)
While testing various
parameters I saw this
message on the Console
(long list). It disappeared
when I re-run the script
Dr.EW
Johnny Heikell
18. Miscellaneous
A hotchpotch of philosophy and
realism that hopefully is of use
Return to Contents
The problem-solving
process
The problem-solving process for a computational problem typically goes
through the following steps (not a textbook definition):
1.
2.
3.
4.
5.
6.
Programming pitfalls
(1/4)
Programming pitfalls
(2/4): error types
Programming pitfalls
(3/4): error messages
Incompatible vector lengths
would be a better error message
-->[1 2 3] + [4 5]
!--error 8
-->[1 2 3] * [4 5 6]
!--error 10
Inconsistent multiplication.
-->sqrt = 5^2 + 3*17
Warning : redefining function:
sqrt
Here you
sqrt =
76.
funcprot(0)
to avoid this
message
can see. Use
that
the warning
redefining
function
does have a meaning. I have improperly used sqrt as a
variable name, but Scilab recognizes it is a built-in
function. The answer is correct, but one should rather
change the variable name. Check help name if you are
uncertain if an intended variable name is reserved
Programming pitfalls
(4/4): the endless loop
I have several times mentioned
the risk of creating an endless
loop, so lets look at this little beast
When you execute the script you
have to crash the program to stop
it. The easiest way is to press the
Close button on the Console and
then reload Scilab
Why does the loop not end?
Because we die from old age
before the variable n by chance
gets exactly the value 0.5
// endless_loop.sce
// Demonstrates an endless loop.
// Execution ends only by crashing
// the program (click on the Close
// button (X) on the Console)
/
/
/
/
n = .1;
dt = getdate();
rand('seed',1000*dt(9) + dt(10));
while n ~=0.5;
n = rand(0,'normal');
end;
disp(n)
Debugging (1/2)
Debugging (2/2):
validation
// add_demo1.sce
clc;
add = 0;
i = 0;
while ( i < 100 )
i = i + 1;
if ( modulo( i, 2 ) == 0 ) then
continue;
end
add = add + i;
end
2500.
disp( add )
// add_demo2.sce
clc;
add = sum(1:2:100);
disp(add)
2500.
// measure_time1.sce
clear,clc;
x=[];
// Initate vector
y=[];
// Ditto
tic();
// Start stopwatch
for t=0:0.0002:2*%pi
x=[x; t];
y=[y; sin(t)];
end
time=toc(); // Stop watch
disp(time) // Display time
0.
0.
2.
0.9092974
4. - 0.7568025
6. - 0.2794155
17.389
0.014
// measure_time2.sce
clear,clc;
tic();
t = (0:0.0002:2*%pi)';
[t,sin(t)]
disp(toc())
0.009
x = ones(100000,1);
disp(toc())
0.005
!k = 200660 !
!time = 10.142 !
tic();
k = 0;
for i = 1:1000000
x = rand(1,1);
if x < 0.2 then
k = k + 1;
end
end
disp(['k =' string(k)])
disp(['time =' string(toc())])
tic();
k = length(find(rand(1000000,1) < 0.2));
disp(['k =' string(k)])
disp(['time =' string(toc())])
!k = 199649 !
!time = 0.298 !
Discrepancy in time
measurements (1/2)
I wanted to check Scilabs computation time for a cased given in a
textbook on Matlab by Hahn & Valentine. First I did it on the Console
and then on the Editor, but the results did not match:
-->tic();
-->s = 0;
-->for n = 1:100000
-->s = s + n;
-->end
-->time = toc();
// scilab-matlab_loop.sce
clc;
tic();
s = 0;
for n = 1:100000
s = s + n;
end
time = toc();
disp(time)
0.453
Discrepancy in time
measurements (2/2)
And here is the same in vectorized form:
-->tic();
-->n = 1:100000;
-->s = sum(n);
// scilab-matlab_vectorized.sce
clc;
tic();
n = 1:100000;
s = sum(n);
time = toc();
disp(time)
0.016
-->time = toc();
The bug (Scilab bug #8942) remains unsolved and its true influence
is unknown to me. The Scilab team gives the unhelpful suggestion to
download the mentioned file
hold on
!--error 4
Undefined variable: hold
Dr.EW
Johnny Heikell
Return to Contents
START
Any changes?
Yes
EXIT pressed?
Yes
Close GUI
END
No
Implement
changes
No
Go to the MAIN
program below if you
want to proceed in a
logical order
The first subroutine,
initial_GUI(), creates
the initial sine plot
within the Graphics
Window; including
title and axes labels
function initial_GUI()
t = linspace(0,7,200);
w = 5;
// Initial angular frequency
plot2d(t,sin(w.*t),..
// Initial plot w=5 rad/s
rect = [0,-1.1,7,1.1]);
a = gca();
a.axes_bounds = [0.2,0,.8,1]; // Frame dimensions & location
xtitle("GUI DEMO WITH sin (wt)",...
"Time [s]","Amplitude");
a.font_size = 3;
// Axes mark size
a.x_label.font_size = 3;
// x_label size
a.y_label.font_size = 3;
// y_label size
a.title.font_size = 3;
// Title size
endfunction
Ex 6-1:
script/
The next two
subroutines respond to
user commands (slider
and radiobuttons
respectively), and point
to the fourt subroutine,
new_GUI_data()
An existing plot is
erased
The slider goes from
end to end in 10 steps
The if-then-else-end
constructs register the
status of whichever
radiobutton has been
clicked
function update_radio()
new_GUI_data();
endfunction
// IF radiobutton click
// GOTO new_GUI_data()
function new_GUI_data()
t = linspace(0,7,200)
drawlater();
// Delay changes
a = gca();
if (a.children~=[]) then
// IF frame contains graph...
delete(a.children);
// then delete graph
end
w = h_slider.value/10;
// Slider range: 10 steps
plot2d(t,sin(w.*t));
if (h_radio1.value == 0) then
// Check status of style button
a.children.children.polyline_style=1; // Basic style: line
else
a.children.children.polyline_style=3; // IF clicked: bars
end
if h_radio2.value==0 then
// Check status of color button
a.children.children.foreground=1;
// Basic color: black
else
a.children.children.foreground=2;
// IF clicked: blue
end
drawnow();
endfunction
h_slider= uicontrol(h_graph,...
"style","slider",...
// Declare slider
"Min",0,...
// Slider start value
"Max",100,...
// Slider end value
"value",50,...
// Initial slider value
"position",[10 size_y-270 180 20],... // Slider size & location
"callback","update_slider();... // GOTO to update_slider()
foo = strcat([ ' w = ' string(h_slider.value/10)...
' rad/s ']);h_text_slider.string = foo");
slidelbl = strcat(["w = 5 rad/s"]);
// Define initial label
h_text_slider = uicontrol(h_graph,...
"style","text",...
// Declare text
"horizontalalignment","center",...
// Position in reserved field
"string",slidelbl,...
// Add slider label
"fontsize",14,...
"backgroundColor",[1 1 1],...
// White background
"position",[10 size_y-310 180 20]);
// Field size & location
// Declare radiobutton
// Initial button value
// GOTO to update_radio()
// Declare button text
// Gray background
// Field size & location
Notice the callback statements. They are the beasts that make us jump
up to (GOTO) the subroutine in case (here to update_radio())
// Declare radiobutton
// Initial button value
// GOTO to update_radio()
// Declare button text
// Gray background
// Field size & location
Ex 6-1: discussion
// animation_pincon_m2.sce
//------------------------------------------------------------------------------/
// The script plots the track of a blue polygon (rectangle)
/
// with red border, as it turns around its axis while racing
/
// counterclockwise in a circular loop on a black background.
/
// The rectangle can be chaged to a trapetzoid or other shape
/
// by changing element values in the matrix polygon. Changing /
// theta arguments in the matrix align gives different effects
/
//------------------------------------------------------------------------------/
clear,clc,clf;
// Basic parameters:
//---------------------steps = 100;
// Steps per circular loop
blength = 0.6;
// Basic length of polygon
width = 0.3;
// Basic width of polygon
radius = 0.6;
// Radius of circular loop
revolutions = 1;
// Number of loops to run
Ex 6-2: animation of a
waltzing polygon (2/4)
Ex 6-2: animation of a
waltzing polygon (3/4)
Ex 6-2: animation of a
waltzing polygon (4/4)
In this screenshot the
polygon (rectangle) has made
just over three quarters of its
counterclockwise loop. At the
same time it has spun 2
times around its axis, and has
begun the last turn. There
are 100 position samples on a
full loop (steps = 100;) and
it completes in a few seconds
// grayplot_demo.sce /
// Gray area map with level curves using /
// grayplot()/Sgrayplot() & contour2d() to /
// create illusion of a 3D space /
clear,clc,clf();
// Plot function:
//--------------------
Z = sin(x)'*cos(y);
Sgrayplot(x,y,Z)
// Function to plot
// Smoothed grayplot
cos(y)
sin(x)
/
/
clear,clc,clf;
//
---- SUBROUTINE ---/
// The plot2d() function defines the figure, /
// xfarcs() adds colored sectors to the plot /
function create_sectors(r, angle, width, col)
plot2d(%nan,%nan,-1,"031"," ",[-1,-1,1,1])
arcs=[-r;r;2*r;2*r;(angle-width/2)*64;width*64];
xfarcs(arcs,col)
// Add sectors
xtitle('COLORED SECTORS')
endfunction
rad = [.9,.6,1,.5]
// Sector radii
angle = [0,135,225,270] // Sector midpoints
width = [45,75,60,80]
// Sector widths
colors = [2,3,5,7]
// Color definitions
// Call subroutine:
//-----------------------
create_sectors(rad,angle,width,colors)
Finish
L2
x2
2
Start
L1
x1
Base motor
Elbow motor
Hand
b= T\d
%
% Equations of motion
L1 = 4;
L2 = 3;
t = linspace(0,2,401);
tq = [ t.^5; t.^4; t.^3 ];
theta1 = theta10 + a*tq;
theta2 = theta20 + b*tq;
x1 = L1*cos(theta1) + L2*cos(theta1 + theta2);
x2 = L1*sin(theta1) + L2*sin(theta1 + theta2);
%
% Plot path of hand
plot(x1,x2),...
xlabel(x_1),...
ylabel(x_2),...
title(Path of robot hand),...
text(4.3,0,t=0s: (x_1,x_2) = (6.5,0)),...
text(0.2,2,t=2s: (x_1,x_2) = (0,2))
+a4t2+a5t
2(t) = 2(0)+b1t5+b2t4+b3t3+
+b4t2+b5t
tf^5
tf^4
tf^3
5*tf^4 4*tf^3 3*tf^2
// Angular velocity
20*tf^3 12*tf^2 6*tf ]; // Angular acceleration
c = [ theta1tf - theta10; 0; 0 ]; // Theta 1 movement
a = T\c
// Coefficient vector a
disp(['Coefficients for theta1 motion:'])
disp([string(a')])
d = [ theta2tf - theta20; 0; 0 ];
// Theta 2 movement
b= T\d
// Coefficient vector b
disp(['Coefficients for theta2 motion:'])
disp([string(b')])
// Equations of motion:
//------------------------------
L1 = 4;
// Length of upper arm [feet]
L2 = 3;
// Length of lower arm [feet]
t = linspace(0, 2, 401);
// Computation steps
tq = [ t.^5; t.^4; t.^3 ];
theta1 = theta10 + a'*tq; // Base motor angular speed
theta2 = theta20 + b'*tq; // Elbow motor angular speed
x1 = L1*cos(theta1) + L2*cos(theta1 + theta2); // x1 position
x2 = L1*sin(theta1) + L2*sin(theta1 + theta2); // x2 position
plot(x1,x2),..
xlabel('x_1'),..
ylabel('x_2'),..
title('PATH OF A ROBOT HAND'),..
h1 = legend(['START: t=0s, (x_1,x_2) = (6.5,0); ..
STOP: t=2s, (x_1,x_2) = (0,2)'], 3)
/ clear,clc,clf;
// **** SUBOUTINE **** //
// Attach defined points to the spheres:
function [x, y, z] = facet(v, h)
x = cos(v)'*cos(h);
y = cos(v)'*sin(h);
z = sin(v)'*ones(h);
endfunction
// Facet x-matrix
// Facet y-matrix
// Facet z-matrix
// 3D box size
// Double buffer
// Surface color
e1 = gce();
e1.foreground = color('red'); // Facet edge color
e2 = gce();
e2.foreground = color('blue'); // Facet edge color
show_pixmap();
end
f.pixmap = "off";
Dr.EW
Johnny Heikell
20. Adieu
Final words to accompany you in
your struggle for survival of the
fittest
Return to Contents
We have reached the end of our journey. The road was longer and
bumpier than I anticipated
There is much more to Scilab but we are on our way if we master
even this material (think of an office software package and how
little of its potential you really know even if you use it daily)
The most important next step is to do Scilab simulations on our own,
to solve problems in our particular sphere of interest
And for everybodys sake, keep reminding the Scilab team about the
need for a comprehensive, up-to-date tutorial. To repeat an old
engineering adage: The job isnt done until the paperwork is done!
All the best and take care
JH
When I think over what I have said, I envy dumb people.
Seneca (4 B.C.A.D. 65).