### 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:

- addition
- division example 1 ,

### 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.