Simple Matrix Manipulation Extressions

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Simple Matrix Manipulation Extressions

John Smith-74
Hello,
      Are there any simple expressions for these octave expressions:
In each case I introduce loops, multiplications or something a bit
horrible to achieve something fairly simple.

1. given matrix A and row vector V , add V to every row of A

        A + ones(rows(A),1) * V

2. similar problem for multiply:

        A * diag(V)
    or  A .* ones(rows(A),1) * V

3. given a matrix A and a scalar s, take the minimum of an element of the
   matrix and the scalar.

        (A < s) .* A + (s <= A) .* s)

4. given two same sized matrices A, B, find the pair-wise minimum of each
   element:
        (A < B) .* A + (A >= B) .* B
   
5. given a (big) matrix A, and (small) vector V, for each element a
   of A find the number of V elements smaller than a

        count = zeros(size(A)) ;
        for r=1:n
          count = count + (V(r) < A) ;
        endfor

   Is there a way to avoid the loop? we can sort the V if that helps.

   For A a scalar we might do something like

        count = sum( V < A ) ;

6. V is a vector, r is a matrix of integer indices into V. I seek to
   build a matrix with the size of r, of elements of V

      for i1=1:rows(r)
         for i2=1:columns(r)
           W(i1,i2) = V(r(i1,i2));
         endfor
      endfor

    or (faster)

      W = V(r) ;
      W = reshape(W, rows(r), columns(r)) ;

7. rx and ry are same sized integer matrices, A is a matrix. I seek to
   use r1 and r2 as indices into A to form a new matrix:

      for i1 = 1:rows(rx)
        for i2 = 1:columns(rx)
          B(i1,i2) = A( rx(i1,i2)) , ry(i1,i2)) ) ;
        endfor
      endfor

   The equivalent vector expression  W=V(r) is very simple.
   The loops can be avoided by reshaping the matrices to vectors, working
   in vectors, and reshaping back afterwards.

 
For each case I do have a solution, but generally I don't like it.

        John

Sorry if I should have RTFMed a bit more carefully.



Reply | Threaded
Open this post in threaded view
|

Simple Matrix Manipulation Extressions

John W. Eaton-6
On  8-Nov-1997, john <[hidden email]> wrote:

|       Are there any simple expressions for these octave expressions:
| In each case I introduce loops, multiplications or something a bit
| horrible to achieve something fairly simple.
|
| 1. given matrix A and row vector V , add V to every row of A
|
|         A + ones(rows(A),1) * V
|
| 2. similar problem for multiply:
|
|         A * diag(V)
|     or  A .* ones(rows(A),1) * V

Some future version of Octave will probably allow things like

  A .+ V

and

  A .* V

to do what you expect.  For now, you have to use a multiplication or
indexing tricks to convert the vector to a matrix of the proper size.

| 3. given a matrix A and a scalar s, take the minimum of an element of the
|    matrix and the scalar.
|
|         (A < s) .* A + (s <= A) .* s)

min (A, s)

| 4. given two same sized matrices A, B, find the pair-wise minimum of each
|    element:
|         (A < B) .* A + (A >= B) .* B

min (A, B)

I don't know of better ways to do the other tasks you mention.

jwe


Reply | Threaded
Open this post in threaded view
|

Re: Simple Matrix Manipulation Extressions

Dirk Laurie
In reply to this post by John Smith-74
john wrote:

>
>       Are there any simple expressions for these octave expressions:
> In each case I introduce loops, multiplications or something a bit
> horrible to achieve something fairly simple.
>
> 5. given a (big) matrix A, and (small) vector V, for each element a
>    of A find the number of V elements smaller than a
>
>         count = zeros(size(A)) ;
>         for r=1:n
>           count = count + (V(r) < A) ;
>         endfor
>
>    Is there a way to avoid the loop? we can sort the V if that helps.
>
>    For A a scalar we might do something like
>
>         count = sum( V < A ) ;
>

 do_fortran_indexing=1;
 [x,j]=sort(A(:));                 % The method works for two vectors
 [x,k]=sort([x; v(:)]);  
 m=1:length(k); m(k)=1:length(k);
 count=A; count(j)=m(1:length(j))-(1:length(j));

I suppose this is `a bit horrible' but it does have complexity
less than length(x)*length(v) and there are no loops.  It will
not work properly if the internal sorting algorithm of octave
allows equal elements to exchange places.

Dirk


Reply | Threaded
Open this post in threaded view
|

Re: Simple Matrix Manipulation Extressions

John W. Eaton-6
On 10-Nov-1997, Dirk Laurie <[hidden email]> wrote:

|  do_fortran_indexing=1;
|  [x,j]=sort(A(:));                 % The method works for two vectors
|  [x,k]=sort([x; v(:)]);  
|  m=1:length(k); m(k)=1:length(k);
|  count=A; count(j)=m(1:length(j))-(1:length(j));
|
| I suppose this is `a bit horrible' but it does have complexity
| less than length(x)*length(v) and there are no loops.  It will
| not work properly if the internal sorting algorithm of octave
| allows equal elements to exchange places.

No, it doesn't -- Octave's sort function is based on algorithm 5.2.4L
from Knuth, Volume 3, and it is stable.

jwe