! 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
|