/usr/share/axiom-20170501/src/algebra/MOEBIUS.spad is in axiom-source 20170501-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | )abbrev domain MOEBIUS MoebiusTransform
++ Author: Stephen "Say" Watt
++ Date Created: January 1987
++ Date Last Updated: 11 April 1990
++ Description:
++ MoebiusTransform(F) is the domain of fractional linear (Moebius)
++ transformations over F. This a domain of 2-by-2 matrices acting on P1(F).
MoebiusTransform(F) : SIG == CODE where
F : Field
OUT ==> OutputForm
P1F ==> OnePointCompletion F -- projective 1-space over F
SIG ==> Group with
moebius : (F,F,F,F) -> %
++ moebius(a,b,c,d) returns \spad{matrix [[a,b],[c,d]]}.
shift : F -> %
++ shift(k) returns \spad{matrix [[1,k],[0,1]]} representing the map
++ \spad{x -> x + k}.
scale : F -> %
++ scale(k) returns \spad{matrix [[k,0],[0,1]]} representing the map
++ \spad{x -> k * x}.
recip : () -> %
++ recip() returns \spad{matrix [[0,1],[1,0]]} representing the map
++ \spad{x -> 1 / x}.
shift : (%,F) -> %
++ shift(m,h) returns \spad{shift(h) * m}
++ (see shift from MoebiusTransform).
scale : (%,F) -> %
++ scale(m,h) returns \spad{scale(h) * m}
++ (see shift from MoebiusTransform).
recip : % -> %
++ recip(m) = recip() * m
eval : (%,F) -> F
++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)}
++ where \spad{m = moebius(a,b,c,d)}
++ (see moebius from MoebiusTransform).
eval : (%,P1F) -> P1F
++ eval(m,x) returns \spad{(a*x + b)/(c*x + d)}
++ where \spad{m = moebius(a,b,c,d)}
++ (see moebius from MoebiusTransform).
CODE ==> add
Rep := Record(a: F,b: F,c: F,d: F)
moebius(aa,bb,cc,dd) == [aa,bb,cc,dd]
a(t:%):F == t.a
b(t:%):F == t.b
c(t:%):F == t.c
d(t:%):F == t.d
1 == moebius(1,0,0,1)
t * s ==
moebius(b(t)*c(s) + a(t)*a(s), b(t)*d(s) + a(t)*b(s), _
d(t)*c(s) + c(t)*a(s), d(t)*d(s) + c(t)*b(s))
inv t == moebius(d(t),-b(t),-c(t),a(t))
shift f == moebius(1,f,0,1)
scale f == moebius(f,0,0,1)
recip() == moebius(0,1,1,0)
shift(t,f) == moebius(a(t) + f*c(t), b(t) + f*d(t), c(t), d(t))
scale(t,f) == moebius(f*a(t),f*b(t),c(t),d(t))
recip t == moebius(c(t),d(t),a(t),b(t))
eval(t:%,f:F) == (a(t)*f + b(t))/(c(t)*f + d(t))
eval(t:%,f:P1F) ==
(ff := retractIfCan(f)@Union(F,"failed")) case "failed" =>
(a(t)/c(t)) :: P1F
zero?(den := c(t) * (fff := ff :: F) + d(t)) => infinity()
((a(t) * fff + b(t))/den) :: P1F
coerce t ==
var := "%x" :: OUT
num := (a(t) :: OUT) * var + (b(t) :: OUT)
den := (c(t) :: OUT) * var + (d(t) :: OUT)
rarrow(var,num/den)
proportional?: (List F,List F) -> Boolean
proportional?(list1,list2) ==
empty? list1 => empty? list2
empty? list2 => false
zero? (x1 := first list1) =>
(zero? first list2) and proportional?(rest list1,rest list2)
zero? (x2 := first list2) => false
map((f1:F):F +-> f1/x1, list1) = map((g1:F):F +-> g1/x2, list2)
t = s ==
list1 : List F := [a(t),b(t),c(t),d(t)]
list2 : List F := [a(s),b(s),c(s),d(s)]
proportional?(list1,list2)
|