! 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