home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / BASIC / UBAS821.ZIP / LLL.UB < prev    next >
Encoding:
Text File  |  1989-02-15  |  5.6 KB  |  122 lines

  1.     1   ' This program impliments the reduction algorithm of Lengstra, Lengstra,
  2.     2   ' and Lovasz (Math. Ann. 261 (1982) 515-534) to obtain a "reduced basis"
  3.     3   ' for a positive definite real valued bilinear form A(-,-) on Z^n.
  4.     4   ' I have added a search algorithm to find short vectors for the form.
  5.     5   '
  6.     6   ' The parameter PP should be between .25 and 1.  The routine seems
  7.     7   ' fairly insensitive to its value.
  8.     8   '      Written by W.D. Neumann
  9.    10   word 12:point 6
  10.    20   N%=40
  11.    30   dim A(N%,N%),B(N%,N%),C(N%,N%),M(N%,N%),V(N%) 'used by main algorithm
  12.    40   dim X(N%),Y(N%),Z(N%) '        used by *SEARCH
  13.    50   PP=0.9
  14.    60   '
  15.    70   ' Set up a form to play with to test the routine.
  16.    71   '
  17.    73   N%=4:X=sqrt(3)+sqrt(2)-2
  18.    74   for I=0 to N%:for J=0 to N%:A(I,J)=8^24*X^(I+J):next:A(I,I)=A(I,I)+1:next
  19.    80   '
  20.    81   ' The minimal polynomial for X gives a short vector for this form.
  21.    82   '
  22.    83   gosub *MAIN
  23.    84   gosub *PRINTFORM:gosub *PRINTBASE:gosub *PRINTINV
  24.    85   gosub *SEARCH:goto 85
  25.   100   '
  26.   110   ' Subroutine to compute the A-inner product of d(n,-) and d(m,-)
  27.   120   ' A() must be initialized to the definite form in question.
  28.   130   '
  29.   140   *IP(&D(),N,M)
  30.   141   local I,J
  31.   142   clr IP
  32.   150   for I=0 to N%:for J=0 to N%:IP=IP+A(I,J)*D(N,I)*D(M,J):next:next
  33.   160   return
  34.   200   '
  35.   210   *MAIN
  36.   220   '
  37.   230   ' At any time during the reduction, B(i,-) is the ith basis element.
  38.   240   ' So BABt is the matrix of the form with respect to the B-basis.
  39.   250   '  (Bt means transpose of B.)
  40.   260   ' We start with the standard basis, though this is not essential.
  41.   270   '
  42.   280   clr block B(0..N%,0..N%):for I=0 to N%:B(I,I)=1:next I
  43.   290   '
  44.   300   ' M will be a lower triangular matrix with 1's on the diagonal
  45.   310   ' (its entries below the diagonal are M(i,j)).  We do a Gram
  46.   320   ' reduction to find C and M such that B=MC and CACt=Diag(V1,...,Vn).
  47.   330   ' In particular, (A =) BABt = MVMt, where V is diagonal.
  48.   340   '
  49.   350   print "Initializing reduction...";
  50.   360   block C(0..N%,0..N%)=block B(0..N%,0..N%)
  51.   370   for I=0 to N%
  52.   380   for J=0 to I-1
  53.   390   gosub *IP(&C(),I,J):M(I,J)=IP/V(J)
  54.   400   for K=0 to N%:C(I,K)=C(I,K)-M(I,J)*C(J,K):next K
  55.   410   next J
  56.   420   gosub *IP(&C(),I,I):V(I)=IP
  57.   430   next I
  58.   440   '
  59.   450   ' We re-use C(-,-) to hold B^-1 (actually (old B)*(new B)^-1
  60.   460   ' for any initial choice of B).  B^-1 is not needed for most
  61.   470   ' applications, so the code to compute it can usually be deleted.
  62.   480   ' We first initialize it.
  63.   490   '
  64.   500   clr block C(0..N%,0..N%):for I=0 to N%:C(I,I)=1:next I
  65.   510   '
  66.   520   ' The main reduction algorithm follows.  It operates on the basis
  67.   530   ' B so that after reduction we have new B,M,V still satisfying
  68.   540   ' BABt=MVMt, but with all Mij <= .5 and with a constraint on
  69.   550   ' the entries of V (which implies V(k) >= V(k-1)*(PP-.25) ).
  70.   560   '
  71.   570   print "STARTING REDUCTION"
  72.   580   K=1:goto *R1
  73.   590   *R2:M=M(K,K-1):V=V(K)+M*M*V(K-1):M(K,K-1)=M*V(K-1)/V
  74.   600   V(K)=V(K-1)*V(K)/V:V(K-1)=V
  75.   610   swap block B(K,0..N%),block B(K-1,0..N%):swap block C(0..N%,K),block C(0..N%,K-1)
  76.   620   if K>1 then swap block M(K,0..K-2),block M(K-1,0..K-2)
  77.   630   for I=K+1 to N%
  78.   640   V=M(I,K):M(I,K)=M(I,K-1)-M*V:M(I,K-1)=V+M(K,K-1)*M(I,K):next
  79.   650   if K>1 then dec K
  80.   660   *R1:L=K-1:gosub *R3
  81.   670   if V(K)/V(K-1)+M(K,K-1)*M(K,K-1)<PP goto *R2
  82.   680   for L=K-2 to 0 step -1:gosub *R3:next L
  83.   690   inc K:if K<=N% goto *R1
  84.   700   return '          -------------------->
  85.   710   *R3:if abs(M(K,L))<=0.5 then return
  86.   720   R=int(0.5+M(K,L))
  87.   730   for I=0 to N%:B(K,I)=B(K,I)-R*B(L,I):C(I,L)=C(I,L)+R*C(I,K):next I
  88.   740   M(K,L)=M(K,L)-R:for I=0 to L-1:M(K,I)=M(K,I)-R*M(L,I):next
  89.   750   return
  90.   760   '
  91.   770   '   The following routine uses the normal form to search for ALL
  92.   780   '   vectors up to a given squared length with respect to the form.
  93.   790   '   It only list one of each pair w, -w.
  94.   800   '
  95.   810   *SEARCH:K=N%:clr Y(N%),Z(N%),NN
  96.   820   input "Search up to square length (try v(0) for shortest vector)";TT
  97.   830   input "Print vectors (0/1)";SS%:if SS% then print "vector | square len."
  98.   840   goto *S1
  99.   850   *S0:dec K:Z(K)=0:for I=K+1 to N%:Z(K)=Z(K)+M(I,K)*X(I):next
  100.   860   Y(K)=Y(K+1)+V(K+1)*(X(K+1)+Z(K+1))^2
  101.   870   *S1:X(K)=int(sqrt((TT-Y(K))/V(K))-Z(K))
  102.   880   *S2:while V(K)*(X(K)+Z(K))^2>TT-Y(K):inc K:dec X(K):wend
  103.   890   'if K=N%+1 then print "ERROR":stop:return
  104.   900   if K goto *S0
  105.   910   if or{X(0),Y(0)}-1 then print 2*NN;"nonzero vectors up to";TT:return
  106.   920   if SS% then for I=0 to N%:AC=0:for J=0 to N%:AC=AC+X(J)*B(J,I):next:print using(5),AC;:next:print tab(60);"|";:PR=V(0)*(X(0)+Z(0))^2+Y(0):gosub *PR:print
  107.   930   inc NN:dec X(K):goto *S2
  108.   940   '
  109.   950   *PRINTFORM:print "Form with respect to new basis:"
  110.   960   for I=0 to N%:for J=0 to N%:if J<I then PR=M(J,I):gosub *PR:goto 980
  111.   970   gosub *IP(&B(),I,J):M(I,J)=IP:PR=IP:gosub *PR
  112.   980   next:print:next:return
  113.   990   *PRINTLENGTHS:print "Lengths of basis vectors":for I=0 to N%:gosub *IP(&B(),I,I):PR=IP:gosub *PR:next:print:return
  114.  1000   *PRINTBASE:print "Basis":for I=0 to N%:for J=0 to N%:print using(5),B(I,J);:next:print:next:return
  115.  1010   *PRINTINV:print "Inverse of basis matrix":for I=0 to N%:for J=0 to N%:print C(I,J);:next:print:next:return
  116.  2000   '
  117.  3030   *PR:PE=0:if PR=0 then jump
  118.  3040   while abs(PR)>=10:PR=PR/10:PE=PE+1:wend
  119.  3050   while abs(PR)<1:PR=PR*10:PE=PE-1:wend
  120.  3060   **:print using(4,4),PR;" E";using(3),PE;
  121.  3070   return
  122.