Soft dimensions of
operand in expressions
r = a <arithmetic operator> b
A set of procedures or functions implement the four arithmetic
operations between elements of matrices: add sub mul and dvd. Note that mul is the
element by element multiplication not
the matrix product named prd.
All four operations are handled in the very same way, so that
examples are given for the addition but apply to the
other operations, however replacing 0 (zero) the neutral
element
of the addition (and substraction) by 1 (one) for multiplication (and
division).
The following Scilab expressions:
- r = a + b
- r = a - b
- r = a .* b
- r = a ./ b
translate into:
- add(r,a,b)
- sub(r,a,b)
- mul(r,a,b)
- dvd(r,a,b)
If in the right hand
side (in the expression) operands, a and b,
are matrices of the same dimensions then the operations
is performed
element by element and the result stored in the result matrix r, which will
have the same dimensions as the two operands a and b. This is what
Scilab does:
-->a=[1 2 3; 4 5 6]
a =
1. 2. 3.
4. 5. 6.
-->b = [ 10 20 30; 40 50 60 ]
b =
10. 20. 30.
40. 50. 60.
-->r = a + b
r =
11. 22. 33.
44. 55. 66.
-->
The
same expression r = a + b often arises with either operand a or b being
a scalar or a 1,1 matrix. This is gracefully handled by Scilab:
-->a
a =
1. 2. 3.
4. 5. 6.
-->a + 10
ans =
11. 12. 13.
14. 15. 16.
-->
and this is also
permitted for
mtx
(thanks to
procedure
overloading) using the following avatars for
addition:
- procedure
add(var r: mtx; a:mtx; x:double);
- procedure
add(var r: mtx; x:double; a:mtx);
However
akin operations are often used such as adding (multiplying) a row
vector or a column vector to all rows or columns of a given matrix. In
this case the expression r
= a + b really means duplicate the row or
column vector of one operand to match the size of the other operand.
This is less gracefully achieved in Scilab however:
-->a
a =
1. 2. 3.
4. 5. 6.
-->b
b =
10. 20. 30.
-->a+b
!--error 8
inconsistent addition
-->a + ones(a(:,1))*b
ans =
11. 22. 33.
14. 25. 36.
-->c = [ 10 ; 20 ]
c =
10.
20.
-->a + c*ones(a(1,:))
ans =
11. 12. 13.
24. 25. 26.
-->
In the above example a
3,2 matrix
a is defined
along with a row vector
b
( of the same size as a row
of
a )
and a column vector
c
of the same size as a column of
a. The
expression
a+b
returns an error. One must
explicitly build a matrix of the same dimension as
a by
duplication of
the other operand using a fairly cryptic matrix product with rows or
column vectors of
1
(
ones(a)
return a matrix of the same dimension as the argument
a whose
elements are all equal to
1).
see also the demo programs:
Soft dimensions in expressions
a = a <arithmetic operator> b
When a and b have identical dimensions the following Scilab expressions:
- a = a + b
- a = a - b
- a = a .* b
- a = a ./ b
translate into the following freepascal procedure calls:
- add(a,b)
- sub(a,b)
- mul(a,b)
- dvd(a,b)
However
if a and b have different dimensions the previous Scilab expression
will spawn an error about mismatched dimensions (unless a or b are scalars).
If a has the dimension of a column (resp. row) of b then the most likely interpretation is that the sum of all elements of each row (resp. column) of b should be added to the corresponding element of a as illustrated below:
{
Dimension reduction by an arithmetic operator
Below the Scilab session which mimic the pascal code:
-->a = [ 10; 20]
a =
10.
20.
-->b = [ 1 2 3; 4 5 6]
b =
1. 2. 3.
4. 5. 6.
-->a = a + sum(b,'c')
a =
16.
35.
-->b = b + ( a*ones(b(1,:)) )
b =
17. 18. 19.
39. 40. 41.
-->
}
program add_ab;
uses mtx09;
var a, b: mtx;
begin
tra;
equ(a,'10;20');
equ(b,'1 2 3; 4 5 6');
add(a,b); // the dimensions of a and b define...
add(b,a); // unambiguously the intended operation
end.
{
[jroux@ami ex]$ ./add_ab
# equ [2,1]
10
20
# equ [2,3]
1 2 3
4 5 6
# add [2,1] [2,3]
16
35
# add [2,3] [2,1]
17 18 19
39 40 41
[jroux@ami ex]$
}
If either a or b are scalars the interpretation is consistent with the previous example as illustrated below:
Conclusions
The
two main forms of procedure for arithmetic operators is opr(r,a,b) and
opr(a,b) where a or b can be a double or a mtx. The operand dimensions
define unambiguously the intended operation if they make sense. In
general one may perform meaningful operations bewteen argument of the
same size or row or column vectors or scalars.
In the second
form the two arguments a and b have a different position and
significance. When the 1st (a) is smaller than the 2d (b) then the
operation performed is akin to sum() or prod() to somehow reduce one
dimension of the 2d operand to match the 1st operand target.
This feature avoid to mess up the name space and yet remains fairly clear.