4 (defun maxima::$latticereduce
(L) ; L is maxima list of maxima lists
8 (not (equal (apply 'max
(mapcar 'length
(cdr L
)))
9 (apply 'min
(mapcar 'length
(cdr L
))) )) )
10 (maxima::merror
"Latticereduce needs a list lists as input"))
11 (let* ((vs (mapcar 'cdr
(cdr L
)))
13 (v (make-array (list n
))))
14 (loop for i from
0 to
(- n
1) do
15 (setf (aref v i
) (make-array (list n
) :initial-contents
(nth i vs
))))
17 (cons '(maxima::mlist
)
18 (mapcar #'(lambda (u) (cons '(maxima::mlist
) (coerce u
'list
)))
23 (defun maxima::$integerrelations
(L)
24 (let ((res (integerrelations (cdr L
))))
25 (cons '(maxima::mlist
) (car res
))
28 (defun maxima::$floatrelations
(L)
29 (let ((res (floatrelations (cdr L
))))
30 (cons '(maxima::mlist
) (car res
))
33 (defun maxima::$recognize
(x)
36 ; linear algebra helpers
39 (declare (type (vector number
*) a
))
40 (loop for i from
0 to
(- (length a
) 1) sum
41 (* (aref a i
) (aref a i
) )))
45 (declare (type (vector number
*) a
))
46 (declare (type (vector number
*) b
))
47 (if (not (= (length a
) (length b
)))
48 (error "vadd: length must coincide")
49 (let ((res (make-array (list (length a
)) ))
51 (loop for i from
0 to
(- n
1) do
52 (setf (aref res i
) (+ (aref a i
) (aref b i
))))
56 (declare (type (vector number
*) a
))
57 (declare (type (vector number
*) b
))
58 (if (not (= (length a
) (length b
)))
59 (error "vadd: length must coincide")
60 (let ((res (make-array (list (length a
)) ))
62 (loop for i from
0 to
(- n
1) do
63 (setf (aref res i
) (- (aref a i
) (aref b i
))))
67 (declare (type (vector number
*) a
))
68 (declare (type (vector number
*) b
))
69 (let ((res (make-array (list (length a
)) ))
71 (loop for i from
0 to
(- n
1) do
72 (setf (aref res i
) (* s
(aref a i
))))
77 (declare (type (vector number
*) a
))
78 (declare (type (vector number
*) b
))
79 (if (not (= (length a
) (length b
)))
80 (error "vadd: length must coincide")
81 (loop for i from
0 to
(- (length a
) 1) sum
82 (* (aref a i
) (aref b i
)))))
84 (defvar *gsbasis
* nil
)
87 (defun gso (f mu
) ; returns Gram-Schmidt OGS, updates mu
88 (declare (type vector a
))
89 (declare (type (array number
(* *) mu
)))
91 (g (make-array (list n
) )))
92 (loop for j from
0 to
(- n
1) do
(setf (aref g j
) (aref f j
)))
93 (loop for j from
0 to
(- n
1) do
94 (loop for k from
0 to
(- j
1) do
95 (if (> (norm2 (aref g k
)) 0)
98 (/ (dot (aref f j
) (aref g k
))
99 (dot (aref g k
) (aref g k
))))
100 (setf (aref g j
) (vsub (aref g j
) (smul (aref mu j k
) (aref g k
))))
106 (defun lll (f) ; f is vetor of n vectors
107 (declare (type (vector vector
*) f
))
108 (let* ((n (length f
))
109 (g (make-array (list n
) ))
113 (mu (make-array (list n n
) :initial-element
0)))
114 (loop for j from
0 to
(- n
1) do
115 (setf (aref g j
) (aref f j
))
116 (setf (aref mu j j
) 1))
119 (loop for j from
(- i
1) downto
0 do
121 (vsub (aref g i
) (smul (nint (aref mu i j
)) (aref g j
))))
124 (if (and (> i
0) (> (norm2 (aref gg
(- i
1))) (* 2 (norm2 (aref gg i
)))))
126 (setf temp
(aref g
(- i
1)))
127 (setf (aref g
(- i
1)) (aref g i
))
128 (setf (aref g i
) temp
)
139 (car (list (floor (+ q
(/ 1 2))))))
142 (lll #( #(12 2) #(13 4))))
145 (lll #( #(12 2) #(1 2))))
148 (lll #( #(1 2) #(12 2) )))
151 (lll #( #(1 2) #(9 -
4))))
153 (defun integerRelations (L) ; L ist list of integers
154 ; returns (rel def) such that dotproduct def of rel and L is small
155 (let* ((n (length L
))
156 (z nil
) (g nil
) (res nil
) (optdef 0) (optres nil
) (def 0)
157 (f (make-array (list (+ n
1)))))
158 (setf (aref f
0) (make-array (list (+ n
1)) :initial-element
0))
159 (loop for i from
1 to n do
160 (setf z
(make-array (list (+ n
1)) :initial-element
0))
161 (setf (aref z
0) (nth (- i
1) L
))
165 (setf optdef most-POSITIVE-fixnum
)
166 (loop for k from
1 to n do
169 (loop for i from n downto
1 do
170 (setf res
(cons (aref (aref g k
) i
) res
))
171 (setf def
(+ def
(* (nth (- i
1) L
) (aref (aref g k
) i
))))
173 (if (< (abs def
) (abs optdef
))
183 (print "Should give ((3 -7 4) 0)")
184 (integerRelations '(5707963267 4142135623 2967764890)))
188 (- a
(car (list (floor a
)))))
191 (defun FloatRelations (x &optional
(digits 10)) ; x is a list of floats or doubles
192 (let ((n (length x
)) (digs nil
) (i 0) (nkomma 0)
193 (nkommaStellen0) (xx 0) (expo nil
) (rel nil
) (def 0))
195 (lambda (x) ; x ist float
197 (do () ((< (abs (nkomma (* x
(expt 10d0 s
)))) (expt 1d-1 digits
)))
200 (setf digs
(mapcar nkommaStellen x
))
201 (setf expo
(apply 'max digs
))
202 (setf xx
(mapcar #'(lambda (u) (car (list (floor (* u
(expt 10d0 expo
)))))) x
))
203 (setf rel
(IntegerRelations xx
))
204 (list (car rel
) (/ (cadr rel
) (expt 10.0d0 expo
)))
209 (FloatRelations (list .5707963267d0
.4142135623d0
.2967764890d0
)))
212 (defun mkdif (a b
) (list '(MAXIMA::MPLUS
) a
(list '(MAXIMA::MMINUS
) b
)) )
213 (defun mksum (a b
) (list '(MAXIMA::MPLUS
) a b
) )
214 (defun mkprod (a b
) (list '(MAXIMA::MTIMES
) a b
) )
215 (defun mkexpt (a b
) (list '(MAXIMA::MEXPT
) a b
))
216 (defun mkeq (a b
) (list '(MAXIMA::MEQUAL
) a b
))
218 (defun max2str (expr)
219 (maxima::mfuncall
'maxima
::$string expr
)
222 (defun convert2AlgNum (x &optional
(digits 10)) ; x is float or double
223 (let ((n 0) (nn 6) ;; nn: maximal search degree
224 (xs nil
) (res nil
) (def 0) (sol nil
)
227 (loop for n from
2 to nn do
228 (if (not (null opt
)) (return opt
))
229 (setf xs
(loop for i from
0 to n collect
(expt x i
)))
230 (setf res
(FloatRelations xs digits
))
231 (setf def
(cadr res
))
232 (if (< (abs def
) (expt 10d0
(- digits
)))
235 (loop for i from
0 to n do
236 (setf pol
(mksum pol
(mkprod (nth i
(car res
)) (mkexpt var i
)))))
237 (setf sol
(maxima::meval
(maxima::$solve
(mkeq pol
0) var
)))
238 (if (not (null (cdr sol
))) ; a solution has been found
239 (progn (setq *sol
* sol
)
240 (setf sol
(mapcar 'third
(cdr sol
)))
242 (mapcar #'(lambda (u)
243 (let ((r (maxima::$realpart u
))
244 (i (maxima::$float
(maxima::$imagpart u
))))
245 (if (or (equal i
0) (equal i
0.0) (equal i
0.0d0
))
246 (list u
(abs (- x
(maxima::$float u
))))
247 (list u most-POSITIVE-DOUBLE-FLOAT
)
250 (setf mini most-POSITIVE-DOUBLE-FLOAT
)
251 (loop for p in sol do
(if (< (second p
) mini
) (progn (setf opt
(car p
)) (setq mini
(second p
)))))
258 (defun test7 () ; fails
259 (convert2AlgNum 1.414213562373d0
))
262 (defun test8 () ; works
263 (convert2AlgNum (+ 2 (* 3 1.414213562373d0
))))
266 (defun test9 () :fails
267 (convert2AlgNum (+ 1d0
(sqrt 2d0
) (sqrt 3d0
)) ))