/* Index Minimum Elements of Matrix:
     proc min_rc()
	 proc minks_rc()
Author: Alan G. Isaac aisaac@american.edu
        based on the suggestions of
         David Baird BairdD@AgResearch.CRI.NZ
	 Mico Loretan loretanm@frb.gov
         Scott Thompson <Scott.Thompson@usdoj.gov>
Date: July 1995
Provided without guarantee for public non-commercial use.
*/

/*
Proc: min_rc
Purpose: finds index (ie. row and column number) of the
         minimum element of a matrix.
Format: {min_r,min_c} = min_rc(x);
Input:  x  matrix
Output:	min_r   row index of minimum element
        min_c   column index of minimum element
*/

proc (2) = min_rc(x);
 local colsx,n,min_c,min_r;
    n = minindc(vecr(x));
    colsx=cols(x);
    min_r = int((n-1)/colsx) + 1;
    min_c = n - (min_r - 1)*colsx;
retp(min_r,min_c);
endp;



/*
Proc: mink_rc
Purpose: finds index (ie. row and column number) of the
         k-th smallest element of a matrix.
Format: {mink_r,mink_c} = mink_rc(x,k);
Input:  x  matrix
        k  integer (1 le k le rows(x)*cols(x))
Output:	mink_r   row index of k-th smallest element
        mink_c   column index of k-th smallest element
*/
proc (2) = mink_rc(x,k);
 local colsx, n, missing,mink_r,mink_c;
    colsx=cols(x);
    x=vecr(x);
    missing = {. };
    do while k>1;
       n = minindc(x);
       x[n] = missing;
       k = k-1;
    endo;
    n = minindc(x);
    mink_r = int((n-1)/colsx) + 1;
    mink_c = n - (mink_r - 1)*colsx;
retp(mink_r,mink_c);
endp;




/*
Proc: mink_rc
Purpose: finds index (ie. row and column numbers) of the
         k smallest elements of a matrix.
Format: {min_r,min_c} = mink_rc(x,k);
Input:  x  matrix
        k  scalar (natural number)
Output:	min_r   row index of minimum elements
        min_c   column index of minimum elements
*/

proc (2) = mink_rc(x,k);
 local colsx,rowsx,n,min_c,min_r,sortx,kmin;
    colsx=cols(x);
	rowsx=rows(x);
    sortx = sortc(vecr(x)~seqa(1,1,colsx*rowsx),1);
    kmin = sortx[1:k,1];
    n = sortx[1:k,2];
    min_r = int((n-1)/colsx) + 1;
    min_c = n - (min_r - 1)*colsx;
retp(min_r,min_c);
endp;




/*
Proc: minks_rc
Purpose: finds index (ie. row and column numbers) of the
         k smallest elements of a *symmetric* matrix.
Format: {min_r,min_c} = minks_rc(x,k);
Input:  x  matrix (symmetric)
        k  scalar (natural number)
Output:	min_r   row index of minimum elements
        min_c   column index of minimum elements
Comment: x must be symmetric; there is no error checking.
*/


proc (2) = minks_rc(x,k);
 local colsx,n,min_c,min_r,sortx,kmin;
    colsx=cols(x);
    sortx = sortc(vech(x)~vech(reshape(seqa(1,1,colsx^2),colsx,colsx)),1);
    kmin = sortx[1:k,1];
    n = sortx[1:k,2];
    min_r = int((n-1)/colsx) + 1;
    min_c = n - (min_r - 1)*colsx;
retp(min_r,min_c);
endp;

