|
|||||||||||||||||||||||||||||||||||||||||||
Language BasicsIn the previous chapter we learnt about the workbench. We looked at how to write and execute a program in m-script and java. In this chapter, we will focus on the m-script language specification. This scripting language is a subset of MATLAB's m-language and a mix of octave's scripting language. This chapter is intended for anybody how wish to write programs using the m-script. Here, we will cover the program structure, data structures, expressions, control flow commands, functions and procedures. 3.1 Program StructurenumEclipse can be used in two modes; interactive and programming. In the interactive mode we type the commands on the interpreter window and execute them as we go from one command to another. This mode is useful when you are experimenting with your algorithms or you are using the tool as a sophisticated scientific calculator. In the programming mode we would write a set of commands / statements in a file and execute all the commands in the file together. The commands / statements in both modes are almost same, as they are based on same language specification. In interactive mode you have some additional commands specific for the interactive environment which is not applicable to programming environment. We decided to keep the language case sensitive for a better user experience. Most programming languages have a program name, program start command and end command. numEclipse does not have such notion. numEclipse program is just a collection of commands / statements. Most compilation errors are caused by not declaring or initializing the variables. In numEclipse, there is no need to declare or initialize a variable. Even the size of an array is not required to be initialized, arrays and matrices can grow at runtime. This gives the user enormous power and flexibility. Don’t forget that dynamically changing the matrix size has some computational cost. To get the better performance out of this system it is advisable to initialize the matrix to the desired size, if possible.
3.2 Data TypesThe most important data type supported by m-script is matrix. At this point, we only support one- and two- dimensional matrices. A matrix element could be either real, complex, string, boolean, cell or structure. So all these data types are supported within m-script. However, there are some limitations, as nested data types like structure within a structure or cell within a cell is not supported. Similarly, multi-dimensional array are not supported either. But, we do plan to overcome these deficiencies in future releases.
3.2.1 Real Data TypeReal data type is a double precision floating point number type. It is equivalent to java primitive "double". The maximum value of a real number is realmax, 1.7977e+308, the minimum value is realmin, 4.9000e-324 and the precision of the real number is eps, 2.2204e-016.
>> x = 3.5 x = 3.5000
>> y = 2.7 y = 2.7000
>> z = x + y z = 6.2000
>> realmin realmin = 4.9000E-324
>> realmax realmax = 1.7977E308
>> eps eps = 2.2204E-016
3.2.2 Complex Data TypeA pair of real numbers forms a complex number. The first part is called the real part and the second part is called the imaginary part. There is no java equivalent for this data type.
>> z1 = 2 + 2j z1 = 2.0000 + 2.0000i
>> z2 = -1 + 3i z2 = -1.0000 + 3.0000i
>> z3 = z1 * z2 z3 = -8.0000 + 4.0000i
You would notice in the above example that we use both "i" and "j" to represent the imaginary part. 3.2.3 Boolean Data TypeThe Boolean data type corresponds to the java boolean primitive type. A boolean type variable is limited to only true and false values. An expression evaluating into a number greater than zero will be treated as a true boolean value and a zero value expression will be treated as false.
>> b = 2 > 1 b = true 3.2.4 String TypeThe String data type is equivalent to java String data type. numEclipse uses both single and double quotes to enclose strings unlike MATLAB which uses single quotes only.
>> s1 = 'John' s1 = Ali
>> s2 = 'Hello' s2 = Hello
>> s = s2 + ' ' + s1 s = Hello John
3.2.5 Matrix Data TypeThis is the key data type of this language. There is no java equivalent for this data type. A matrix with only one column represents a mathematical entity vector and a matrix with one row represents a row vector. A matrix is basically a two dimensional array of complex numbers. It also covers real matrices since a complex number without an imaginary part is essentially a real number.
>> A = [1 2 3; 4 5 6; 7 8 9] A = 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000
>> B = [-9 7 4 2 -6 4 1 3 9] B = -9.0000 7.0000 4.0000 2.0000 -6.0000 4.0000 1.0000 3.0000 9.0000
In the first matrix A we use semicolons to separate rows where as in matrix B we just use a newline to indicate the start of new row. In above example, we used spaces to separate the elements in a row. You can also use comma to avoid any ambiguity. 3.3 ExpressionnumEclipse scripting provides everything required to define a very complicated mathematical expression as discussed in the following sections. 3.3.1 Range ExpressionA range expression provides a short cut notation to define a vector. Say we want to define a vector containing positive integers ranging from 1 to 10, using this notation we could define it as follows.
>> m = 1:10 m = 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000 7.0000 8.0000 9.0000 10.0000
Now, if we define a similar vector starting from 10 and ending into 50 but with the incremental steps of 10, it could be defined as follows.
>> n = 1:10:50 n = 1.0000 11.0000 21.0000 31.0000 41.0000
This saves us from listing all the vector elements. Similarly, we could define vectors with descending values using negative incremental steps.
>> u = 10:-2:1 u = 10.0000 8.0000 6.0000 4.0000 2.0000
3.3.2 Conditional ExpressionConditional expression is the other name for Boolean expression. A boolean expression evaluates to either a true or a false value. Unlike MATLAB, numEclipse does have a real boolean type but it still supports the MATLAB’s notion of a boolean. A zero is treated as ‘false’ and a positive number is treated as ‘true’. There could be three types of conditional expressions.
Pure Boolean Expression: A pure Boolean expression is composed of boolean primitives and logical operations, e.g.
>> true && false ans = false
>> ~true ans = false
>> ~false ans = true
numEclipse supports following boolean operators.
Pure Relational Expression: A pure relational expression is composed of numbers (scalar, vector, matrix or complex) and relation operators, e.g.
>> 3 > 1 ans = true
>> A = rand(2) A = 0.7242 0.2868 0.9793 0.9371
>> A > 0 ans = 1.0000 1.0000 1.0000 1.0000
numEclipse supports following relational operators.
Conditional Expression A conditional expression could be a composition of above two types of expression, e.g.
>> A = rand(2) A = 0.7242 0.2868 0.9793 0.9373
>> A > 0 ans = 1.0000 1.0000 1.0000 1.0000
>> z = 1 - i z = 1.0000 i
>> A > 0 | z > 1 ans = 1.0000 1.0000 1.0000 1.0000
3.3.3 Numerical ExpressionnumEclipse allows defining any mathematically correct numeric expression using the data types and operations defined earlier.
>> A A = 0.7242 0.2868 0.9793 0.9373
>> z z = 1.0000 - i
>> b = (A + 1) /2 - z ^ 2 b = 0.8621 + 2.0000i 0.6434 + 2.0000i 0.9896 + 2.0000i 0.9687 + 2.0000i
numEclipse supports following arithmetic operators.
Above operators could be used with any data type where they are mathematically correct. 3.4 Assignment StatementA programming language means nothing without statements. It could be divided into two groups; simple statements and compound statements. numEclipse has only one simple statement i.e. assignment statement. It looks like the following structure. <variable name> = <expression> “=” is the assignment operator. This statement evaluates the expression and assigns the resulting value to the variable named on the left hand side. The left hand side or lvalue must be a valid identifier. Identifier naming convention is same as in java. There is no need to declare a variable before assigning a value. numEclipse automatically determines the data type from the right hand side (or rvalue) or the expression type. The type of a variable could change as we assign a new value of different type to an existing variable.
>> X = 1.0 X = 1.0000
>> Y = [1 2 3; 4 5 6] Y = 1.0000 2.0000 3.0000 4.0000 5.0000 6.0000
>> S = 'Hello World' S = Hello World
>> B = 1 < 2 B = true
If a simple assignment is ended with a semi-colon then the interpreter will not report the value of the right hand side expression on the screen. A matrix assignment involves assigning an element of an existing matrix to a value. In case of a column or row vector, the assignment will be as follows. <variable name> (<expression>) = expression The expression within parenthesis on the left hand side is an index value so it should always evaluate to an integer value respecting the bounds of the matrix. In case of a two dimensional matrix, the assignment will look like as follows. <variable name> (<expression>, <expression>) = expression The first index in the parenthesis determines the row number and the second index determines the column number of the matrix element.
>> A = rand(3) A = 0.8467 0.0952 0.2836 0.9565 0.3782 0.5011 0.7280 0.2052 0.6668
>> A(2, 3) = 1.5 A = 0.8467 0.0952 0.2836 0.9565 0.3782 1.5000 0.7280 0.2052 0.6668
numEclipse functions could return one or more variables so the syntax for assigning single or multiple return values is shown as follows.
Single Assignment >> x = min([1 2 3]]) x = 1.0000
>> x = max([1 2 3]) x = 3.0000
Multiple Assignment >> [k t b c] = KTBC(3) k = 2.0000 -1.0000 0.0000 -1.0000 2.0000 -1.0000 0.0000 -1.0000 2.0000
t = 1.0000 -1.0000 0.0000 -1.0000 2.0000 -1.0000 0.0000 -1.0000 2.0000
b = 1.0000 -1.0000 0.0000 -1.0000 2.0000 -1.0000 0.0000 -1.0000 1.0000
c = 2.0000 -1.0000 -1.0000 -1.0000 2.0000 -1.0000 -1.0000 -1.0000 2.0000
3.5 Control-Flow StatementnumEclipse supports following flow control statements: for, while, if, switch, continue, break and return. These statements are described in the following sections. 3.5.1 For LoopFor loop is a compound statement. It is a repetitive statement since it allows a group of statements to be executed a number of times. The structure of this statement type is a follows
for <identifier> = <range expression> <statement> <statement> . . <statement> end
Here for and end are the keywords and “=” is an operator. “*” indicates that there could be zero or more statements within a for loop.
>> x = 0;
>> for i = 1 : 10 x = x + 1; end;
>> x x = 10
In the above example variable x is assigned a value “0”. The for loop is repeated 10 times and at each iteration x is incremented by 1.
3.5.2 While LoopWhile loop is also a compound statement and it is repetitive in nature. The difference between a for and while loop is that the for loop executes statements for a fixed number of time whereas while loop executes all grouped statements until a condition is satisfied. The structure of a while statement is as follows.
while <conditional expression> <statement> <statement> . . <statement> end
Here while and end are keywords. In this statement the conditional expression is evaluated on the beginning of each iteration, if the conditional expression evaluates to true then the enclosed statements are executed otherwise the loop ends.
>> y = [0 0 0];
>> i = 1;
>> while x > 0 y(i) = x; i = i + 1; x = x - 1; end;
>> x x = 0.0000
>> y y = 3.0000 2.0000 1.0000
In this example three statements are executed until the condition x > 0 is satisfied. 3.5.3 If StatementIf statement is another compound statement. It consists of a conditional expression and one or more groups of statements. If the conditional expression evaluates to true then first group of statements are executed otherwise second group of statements are executed, if present.
if <conditional expression> <statement> . . <statement> elseif <conditional expression> <statement> . . <statement> elseif <conditional expression> <statement> . . <statement> else <statement> . . <statement> end
In the above structure if, elseif, else and end are keywords. There could be zero or more parts elseif sections in a if statement. There could be zero or one else section in a if statement.
>> x = 1;
>> y = 2;
>> if x > 1 y = y + 1; elseif y = y - 1; else y = 0; end;
>> y y = 1.0000
3.5.4 Switch StatementSwitch statement is helpful when you have a lot of elseif statements within a if statement. It switches among several cases based on an expression, as shown in the following syntax diagram.
switch <switch expression> case <case expression> <statement> . . <statement> case <case expression> <statement> . . <statement> otherwise . . case <case expression> <statement> . . <statement> end
The switch expression should be either a string or a scalar value. The case expression should evaluate to the same data type as switch expression.
>> money = 10;
>> switch money case 1 cents = cents + 1; case 5 nickle = nickle + 1; case 10 dime = dime + 1; case 25 quarter = quarter + 1; case 100 dollars = dollars + 1; otherwise disp('invalid amount'); end;
>> dime dime = 1.0000
Unlike C or Java, you do not need to use break statement only first matching case is executed. 3.5.5 ContinueContinue statement moves the control to the next step of the for or while loop.
>> sum = 0;
>> for i = 1 : 100 sum = sum + 1; end;
>> sum sum = 100.0000
>> sum = 0;
>> for i = 1 : 100 if rem(i, 2) == 0 continue; end; sum = sum + 1; end;
>> sum sum = 50.0000
Above example shows how continue statement skips an iteration on condition rem(i, 2) == 0. 3.5.6 BreakBreak statement ends the execution of a for or while loop.
>> sum = 0;
>> for i = 1 : 100 if i == 50 break; end; sum = sum + 1; end;
>> sum sum = 49
Above example shows how the break statement ends the execution of for loop on condition i == 50.
3.5.7 ReturnReturn statement is used in a function. This statement moves the control back to the caller program. Here is an example function.
function mat = myrandom(n) if n < 1 return; else mat = rand(n); end;
The above function returns the control back to the caller program if the input argument is less than 1. Here is the example.
>> x = myrandom(3) x = 0.2660 0.3629 0.6100 0.4861 0.8637 0.5179 0.3443 0.1870 0.7771
>> x = myrandom(1) x = 0.9397
>> x = myrandom(0)
>>
3.6 FunctionnumEclipse allows you to define your own functions. Here is the syntax definition of a function.
function identifier = name (argument1, argument2, ...) <statement> . . <statement> end Or function [identifier1, identifier2, ...] = name (argument1, argument2, ...) <statement> . . <statement> end
The second syntax definition shows that a function can return more than one values in an array. The following code shows the examples of the functions.
function y = variance(x) n = length(x); xbar = mean(x); sum = 0; for i = 1 : n sum = sum + (x(i) - xbar)^2; end; y = sum / n; y = sqrt(y);
function [K, T, B, C] = KTBC(n) % Create the four special matrices assuming n > 1 K = toeplitz([2 -1 zeros(1, n-2)]); T = K; T(1, 1) = 1; B = K; B(1, 1) = 1; B(n, n) = 1; C = K; C(1, n) = -1; C(n, 1) = -1;
The following diagram shows how to call these functions.
>> x = 1:10;
>> var = variance(x) var = 2.8723
>> [k t b c] = KTBC(2) k = 2.0000 -1.0000 -1.0000 2.0000
t = 1.0000 -1.0000 -1.0000 2.0000
b = 1.0000 -1.0000 -1.0000 1.0000
c = 2.0000 -1.0000 -1.0000 2.0000
3.7 ProcedureA procedure is same as a function except it does not return any value. The syntax definition for a procedure is shown below.
function name (argument1, argument2, ...) <statement> . . <statement> end
Here is an example for a procedure.
function proc(x) plot(1:length(x), x); end;
In the following, we show how to call a procedure.
>> proc((1:10).^2)
3.8 Structure Data TypeStructure is a composite data type. It is very similar to struct in C language. Unlike a matrix, a structure can contain data elements of various types. Elements / fields of a structure are named rather than indexed. The following example shows how to create a structure.
>> employee.name = 'John';
>> employee.id = 123;
>> employee.salary = 3000;
>> employee.pref = [10 20; 30 40];
>> employee employee =
perf : 10.0000 20.0000 30.0000 40.0000
name : John id : 123.0000 salary : 3000.0000
In the above example, we use the assignment to create a structure fields. There is no need to declare the structure. The following example shows the use of struct function to create a structure variable.
>> emp = struct('name', 'John', 'id', 123, 'salary', 3000) emp =
name : John id : 123.0000 salary : 3000.0000
This function takes an even number of arguments as a sequence of field name and value pairs. struct('name1', value1, 'name2', value2, ...) Note that the name of a field is provided as a string. The following example shows how to access the value of a structure field.
>> emp.name = 'John';
>> emp.id = 123;
>> emp.salary = 3000;
>> emp.pref = [10 20; 30 40];
>> x = emp.salary x = 3000.0000
>> s = emp.name s = John
Similarly, accessing the value of a field from a structure array is shown below.
>> emp(2).name = 'Peter';
>> emp(2)id = 456;
>> emp(2).salary = 2500;
>> emp(2).perf = [1 2; 3 4];
>> name = emp(2).name name = Peter
>> sal = emp(1).salary sal = 3000.0000
>> x = emp(2).perf(2,2) x = 4.0000
In the above example, we also show how to get a matrix element from a matrix field value of a structure array. Unlike MATLAB, there are no add or remove functions available in numEclipse. You can add a field as shown in above example. There is no method available to remove a field. The implementation of structure is non-strict, i.e., each structure in an array could have entirely different set of fields. The following example shows how to pass a field value to a function.
>> emp.perf ans = 10.0000 20.0000 30.0000 40.0000
>> y = sum(emp.perf) y = 40.0000 60.0000
Here, we show a function which takes an structure array as an input argument.
function y = TotalSalary(x) % x - input argument Structure array of employees % y - output argument Total salary of all employees n = length(x); y = 0; for i = 1 : n y = y + x(i).salary; end;
In the following, we show the call to this function.
>> emp emp =
Index(1) perf : 10.0000 20.0000 30.0000 40.0000
name : John id : 123.0000 salary : 3000.0000
Index(2) perf : 1.0000 2.0000 3.0000 4.0000
name : Peter id : 458.0000 salary : 2500.0000
>> TotalSalary(emp) ans = 5500.0000
Unlike MATLAB, numEclipse does not support nested structures.
3.9 Cell Data TypeCell array is an another composite data type. It is very similar to structure array except the way it organizes the data. In a cell array each element is a cell which can contain data of any other type. A cell array can be created using a function as shown in the following example.
>> c = cell(2,2);
>> c(1, 1) = {'Hello World'};
>> c(2, 1) = {2};
>> c(2, 2) = {1 + 2i};
>> c c =
Cell(1, 1) Hello World
Cell(1, 2) 2.0000
Cell(2, 1) 1.0000 2.0000
Cell(2, 2) 1.0000 + 2.0000i
There is no need to use a function, a cell can be created just by using assignment statement. Keep in mind that a cell is always defined in a curly bracket.
>> ce = {[3.13 2.71]} ce =
3.1300 2.7100
Obtaining data from a cell element is shown in the following example.
>> c c =
Cell(1, 1) Hello World
Cell(1, 2) 2.0000
Cell(2, 1) 1.0000 2.0000 3.0000
Cell(2, 2) 1.0000 + 2.0000i
>> x = c{2, 2} x = 1.0000 + 2.0000i
A cell array cannot be nested in another cell but it can contain structure array. Here is an example.
>> c(1,2) = struct('name', 'John', 'id', 123, 'salary', 3000) c =
Cell(1, 1) Hello World
C(1, 2)
name : John id : 123.0000 salary : 3000
Cell(2, 1) 1.0000 2.0000 3.0000
Cell(2, 2) 1.0000 + 2.0000i
Cell arrays could be passed to a function in a similar manner as structure arrays. There are two cell arrays, varargin and varargout, which have special role in defining variable number of arguments in a function. In the following, we present an example of a function.
function [varargout] = statistics(varargin)
end; This function takes a variable number of input arguments, varargin, and returns a variable number of arguments, varargout. The varargin contains the input arguments in a cell array. In this function, line 3 shows how to compute the number of input arguments. nargin Similarly nargout is used to determine the number of output arguments. Line 6, shows how to use cell array index to get the corresponding input argument. varargin{i} The variable number of output arguments are packed into a cell array, varargout. Line 8, 14 and 15 show how to assign the return values to output arguments. Note that before assignment, you need to know if the output argument is really required. This is done by looking at the number of output arguments using nargout. The following function call shows how to call this function with different number of input and output arguments.
>> [mean var] = statistics(1, 2, 3) mean = 2.0000 var = 0.6667
>> [mean var std] = statistics(1, 2, 3, 4, 5) mean = 3.0000 var = 2.0000 std = 1.4142
>> statistics(1, 2, 3, 4, 5) ans = 3.0000
|