KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jscience > mathematics > numbers > ModuloInteger


1 /*
2  * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
3  * Copyright (C) 2006 - JScience (http://jscience.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package org.jscience.mathematics.numbers;
10
11 import org.jscience.mathematics.structures.Field;
12
13 import javolution.context.LocalContext;
14 import javolution.text.Text;
15 import javolution.xml.XMLFormat;
16 import javolution.xml.stream.XMLStreamException;
17
18 /**
19  * <p> This class represents a modulo integer. It can be used in conjonction
20  * with the {@link org.jscience.mathematics.vectors.Matrix Matrix}
21  * class to resolve modulo equations (ref. number theory).</p>
22  *
23  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
24  * @version 3.0, February 13, 2006
25  * @see <a HREF="http://en.wikipedia.org/wiki/Modular_arithmetic">
26  * Wikipedia: Modular Arithmetic</a>
27  */

28 public final class ModuloInteger extends Number JavaDoc<ModuloInteger> implements Field<ModuloInteger> {
29     
30     /**
31      * Holds the default XML representation for modulo integers.
32      * This representation consists of a simple <code>value</code> attribute
33      * holding the {@link #toText() textual} representation.
34      */

35     protected static final XMLFormat<ModuloInteger> XML = new XMLFormat<ModuloInteger>(ModuloInteger.class) {
36         
37         @Override JavaDoc
38         public ModuloInteger newInstance(Class JavaDoc<ModuloInteger> cls, InputElement xml) throws XMLStreamException {
39             return ModuloInteger.valueOf(xml.getAttribute("value"));
40         }
41         
42         public void write(ModuloInteger mi, OutputElement xml) throws XMLStreamException {
43             xml.setAttribute("value", mi._value.toText());
44             }
45
46          public void read(InputElement xml, ModuloInteger mi) {
47              // Nothing to do, immutable.
48
}
49      };
50
51     /**
52      * The modulo integer representing the additive identity.
53      */

54     public static final ModuloInteger ZERO = new ModuloInteger();
55     static {
56         ZERO._value = LargeInteger.ZERO;
57     }
58
59     /**
60      * The modulo integer representing the multiplicative identity.
61      */

62     public static final ModuloInteger ONE = new ModuloInteger();
63     static {
64         ONE._value = LargeInteger.ONE;
65     }
66
67     /**
68      * Holds the local modulus (for modular arithmetic).
69      */

70     private static final LocalContext.Reference<LargeInteger> MODULUS
71         = new LocalContext.Reference<LargeInteger>();
72
73     /**
74      * Holds the large integer value.
75      */

76     private LargeInteger _value;
77
78     /**
79      * Returns the modulo integer having the specified value (independently of
80      * the current modulo).
81      *
82      * @param value the modulo integer intrinsic value.
83      * @return the corresponding modulo number.
84      */

85     public static ModuloInteger valueOf(LargeInteger value) {
86          return ModuloInteger.newInstance(value);
87     }
88     /**
89      * Returns the modulo integer for the specified character sequence in
90      * decimal number.
91      *
92      * @param chars the character sequence.
93      * @return the corresponding modulo number.
94      */

95     public static ModuloInteger valueOf(CharSequence JavaDoc chars) {
96         return ModuloInteger.newInstance(LargeInteger.valueOf(chars));
97     }
98     
99     /**
100      * Returns the {@link javolution.context.LocalContext local} modulus
101      * for modular arithmetic or <code>null</code> if the arithmetic operations
102      * are non-modular (default).
103      *
104      * @return the local modulus or <code>null</code> if none.
105      * @see #setModulus
106      */

107     public static LargeInteger getModulus() {
108         return MODULUS.get();
109     }
110
111     /**
112      * Sets the {@link javolution.context.LocalContext local} modulus
113      * for modular arithmetic.
114      *
115      * @param modulus the new modulus or <code>null</code> to unset the modulus.
116      * @throws IllegalArgumentException if <code>modulus <= 0</code>
117      */

118     public static void setModulus(LargeInteger modulus) {
119         if ((modulus != null) && (!modulus.isPositive()))
120             throw new IllegalArgumentException JavaDoc("modulus: " + modulus
121                     + " has to be greater than 0");
122         MODULUS.set(modulus);
123     }
124
125     /**
126      * Returns the current modulo value of this number. If the modulus
127      * is {@link #setModulus set} to <code>null</code> the intrinsic value
128      * (the creation value) is returned.
129      *
130      * @return the positive number equals to this number modulo modulus or
131      * this modulo creation value.
132      */

133     public LargeInteger moduloValue() {
134         LargeInteger modulus = MODULUS.get();
135         return (modulus == null) ? _value : _value.mod(modulus);
136     }
137
138     /**
139      * Returns the text representation of the current modulo value of
140      * this number.
141      *
142      * @return the representation of its modulo value.
143      */

144     public Text toText() {
145         return moduloValue().toText();
146     }
147
148     /**
149      * Compares this modulo integer against the specified object
150      * independently of the current modulus.
151      *
152      * @param that the object to compare with.
153      * @return <code>true</code> if that is a modulo number with the same
154      * intrinsic value; <code>false</code> otherwise.
155      */

156     public boolean equals(Object JavaDoc that) {
157         return (that instanceof ModuloInteger) ?
158             _value.equals(((ModuloInteger) that)._value) :
159             false;
160     }
161
162     /**
163      * Returns the hash code for this large integer number.
164      *
165      * @return the hash code value.
166      */

167     public int hashCode() {
168         return _value.hashCode();
169     }
170
171     @Override JavaDoc
172     public boolean move(ObjectSpace os) {
173         if (super.move(os)) {
174             _value.move(os);
175             return true;
176         }
177         return false;
178     }
179
180     @Override JavaDoc
181     public boolean isLargerThan(ModuloInteger that) {
182         return _value.isLargerThan(that._value);
183     }
184
185     @Override JavaDoc
186     public long longValue() {
187         return moduloValue().longValue();
188     }
189
190     @Override JavaDoc
191     public double doubleValue() {
192         return moduloValue().doubleValue();
193     }
194
195     @Override JavaDoc
196     public int compareTo(ModuloInteger that) {
197         return _value.compareTo(that._value);
198     }
199
200     public ModuloInteger times(ModuloInteger that) {
201         LargeInteger value = moduloValue().times(that.moduloValue());
202         LargeInteger modulus = MODULUS.get();
203         return (modulus == null) ? ModuloInteger.valueOf(value)
204                 : ModuloInteger.valueOf(value.mod(modulus));
205     }
206
207     public ModuloInteger plus(ModuloInteger that) {
208         LargeInteger value = moduloValue().plus(that.moduloValue());
209         LargeInteger modulus = MODULUS.get();
210         return (modulus == null) ? ModuloInteger.valueOf(value)
211                 : ModuloInteger.valueOf(value.mod(modulus));
212     }
213
214     public ModuloInteger opposite() {
215         LargeInteger value = moduloValue().opposite();
216         LargeInteger modulus = MODULUS.get();
217         return (modulus == null) ? ModuloInteger.valueOf(value)
218                 : ModuloInteger.valueOf(value.mod(modulus));
219     }
220
221     public ModuloInteger inverse() {
222         LargeInteger modulus = MODULUS.get();
223         if (modulus == null)
224             throw new ArithmeticException JavaDoc("Modulus not set");
225         return ModuloInteger.valueOf(_value.modInverse(modulus));
226     }
227
228     ///////////////////////
229
// Factory creation. //
230
///////////////////////
231

232     private static ModuloInteger newInstance(LargeInteger value) {
233         ModuloInteger m = FACTORY.object();
234         m._value = value;
235         return m;
236     }
237     
238     private static final Factory<ModuloInteger> FACTORY = new Factory<ModuloInteger>() {
239         protected ModuloInteger create() {
240             return new ModuloInteger();
241         }
242     };
243     
244     private ModuloInteger() {
245     }
246
247     private static final long serialVersionUID = 1L;
248 }
Popular Tags