1 ;;; -*- Mode:Lisp; Package:CL-MAXIMA; Syntax:COMMON-LISP; Base:10 -*-;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ;;; Copyright (c) 1984 by William Schelter,University of Texas ;;;;;
5 ;;; All rights reserved ;;;;;
6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10 ; (:init-keywords :the-sparse-matrix :table :array-of-tables
11 ; :array-of-polynomials :type-of-entries :constants-column-number
12 ; :solution-in-macsyma-format :relations :variables :rows)
14 ; (:settable-instance-variables verify-conversion)
15 ; :gettable-instance-variables)
18 ; length-of-array-of-tables
24 ; number-of-independent-terms ;;never occurs
25 ; array-of-polynomials
28 ; constants-column-number
30 ; solution-in-macsyma-format
34 ;;The idea will be to take a list of vectors containing polynomials so
35 ;;why not an array such that the rows will represent the rows of the
36 ;;eventual sparse matrix to be created. The columns (there may be only
37 ;;one) will correspond to possibly different slots of some matrix. Thus
38 ;;if we have 20 2 by 2 matrices with polynomial entries, we shall
39 ;;consider an array 20 by 4. Or better yet why not 20 by 2 by 2. We
40 ;;wish do go through and create a table for each slot of the 2 by 2
41 ;;which lists the terms occurring somewhere in that slot. Then we will
42 ;;go through the polynomials and associate 20 sparse-matrix type rows
43 ;;whose entries will be the coefficients obtained from looking in the
46 ;;Alternateley it is probably better to store the polynomial vectors as
47 ;;elements of a 1 dimensional art-q array. Thus each slot would contain
48 ;;a 2 by 2 art q array its entries being the appropriate polynomial.
50 (defvar $current_variables nil
)
51 (defvar $current_monomials nil
)
52 (defvar $fast_dotsimp t
"will use rat-ncmul")
53 (defvar $order_function
'$monomial_alphalessp
54 "Order used for dot monomials. Tail-alphalessp is another reasonable value.")
55 (defvar $aaaa nil
"Should contain a list of scalar coefficients $aa1 etc.")
56 (defvar $dot_simplifications nil
"Macsyma list of pattern ,replacements")
60 (defmacro get-rid-of-array
(ar)
61 `(return-array (prog1 ,ar
(setq ,ar nil
))))
63 ;(defmethod (polynomial-vectors :fasd-form) ()
64 ; (let ((options-present
65 ; (loop for u in (list :the-sparse-matrix :table :array-of-tables
66 ; :array-of-polynomials :type-of-entries :constants-column-number
67 ; :solution-in-macsyma-format :relations :variables :rows)
68 ; when (catch-error (send self u) nil)
69 ; appending (list u (send self u)))))
70 ; (setq options-present (cons nil options-present))
71 ; `(instantiate-flavor 'polynomial-vectors ',options-present t)))
72 ;(defmethod (polynomial-vectors :init) (plist &aux value )
73 ; (loop for value-name in (list :the-sparse-matrix :table :array-of-tables
74 ; :array-of-polynomials :type-of-entries :constants-column-number
75 ; :solution-in-macsyma-format :relations :variables :rows)
76 ; when (setq value (get plist value-name))
77 ; do (send self :eval-inside-yourself
79 ; (INTERN (string-trim ":"
80 ; (string value-name)) 'MACSYMA ) VALUE)) ))
82 (defun macsyma-display (form)
83 "Takes a macsyma form and displays it"
84 (displa `((mlabel) 1 ,form
)))
87 (grind-top-level form
))
89 (defun list-terms (poly &aux terms
)
90 (cond ((eql poly
0) nil
)
91 ((atom poly
) (setq terms
(list poly
)))
98 (mnctimes (list poly
))
100 (otherwise (error "~A is not a polynomial" poly
))))))
102 ; (cond ((user:appears-in terms 'mplus)
103 ; (format t "~%~A was not fully expanded, so using its expansion" poly)
104 ; (list-terms ($expand poly)))
106 (defmacro remove-second
(a-list)
107 `(rplaca (cdr ,a-list
) (car ,a-list
)))
109 (defun numerical-coefficient-and-monomial (term &aux
(answer 1) (monomial 1))
110 "returns two values the numerical coefficient and either 1 or
111 an atomic variable or a power eg ((mexpt simp) $x 2) or a list l
112 which whose elements would be multiplied ( by doing (cons '(mtimes simp) l) )
113 to obtain the appropriate monomial. This does work."
115 (cond ((numberp term
) (setq answer term
))
116 ((atom term
) (setq monomial term
))
119 (mtimes (cond (($numberp
(second term
)) (setq answer
(second term
))
120 (setq monomial
(cddr term
)))
121 (t (setq monomial
(cdr term
))))
122 (cond ((atom (car monomial
))nil
)
123 ((appears-in (caar monomial
) 'mplus
)
124 (error "Some monomial with a sum in it"))))
125 (mexpt (setq monomial term
))
126 (mnctimes (setq monomial term
))
127 (mncexpt (setq monomial term
))
128 (otherwise (error "~A is not a term." term
)))
129 (cond ((eql 1 (length monomial
)) (setq monomial
(car monomial
))))))
130 (values answer monomial
)) ;;Note this a monomial less the '(mtimes simp)!!!
132 ;;definition: A monomial is 1, or a symbol, or ((mexpt simp) var
133 ;;number) or ((mncexpt simp) var number) or ?((mnctimes simp) var number)?
134 ;;or ((mtimes simp) a1 a2 ... an) where a1, a2, ... an are in the above
135 ;;list( but not 1). Here var stands for a symbol and number stands for
136 ;;an integer bigger than 1.
138 ;;definition: A term is a number, or a monomial, or ((mtimes simp)
141 ;;definition: A polynomial is either a term or ((mplus simp) t1 t2 ...
142 ;;tn) where the t1,.. tn are terms.
144 ;;definition: A premonomial is a monomial with the (mtimes simp)
147 ;;The keys in our hash table will be premonomials. The reason is it is
148 ;;simpler to just remove the ((mtimes simp) number at beginning of a
149 ;;list rather than keeping it. It will also make the hashing slightly
152 (defun make-monomial ( premonomial
)
153 "Returns a monomial given a premonomial"
154 (cond ((atom premonomial
) premonomial
)
155 ((atom (car premonomial
)) (cons '(mtimes simp
) premonomial
))
156 ; ((eq (caar premonomial) 'mexpt) premonomial)
157 ; (t (cons '(mtimes simp) premonomial))))
158 (t (case (caar premonomial
)
160 (mnctimes premonomial
)
161 (mncexpt premonomial
)
162 (otherwise (cons '(mtimes simp
) premonomial
))))))
164 (defun make-premonomial (monomial)
165 (cond ((atom monomial
) monomial
)
167 (delete '(mtimes simp
) monomial
:test
#'equal
))))
168 (defun macsyma-list (&rest l
)
169 (cons '(mlist simp
) (copy-list l
)))
171 (defun show-coeff (poly )
172 (loop for u in
(list-terms poly
)
173 do
(multiple-value-bind (coefficient guts-monomial
)
174 (numerical-coefficient-and-monomial u
)
175 (format t
"~%~A has coefficient ~D and monomial ~A" u coefficient
176 (make-monomial guts-monomial
))
177 (displa (macsyma-list u coefficient
(make-monomial guts-monomial
))))))
179 ;(setf (function $tee) (function convert-polynomial-to-vector))
181 (defvar *one-dimensional-array
* (make-array 100 :fill-pointer
0 :adjustable t
) "A temporary one dimensional array")
183 (defun convert-polynomial-to-vector (polynomial hash-table
&optional last-column-number parts-of-monomial
)
184 "Returns the row corresponding to the polynomial and the new last-column-number.
185 The first argument is a regular macsyma polynomial in expanded form as returned
186 by Expand(polynomial);. The second argument is the hash-table, and the last is the
187 number of entries in the hash table."
188 (let* ((terms (list-terms polynomial
))
190 ; (last-column-number (send hash-table :filled-elements))
193 (setq answer
(make-array (* 2 (length terms
)) :fill-pointer
0 :adjustable t
))
194 (cond ((null last-column-number
)
195 (setq last-column-number
196 (hash-table-count hash-table
))))
197 (cond ((null parts-of-monomial
) (setq parts-of-monomial
198 'numerical-coefficient-and-monomial
)))
200 do
(multiple-value-bind (coeff mon
)
201 (funcall parts-of-monomial u
)
202 (cond ((setq col
(gethash mon a-table
)))
203 (t (setq col
(1+ last-column-number
))
204 (setq last-column-number col
)
205 (setf (gethash mon a-table
) col
)))
206 (vector-push-extend col answer
)
207 (vector-push-extend coeff answer
)))
209 (collect-coefficients answer
)
210 (maybe-move-back-fill-pointer answer
)
211 (values answer last-column-number
)))
213 (defmacro reverse-two-values
(form)
214 `(multiple-value-bind (.first. .second.
),form
215 (values .second. .first.
)))
217 (defun mac-add* (&rest l
&aux tem
)
218 (setq tem
(apply #'add
* l
))
219 (cond (($zerop tem
) 0)
222 (defun collect-coefficients ( a-row
&aux col sum
)
223 (loop for i below
(length (the cl
:array a-row
)) by
2
224 when
(setq col
(aref a-row i
))
227 (setq sum
(aref a-row
(1+ i
)))
228 (loop for ii from
(+ i
2) below
(length (the cl
:array a-row
)) by
2
229 when
(equal col
(aref a-row ii
))
232 (setq sum
(mac-add* sum
(aref a-row
(1+ ii
))))
233 (setf (aref a-row ii
) nil
)
234 (setf (aref a-row
(1+ i
)) sum
))))
236 (defun sc_and_nc_parts (monomial)
237 (reverse-two-values (extract_nc_and_sc_parts monomial
)))
239 (defun $list_terms
(f)
240 (macsyma-list (list-terms f
)))
243 (defun get-key (table value
)
244 (loop for ke being the hash-keys in table using
(hash-value val
)
245 when
(equal val value
)
248 ;; (defun convert-polynomial-row (row hash-table &aux terms cof col mon)
249 ;; "This should actually return something equal to the original polynomial
250 ;; which was fed into convert-polynomial-to-vector"
252 ;; (loop for ii below (length (the cl:array row)) by 2
253 ;; when (setq col (aref row ii ))
255 ;; (setq mon (get-key hash-table col))
256 ;; (setq cof (aref row (1+ ii )))
258 ;; (mul* cof (make-monomial mon))))
259 ;; ; (cond ((atom mon)(list '(mtimes simp) cof mon))
260 ;; ; ((eq (car mon) 'mexpt) (list '(mtimes simp) cof mon))
261 ;; ; (t (append (list '(mtimes simp) cof) mon)))))
262 ;; (append '((mplus simp)) terms))
264 (defun convert-polynomial-row (row hash-table
&aux terms cof col mon
)
265 "This should actually return something equal to the original polynomial
266 which was fed into convert-polynomial-to-vector"
268 (loop for ii below
(length (the cl
:array row
)) by
2
269 when
(setq col
(aref row ii
))
271 (setq mon
(get-key hash-table col
))
272 (setq cof
(aref row
(1+ ii
)))
275 (mul* cof
(make-monomial mon
))))
276 (apply #'add
* terms
))
278 (defun make-one-dimensional (an-array)
279 (if (= (array-rank an-array
) 1)
281 (make-array (apply #'* (array-dimensions an-array
)) :adjustable t
:displaced-to an-array
)))
283 (defun total-dimension (an-array)
284 (apply #'* (array-dimensions an-array
)))
286 (defmacro equation-length
(eqn)
287 `(cond ((atom ,eqn
) 1)
288 (($plusp
,eqn
) (1- (length ,eqn
)))
291 (defun pv-get-rows-from-macsyma-equations
292 (self equations
; &optional variables
293 &aux tem temp-array
) ; corresponding-variables-column)
294 (check-arg equations $listp
"Macsyma list")
295 (setq temp-array
(make-array (length equations
) :fill-pointer
0 :adjustable t
))
296 (loop for u in
(cdr equations
)
298 (setq tem
(bring-to-left-side u
))
301 (cond ((zerop tem
)(format t
"~%Eliminate Trivial equation"))
302 (t (format t
"~%Warning: Inconsistent equation ~A = 0" tem
))))
303 (t (vector-push-extend tem temp-array
))))
306 ( pv-get-rows-from-array-of-polynomials self temp-array
)
307 (setf (pv-constants-column-number self
) (gethash 1 (pv-table self
) ))
308 ( pv-set-up-sparse-matrix-from-rows self
))
309 (defun pv-set-up-sparse-matrix-from-rows (self)
310 (cond ( (pv-the-sparse-matrix self
) nil
)
311 (t (setf (pv-the-sparse-matrix self
) (make-sparse-matrix))))
312 ( sp-set-rows
(pv-the-sparse-matrix self
) (pv-rows self
))
313 ( sp-set-type-of-entries
(pv-the-sparse-matrix self
)
314 (pv-type-of-entries self
))
315 (cond ((pv-constants-column-number self
)
316 ( sp-set-constants-column
317 (pv-the-sparse-matrix self
)
318 (pv-constants-column-number self
)))
319 (t (setf (sp-constants-column
320 (pv-the-sparse-matrix self
)) nil
))))
322 (defun pv-reduce (self)
323 ( pv-set-up-sparse-matrix-from-rows self
)
324 ( sp-reduce
(pv-the-sparse-matrix self
))
325 (format t
"~%The rank is ~D"
326 ( sp-number-of-pivots
(pv-the-sparse-matrix self
))))
328 (defmacro solution-corresponds-to-column
(a-solution)
329 ; `(array-leader ,a-solution 1))
330 `(getf (pv-solution-plist self
) ,a-solution
))
332 (defvar *show-solve
* t
)
333 (defvar $solution_parameter
'$par
"The prefix for the parameters in solve-suitable-to-sublis,
334 a value of nil uses the values in table instead.")
336 (defun poly-identity (x)
340 (defun pv-solve-suitable-to-sublis
341 (self &aux the-solutions the-special-solution dim tem col-list no-pivot
342 answer final-answer this-row
(val 0) parameter
343 special-contribution corresponding-variables-column
344 columns-used-to-pivot
)
346 (format t
"~%Starting to solve. There are ~D equations with ~D unknowns occurring."
347 ( sp-number-of-rows
(pv-the-sparse-matrix self
))
348 (length ( sp-list-of-all-columns-occurring
(pv-the-sparse-matrix self
))))))
350 ( sp-solve
(pv-the-sparse-matrix self
) :reduce t
)
351 (setf col-list
( sp-list-of-all-columns-occurring
(pv-the-sparse-matrix self
)))
352 (setq the-solutions
( sp-rows
( sp-solutions
(pv-the-sparse-matrix self
))))
353 (setq the-special-solution
354 ( sp-special-solution
355 ( sp-solutions
(pv-the-sparse-matrix self
))))
356 (setq dim
(array-total-size the-solutions
))
357 (setq no-pivot
(sp-columns-with-no-pivot(pv-the-sparse-matrix self
)))
358 (cond (the-special-solution
359 (setq columns-used-to-pivot
360 (sp-columns-used-to-pivot(pv-the-sparse-matrix self
) ))))
361 (cond (*show-solve
* (format t
"~%The dimension of the solution space is ~D" dim
)))
364 (loop for i in col-list
367 (setq special-contribution
0)
368 (loop for ii below
(length (the cl
:array the-solutions
))
370 (setq this-row
(aref the-solutions ii
))
371 (setq corresponding-variables-column
372 (solution-corresponds-to-column this-row
))
373 (setq tem
(row-entry this-row i
))
374 ;;;corresponding-variables-column
377 (cond ($solution_parameter
(setq parameter
(intern (format nil
"~a~d" $solution_parameter ii
))))
379 (error "unexpected case")
381 (get-key (pv-table self
)
382 corresponding-variables-column
))))
383 (setq val
(sp-mul* tem
385 (setq answer
(sp-add* answer val
)))
386 (cond (the-special-solution
387 (setq special-contribution
388 (poly-identity (row-entry the-special-solution i
)))))
389 (setq answer
(sp-add* answer special-contribution
))
392 (get-key (pv-table self
) i
)
393 (new-disrep answer
))))
394 (setf (pv-solution-in-macsyma-format self
) (cons '(mlist) final-answer
)))
397 (defun pv-get-rows-from-list-of-polynomials
398 (self mac-list
&optional parts-of-monomial
&aux ar
)
399 (setq ar
(make-array (length (cdr mac-list
)) :adjustable t
))
400 (fillarray ar
(cdr mac-list
))
401 ( pv-get-rows-from-array-of-polynomials self ar parts-of-monomial
))
403 (defun $find_rank_of_list_of_polynomials
(a-list &aux cols
)
404 (declare (special $poly_vector
))
405 ( pv-get-rows-from-list-of-polynomials $poly_vector a-list
)
406 ( pv-set-up-sparse-matrix-from-rows $poly_vector
)
407 (let ((sp ( pv-the-sparse-matrix $poly_vector
)))
409 (setq cols
( sp-column-used-in-row sp
))
410 (loop for i below
(length (the cl
:array cols
))
413 finally
(return rank
))))
415 (defun pv-get-rows-from-array-of-polynomials
416 (self an-array
&optional parts-of-monomial last-column-number
)
417 "Takes AN-ARRAY whose entries are polynomials or Art-q-n arrays of polynomials.
418 It uses the parts-of-monomial if supplied to get the coefficients"
419 (let* ((number-of-rows (length (the cl
:array an-array
)))
420 first-element a-row poly partial-row
)
421 (cond ((> 0 number-of-rows
)(setq first-element
(aref an-array
0))))
422 (cond ((arrayp first-element
)
423 (setf (pv-length-of-array-of-tables self
) (total-dimension first-element
))
424 (setf (pv-type-of-polynomials self
) :polynomial-vectors
)
425 (cond ( (pv-array-of-tables self
) nil
)
426 (t ( pv-set-up-hash-tables self
))))
427 (t (setf (pv-type-of-polynomials self
) :polynomial
)
428 (cond (( pv-table self
) (clrhash (pv-table self
) ))
429 (t ( pv-set-up-hash-tables self
)))))
430 (setf (pv-rows self
) (make-array number-of-rows
:adjustable t
))
432 (setf (pv-array-of-polynomials self
) an-array
)
434 (pv-type-of-polynomials self
)
436 (loop for i below number-of-rows
438 (setq poly
(aref an-array i
))
439 (setq a-row
(convert-polynomial-to-vector
440 poly
(pv-table self
) nil parts-of-monomial
))
441 (setf (aref (pv-rows self
) i
) a-row
)
443 (cond ((pv-verify-conversion self
)
444 (check-conversion poly a-row
(pv-table self
))))))
447 (loop for i below number-of-rows
449 (setq poly-vector
(make-one-dimensional
450 (aref (pv-array-of-polynomials self
) i
)))
451 (setf (aref (pv-array-of-polynomials self
) i
) poly-vector
)
452 (setq a-row
(make-array (length poly-vector
) :fill-pointer
0 :adjustable t
))
453 (setf (aref (pv-rows self
) i
) a-row
)
454 (loop for ii below
(array-total-size poly-vector
)
456 (setq poly
(aref poly-vector ii
))
457 (multiple-value (partial-row last-column-number
)
458 (convert-polynomial-to-vector
460 (aref (pv-array-of-tables self
) i
)
461 (pv-last-column-number self
) parts-of-monomial
))
462 (setf (pv-last-column-number self
) last-column-number
)
463 (cond ((pv-verify-conversion self
)
464 (check-conversion poly partial-row
465 (aref (pv-array-of-tables self
) i
))))
466 (loop for k below
(length (the cl
:array partial-row
))
467 do
(vector-push-extend (aref partial-row k
) a-row
))
468 ;;; (get-rid-of-array partial-row)
470 ( pv-check-type-of-entries self
))
472 (defun check-conversion (polynomial row table
&aux poly
)
473 (cond ((equal (setq poly
(convert-polynomial-row row table
)) polynomial
)
474 (format t
"~%Checking polynomial ~A and table ~A. Conversion OK." row table
))
476 "~%The converted row ~A and the polynomial ~A with translation table
477 ~A do not agree. They differ by " row polynomial table
)
478 (displa (mul* poly
(add* -
1 polynomial
))))))
480 (defun pv-check-type-of-entries (self &aux a-row
)
481 (setf (pv-type-of-entries self
) (or modulus
:rational
))
483 (loop for ii below
(length (the cl
:array
(pv-rows self
)))
485 (setq a-row
(aref (pv-rows self
) ii
))
486 (loop for i below
(length (the cl
:array a-row
)) by
2
487 when
(and (aref a-row i
) (not (numberp (aref a-row
(1+ i
)))))
488 do
(setf (pv-type-of-entries self
) ':any-macsyma
)
489 (throw 'done
'done
))))
490 (format t
"~%Using entry type ~A." (pv-type-of-entries self
)))
492 (defun pv-set-up-hash-tables (self)
493 (case (pv-type-of-polynomials self
)
494 (:polynomial
(setf (pv-table self
) (make-hash-table :test
'equal
)))
496 (setf (pv-last-column-number self
) 0)
497 (setf (pv-array-of-tables self
)
498 (make-array (pv-length-of-array-of-tables self
) :fill-pointer
0 :adjustable t
))
499 (loop for i below
(pv-length-of-array-of-tables self
)
501 (vector-push (make-hash-table :test
'equal
) (pv-array-of-tables self
))))))
504 (defun $my_sum
(quote-form quote-index start
&optional end
&aux answer
)
505 (setq quote-form
(subst 'ind quote-index quote-form
))
506 (setq start
(meval start
))
507 (setq end
(meval end
))
510 (loop for ind from start to end
514 (loop for ind in
(cdr start
)
516 (meval quote-form
)))))
517 (setq answer
(meval* (cons '(mplus) answer
)))
520 (defun $list_dot
(l ll
)
521 (apply #'add
* (loop for u in
(cdr l
) for v in
(cdr ll
)
522 collecting
(mul* u v
))))
524 (defun permutations (a-list &optional
(size (length a-list
)) &aux answer
)
525 (setq answer
(loop for u in a-list collecting
(list u
)))
526 (loop for i below
(1- size
)
529 (loop for v in a-list
531 (loop for perm in answer
532 when
(not (member v perm
:test
#'equal
))
533 collecting
(cons v perm
)))))
537 (defun sign-of-permutation (perm-of-first-n-non-negative-integers)
538 "Will return the proper sign of a permutation of the first n non-negative integers"
539 (nsign-of-permutation (copy-list perm-of-first-n-non-negative-integers
)))
541 (defun nsign-of-permutation (perm &aux tem
)
542 (let ((sub1-leng (1- (length perm
))))
543 (cond ((zerop sub1-leng
) 1)
544 ((eq (setq tem
(car (last perm
))) sub1-leng
)
545 (nsign-of-permutation (nbutlast perm
)))
546 (t (nsubst tem sub1-leng perm
)
547 (- (nsign-of-permutation (nbutlast perm
)))))))
549 (defun $make_art_q
(&rest indices
)
550 (make-array indices
:adjustable t
))
552 (defun $first_variable
(monomial )
553 (cond ((numberp monomial
) nil
)
554 ((atom monomial
) monomial
)
555 (t (loop for u in monomial do
(print u
)
556 (cond ((numberp u
) nil
)
557 ((atom u
) (return u
))
558 ((member u
'((mtimes simp
) (mtimes)
559 (mexpt simp
) (mncexpt simp
) (mncexpt)
560 (mnctimes simp
)(mnctimes)) :test
#'equal
) nil
)
561 ((member (car u
)'((mtimes simp
) (mtimes)
562 (mnctimes simp
)(mnctimes)) :test
#'equal
)
563 (return ($first_variable
(cdr u
))))
564 (t (return (second u
))))))))
568 (simplifya (cons '(mnctimes) (copy-list l
)) nil
))
571 (defun $convert_right_to_left
(a b
)
572 (let* ((f ($expand
(add* (m. a
'$x
) (m. b
'$y
))))
573 (terms (list-terms f
)) x-terms y-terms
)
574 (loop for u in terms do
575 (format t
"~%For term ~A" u
)
576 (cond ((equal ($first_variable u
) '$x
) (setq x-terms
(cons u x-terms
)))
577 ((equal ($first_variable u
) '$y
) (setq y-terms
(cons u y-terms
)))
578 (t (error "~A has first variable not x or y" u
))))
580 (macsyma-list (apply 'add
* x-terms
) (apply 'add
* y-terms
))))
582 (defun $split_into_x_and_y
(f)
583 (let ((terms (list-terms f
)) x-terms y-terms
)
584 (loop for u in terms do
585 (format t
"~%For term ~A" u
)
586 (cond ((equal ($first_variable u
) '$x
) (setq x-terms
(cons u x-terms
)))
587 ((equal ($first_variable u
) '$y
) (setq y-terms
(cons u y-terms
)))
588 (t (error "~A has first variable not x or y" u
))))
590 (macsyma-list (apply 'add
* x-terms
) (apply 'add
* y-terms
))))
592 (defun $matrix_entry
(x i j
) (nth i
(nth j x
)))
594 (defun initial-equal (list-a list-b
)
595 (not (loop for u in list-a for v in list-b
599 (defun initial-sublist (lista biglist
)
600 (cond ((< (length biglist
) (length lista
)) nil
)
601 (t (initial-equal lista biglist
))))
605 (defun $replace_the_pattern
(adp pattern replacement
&aux tem
)
606 "replaces the pattern in ADP (a dot product) by replacement. When
607 inserted in the simplifier simpmnct it does the replacement whenever
609 (cond ((atom adp
) adp
)
610 ((equal (caar adp
) 'mnctimes
)
611 (cond ((setq tem
(ordered-sublist (cdr pattern
) (cdr adp
)))
612 (ncmul* (ncmuln (car tem
) t
) replacement
(ncmuln (cadr tem
)t
)))
617 "If nil the simplifier will use $dot_simplifications to reduce
618 dot_products, much the same as can be obtained by doing $dotsimp")
620 (defun dotsimp-one-term (monom coeff ignor
) ignor
621 (mul* coeff
($expand
($dot_simp_monomial monom
))))
623 (defun dotsimp-atom (expr)
624 (loop for u in
(cdr $dot_simplifications
)
626 when
(and (oddp i
)(eq u expr
))
627 do
(return (nth (1+ i
) $dot_simplifications
))
628 finally
(return expr
)))
629 (defvar *troublesome-variables
* nil
)
630 (defun check-rat-order (expr &optional
(variables *troublesome-variables
*)
631 &aux maybe-out-of-order nc-product-appeared
)
632 (cond ((and (consp expr
)($ratp expr
))
633 (loop for v in
(third (car expr
))
634 when
(not (fast-scalarp v
))
635 do
(setq nc-product-appeared t
)
636 when
(and (member v variables
:test
#'eq
) nc-product-appeared
)
637 do
(setq maybe-out-of-order t
))))
638 (cond (maybe-out-of-order
639 (setq nc-product-appeared nil
)
640 (setq maybe-out-of-order nil
)
641 (loop for v in
(third (car expr
))
642 for w in
(fourth (car expr
))
643 when
(and (not (atom v
))(eq (caar v
) 'mnctimes
))
644 do
(setq nc-product-appeared t
)
645 when
(and (member v variables
:test
#'eq
) nc-product-appeared
646 (appears-in (cdr expr
) w
))
648 (setq maybe-out-of-order t
)))
650 (cond (maybe-out-of-order
651 (setq nc-product-appeared nil
)
652 (cond ((loop for v in
(third (car expr
))
653 for w in
(fourth (car expr
))
654 when
(and (not (atom v
)) (eq (caar v
) 'mnctimes
)
655 (appears-in (cdr expr
) w
))
656 do
(setq nc-product-appeared t
)
657 when
(and (member v variables
:test
#'eq
) nc-product-appeared
658 (appears-in (cdr expr
) w
))
660 (format t
"~%~%~%*************Changing rat order")
661 (beep)(break 'change
)
662 (setq expr
($nc_rat expr
))))))
664 (defun get-varlist (expr)
665 (cond (($ratp expr
)(third (car expr
)))
667 ;(defun minimize-varlist-and-genvar (expr)
668 ; (cond (($ratp expr)
669 ; (let ((var-list (third (car expr)))
670 ; (gen-var (fourth (car expr))))
672 ; (loop for v in var-list
674 ; when (user:appears-in (cdr expr) w)
675 ; collecting v into new-varlist
677 ; collecting w into new-genvar
678 ; finally (setf (third (car expr)) new-varlist)
679 ; (setf (fourth (car expr)) new-genvar)))))
681 (defmacro check-nc-rat-order
(expr)
682 ` (progn (format t
"~%checking order for ~A" ',expr
)
683 (setq ,expr
(check-rat-order ,expr
))))
684 (defun varlist (expr)
688 (defmacro show-varlist
(expr)
689 `(progn (format t
"~%The varlist for ~A is"',expr
)
690 (gt (varlist ,expr
))))
693 (defvar $radical nil
)
694 (defvar $radical_nilpotent_of_order
0)
695 (defun nil-radicalp (monom )
696 "gives nil if monom not in radical otherwise gives the power it is in"
697 (cond ((atom monom
) (setq monom
(list nil monom
))))
700 (loop for v in
(cdr $radical
)
702 (loop for w in
(cdr monom
)
703 when
(eq w v
) do
(setq answer
(1+ answer
))))
704 (cond ((zerop answer
) nil
)
706 (defun in-nth-power-radical (monom n
&aux tem
)
707 (cond ((setq tem
(nil-radicalp monom
))(> tem
(1- n
)))))
712 ;;;newest version with saving possible reset inside
713 (defun dot-show (nc-list)
714 (cond ((atom nc-list
) (princ nc-list
))
715 (t(format t
"~A" (string-trim "$" (string (second nc-list
))))
716 (loop for v in
(cddr nc-list
) do
717 (format t
".~A" (string-trim "$" (string v
)))))))
719 (defun new-rat-dotsimp (expr &aux
(answer 0) repl the-num the-denom the-rest tem
)
720 (format t
"~%Beginnning to new-rat-dotsimp ")
721 (cond (($must_replacep expr
)
722 (loop while
(not ($zerop expr
))
726 (cond (($must_replacep expr
))
727 (t (return (header-poly (n+ answer expr
)))))
728 (setq-num-den the-num the-denom expr
)
730 ; (cond ((affine-polynomialp expr) (setq the-num expr the-denom 1))
731 ; ((rational-functionp expr) (setq the-num (num expr) the-denom (denom expr)))
732 ; (t (fsignal "expr is supposed to be poly or rational-functionp")))
733 ; (cond ((numberp the-num)(setq answer (n+ answer expr))
734 (cond ((poly-scalarp the-num
)(setq answer
(n+ answer expr
))
735 (return (header-poly answer
))))
736 (setq tem
(get (car the-num
) 'disrep
))
738 (contains-a-zero-replacement tem
)
740 (format t
"~%Simplifying the worst monomial: ")(dot-show tem
)
741 (cond ((setq expr
(fifth the-num
)))
744 when
($must_replacep tem
) ;; (setq tem (get (car the-num) 'disrep)))
746 (format t
"~%Simplifying the worst monomial: ")(dot-show tem
)
747 (setq repl
(n* (third the-num
) ($dot_simp_monomial tem
)))
748 (cond ((setq the-rest
(fifth the-num
))
750 (setq expr
(n+ the-rest repl
))
752 (setq expr
(nred expr the-denom
)))
753 (t (setq expr
(nred repl the-denom
))))
756 (format t
"~%Simplifying the worst monomial: ")(dot-show tem
)
757 (format t
"adding it to answer")
758 (cond ((fifth the-num
)(setq expr
(nred (fifth the-num
) the-denom
))) ;cons?
760 (setq answer
(n+ answer
(nred (subseq the-num
0 3) the-denom
)))
763 (setq tem nil the-num nil the-denom nil
)
764 finally
(return (header-poly answer
))))
765 (t (header-poly expr
))))
767 (defun rat-dotsimp (expr &aux
(answer 0) repl monom term cof tem simped-monom
)
768 (format t
"~%Beginning to rat-dotsimp..")
769 (setq expr
(minimize-varlist expr
))
770 ; (setq upper-bound-for-gen-var (expt (length (cdr $current_variables))
771 ; ($nc_degree expr)))
772 ; (cond (*genvar* nil)
773 ; (t (setq *genvar* (copy-list genvar))))
774 ; (setq the-dif (max 0 (- (length *genvar*) upper-bound-for-gen-var (length (varlist expr))))
775 ; (setq gen-vars (nthcdr the-dif *genvar*))
776 ; (let ((genvar gen-vars))
778 (loop while
(and (not ($zerop expr
))($must_replacep expr
))
780 (multiple-value (monom cof
) (find-worst-nc-monomial expr
))
781 ; (check-nc-rat-order expr)))
782 (cond (($must_replacep monom
)
783 (setq expr
(vsub* expr
(vmul* cof monom
)))
784 ; (check-nc-rat-order expr)
785 (setq simped-monom
($dot_simp_monomial monom
))
786 (setq repl
(vmul* cof simped-monom
))
787 ; (check-nc-rat-order expr)
788 ; (check-nc-rat-order repl)
789 (cond (($must_replacep repl
)
790 (setq tem
(vadd* repl expr
))
792 (t (setq answer
(vadd* repl answer
)))))
793 (t (setq expr
(vsub* expr
(setq term
(vmul* cof monom
))))
794 (setq answer
(vadd* term answer
))))
796 ; (setq *genvar* (copy-list genvar))
797 (return (minimize-varlist (vadd* expr answer
)))))
801 (defun $dotsimp
(expr &aux
(answer 0) term cof varlist monom repl
(prev-monom 'zzzzz
))
802 (cond ((and $fast_dotsimp
(not(or (mbagp expr
) ($ratp expr
))))
803 (cond ($new_fast_dotsimp
(setq expr
($new_rat expr
)))
804 (t (setq expr
($vrat expr
))))))
805 (cond ((not (or (atom expr
)$fast_dotsimp
($ratp expr
)))
806 (setq expr
($multthru
($ratsimp
($expand expr
))))))
808 ((atom expr
)(setq answer
(dotsimp-atom expr
)))
810 (cond ($new_fast_dotsimp
(setq answer
(new-rat-dotsimp (cdr expr
))))
811 (t (setq answer
(rat-dotsimp expr
)))))
812 ((mbagp expr
)(setq answer
(cons (car expr
) (mapcar #'$dotsimp
(cdr expr
)))))
813 ((member (caar expr
) '(mtimes mnctimes
) :test
#'equal
)
814 (setq answer
(apply 'dotsimp-one-term
815 (multiple-value-list (find-worst-nc-monomial expr
))))
816 (cond (($must_replacep answer
)
817 (setq answer
($dotsimp answer
)))
819 ((equal (caar expr
) 'mplus
)
820 (loop while
(not (and (numberp expr
) (zerop expr
)))
821 count t into the-count
823 (cond ((not(atom expr
))
824 (show (length expr
))))
825 (multiple-value (monom cof term
)(find-worst-nc-monomial expr
))
826 (cond ((not (funcall $order_function monom prev-monom
))
827 (show prev-monom monom
)
828 (format t
"****** out of order ****")
830 (setq prev-monom monom
)
831 (cond (($must_replacep monom
)
832 ;;the following expand may be unnecessary with dotdistrib at true.
834 (setq repl
($multthru
(mul* cof
($expand
($dot_simp_monomial monom
)))))
835 (cond ((loop for v in
*troublesome-variables
*
839 (format t
"~%Ratsimping repl")
840 (setq repl
($multthru
($ratsimp repl
)))))
841 (setq expr
(sub* expr term
))
842 (setq expr
(add* repl expr
)))
844 (cond ((fast-scalarp term
)(setq expr
($multthru
($ratsimp expr
)))))
845 (setq expr
(sub* expr term
))(setq answer
(add* answer term
))))
846 finally
(show the-count
))))
851 ;(defun $tes (expr &aux tem1 tem2 tem3)
852 ; (let (( $free_dot t))
853 ; (setq tem1 ($dotsimp expr))
854 ; (setq $free_dot nil)
857 ; (setq tem2 (loop until (equal tem2 tem3)do
860 ; (setq tem3 (meval* ($expand (meval* tem3)))) ;(displa tem3)
861 ; finally (return tem3)))
862 ; ($ratsimp (sub* tem1 tem2))))
864 (defun remove_nth (n a-list
)
865 (cond ((zerop n
)(rplaca a-list
(cadr a-list
))(rplacd a-list
(cddr a-list
)) a-list
)
866 ((< n
(length a-list
))
867 (rplacd (nthcdr (1- n
) a-list
) (nthcdr (1+ n
) a-list
))
871 (defun $simp_ncmuln
(a-list flag
)
872 (cond ((and $free_dot $dot_simplifications
)
873 ($dotsimp
(ncmuln a-list flag
) ))
874 (t (ncmuln a-list flag
))))
875 (defun $simp_ncmul
(&rest a-list
)
876 ($simp_ncmuln
(copy-list a-list
) nil
))
878 ;(defun rat-ncmul (&rest a-list)
879 ; (cond ((and $free_dot $dot_simplifications)
880 ; ($dotsimp ($nc_rat (ncmuln a-list nil) )))
881 ; (t ($nc_rat (ncmuln (copy-list a-list) nil)))))
885 (loop for v in
(cdr f
)
886 collecting
($dncmul v g
) into vtemp
887 finally
(return (apply 'add vtemp
))))
890 (loop for u in
(cdr g
)
891 collecting
(ncmul f u
) into tem
892 finally
(return (apply 'add tem
))))
895 (defun dotsimp2 (expression )
896 (cond ((atom expression
) nil
)
897 ((equal (caar expression
) 'mnctimes
)(setq expression
($dot_simp_monomial expression
)))
898 (t (dotsimp1 expression
)))
901 (defun dotsimp1 (expression )
902 (cond ((atom expression
) expression
)
903 (t (rplaca expression
($dot_simp_monomial
(car expression
)))
904 (dotsimp1 (car expression
))
905 (dotsimp1 (cdr expression
)))))
907 (defvar *nonsense
* (list 'nonsense
))
909 (defun $dot_simp_monomial
(monom &aux answer tem
(init-monom monom
))
911 (dotsimp-atom monom
))
914 ((equal (caar monom
) 'mnctimes
)
915 (cond ($dot_simplifications
917 (catch 'found-replace
918 (let (pattern replacement tema
)
921 (setq tem
(cdr $dot_simplifications
))
922 (setq monom
(cdr monom
))
924 when
(and $new_fast_dotsimp
925 (or (eql 0 (second tem
))
926 (eq (rzero) (cdr (second tem
)))))
927 ; ($zerop (second tem)))
928 do
(setq tem
(cddr tem
))
931 (cond ((atom (setq pattern
(car tem
)))
932 (cond ((member pattern monom
:test
#'equal
)
934 ;;the case of an atomic pattern by making
935 ;;it a standard list '(nonsense)
936 (setq pattern
(list pattern
)))
937 (t (setq pattern
*nonsense
*))))
938 (t (setq pattern
(cdr pattern
))))
940 (setq replacement
(car tem
) tem
(cdr tem
))
943 (initial-sublist pattern monom
)
945 (setq tema
(subseq (cdr init-monom
) 0 (- (length init-monom
) (length monom
) 1)))
946 (cond ($new_fast_dotsimp
948 (new-rat-ncmul1 (ncmuln tema t
)
950 (ncmuln (nthcdr (length pattern
) monom
) t
))))
953 (rat-ncmul (ncmuln tema t
)
955 (ncmuln (nthcdr (length pattern
) monom
) t
)))))
956 (throw 'found-replace answer
))))))
957 (if answer answer init-monom
))
961 (defmacro $declare_order_weights
(&rest l
)
962 (loop for i below
(length l
) by
2
964 (putprop (nth i l
) (nth (1+ i
) l
) :order-weight
)))
966 (defmacro $declare_weights
(&rest l
)
967 (loop for i below
(length l
) by
2
969 (putprop (nth i l
) (nth (1+ i
) l
) :weight
)))
971 (defun $dot_productp
(x)
974 ((equal (caar x
) 'mnctimes
))))
976 ;could add to end of simpnct to change the simplifier.
977 ;;;The next part uses the $dot_simplifications to change the result, by doing replacement
978 ;;;For example Dot_simplifications:[y.x.x,-x.x.y,w.v,v.w] will do y.x.x-->-x.x.y and w.v-->v.w
979 ;;;Be careful that dot simplifications in effect will affect the attempt to define
980 ;;;new dot_simplifications. It might be better to set it to false first and then redefine it.
982 ; (cond (dot-simps (setq dot-simps (cdr dot-simps))
983 ; (loop while dot-simps
985 ; (setq answer ($replace_the_pattern answer (car dot-simps)
986 ; (second dot-simps)))
987 ; (setq dot-simps (cddr dot-simps))
988 ; finally (return answer)))
992 (defun $my_coeff
(f x
)
993 "like $coeff except it always works on general rep, and if x is 1 it picks the scalar part"
994 (cond (($ratp f
)(setq f
($ratsimp f
))))
995 (cond ((atom f
)(cond ((equal f x
) 1)
998 ((eq (caar f
) 'mtimes
)(cond ((member x f
:test
#'equal
)
999 (delete x
(copy-list f
) :test
#'equal
))
1000 ((and (equal x
1) ($scalarp f
)) f
)
1002 ((member (caar f
) '(mplus mlist mequal
) :test
#'eq
)
1003 (simplifya (cons (list (caar f
))
1004 (mapcar #'(lambda (y)
1005 ( $my_coeff y x
)) (cdr f
))) nil
))))
1007 (defun $ncoeff
(f x
&optional
(exponent 1))
1008 (cond ((eql x
1) ($my_coeff f x
))
1009 ((equal exponent
1)($coeff f x
))
1010 (t ($coeff f x exponent
))))
1013 ;(defun $extract_linear_equations (equations independent-monomials &aux ($expop 100)
1016 ; "Equations is a list of equations or expressions. Matrix
1017 ; equations could have been treated by subtracting the right side from
1018 ; the left side and then adding the list of entries to those in
1021 ; (check-arg equations $listp "A Macsyma List")
1022 ; (check-arg independent-monomials $listp "A Macsyma List")
1023 ; (setq answer (loop for u in (cdr independent-monomials)
1025 ; (loop for eqn in (cdr equations)
1027 ; collecting ($nc_coeff eqn u )
1028 ; when (appears-in eqn '$matrix)
1030 ; (cond ((eq (caar eqn) 'mequal)
1031 ; (setq tem (sub (second eqn) (third eqn))))
1032 ; (t (setq tem eqn)))
1033 ; (loop for row in (cdr tem)
1035 ; (loop for element in (cdr row)
1036 ; when (not ($zerop (setq ttemp ($nc_coeff element u))))
1037 ; collecting ttemp))
1039 ; collecting ($nc_coeff eqn u ))))
1040 ; (cons '(mlist simp) (union answer)))
1043 (defun $matrix_equationp
(expr)
1044 (or ($matrixp expr
) (and (null (atom expr
))(eq (caar expr
) 'mequal
)
1045 (null (atom (second expr
)))($matrixp
(second expr
)))))
1048 (defvar $last_monomials
'((mlist)))
1050 (defun $extract_linear_equations
(equations &optional
(independent-monomials
1051 ($list_nc_monomials equations
)))
1052 (check-arg equations $listp
"A Macsyma List")
1053 (loop for v in
(cdr equations
)
1054 do
(assert (or (atom v
) (not (equal(caar v
) 'mequal
)))))
1055 (cons '(mlist) (mapcar 'new-disrep
1056 (extract-linear-equations (st-rat equations
)
1057 (st-rat independent-monomials
)))))
1059 ;(defun $extract_linear_equations (equations &optional (independent-monomials ($list_nc_monomials equations))&aux ($expop 100)
1062 ; "Equations is a list of equations or expressions. Matrix
1063 ; equations could have been treated by subtracting the right side from
1064 ; the left side and then adding the list of entries to those in
1067 ; (check-arg equations $listp "A Macsyma List")
1068 ; (setq $last_monomials independent-monomials)
1069 ; (check-arg independent-monomials $listp "A Macsyma List")
1070 ; (setq answer (loop for u in (cdr independent-monomials)
1072 ; (loop for eqn in (cdr equations)
1074 ; collecting ($nc_coeff eqn u )
1075 ; when ($matrix_equationp eqn)
1078 ; (cond ((eq (caar eqn) 'mequal)
1079 ; (setq tem (sub (second eqn) (third eqn))))
1080 ; (t (setq tem eqn)))
1081 ; (loop for row in (cdr tem)
1083 ; (loop for element in (cdr row)
1084 ; when (not ($zerop (setq ttemp ($nc_coeff element u))))
1085 ; collecting ttemp)))
1087 ; collecting ($nc_coeff eqn u ))))
1088 ; (cons '(mlist simp) (zl-UNION answer)))
1091 (defun extract-linear-equations (list-eqns &optional tem all-ind-mons
)
1092 (loop for v in list-eqns
1093 with varl with ind-mons
= all-ind-mons
1094 do
(cond ((affine-polynomialp v
) nil
)
1095 ((rational-functionp v
)
1096 (setq v
(function-numerator v
)))
1098 "list-eqns should be a list of polynomials or rational functions")))
1099 (cond ((null all-ind-mons
)
1100 (setq varl
(list-variables list-eqns
))
1101 (setq ind-mons
(loop for vv in varl with mon
= (list nil
1 1)
1102 do
(setf (car mon
) vv
)
1103 when
(not (poly-scalarp mon
))
1107 (loop for va in ind-mons
1108 when
(not (pzerop (setq tem
(pcoeff v
(list va
1 1)))))
1112 (defun member-even (item a-list
&aux lis answer
)
1113 (cond ((evenp (length a-list
)) (setq lis a-list
))
1114 (t (setq lis
(butlast a-list
)) (cond ((equal (car (last a-list
)) item
)
1115 (setq answer item
)))))
1116 (cond ((null answer
)
1119 (cond ((equal item
(car lis
)) (return item
)))
1120 (setq lis
(cddr lis
))))
1123 (defun initial-segment-is-replaced (a-list)
1124 (cond ((atom a-list
) (member-even a-list
(cdr $dot_simplifications
)))
1126 (loop for i from
1 to
(length a-list
)
1128 (cond ((member-even (subseq a-list
0 i
) (cdr $dot_simplifications
)) (return t
)))))))
1130 ;(defun $mono (a-list n &optional $sort &aux answer tem ans1 sorted-cdr-list)
1131 ; "Returns the dot-monomials which will not be replaced by $dot_simplifications
1132 ; They are tail sorted if the optional third argument is given"
1133 ; (check-arg a-list $listp "a Macsyma list")
1134 ; (cond ((eql n 0) (cons '(mlist simp) '(1)))
1135 ; ((eql n 1) (setq answer (copy-list a-list))
1136 ; (loop for v in (cdr answer)
1137 ; when (member-even v $dot_simplifications)
1138 ; do (setq answer (delete v answer)))
1141 ; (setq sorted-cdr-list (sort (cdr a-list) '(lambda (x y) (alphalessp y x))))
1142 ; (setq answer (loop for u in sorted-cdr-list collecting (cons '(mnctimes simp) (list u))))
1143 ; (loop for i from 1 below n
1145 ; (loop for u in sorted-cdr-list
1147 ; (loop for v in answer
1149 ; (setq tem (cons u (cdr v)))
1150 ; (setq tem (cons '(mnctimes simp) tem))
1151 ; (cond ((initial-segment-is-replaced tem) nil)
1152 ; (t (setq answer1 (cons tem answer1 ))))))
1153 ; (setq answer answer1)
1154 ; (setq answer1 nil))
1155 ; (cond ($sort (setq answer (sort answer 'tail-alphalessp))))
1156 ; (cons '(mlist simp) answer)) ))
1157 ;;a*x.y^^2.z*b*c we want to extract x.y^^2.z
1158 (defun $extract_nc_part
(monomial &aux sc-part nc-part
)
1159 "Returns first value nc-part of monomial and second value the sc-part if
1160 that can be obtained without consing, nil otherwise. It uses the scalar property
1161 to check if a single atom is scalar or not, with things like ((mexpt simp) z 2) always
1162 assumed scalar. If there are two non-scalars * together it only takes the first one.
1163 If there are two ((mnctimes ..) ) It only takes the first one. "
1164 ;(setq monomial (simplifya monomial nil))
1166 ((atom monomial
) (cond (($scalarp monomial
) (setq nc-part
1 sc-part monomial
))
1167 (t (setq nc-part monomial
) (setq sc-part
1))))
1168 (t (case (caar monomial
)
1170 (loop for u in
(cdr monomial
)
1173 ((and (not (atom u
)) (eq (caar u
) 'mnctimes
))
1175 (cond ((eql (length monomial
) 3)
1176 (cond ((eq (second monomial
) u
)
1177 (setq sc-part
(third monomial
)))
1179 (second monomial
))))))
1181 (cond ((null nc-part
)
1182 (loop for u in
(cdr monomial
)
1183 when
(and (atom u
) (not ($scalarp u
)))
1184 do
(setq nc-part u
)
1185 (cond ((eql (length monomial
) 3)
1186 (cond ((eq (second monomial
) u
)
1187 (setq sc-part
(third monomial
)))
1189 (second monomial
))))))
1191 (cond ((null nc-part
) (setq nc-part
1 sc-part monomial
))))
1192 (mnctimes (setq nc-part monomial sc-part
1))
1193 (mexpt (setq nc-part
1 sc-part monomial
)) ;
1194 (otherwise (error "~A is not a product" monomial
)))))
1195 (values nc-part sc-part
))
1197 (defun extract_nc_and_sc_parts (monomial )
1198 (multiple-value-bind (nc-part sc-part
) ($extract_nc_part monomial
)
1199 (cond ((null sc-part
) (setq sc-part
(loop for u in monomial
1200 when
(not(eq u nc-part
))
1202 (cond ((eql (length sc-part
) 2) (setq sc-part
(cadr sc-part
))))))
1205 (values nc-part sc-part
)))
1206 (defun $extract_nc_and_sc_parts
(monomial )
1207 (multiple-value-bind (nc-part sc-part
) (extract_nc_and_sc_parts monomial
)
1209 (cons '(mlist simp
) (list nc-part sc-part
))))
1211 ;;fast_linsolve should be like linsolve but should convert the system
1212 ;;to a sparse matrix and then solve it. It should return the answer as a list
1213 ;;of solutions suitable for sublis if a certain flag is on. Otherwise
1214 ;;it would leave them as the sparse-matrix.
1216 ;;Polynomial_linsolve should extract the equations from some equations using
1217 ;;certain independent monomials occurring. It should then solve the system,
1218 ;;and if a flag is on return the list of solutions suitable for sublis.
1219 ;;a slow version could be:
1220 (defvar $fast_solve t
"Generally used to decide whether to call $linsolve or $fast_linsolve.
1221 The latter works only for number coefficients, while the former works using rattimes, etc.")
1223 (defun $setfy
(a-list)
1224 (loop for v in a-list
1225 when
(not (member v tem
:test
#'equal
))
1226 collecting v into tem
1227 finally
(return tem
)))
1229 (defun $list_nc_monomials
(expr &aux answer
)
1230 (cond ((atom expr
) '((mlist simp
)))
1231 ((eq (caar expr
) 'mnctimes
)`((mlist simp
) ,expr
))
1232 ((member (caar expr
) '(mlist mequal $matrix
) :test
#'eq
)
1233 (loop for u in
(cdr expr
)
1234 appending
(cdr ($list_nc_monomials u
)) into a-list
1235 finally
(return (cons '(mlist simp
) ($setfy a-list
)))))
1236 (t (setq expr
($expand expr
))
1237 (cond ((eq (caar expr
) 'mplus
)
1238 (loop for u in
(cdr expr
)
1239 when
(not (member (setq answer
(extract_nc_and_sc_parts u
))
1240 a-list
:test
#'equal
))
1241 collecting answer into a-list
1242 finally
(return (cons '(mlist simp
) a-list
))))
1243 ((eq (caar expr
) 'mtimes
)
1245 (list (extract_nc_and_sc_parts expr
))))
1246 (t '((mlist simp
)))))))
1247 (defun $reverse_equation
(eqn)
1248 (cond ((atom eqn
) eqn
)
1249 ((eq (caar eqn
) 'mequal
)(list (car eqn
) (third eqn
) (second eqn
)))
1252 (defvar *monomial-table
* (make-hash-table :test
'equal
))
1254 (defun nc-monomial-table (monom &aux repl
)
1255 (cond ((atom monom
) monom
)
1256 ((atom (car monom
)) monom
)
1257 (t (cond ((eq (caar monom
) 'mnctimes
)
1259 (setq repl
(gethash monom
*monomial-table
* ))
1260 (cond (repl (copy-tree repl
))
1261 (t (setq repl
($rat monom monom
))
1262 (setf (gethash monom
*monomial-table
*) repl
)
1266 (defun new-rat-ncmul (&rest list-of-terms
&aux
(denom 1))
1267 (setq list-of-terms
(copy-list list-of-terms
))
1268 (loop for v in list-of-terms
1270 when
(and (not (numberp v
))
1271 (or (affine-polynomialp v
)
1272 (rational-functionp v
)))
1274 (cond ((rational-functionp v
)(setq denom
(denom v
))))
1275 (return (cons (poly-ncmul1 (ncmuln (subseq list-of-terms
0 i
) nil
)
1277 (ncmuln (nthcdr (1+ i
) list-of-terms
) nil
)) denom
))
1278 finally
(return (ncmuln list-of-terms nil
))))
1280 (defun rat-ncmul (&rest list-of-terms
)
1281 (setq list-of-terms
(copy-list list-of-terms
))
1282 (loop for v in list-of-terms
1286 (return (ncmul1 (ncmuln (subseq list-of-terms
0 i
) nil
)
1288 (ncmuln (nthcdr (1+ i
) list-of-terms
) nil
)))
1289 finally
(return (ncmuln list-of-terms nil
))))
1291 (defun ncmul1 (mon expr mon1
)
1292 (setq expr
(minimize-varlist expr
))
1293 (loop for v in
(third (car expr
))
1294 when
(not (fast-scalarp v
))
1295 collecting
(ncmul* mon v mon1
) into tem
1296 else collecting v into tem
1297 finally
(return (cons (list 'mrat
'simp tem
(fourth (car expr
)))
1300 (defun mysub (expr replacement-function
)
1301 (mysub1 (copy-tree expr
) replacement-function
))
1302 (defun mysub1 (vv h
)
1303 (cond ((atom vv
) (funcall h vv
))
1304 (t (rplaca vv
(funcall h
(car vv
)))
1305 (rplacd vv
(funcall h
(cdr vv
)))))
1306 (cond ((atom vv
) vv
)
1307 (t (rplaca vv
(mysub1 (car vv
) h
))
1308 (cond ((not (eq (car vv
) 'mrat
)) ( rplacd vv
(mysub1 (cdr vv
) h
)))
1311 (defun max-for-pred (a-list pred
)
1312 (let ((w (car a-list
)))
1313 (loop for v in a-list
1314 when
(funcall pred v w
)
1316 finally
(return w
))))
1319 ;(defun find-worst-nc-monomial (expr &aux answer ans1 tem1
1320 ; cof coefficient answeru repeat-flag)
1321 ; "expr should be somewhat expanded. The result of ($multthru expr) is ok."
1322 ; (cond ((and (not ($plusp expr))
1323 ; (user:appears-in expr 'mplus))(setq expr ($multthru ($ratsimp ($expand expr))))
1324 ; (format t "~%find-worst-nc-monomial was applied to a non sum. Expanding and continuing with " )(displa expr)))
1325 ; (cond ((atom expr) (setq answer expr coefficient 1 answeru expr))
1326 ; ((eq (caar expr) 'mnctimes)(setq answer expr coefficient 1 answeru expr))
1327 ;; ((member (caar expr) '(mlist mequal) :test #'eq) (loop for u in (cdr expr)
1328 ;; appending (cdr ($list_nc_monomials u)) into a-list
1329 ;; finally (return (cons '(mlist simp) ($setfy a-list)))))
1330 ; ((eq (caar expr) 'mplus) (loop for u in (cdr expr)
1331 ; when (null answer)do (setq answeru u)
1332 ; (multiple-value ( answer coefficient)
1333 ; (extract_nc_and_sc_parts u))
1335 ; (funcall $order_function answer
1336 ; (progn (multiple-value (ans1 cof)
1337 ; (extract_nc_and_sc_parts u))
1339 ; do (setq answer ans1 coefficient cof answeru u)
1340 ; else when (equal ans1 answer)
1341 ; do (setq repeat-flag answer) ;(show repeat-flag)
1342 ; finally (return answer)))
1343 ; ((eq (caar expr) 'mtimes)(multiple-value (answer coefficient
1344 ; (extract_nc_and_sc_parts expr))
1345 ; (setq answeru expr)))
1346 ; (cond ((equal repeat-flag answer)(setq coefficient ($my_nc_coef expr answer))
1347 ; (setq answeru (mul* coefficient answer))
1348 ; (cond (($zerop coefficient)
1349 ; (format t "~%Having to ratsimp expression of length ~A"(length expr))
1350 ; (setq tem1 ($multthru ($ratsimp expr)))
1351 ; (cond ((fast-scalarp tem1)(setq coefficient tem1)
1352 ; (setq answeru tem1) (setq answer 1)(format t "...it was scalar"))
1354 ; (format t "...starting to look for worst monomial again")
1355 ; (multiple-value (answer coefficient answeru)
1356 ; (find-worst-nc-monomial tem1))))))))
1358 ; (values answer coefficient answeru)))
1360 (defun $nc_rat
(expr &aux monoms
)
1361 (setq monoms
(cdr ($list_nc_monomials expr
)))
1362 (apply '$rat
(cons expr monoms
)))
1364 (defun $re_rat_the_dot_simplifications
()
1365 (loop for v in
(cdr $dot_simplifications
)
1367 when
(and (evenp i
) )
1368 collecting
(minimize-varlist ($new_rat
(new-disrep (cdr v
)))) into tem
1369 else collecting v into tem
1370 finally
(return (cons '(mlist simp
) tem
))))
1372 ;(defun $rat_the_dot_simplifications ()
1373 ; (loop for v in (cdr $dot_simplifications)
1375 ; when (and (evenp i) (not ($ratp v)))
1376 ; collecting (minimize-varlist ($new_rat v)) into tem
1377 ; else collecting v into tem
1378 ; finally (return (cons '(mlist simp) tem))))
1380 (defun show-genvar (&optional
(a-list genvar
))
1381 (loop for v in a-list
1383 (format t
"~%~A disreps ~A value ~A" v
(get v
'disrep
) (symbol-value v
))))
1385 (defun find-worst-nc-monomial (expr &aux answer ans1 tem1 cof coefficient answeru the-worst repeat-flag
)
1386 "expr should be somewhat expanded. The result of ($multthru expr) is ok."
1388 (loop for v in
(third (car expr
))
1389 for gen-var in
(fourth (car expr
))
1390 when
(and (not ($scalarp v
))
1391 (appears-in (cdr expr
) gen-var
)
1392 (or (null the-worst
)(funcall $order_function
1396 finally
(setq answer the-worst
))
1397 (setq coefficient
($nc_coeff expr answer
)))
1398 ((and (not ($plusp expr
))
1399 (appears-in expr
'mplus
))
1400 (setq expr
($multthru
($ratsimp
($expand expr
))))
1401 (format t
"~%find-worst-nc-monomial was applied to a non sum. Expanding and continuing with " )(displa expr
)))
1402 (cond (($ratp expr
) nil
)
1403 ((atom expr
) (setq answer expr coefficient
1 answeru expr
))
1404 ((eq (caar expr
) 'mnctimes
)(setq answer expr coefficient
1 answeru expr
))
1405 ((eq (caar expr
) 'mplus
) (loop for u in
(cdr expr
)
1408 (multiple-value ( answer coefficient
)
1409 (extract_nc_and_sc_parts u
))
1411 (funcall $order_function
1413 (progn (multiple-value
1415 (extract_nc_and_sc_parts u
))
1417 do
(setq answer ans1 coefficient cof answeru u
)
1418 else when
(equal ans1 answer
)
1419 do
(setq repeat-flag answer
) ;(show repeat-flag)
1420 finally
(return answer
)))
1421 ((eq (caar expr
) 'mtimes
)(multiple-value (answer coefficient
)
1422 (extract_nc_and_sc_parts expr
))
1423 (setq answeru expr
)))
1424 (cond ((equal repeat-flag answer
)(setq coefficient
($nc_coeff expr answer
))
1425 (setq answeru
(mul* coefficient answer
))
1426 (cond (($zerop coefficient
)
1427 (format t
"~%Having to ratsimp expression of length ~A"(length expr
))
1428 (setq tem1
($multthru
($ratsimp expr
)))
1429 (cond ((fast-scalarp tem1
)(setq coefficient tem1
)
1430 (setq answeru tem1
) (setq answer
1)
1431 (format t
"...it was scalar"))
1433 (format t
"...starting to look for worst monomial again")
1434 (multiple-value (answer coefficient answeru
)
1435 (find-worst-nc-monomial tem1
))))))))
1437 (values answer coefficient answeru
))
1439 (defun $my_nc_coef
(expr var
&aux answer coeff
)
1440 (check-arg expr
'$plusp
"macsyma sum")
1441 (loop for v in
(cdr expr
)
1442 when
(equal var
(progn
1443 (multiple-value ( answer coeff
) (extract_nc_and_sc_parts v
))
1445 collecting coeff into the-coeff
1446 finally
(return ($ratsimp
(cons '(mplus) the-coeff
)))))
1448 ;;note that in cre form the noncommutative monomials seem to always come
1449 ;;after the atomic variables in the genvar list ( use (mapcar 'describe genvar) to see this).
1450 ;;This means the my-ratcoeff is justified since it assumes the noncommutative variables
1451 ;;are more main, ie come later in the list.
1454 (and (consp x
) (eq (caar x
) 'mplus
)))
1456 (defun $nc_coeff
(expr monom
&optional
(deg 1) &aux tem1 answer
)
1457 (setq answer
(cond ((atom expr
)
1458 (if (eq monom expr
) 1 0))
1461 (mtimes (cond ((appears-in expr monom
)
1462 (loop for v in
(cdr expr
)
1463 when
(appears-in v monom
)
1466 collecting v into the-rest
1467 finally
(return (mul* (apply #'mul
* the-rest
) ($nc_coeff tem1 monom
)))))
1469 (mplus (loop named sue for v in
(cdr expr
)
1470 when
(appears-in v monom
)
1471 collecting v into tem1
1475 collecting
($nc_coeff w monom
) into the-cof
1476 finally
(return-from sue
(apply #'add
* the-cof
)))
1477 (return-from sue
0))))
1479 (rat (cond ((appears-in (cdr expr
) monom
)
1480 (div* ($nc_coeff
(second expr
) monom
) (third expr
)))))
1482 (mnctimes (cond ((equal (cdr monom
) (cdr expr
)) 1)))
1483 (mrat (my-ratcoeff expr monom deg
))
1484 (otherwise (error "invalid expression~A" expr
))))))
1485 (if answer answer
0))
1487 (defun number-and-zerop (x)
1488 (and (numberp x
) (zerop x
)))
1490 ;;this version may not work if the expr is not expanded
1491 ;; (defun $nc_coeff (expr monom &optional (deg 1) &aux tem1 answer)
1492 ;; "This will probably work only on forms that are in expanded form"
1493 ;; (setq answer (cond ((atom expr)
1494 ;; (if (eq monom expr) 1 0))
1496 ;; (case (caar expr)
1497 ;; (mtimes (loop for u in (cdr expr)
1498 ;; when (equal u monom)
1501 ;; (apply #'mul* (cdr (delete monom (copy-list expr) :test #'equal))))
1502 ;; when (and ($sump u)
1503 ;; (setq tem1 ($nc_coeff u monom))
1504 ;; (not (number-and-zerop tem1)))
1506 ;; (return (apply #'mul* tem1 (delete u (copy-list (cdr expr)) :test #'equal)))
1507 ;; finally (return 0)))
1508 ;; (mplus (loop named sue for v in (cdr expr)
1509 ;; do (setq tem1 ($nc_coeff v monom))
1510 ;; when (not (and (numberp tem1)(zerop tem1)))
1511 ;; collecting tem1 into tem
1514 ;; (return-from sue (apply #'add* tem))
1515 ;; (return-from sue 0))))
1517 ;; (rat (cond ((appears-in (cdr expr) monom)
1518 ;; (div* ($nc_coeff (second expr) monom)
1522 ;; (cond ((equal (cdr monom) (cdr expr)) 1)))
1523 ;; (mrat (my-ratcoeff expr monom deg))
1524 ;; (otherwise (error "invalid expression~A" expr))))))
1525 ;; (cond (answer answer)
1528 (defun ncsimp (expr)
1529 (cond (($scalarp expr
) expr
)
1531 ((member 'ncsimp
(car expr
)) expr
:test
#'eq
)
1533 (let ((nc-monoms ($list_nc_monomials expr
)))
1534 (loop for vv in
(cdr nc-monoms
)
1535 collecting
(mul* vv
($ratsimp
($nc_coeff expr vv
)))into the-sum
1536 finally
(cond ((> (length (cdr nc-monoms
)) 1)
1538 (return (rplaca (apply 'add
* the-sum
) '(mplus simp ncsimp
))))
1539 (t (car the-sum
))))))))
1543 (defun $independent_linsolve
(eqns independent-monomials
&optional unknowns
&aux equations
)
1544 (setq equations
($extract_linear_equations eqns independent-monomials
))
1545 (cond ($fast_solve
($fast_linsolve equations unknowns
))
1547 (cond ((null unknowns
)
1549 ($list_of_variables equations
))))
1550 ($linsolve equations unknowns
))))
1551 (defun $extr_eqns
(eqns independent-monomials
&optional unknowns
&aux equations
)
1552 (setq equations
($extract_linear_equations eqns independent-monomials
))
1553 (cond ((null unknowns
)(setq unknowns
($list_of_variables equations
))))
1554 (macsyma-list equations unknowns
))
1556 (defun $nc_coefficients
(eqns &aux ans
)
1557 (let (vars (rat-subs ($tellrat
)))
1558 (setq ans
($extr_eqns eqns
($list_nc_monomials eqns
)))
1559 (setq vars
(third ans
))
1560 (loop for v in
(cdr vars
)
1561 when
(or ($constantp v
)
1562 (appears-in rat-subs v
))
1563 do
(setq vars
(delete v vars
:test
#'equal
)))
1564 (list '(mlist simp
) (second ans
) vars
)))
1566 (defun $find_relations_in_free_ring
(a-list &aux answers eqns gen-sum repr
)
1567 (check-arg a-list
'$listp
"macsyma list")
1568 (setq gen-sum
($general_sum a-list $aaaa
))
1569 (setq eqns
($nc_coefficients
(list '(mlist simp
) gen-sum
)))
1570 (setq answers
($fast_linsolve eqns
))
1571 (setq repr
($sublis answers
( $general_sum
1572 (loop for i from
1 to
($length
(cdr a-list
))
1573 collecting
($concat
'$term i
) into temm
1574 finally
(return (cons '(mlist) temm
)))
1575 ; ($create_list ($concat '$term 'i) 'i 1 ($length (cdr a-list)))
1577 (list '(mlist simp
) repr answers
))
1579 (defun $list_of_variables
(l &aux variables
)
1580 (declare (special variables
))
1581 (cond ((atom l
) (error "~A is not a list" l
))
1582 (t (aux_to_list_of_variables l
'variables
)))
1583 (cons '(mlist simp
) variables
))
1585 (defun aux_to_list_of_variables (l var1
)
1589 (not (member l
'(simp mtimes mplus mexpt mlist mrat rat mnctimes
1590 mncexpt mequal $matrix
) :test
#'eq
))
1591 (not (member l
(symbol-value var1
) :test
#'eq
)))
1592 (setf (symbol-value var1
) (cons l
(symbol-value var1
))))))
1596 (aux_to_list_of_variables u var1
)))))
1598 (defun $firstn
(n a-list
)
1599 (subseq a-list
0 (1+ n
)))
1601 (defun create-list2 (form l
)
1602 (cons '(mlist) (apply #'create-list1 form l
)))
1604 (defun $general_sum
(terms &optional coefficients
&aux answer
)
1605 (when (null coefficients
)
1606 (setq coefficients
(create-list2 '($concat
'$aa i
) `(i 1 ,(1- (length terms
)))))
1607 (mfuncall '$declare_scalar_list coefficients
))
1608 (when (> (length terms
) (length coefficients
))
1609 (error "not enough coefficients"))
1610 (setq answer
(loop for u in
(cdr terms
) with sum
= 0
1611 for v in
(cdr coefficients
)
1612 do
(setq sum
(add* sum
(mul* u v
)))
1613 finally
(return sum
)))
1614 (values answer coefficients
))
1616 (defun a-less (u v
) (or (alphalessp u v
) (eq u v
)))
1618 (defremember commutative-monomials
(a-list n
&optional
(type-of-weight :weight
) (reset nil
))
1619 (let ((atomic-terms))
1620 (cond (reset (remprop 'commutative-monomials
:memory-table
)))
1621 (cond ((eql n
0) nil
)
1623 (loop for v in a-list
1624 when
(eql n
(degree v type-of-weight
))
1625 collecting
(list v
) into tem
1626 finally
(setq atomic-terms tem
))
1630 (loop for v in a-list
1631 when
(eql n
(degree v type-of-weight
))
1632 collecting
(list v
) into tem
1633 finally
(setq atomic-terms tem
))
1634 (loop for v in a-list
1636 (loop for w in
(commutative-monomials a-list
1637 (- n
(degree v type-of-weight
))
1640 when
(a-less v
(car w
))
1641 collecting
(cons v w
))
1643 finally
(return (append atomic-terms tem1
)))))))
1647 (defun degree (a-list &optional
(type-of-weight :weight
) &aux tem
)
1648 (cond ((atom a-list
) (cond ((setq tem
(get a-list type-of-weight
)) tem
)
1651 (loop for v in a-list
1652 when
(setq tem
(get v type-of-weight
))
1653 summing tem into answer
1654 else summing
1 into answer
1655 finally
(return answer
)))))
1657 (defun $commutative_dot_monomials
(a-list degree
&aux answer
)
1658 (setq answer
(commutative-monomials (cdr a-list
) degree
:weight t
))
1659 (setq answer
(loop for u in answer collecting
(cons '(mnctimes) u
)))
1660 (cons '(mlist simp
) answer
))
1662 (defun $declare_scalar_list
(l &aux fn
)
1663 (setq fn
(get '$declare
'mfexpr
*))
1665 (loop for u in
(cdr l
) do
(funcall fn
(list nil u
'$scalar
)) ))
1666 (t (loop for u in
(cdr l
) do
(eval `($declare
,u $scalar
))))))
1670 (and (consp x
) (consp (car x
)) (eq (caar x
) 'mplus
)))
1672 (defun $list_nc_parts
(f &aux answer
)
1673 (cond ((numberp f
) nil
)
1674 ((atom f
)(cond (($scalarp f
) nil
)
1676 ((eq (caar f
) 'mnctimes
) f
)
1677 ((eq (caar f
) 'mtimes
)($extract_nc_part f
))
1679 (check-arg f $plusp
"Maxima sum")
1680 (setq answer
(loop for u in
(cdr f
)
1681 collecting
($extract_nc_part u
)))
1682 (cons '(mlist simp
) answer
))))
1685 (:load-toplevel
:compile-toplevel
)
1686 (defvar $poly_vector
(make-polynomial-vectors)))
1688 (defvar $type_of_entries_for_poly_vector
:any-macsyma
)
1690 (defun $constant_term
(expr variables
)
1692 (cond ((member expr variables
:test
#'eq
) 0)
1694 ((not ($plusp expr
))
1695 (cond ((appears-in expr
'mplus
)
1696 (error "should expand expr before taking const"))
1698 (loop for v in
(cdr variables
)
1699 when
(appears-in expr v
)
1701 finally
(return expr
)))))
1703 (loop for v in
(cdr expr
)
1704 when
(not (loop for w in
(cdr variables
)
1705 when
(appears-in v w
)
1707 collecting v into the-constants
1708 finally
(return (addn the-constants t
))))))
1709 ;(defun sh ( poly &aux tem)
1710 ; (cond ((equal (cdr poly) 1)nil)
1711 ; (t (setq poly (cons poly 1))))
1712 ; (setq tem (cons (list 'mrat 'simp varlist genvar) poly))
1716 (defvar $sparse_matrix nil
)
1718 (defun pv-get-rows-from-macsyma-equations-and-variables
1719 (self equations the-variables
&aux
(eqn-no -
1) rat-vars rat-eqn
1720 constants-column const cof a-row
)
1721 (setf (pv-rows self
) (make-array (length equations
) :fill-pointer
0 :adjustable t
))
1722 (cond (( pv-table self
)(clrhash (pv-table self
) ))
1723 (t (setf (pv-table self
) (make-hash-table :test
'equal
))))
1724 (setf (pv-type-of-entries self
) :rational
)
1726 ((.table.
(pv-table self
)))
1727 (setq constants-column nil
)
1728 (setq rat-vars
(mapcar 'add-newvar
(cdr the-variables
)))
1729 (cond (($listp equations
)(setq equations
(cdr equations
))))
1730 (loop for eqn in equations
1732 (cond ((or (rational-functionp eqn
) (affine-polynomialp eqn
)) nil
)
1733 (t (cond (($ratp eqn
) (setq eqn
($ratdisrep eqn
))))
1734 (setq eqn
(bring-to-left-side eqn
))))
1735 (cond (($zerop eqn
) (format t
"~%Eliminating Trivial Equation."))
1736 (($numberp eqn
) (error "~%Inconsistent equation ~A" eqn
))
1738 (setq a-row
(make-array (* 2 (equation-length eqn
)) :fill-pointer
0 :adjustable t
))
1739 (vector-push-extend a-row
(pv-rows self
))
1740 (setq rat-eqn
(function-numerator (st-rat eqn
)))
1741 (loop for v in rat-vars
1742 for vv in
(cdr the-variables
)
1745 (setq cof
(pcoeff rat-eqn
(list v
1 1)))))
1747 (cond ((not (numberp cof
))
1748 (setf (pv-type-of-entries self
) :any-macsyma
)))
1749 (vector-push-extend n a-row
)
1750 (vector-push-extend cof a-row
)
1751 (setf (gethash vv .table.
) n
))
1752 (cond ((not ($zerop
(setq const
1753 (pcoeff rat-eqn
1 rat-vars
))))
1754 (cond ((not (numberp const
))
1755 (setf (pv-type-of-entries self
) ':any-macsyma
)))
1756 (cond (constants-column nil
)
1757 (t (setq constants-column
1758 (make-array (length equations
)
1762 :initial-element
'0))
1764 (setf (aref constants-column eqn-no
) const
)
1765 (setf (pv-constants-column-number self
) 0))))))
1767 (adjust-array (pv-rows self
)
1768 (max (length (the cl
:array
(pv-rows self
)))
1770 :fill-pointer
(fill-pointer (pv-rows self
)))
1771 (cond (constants-column (setf (pv-constants-column-number self
) 0)
1774 (max (length (the cl
:array
(pv-rows self
))) 1)
1777 (fill-pointer (pv-rows self
)))
1779 (pv-set-up-sparse-matrix-from-rows self
)
1780 (cond (constants-column
1781 (setf (sp-constants-column (pv-the-sparse-matrix self
)) constants-column
))))
1783 ;(defun pv-get-rows-from-macsyma-equations-and-variables
1784 ; (self equations the-variables &aux (eqn-no -1)
1785 ; constants-column const cof a-row)
1786 ; (setf (pv-rows self) (make-array (length equations) :fill-pointer 0 :adjustable t))
1787 ; (cond (( pv-table self)(clrhash (pv-table self) ))
1788 ; (t (setf (pv-table self) (make-hash-table :test 'equal))))
1789 ; (setf (pv-type-of-entries self) :rational)
1791 ; ((.table. (pv-table self)))
1792 ; (setq constants-column nil)
1793 ; (loop for eqn in (cdr equations)
1794 ; do (cond (($ratp eqn) (setq eqn ($ratdisrep eqn))))
1795 ; (setq eqn (bring-to-left-side eqn))
1796 ; (cond (($zerop eqn) (format t "~%Eliminating Trivial Equation."))
1797 ; (($numberp eqn) (error "~%Inconsistent equation ~A" eqn))
1798 ; (t (incf eqn-no 1)
1800 ; (setq a-row (make-array (* 2 (equation-length eqn)) :fill-pointer 0 :adjustable t))
1801 ; (array-push-extend (pv-rows self) a-row)
1802 ; (loop for v in (cdr the-variables)
1805 ; (setq cof ($nc_coeff eqn v))))
1807 ; (cond ((not (numberp cof))
1808 ; (setf (pv-type-of-entries self) :any-macsyma)))
1809 ; (array-push-extend a-row n)
1810 ; (array-push-extend a-row cof)
1811 ; (setf (gethash v .table.) n))
1812 ; (cond ((not ($zerop (setq const
1813 ; ($constant_term eqn the-variables))))
1814 ; (cond ((not (numberp const))
1815 ; (setf (pv-type-of-entries self) ':any-macsyma)))
1816 ; (cond (constants-column nil)
1817 ; (t (setq constants-column
1818 ; (make-array (length equations)))
1819 ; (fillarray constants-column '(0))))
1820 ; (aset const constants-column eqn-no)
1821 ; (setf (pv-constants-column-number self) 0))))))
1823 ; (adjust-array-size (pv-rows self) (array-active-length (pv-rows self)))
1824 ; (cond (constants-column (setf (pv-constants-column-number self) 0)
1825 ; (adjust-array-size constants-column (array-active-length (pv-rows self)))))
1826 ; (pv-set-up-sparse-matrix-from-rows self )
1827 ; (cond (constants-column
1828 ; (setf (sp-constants-column (pv-the-sparse-matrix self)) constants-column)))))
1831 (defun fast-linsolve (poly-eqns variables
&aux answer
(add-to-dim 0) table
)
1832 (cond ((get (car variables
) 'disrep
))
1833 (t (fsignal "variables should be genvars")))
1834 (setq variables
(cons '(mlist) (loop for v in variables collecting
(get v
'disrep
))))
1835 ( pv-get-rows-from-macsyma-equations-and-variables $poly_vector
1836 poly-eqns variables
)
1838 (format t
"~%Assuming entries of type ~A" ( pv-type-of-entries $poly_vector
))
1839 (cond (variables (setf table
( pv-table $poly_vector
))
1841 (loop for u in
(cdr variables
)
1842 when
(null (gethash u table
))
1844 (format t
"~%The variable ~A did not appear." u
)))
1846 ((not (zerop add-to-dim
))
1848 t
"~%Thus we should add ~D to the dimension of the solution space."
1850 (setf answer
( pv-solve-suitable-to-sublis $poly_vector
))
1853 (defun $fast_linsolve
(eqn &optional variables
&aux answer table add-to-dim
)
1854 "Solves list of EQUATIONS in a list of VARIABLES"
1855 (cond ((polynomial-vectors-p $poly_vector
) nil
)
1856 (t (setf $poly_vector
(make-polynomial-vectors ))))
1857 (setf (pv-type-of-entries $poly_vector
) $type_of_entries_for_poly_vector
)
1858 (cond (variables ( pv-get-rows-from-macsyma-equations-and-variables $poly_vector
1861 ( pv-get-rows-from-macsyma-equations $poly_vector eqn
)))
1862 (cond (modulus (setf (pv-type-of-entries $poly_vector
) modulus
)))
1863 (format t
"~%Assuming entries of type ~A" ( pv-type-of-entries $poly_vector
))
1864 (cond (variables (setf table
( pv-table $poly_vector
))
1866 (loop for u in
(cdr variables
)
1867 when
(null (gethash u table
))
1869 (format t
"~%The variable ~A did not appear." u
)))
1871 ((not (zerop add-to-dim
))
1873 t
"~%Thus we should add ~D to the dimension of the solution space."
1875 (setf answer
( pv-solve-suitable-to-sublis $poly_vector
))
1878 (defun $nexp
(u n
&aux answer
)
1879 (cond ((atom u
) (ncmuln (loop for i below n collecting u
) t
))
1884 (ncmuln answer t
))))
1886 (defun $collect
(expr)
1890 (defun $subtract_monomial
(expr mon
)
1891 (sub expr
(mul ($nc_coeff expr mon
) mon
)))
1893 (defvar *start-dot-replace
* nil
)
1895 (defun replace-dot-simplifications (expr)
1896 (let ((dot-simps $dot_simplifications
) (answer expr
) )
1897 (cond ((and dot-simps
*start-dot-replace
*)
1898 (setf dot-simps
(cdr dot-simps
))
1899 (loop while dot-simps
1901 (setf answer
(test_pattern answer
(car dot-simps
)
1902 (second dot-simps
)))
1903 (setf dot-simps
(cddr dot-simps
))
1904 finally
(return answer
)))
1908 (defun test_pattern (adp pattern replacement
&aux tem
)
1909 "replaces the pattern in ADP (a dot product) by replacement. When
1910 inserted in the simplifier simpmnct it does the replacement whenever
1912 (cond ((atom adp
) adp
)
1913 ((equal (caar adp
) 'mnctimes
)
1914 (cond ((setf tem
(ordered-sublist (cdr pattern
) (cdr adp
)))
1915 (ncmul (ncmuln (car tem
) t
) replacement
(ncmuln (cadr tem
) t
)))
1919 (defun $nsdot
(&rest l
)
1920 (let (($dot_simplifications nil
))
1922 (defun $sort_mono
(variables degree
)
1923 ($sort
($mono variables degree
) $order_function
))
1925 (defun tail-alphalessp (x y
)
1926 "If x and y are lists ordering priority is based on the ends not the beginning of the lists"
1927 (cond ((and (atom x
) (atom y
)) (alphalessp x y
))
1928 ((atom x
) (alphalessp x
(car (last y
))))
1929 ((atom y
) (alphalessp (car (last x
)) y
))
1930 (t (let ((lengx (length x
))(lengy (length y
)) xi yj
)
1931 (loop for i downfrom
(1- lengx
) to
0
1932 for j downfrom
(1- lengy
) to
0
1934 (setf xi
(nth i x
)) (setf yj
(nth j y
))
1935 (cond ((alphalessp xi yj
)(return t
))
1936 ((alphalessp yj xi
)(return nil
)))
1937 finally
(return (< lengx lengy
)))))))
1939 (deff $tail_alphalessp
#'tail-alphalessp
)
1941 (defun unreplaced-monomials-in-dot-simplifications
1942 (&optional
(macsyma-list $dot_simplifications
)&aux tem answer
)
1943 (check-arg macsyma-list $listp
"macsyma list")
1944 (loop for i from
2 below
(length macsyma-list
) by
2
1947 ($list_nc_parts
(nth i macsyma-list
)))
1948 (cond (($listp tem
)(setf tem
(cdr tem
)))
1949 (t (setf tem
(list tem
))))
1951 (setf answer
(zl-union answer tem
)))
1955 (defun ordered-sublist (small big
&aux answer
(some-of-big big
))
1956 "Returns nil unless small appears in big in which case a list
1957 of alternating terms before and terms after each occurrence is returned"
1958 (loop while some-of-big
1959 when
(initial-sublist small some-of-big
)
1960 do
(setf answer
(append
1961 (list (subseq big
0 (- (length big
) (length some-of-big
)))
1962 (nthcdr (length small
) some-of-big
))
1965 (setf some-of-big
(cdr some-of-big
)))
1968 (defvar $table_of_unreplaced nil
)
1970 (defvar $unreplaced nil
)
1972 (defun $set_dot_simplifications
( l
)
1973 (setf $dot_simplifications nil
)
1975 (setf $dot_simplifications
(copy-list l
))
1978 (setf $dot_simplifications
(subseq l
0 3))
1983 (setf $dot_simplifications
(append $dot_simplifications
1984 (list (meval (car l
)))))
1985 (setf $dot_simplifications
(append $dot_simplifications
1986 (list (meval (cadr l
)))))
1991 (defvar $free_monomials nil
)
1992 (defvar $do_not_change_free_monomials nil
)
1994 (defun $generate_array_of_relations
(variables degree relations
1996 additional-degree answer
($expop
100) ans1
1997 ($dot_simplifications nil
))
2000 answer
(make-array 64 :fill-pointer
0 :adjustable t
))
2001 (loop for gen in
(cdr relations
)
2003 (setf additional-degree
(- degree
($nc_degree gen
)))
2004 (loop for j to additional-degree
2006 (loop for left-multiple in
(cdr ($mono variables j
))
2008 (setf left-times-gen
(ncmul left-multiple gen
))
2010 (loop for right-multiple in
(cdr ($mono variables
2011 (sub additional-degree j
)))
2014 (ncmul left-times-gen
2015 right-multiple
) answer
)))))
2017 (setf ans1
(adjust-array answer
(length (the cl
:array answer
))
2018 :fill-pointer
(fill-pointer answer
)))
2024 ;(defun $tes (n relations &aux tem)
2025 ; (setf tem ($generate_array_of_relations '((mlist simp) $x $y) n relations))
2026 ; ( pv-get-rows-from-array-of-polynomials $poly_vector tem 'sc_and_nc_parts)
2027 ; ( pv-set-up-sparse-matrix-from-rows $poly_vector )
2028 ; ( pv-reduce $poly_vector ))
2029 (defvar $poly_vector1
(make-polynomial-vectors))
2031 (defun $find_rank
(nc-polynomials )
2032 ( pv-get-rows-from-array-of-polynomials
2033 $poly_vector1 nc-polynomials
'sc_and_nc_parts
)
2034 ( pv-set-up-sparse-matrix-from-rows $poly_vector1
)
2035 ( pv-reduce $poly_vector1
)
2036 ( sp-number-of-pivots
( pv-the-sparse-matrix $poly_vector1
)))
2039 (defun $find_simplifications
(nc-polynomial-relations)
2040 (pv-get-rows-from-array-of-polynomials $poly_vector nc-polynomial-relations
2042 (pv-set-up-sparse-matrix-from-rows $poly_vector
)
2043 (pv-solve-suitable-to-sublis $poly_vector
))
2045 (defun join-arrays (&rest l
&aux answer
)
2046 (setf answer
(make-array 100 :fill-pointer
0 :adjustable t
))
2049 (loop for i below
(length (the cl
:array u
))
2051 (vector-push-extend (aref u i
) answer
)))
2052 (adjust-array answer
(length (the cl
:array answer
))
2053 :fill-pointer
(fill-pointer answer
)))
2056 (defvar $new_fast_dotsimp t
)
2057 (defun $com
(x y
&optional
(zet 1) &aux term1 term2
)
2058 (setf term1
( ncmul
* x y
))
2059 (setf term2
( ncmul
* y x
))
2060 (setf term2
(mul* zet term2
))
2061 ($ratsimp
($dotsimp
(sub* term1 term2
))))
2067 (defvar $relations nil
)
2068 (defvar $previous_degree nil
)
2069 (defvar $graded_relations nil
)
2070 (defun set-up-graded-relations (the-variables deg new-relations
2071 &aux poly-vectors nc-polynomials finished
)
2072 (cond ((not (arrayp $graded_relations
))(setf $graded_relations
(make-array 25 :adjustable t
))))
2073 (cond ((null (aref $graded_relations deg
))
2074 (setf (aref $graded_relations deg
) (make-polynomial-vectors))))
2075 (setf poly-vectors
(aref $graded_relations deg
))
2076 (cond ((or (not (equal ( pv-relations poly-vectors
) new-relations
))
2077 (not (equal ( pv-variables poly-vectors
) the-variables
)))
2080 (format t
"~%Calculating relations in degree ~A of" deg
)
2081 (displa new-relations
)
2082 (setf (pv-relations poly-vectors
) new-relations
)
2083 (setf ( pv-variables poly-vectors
) the-variables
)
2084 (setf nc-polynomials
($generate_array_of_relations
2085 the-variables deg new-relations
))
2086 ( pv-get-rows-from-array-of-polynomials poly-vectors nc-polynomials
2088 ( pv-set-up-sparse-matrix-from-rows poly-vectors
)
2090 (cond (finished nil
)
2091 (t (setf (pv-relations poly-vectors
) nil
))))
2092 ( pv-reduce poly-vectors
))))
2094 (defun $find_central_elements
(variables degree
&optional
(relations $relations
) ;(reset nil)
2095 &aux poly-vectors terms gen-sum answer a-row com basis all-eqns
)
2096 "assumes relations homogeneous of same degree"
2097 (check-arg relations $listp
"macsyma list")
2099 ; (setf tem ($generate_array_of_relations variables (1+ degree) relations))
2101 (set-up-graded-relations variables
(1+ degree
) relations
)
2102 (set-up-graded-relations variables degree relations
)
2103 (setf basis
(cons '(mlist simp
)( pv-get-basis
(aref $graded_relations degree
) )))
2104 (setf poly-vectors
(aref $graded_relations
(1+ degree
)))
2105 (cond ((< (length $aaaa
) (length (setf terms basis
)))
2106 (setf $aaaa
(loop for i below
(length terms
)
2107 collecting
($concat
'$aa i
) into vars
2108 finally
(return (cons '(mlist simp
) vars
))))
2109 ($declare_scalar_list $aaaa
)))
2110 (setf gen-sum
($general_sum basis $aaaa
))
2112 (loop for u in
(cdr variables
)
2114 (setf com
($com gen-sum u
))
2115 (setf a-row
(convert-polynomial-to-vector com
( pv-table poly-vectors
)
2116 nil
'sc_and_nc_parts
))
2117 (sp-set-type-of-entries ( pv-the-sparse-matrix poly-vectors
) ':any-macsyma
)
2118 (sp-reduce-row-with-respect-to-rows ( pv-the-sparse-matrix poly-vectors
) a-row
)
2119 appending
(loop for i below
(length (the cl
:array a-row
)) by
2
2121 collecting
($rat
(aref a-row
(1+ i
))))
2123 finally
(setf all-eqns
(cons '(mlist simp
) eqns
)))
2125 ; (loop for v in (cdr all-eqns) do (displa v))
2127 (setf answer
($fast_linsolve all-eqns
(subseq $aaaa
0 (length terms
))))
2128 (setf answer
($sublis answer gen-sum
)))
2130 ; ($express_in_terms_of_basis variables answer relations))
2134 (defun pv-get-basis (self &aux monoms
)
2135 "Grabs the non-pivots"
2137 (let ((col-used-to-pivot ( sp-columns-used-to-pivot
(pv-the-sparse-matrix self
)))
2138 ($dot_simplifications nil
))
2140 (setf monoms
(cdr ($mono
(pv-variables self
)
2141 ($nc_degree
(get-key (pv-table self
) 1)))))
2142 (loop for v in monoms
2144 (gethash v
(pv-table self
) ) col-used-to-pivot
))
2148 ;(defun $test ($generators &aux tem temp2 relations)
2149 ; (setf tem ($generate_array_of_relations 1 2 (cons '(mlist simp)
2150 ; (list (nth 2 $generators)))))
2151 ; (setf temp2 ($generate_array_of_relations 1 1 (cons '(mlist simp)
2152 ; (list (nth 1 $generators)
2153 ; (nth 3 $generators)))))
2154 ; (setf relations (join-arrays tem temp2))
2155 ; ($find_rank relations))
2158 (defun $express_in_terms_of_basis
( variables form
&optional
2159 (relations $relations
);(reset nil)
2160 &aux a-row deg poly-vectors
)
2161 (setf deg
($nc_degree form
))
2162 (set-up-graded-relations variables deg relations
)
2163 (setf poly-vectors
(aref $graded_relations deg
))
2164 (setf a-row
(convert-polynomial-to-vector form
( pv-table poly-vectors
)
2165 nil
'sc_and_nc_parts
))
2166 (sp-set-type-of-entries ( pv-the-sparse-matrix poly-vectors
) ':any-macsyma
)
2167 (sp-reduce-row-with-respect-to-rows
2168 ( pv-the-sparse-matrix poly-vectors
) a-row
)
2169 (loop for ii below
(length (the cl
:array a-row
)) by
2
2170 when
(aref a-row ii
)
2171 collecting
(mul* (aref a-row
(1+ ii
))
2172 ( get-key
( pv-table poly-vectors
) (aref a-row ii
)))
2174 finally
(return (apply 'add
* tem
))))
2176 (defun $test
($generators
)
2177 ($find_rank
($generate_array_of_relations
(macsyma-list '$w
'$x
'$y
) 4 $generators
)))
2178 (defun $find_rank_of_relations
(var deg
&optional
(relat $relations
))
2179 ($find_rank
($generate_array_of_relations var deg relat
)))
2181 (defvar $leading_monomial_is_lowest_degree t
"Should be true for power series")
2183 (defun $nc_degree
(f &optional
(type-of-weight :weight
) &aux tem
)
2186 (cond ((or (numberp f
)($scalarp f
))0)
2187 (t (cond ((setf tem
(get f type-of-weight
)) tem
)
2189 ((affine-polynomialp f
) (+ ($nc_degree
(get (car f
) 'disrep
)) ($nc_degree
(fifth f
))))
2191 ;;; (($plusp f)($nc_degree (second f) type-of-weight ))
2192 (($ratp f
) ($nc_degree
(num (cdr f
))))
2194 (cond ($leading_monomial_is_lowest_degree
2195 (loop for v in
(cdr f
)
2196 minimize
($nc_degree v type-of-weight
)))
2197 (t (loop for v in
(cdr f
)
2198 maximize
($nc_degree v type-of-weight
)))))
2199 ((eq (caar f
) '$power
) (vmul* ($nc_degree
(second f
) type-of-weight
) (third f
)))
2201 ((eq (caar f
) 'mtimes
)
2202 (loop for u in
(cdr f
)
2203 maximize
($nc_degree u type-of-weight
)))
2204 ;;; ($nc_degree (extract_nc_and_sc_parts f) type-of-weight ))
2205 ((eq (caar f
) 'rat
) 0)
2206 ((eq (caar f
) 'mrat
)
2207 (cond ($leading_monomial_is_lowest_degree
2208 (loop for v in
(varlist f
)
2210 when
(and (not (fast-scalarp v
))(appears-in (cdr f
) w
))
2211 minimize
($nc_degree v type-of-weight
)))
2213 (loop for v in
(varlist f
)
2215 when
(and (not (fast-scalarp v
))(appears-in (cdr f
) w
))
2216 maximize
($nc_degree v type-of-weight
)))))
2217 ((eq (caar f
) 'mnctimes
)
2218 (loop for u in
(cdr f
)
2220 ($nc_degree u type-of-weight
)))
2221 (t (error "The degree of ~A is undefined." f
))))
2222 (defvar $current_replacements nil
)
2223 (defvar $current_weights nil
)
2225 (defun free-ncmul (&rest l
)
2226 (let (($dot_simplifications nil
))
2227 (ncmuln (copy-list l
) t
)))
2229 (defun $mono
(variables n
&optional reset
&aux deg
)
2230 (cond (reset (clear-memory-function '$mono-aux
)))
2231 (loop for v in
(cdr $dot_simplifications
) by
#'cddr
2232 when
(<= (setq deg
($nc_degree v
)) n
)
2233 collecting v into repls
2235 do
(return '(mlist))
2237 ($mono-aux variables n repls
))))
2239 (defremember $food
(a b
)
2242 (defremember $mono-aux
(variables n repls
&aux tem
)
2244 ((eql n
0) '((mlist) 1))
2247 (loop for v in
(cdr variables
)
2248 for deg
= ($nc_degree v
)
2249 with op
= '(mnctimes simp
)
2251 (loop for mon in
(cdr ($mono-aux variables
(- n deg
) repls
))
2254 (cond ((numberp mon
)
2255 (cond ((not ($must_replacep v
))
2258 (cond ((not ($must_replacep
2259 (setq tem
(list op v mon
))))
2262 (cond ((not ($must_replacep
2263 (setq tem
(cons op
(cons v
(cdr mon
))))))
2265 finally
(return (nreverse answ
))))))))
2267 ;;;this is too messy.
2268 ;(defun $mono (variables n &optional reset &aux answer tem)
2269 ; (cond (reset (setq $current_variables nil)))
2271 ; ((< n 0) (cons '(mlist simp)nil))
2273 ; (check-current-variables variables n)
2274 ; (cond ((> (1+ n) (array-total-size $current_monomials))
2275 ; (setq $current_monomials
2276 ; (adjust-array-size $current_monomials (+ n 10)))))
2277 ; (loop for v in (cdr variables)
2278 ; when ($must_replacep v)
2279 ; do (setq variables (zl-delete v variables )))
2281 ; ((setq answer (aref $current_monomials n)) answer)
2282 ; ((eql n 0) (aset '((mlist simp) 1) $current_monomials 0)
2283 ; '((mlist simp) 1))
2286 ; (loop for u in (cdr variables)
2287 ; when (not (zerop ($nc_degree u)))
2290 ; in (cdr ($mono variables (- n ($nc_degree u))))
2291 ; when (not (initial-segment-is-replaced
2292 ; (setq tem (free-ncmul u ww))))
2297 ; (list u ) into monos
2298 ; finally (setq answer (cons '(mlist simp) monos))
2302 ; $current_monomials n)(return answer)))))))
2305 ;(defun check-current-variables (variables n &aux deg )
2306 ; (cond ((or (null $current_variables)(null $current_replacements))
2307 ; (setq $current_variables variables)
2308 ; (setq $current_weights
2309 ; (loop for v in (cdr variables)
2311 ; ($nc_degree v) into weight-list
2312 ; finally (return (cons '(mlist simp) weight-list))))
2313 ;; (loop for arr in '($current_replacements $current_monomials)
2315 ;; (cond ((arrayp (symbol-value arr))(fillarray (symbol-value arr) nil))
2316 ;; (t (setf (symbol-value arr) (make-array 35 :fill-pointer 0 adjustable t :leader-length 2 )))))
2317 ; (cond ((arrayp $current_monomials)(fillarray $current_monomials nil))
2318 ; (t (setq $current_monomials
2319 ; (zl-make-array 35 :fill-pointer 0 :adjustable t :leader-length 2 ))))
2320 ; (cond ((arrayp $current_replacements)(fillarray $current_replacements nil))
2321 ; (t (setq $current_replacements
2322 ; (make-array 35 :fill-pointer 0 :adjustable t :leader-length 2 ))))
2323 ; (loop for u in (cdr $dot_simplifications)
2326 ; (setq deg ($nc_degree u))
2327 ; (aset (cons u (aref $current_replacements deg))
2328 ; $current_replacements deg))
2329 ; (setf (array-leader $current_replacements 1) $current_variables))
2333 ; (equal $current_variables variables)
2334 ; (equal (array-leader $current_replacements 1) variables)
2335 ; (loop for u in (cdr variables) and v in (cdr $current_weights)
2336 ; when (not (eql ($nc_degree u) v))
2340 ; finally (return t))))
2341 ; (setq $current_variables nil)(check-current-variables variables n))
2343 ; (loop for u in (cdr $dot_simplifications)
2346 ; (setq deg ($nc_degree u)) n)
2347 ; count 1 into num-repl
2349 ; (cond ((not (zl-member u(aref $current_replacements deg)))
2351 ; finally (cond ((not (eq num-repl
2352 ; (loop for i to n summing
2354 ; $current_replacements i)))))
2357 ; (loop for i from n below (array-total-size $current_monomials)
2358 ; do (aset nil $current_monomials i)
2359 ; (aset nil $current_replacements i))
2360 ; (loop for u in (cdr $dot_simplifications)
2362 ; when (>= (setq deg ($nc_degree u)) n)
2366 ; $current_replacements deg))
2367 ; $current_replacements deg)))
2368 ; (t 'they-were-ok)))))
2370 ;(defun $separate_parameters (expr list-parameters)
2372 ; (loop for par in (cdr list-parameters)
2373 ; do (setf answer (copy-list expr))
2376 ; (loop for other-par in (cdr list-parameters)
2377 ; when (not (eq other-par par))
2378 ; do (setf answer (nsubst 0 other-par answer))
2379 ; else do (setf answer (nsubst 1 other-par answer))
2380 ; do (displa answer)
2381 ; finally (return ($ratsimp answer)))
2383 ; finally (return (cons '(mlist simp) tem))))
2385 (defun $separate_parameters
(expression &rest parameters
&aux answer list-parameters
)
2386 (cond ((null parameters
) (setf parameters
'("aa" "par"))))
2387 (setf list-parameters
(apply '$list_variables expression parameters
))
2388 (loop for par in
(cdr list-parameters
)
2389 do
(setf answer
(copy-list expression
))
2391 (loop for other-par in
(cdr list-parameters
)
2392 when
(not (eq other-par par
))
2393 collecting
(list '(mequal) other-par
0) into subs
2394 else collecting
(cons '(mequal) (list other-par
1)) into subs
2395 finally
(return ($ratsimp
2396 ($sublis
(cons '(mlist simp
)subs
) answer
))))
2398 finally
(return (cond ((null (cdr list-parameters
))
2399 (format t
"~%Special soln:")
2400 (list '(mlist) expression
))
2401 (t (cons '(mlist simp
) tems
))))))
2403 (defun pv-clean-up (self)
2404 (setf (pv-relations self
) nil
)
2405 (setf (pv-variables self
) nil
)
2406 (setf (sp-rows (pv-the-sparse-matrix self
)) nil
)
2407 (setf (pv-rows self
) nil
)
2408 (clrhash (pv-table self
) ))
2412 (defun $find_relation
(variables degree monoms
&optional
(relations $relations
)
2414 &aux poly-vectors terms gen-sum answer a-row eqns all-eqns
)
2415 "assumes relations homogeneous of same degree"
2416 (check-arg relations $listp
"macsyma list")
2417 (check-arg monoms $listp
"macsyma list")
2418 ; (setf tem ($generate_array_of_relations variables (1+ degree) relations))
2421 (set-up-graded-relations variables degree relations
)
2422 ; (setf basis (cons '(mlist simp)( pv-get-basis (aref $graded_relations degree) )))
2423 (setf poly-vectors
(aref $graded_relations degree
))
2426 (cond ((< (length $aaaa
) (length (setf terms monoms
)))
2427 (setf $aaaa
(loop for i below
(length terms
)
2428 collecting
($concat
'$aa i
) into vars
2429 finally
(return (cons '(mlist simp
) vars
))))
2430 ($declare_scalar_list $aaaa
)))
2431 (setf gen-sum
($general_sum monoms $aaaa
))
2433 (setf a-row
(convert-polynomial-to-vector gen-sum
( pv-table poly-vectors
)
2434 nil
'sc_and_nc_parts
))
2435 (sp-set-type-of-entries
2436 ( pv-the-sparse-matrix poly-vectors
) ':any-macsyma
)
2437 (sp-reduce-row-with-respect-to-rows
2438 ( pv-the-sparse-matrix poly-vectors
) a-row
)
2439 (setf eqns
(loop for i below
(length (the cl
:array a-row
)) by
2
2441 collecting
($rat
(aref a-row
(1+ i
)))))
2443 (setf all-eqns
(cons '(mlist simp
) eqns
))
2444 (setf answer
($fast_linsolve all-eqns
(subseq $aaaa
0 (length monoms
))))
2445 (setf answer
($sublis answer gen-sum
)))
2446 (defvar *show-entry-type
* t
)
2448 (defun $determinant_of_equations
(eqn &optional variables
&aux answer
)
2449 (cond ((eq (type-of $poly_vector
) 'polynomial-vectors
) nil
)
2450 (t (setq $poly_vector
(make-polynomial-vectors))))
2451 (setf (pv-type-of-entries $poly_vector
) $type_of_entries_for_poly_vector
)
2452 (cond (variables ( pv-get-rows-from-macsyma-equations-and-variables $poly_vector
2455 ( pv-get-rows-from-macsyma-equations $poly_vector eqn
)))
2456 (cond (*show-entry-type
*
2457 (format t
"~%Assuming entries of type ~A" (pv-type-of-entries $poly_vector
))))
2458 (setq answer
(sp-determinant (pv-the-sparse-matrix $poly_vector
)))
2459 (new-disrep answer
))
2462 ;(defun fast-linsolve (eqns vari &aux solu)
2463 ; (setq solu ($fast_linsolve eqns (cons '(mlist)(mapcar #'(lambda (u) (get u 'disrep)) vari))))
2464 ; (show (length solu))
2465 ; (loop for v in (cdr solu)
2466 ; collecting (cons (add-newvar (second v)) (st-rat (third v)))))
2470 (defun $special_find_central_elements
(vari deg infinites
2471 &aux mons gen-sum $vari_left
2472 comu ncmonos eqns solus general
)
2473 (setq mons
($mono vari deg
))
2475 (append mons
(loop for v in
(cdr mons
)
2476 collecting
(ncmul* infinites v
))))
2478 (setq gen-sum
($general_sum mons $aaaa
))
2479 (setq general gen-sum
)
2480 (loop for v in
(cdr vari
)
2482 (setq comu
($com general v
))
2483 (setq ncmonos
($list_nc_monomials comu
))
2484 (setq eqns
($extract_linear_equations
`((mlist) ,comu
) ncmonos
))
2485 (setq solus
($fast_linsolve eqns
($list_variables eqns
"aa")))
2486 (setq general
(meval* ($sublis solus general
)))
2488 (setq $vari_left
($list_variables general
"aa" "par"))
2489 (loop for v in
(cdr $vari_left
)
2490 for aa in
(cdr $aaaa
)
2491 collecting
(cons v aa
) into subs
2492 finally
(setq general
(sublis subs general
)))
2494 ($separate_parameters general
))
2497 (defun $solve_nc_coefficients
($list-eqns
&rest variable-strings
)
2498 ($fast_linsolve
($extract_linear_equations $list-eqns
($list_nc_monomials $list-eqns
))
2499 (apply '$list_variables $list-eqns variable-strings
)))
2503 (defun gencoeff (form mon
&optional
( vars-to-exclude
(list-variables mon
)) &aux answ
)
2504 "coerces to poly if possible. FORM should be a affine-polynomialp or rational-functionp"
2505 (cond ((affine-polynomialp form
) (pcoeff form mon vars-to-exclude
))
2506 ((rational-functionp form
)(setq answ
(pcoeff (num form
) mon vars-to-exclude
) )
2507 (cond ((pzerop answ
) 0)
2508 (t (setq answ
(ratreduce answ
(denom form
)))
2509 (cond ((eql 1 (denom answ
))(num answ
))
2511 (t (fsignal "unknown type. Wants a polynomial or rational-function."))))
2513 (defun poly-data-from-nc-matrix (nc-matrix &aux mat-polys monom-vector monoms-in-each-column
2516 "Takes input like matrix([x.y+a*y.z,z.z+v,..],[...,...,..],...,[...,...,]])
2517 and returns a poly-data. pd-convert-to-maxima-format is the inverse."
2518 (iassert ($matrixp nc-matrix
))
2520 (loop for v in
(cdr nc-matrix
)
2522 (loop for vv in
(cdr v
)
2523 collecting
(st-rat vv
))))
2525 (loop for i from
0 below
(length (first mat-polys
))
2527 (loop for v in mat-polys
2529 do
(setq tem
(zl-union (list-variables (nth i v
)) tem
))
2530 when
(and (not (member 1 tem
))
2531 (not (pzerop (gencoeff (nth i v
) 1 tem
))))
2532 do
(setq tem
(cons 1 tem
))
2534 (loop for va in tem when
(eql va
1)
2536 else when
(> ($nc_degree
(get va
'disrep
)) 0)
2537 collecting
(list va
1 1 ))))))
2538 (setq monoms-in-each-column
(mapcar 'length monom-vector
))
2539 (setq the-segment
(loop for v in monoms-in-each-column
2541 summing v into all
))
2542 (setq rows
(make-array (length mat-polys
) :fill-pointer
(length mat-polys
)))
2543 (loop for ro in mat-polys
2546 (setq a-row
(make-array 10 :fill-pointer
0 :adjustable t
))
2547 (setf (aref rows ii
) a-row
)
2549 for monoms in monom-vector
2550 for n in monoms-in-each-column
2552 (loop for mon in monoms
2555 do
(setq cof
(gencoeff pol mon
(list-variables monoms
)))
2557 do
(setq cof
(gencoeff pol mon
))
2558 when
(not (pzerop cof
))
2560 (vector-push-extend (+ i tot-monoms
) a-row
)
2561 (vector-push-extend cof a-row
))
2562 summing n into tot-monoms
))
2563 (make-poly-data :segments the-segment
2565 :big-monom-list
(loop for v in monom-vector nconc v
)))
2567 (defun segment-interval (segments spot
)
2568 (loop for v in segments
2572 finally
(return ii
)))
2574 (defun pd-convert-to-maxima-format (pd &aux tem where lis a-row
)
2576 (loop for i below
(fill-pointer (pd-rows pd
))
2578 (setq lis
(make-list (length (pd-segments pd
)) :initial-element
0))
2579 (loop for k below
(fill-pointer (setq a-row
(aref (pd-rows pd
) i
))) by
2
2580 when
(setq tem
(aref a-row k
))
2581 do
(setq where
(segment-interval (pd-segments pd
) tem
) )
2582 (setf (nth where lis
) (n+ (nth where lis
)
2583 (n* (aref a-row
(1+ k
))
2584 (nth tem
(pd-big-monom-list pd
))))))
2585 (setq lis
(mapcar 'new-disrep lis
))
2586 when
(loop for v in lis when
(not (pzerop v
))do
(return t
))
2587 collecting
(cons '(mlist) (mapcar 'new-disrep lis
)))))
2589 (defun id (mat &aux
(pd (poly-data-from-nc-matrix mat
)) )
2591 (pd-convert-to-maxima-format pd
))
2593 (defun reduce-poly-data (pd &aux sp
)
2594 (setq sp
(sp-make-sparse-matrix (pd-rows pd
)))
2599 (defun $nc_matrix_row_reduce
(mat &aux pd
)
2600 "Does row reduction, assuming that the set of non commutative monomials
2601 are linearly independent, so that matrix([x.y,0],[x,0],[1,0]) is already
2602 reduced. Like most of the nc stuff it assumes that scalars preced non
2603 scalars in the alphabet"
2604 (setq pd
(poly-data-from-nc-matrix mat
))
2605 (reduce-poly-data pd
)
2606 (pd-convert-to-maxima-format pd
))
2608 (defun $nc_matrix_quotient
(mat1 modulo-mat
&aux all-rows big-mat big-pd
)
2609 "returns a matrix whose rows are a basis for the quotient row space of mat1 modulo modulo-mat"
2610 (iassert ($matrixp modulo-mat
)) (iassert ($matrixp mat1
))
2611 (setq big-mat
(append modulo-mat
(cdr mat1
)))
2612 (setq big-pd
(poly-data-from-nc-matrix big-mat
))
2613 (setq all-rows
(listarray (pd-rows big-pd
)))
2614 (multiple-value-bind (sp1 sp2
)
2615 (sp-quotient-space-basis (subseq all-rows
0 ($length modulo-mat
))
2616 (nthcdr ($length modulo-mat
) all-rows
))
2618 (setf (pd-rows big-pd
) (sp-rows sp1
))
2619 (pd-convert-to-maxima-format big-pd
)))