KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > lisp > Complex


1 /*
2  * Complex.java
3  *
4  * Copyright (C) 2003-2004 Peter Graves
5  * $Id: Complex.java,v 1.29 2004/06/04 16:24:29 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.lisp;
23
24 public final class Complex extends LispObject
25 {
26     private final LispObject realpart;
27     private final LispObject imagpart;
28
29     private Complex(LispObject realpart, LispObject imagpart)
30     {
31         this.realpart = realpart;
32         this.imagpart = imagpart;
33     }
34
35     public static LispObject getInstance(LispObject realpart,
36                                          LispObject imagpart)
37         throws ConditionThrowable
38     {
39         if (!realpart.realp())
40             return signal(new TypeError(realpart, Symbol.REAL));
41         if (!imagpart.realp())
42             return signal(new TypeError(imagpart, Symbol.REAL));
43         if (realpart instanceof LispFloat)
44             imagpart = LispFloat.coerceToFloat(imagpart);
45         else if (imagpart instanceof LispFloat)
46             realpart = LispFloat.coerceToFloat(realpart);
47         if (imagpart instanceof Fixnum) {
48             if (((Fixnum)imagpart).getValue() == 0)
49                 return realpart;
50         }
51         return new Complex(realpart, imagpart);
52     }
53
54     public LispObject getRealPart()
55     {
56         return realpart;
57     }
58
59     public LispObject getImaginaryPart()
60     {
61         return imagpart;
62     }
63
64     public LispObject typeOf()
65     {
66         return Symbol.COMPLEX;
67     }
68
69     public LispClass classOf()
70     {
71         return BuiltInClass.COMPLEX;
72     }
73
74     public LispObject typep(LispObject type) throws ConditionThrowable
75     {
76         if (type == Symbol.COMPLEX)
77             return T;
78         if (type == Symbol.NUMBER)
79             return T;
80         if (type == BuiltInClass.COMPLEX)
81             return T;
82         if (type == BuiltInClass.NUMBER)
83             return T;
84         return super.typep(type);
85     }
86
87     public LispObject NUMBERP()
88     {
89         return T;
90     }
91
92     public boolean numberp()
93     {
94         return true;
95     }
96
97     public boolean eql(LispObject obj)
98     {
99         if (this == obj)
100             return true;
101         if (obj instanceof Complex) {
102             Complex c = (Complex) obj;
103             return realpart.eql(c.realpart) && imagpart.eql(c.imagpart);
104         }
105         return false;
106     }
107
108     public boolean equal(LispObject obj)
109     {
110         return eql(obj);
111     }
112
113     public boolean equalp(LispObject obj) throws ConditionThrowable
114     {
115         return isEqualTo(obj);
116     }
117
118     public final LispObject incr() throws ConditionThrowable
119     {
120         return new Complex(realpart.add(Fixnum.ONE), imagpart);
121     }
122
123     public final LispObject decr() throws ConditionThrowable
124     {
125         return new Complex(realpart.subtract(Fixnum.ONE), imagpart);
126     }
127
128     public LispObject add(LispObject obj) throws ConditionThrowable
129     {
130         if (obj instanceof Complex) {
131             Complex c = (Complex) obj;
132             return getInstance(realpart.add(c.realpart), imagpart.add(c.imagpart));
133         }
134         return getInstance(realpart.add(obj), imagpart);
135     }
136
137     public LispObject subtract(LispObject obj) throws ConditionThrowable
138     {
139         if (obj instanceof Complex) {
140             Complex c = (Complex) obj;
141             return getInstance(realpart.subtract(c.realpart), imagpart.subtract(c.imagpart));
142         }
143         return getInstance(realpart.subtract(obj), imagpart);
144     }
145
146     public LispObject multiplyBy(LispObject obj) throws ConditionThrowable
147     {
148         if (obj instanceof Complex) {
149             LispObject a = realpart;
150             LispObject b = imagpart;
151             LispObject c = ((Complex)obj).getRealPart();
152             LispObject d = ((Complex)obj).getImaginaryPart();
153             // xy = (ac - bd) + i(ad + bc)
154
// real part = ac - bd
155
// imag part = (a + b)(c + d) - ac - bd
156
LispObject ac = a.multiplyBy(c);
157             LispObject bd = b.multiplyBy(d);
158             return Complex.getInstance(ac.subtract(bd),
159                                        a.add(b).multiplyBy(c.add(d)).subtract(ac).subtract(bd));
160         }
161         return Complex.getInstance(realpart.multiplyBy(obj),
162                                    imagpart.multiplyBy(obj));
163     }
164
165     public LispObject divideBy(LispObject obj) throws ConditionThrowable
166     {
167         if (obj instanceof Complex) {
168             LispObject a = realpart;
169             LispObject b = imagpart;
170             LispObject c = ((Complex)obj).getRealPart();
171             LispObject d = ((Complex)obj).getImaginaryPart();
172             LispObject ac = a.multiplyBy(c);
173             LispObject bd = b.multiplyBy(d);
174             LispObject bc = b.multiplyBy(c);
175             LispObject ad = a.multiplyBy(d);
176             LispObject denominator = c.multiplyBy(c).add(d.multiplyBy(d));
177             return Complex.getInstance(ac.add(bd).divideBy(denominator),
178                                        bc.subtract(ad).divideBy(denominator));
179         }
180         return Complex.getInstance(realpart.divideBy(obj),
181                                    imagpart.divideBy(obj));
182     }
183
184     public boolean isEqualTo(LispObject obj) throws ConditionThrowable
185     {
186         if (obj instanceof Complex) {
187             Complex c = (Complex) obj;
188             return (realpart.isEqualTo(c.realpart) &&
189                     imagpart.isEqualTo(c.imagpart));
190         }
191         if (obj.numberp()) {
192             // obj is a number, but not complex.
193
if (imagpart instanceof LispFloat) {
194                 if (((LispFloat)imagpart).getValue() == 0) {
195                     if (obj instanceof Fixnum)
196                         return ((Fixnum)obj).getValue() == ((LispFloat)realpart).getValue();
197                     if (obj instanceof LispFloat)
198                         return ((LispFloat)obj).getValue() == ((LispFloat)realpart).getValue();
199                 }
200             }
201             return false;
202         }
203         signal(new TypeError(obj, "number"));
204         // Not reached.
205
return false;
206     }
207
208     public boolean isNotEqualTo(LispObject obj) throws ConditionThrowable
209     {
210         return !isEqualTo(obj);
211     }
212
213     public LispObject ABS() throws ConditionThrowable
214     {
215         double real = LispFloat.coerceToFloat(realpart).getValue();
216         double imag = LispFloat.coerceToFloat(imagpart).getValue();
217         return new LispFloat(Math.sqrt(real * real + imag * imag));
218     }
219
220     public boolean zerop() throws ConditionThrowable
221     {
222         return realpart.zerop() && imagpart.zerop();
223     }
224
225     public LispObject COMPLEXP()
226     {
227         return T;
228     }
229
230     public int sxhash() throws ConditionThrowable
231     {
232         return (mix(realpart.sxhash(), imagpart.sxhash()) & 0x7fffffff);
233     }
234
235     public int psxhash() throws ConditionThrowable
236     {
237         return (mix(realpart.psxhash(), imagpart.psxhash()) & 0x7fffffff);
238     }
239
240     public String JavaDoc writeToString() throws ConditionThrowable
241     {
242         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("#C(");
243         sb.append(realpart.writeToString());
244         sb.append(' ');
245         sb.append(imagpart.writeToString());
246         sb.append(')');
247         return sb.toString();
248     }
249 }
250
Popular Tags