source: CGBLisp/src/rat.lisp@ 8

Last change on this file since 8 was 8, checked in by Marek Rychlik, 15 years ago

Moving sources into trunk

File size: 3.0 KB
Line 
1#|
2 $Id: rat.lisp,v 1.4 2009/01/22 04:07:12 marek Exp $
3 *--------------------------------------------------------------------------*
4 | Copyright (C) 1994, Marek Rychlik (e-mail: rychlik@math.arizona.edu) |
5 | Department of Mathematics, University of Arizona, Tucson, AZ 85721 |
6 | |
7 | Everyone is permitted to copy, distribute and modify the code in this |
8 | directory, as long as this copyright note is preserved verbatim. |
9 *--------------------------------------------------------------------------*
10|#
11;;
12;; Arithmetic on rational functions in n variables
13;; They are represented as conses of two polynomials, represented
14;; as in the monom package, ordered lexicographically (the default
15;; of the monom package).
16;; This package is trivial in the sense that it does not produce
17;; results in which numerator and denominator are relatively prime.
18;; However, zero testing works correctly. This is all that is
19;; needed for the resultant package
20;;
21
22(defpackage "RAT"
23 (:export num denom rat+ rat- rat* rat/ scalar-times-rat scalar-div-rat
24 rat-zerop rat-uminus rat-expt rat-constant rat-to-poly
25 rat-simplify)
26 (:use "ORDER" "POLY-GCD" "DIVISION" "POLY" "COMMON-LISP"))
27
28(in-package "RAT")
29
30(proclaim '(optimize (speed 0) (debug 3)))
31
32(defun num (p) (car p)) ;numerator
33(defun denom (p) (cdr p)) ;denominator
34
35(defun rat-simplify-2 (num denom)
36 (let ((gcd (poly-gcd num denom)))
37 (cons (poly-exact-divide num gcd)
38 (poly-exact-divide denom gcd))))
39
40(defun rat-simplify (p)
41 (rat-simplify-2 (car p) (cdr p)))
42
43(defun rat+ (p q)
44 ;; p1/p2+q1/q2=(p1*q2+p2*q1)/(p2*q2)
45 (rat-simplify-2
46 (poly+ (poly* (num p) (denom q))
47 (poly* (denom p) (num q)))
48 (poly* (denom p) (denom q))))
49
50(defun rat- (p q)
51 ;; p1/p2-q1/q2=(p1*q2+p2-q1)/(p2*q2)
52 (rat-simplify-2
53 (poly- (poly* (num p) (denom q))
54 (poly* (denom p) (num q)))
55 (poly* (denom p) (denom q))))
56
57;; This could be more efficient if it simplified before multiplication
58(defun rat* (p q)
59 (rat-simplify-2
60 (poly* (num p) (num q))
61 (poly* (denom p) (denom q))))
62
63(defun rat/ (p q)
64 (rat-simplify-2
65 (poly* (num p) (denom q))
66 (poly* (denom p) (num q))))
67
68(defun scalar-times-rat (scalar p)
69 (cons (scalar-times-poly scalar (num p)) (denom p)))
70
71;; scalar/rational-fun
72(defun scalar-div-rat (scalar p)
73 (cons (scalar-times-poly scalar (denom p)) (num p)))
74
75(defun rat-zerop (p)
76 (endp (car p)))
77
78(defun rat-uminus (p)
79 (cons (minus-poly (car p)) (cdr p)))
80
81(defun rat-expt (p n)
82 (cons (poly-expt (car p) n) (poly-expt (cdr p) n)))
83
84(defun rat-constant (c n)
85 "Make a constant rational function equal to c with n variables"
86 (cons (list (cons (make-list n :initial-element 0) c))
87 (list (cons (make-list n :initial-element 0) 1))))
88
89(defun rat-to-poly (p)
90 "Attempt to convert a rational function to a polynomial by
91dividing numerator by denominator. Error if not divisible"
92 (poly-exact-divide (car p) (cdr p)))
Note: See TracBrowser for help on using the repository browser.