Lindo Systems

! Gram-Schmidt orthogonalization, Modified;
! Given an input matrix A,
   For each column j, 
     add multiples of earlier columns to it
     so that column j is
      independent of(or is orthogonal to,
      or has a zero inner product with) all
     earlier columns,
   giving an output matrix V;

! Keywords: Gram-Schmidt orthogonalization, Independent vectors,
       LINGO, Orthogonal, Zero correlation, Zero innerproduct;

SETS:
 ROW;
 COL;
 RXC( ROW, COL): A, V;
ENDSETS
DATA:
 ZERO = .00000001; ! Zero tolerance;
 COL = 1..4;
 ROW = 1..4;
  A =  
 1 -1.22653	-0.84162	-1.34076	
 1 -0.27932	-0.15097	-0.22754	
 1 0.201893	0.050154	0.331853	
 1 1.281552	1.174987	0.994458	
;
 
ENDDATA

!This requires LINGO 10 or later;
CALC:
  N = @SIZE(COL);
  M = @SIZE(ROW);
! If the A matrix is already orthogonal,
  then setting V = A is sufficient....;
 @FOR( RXC(i,j):
   V(i,j) = A(i,j)
     );
 ! Now take care of nonorthogonality of
    column k with column j;
 @FOR( COL(k)| k #LT# N:
   SCALE = @SUM( ROW(i): V(i,k)^2);
   @IFC( SCALE #GT# ZERO:
    ! Make all columns j > k orthogonal to k;
     @FOR( COL(j)| j #GT# k:
      DOTP = @SUM( ROW(i): V(i,k)* V(i,j));
 ! We want ALPHA so V(,k)*(V(,j)-ALPHA*V(,k)) = 0,
    or DOTP - ALPHA*SCALE = 0, so;
       ALPHA = DOTP/SCALE;
       @FOR(ROW(i):
         V(i,j) = V(i,j) - ALPHA*V(i,k);
           );
         );!End loop over j;
      );  !End IFC;
     SCALE = SCALE^.5;
     );   !End loop over k;

  ! Optionally, rescale;
   @FOR( COL(k):
      SCALE = @SUM(ROW(i): V(i,k)^2)/@SIZE(ROW);
      @IFC( SCALE #GT# ZERO:
        SCALE = SCALE^.5;
        @FOR( ROW(i):
          V(i,k) = V(i,k)/SCALE;
            );
           );
       );
! Optionally, write out the matrix;
  @FOR( ROW(i):
    @FOR( COL(j): @WRITE(' ',@format("#17.8f",V(i,j))));
    @WRITE( @NEWLINE(1));
      );
  @WRITE( @NEWLINE(2));
ENDCALC