001: package JSci.maths.vectors;
002:
003: import JSci.GlobalSettings;
004: import JSci.maths.Mapping;
005: import JSci.maths.MathInteger;
006: import JSci.maths.MathDouble;
007: import JSci.maths.groups.AbelianGroup;
008: import JSci.maths.algebras.Module;
009: import JSci.maths.fields.Ring;
010: import JSci.maths.algebras.VectorSpace;
011: import JSci.maths.fields.Field;
012:
013: /**
014: * An optimised implementation of a 3D double vector.
015: * @version 2.0
016: * @author Mark Hale
017: */
018: public final class Double3Vector extends AbstractDoubleVector {
019: protected double x;
020: protected double y;
021: protected double z;
022:
023: /**
024: * Constructs an empty 3-vector.
025: */
026: public Double3Vector() {
027: super (3);
028: }
029:
030: /**
031: * Constructs a 3-vector.
032: * @param x x coordinate.
033: * @param y y coordinate.
034: * @param z z coordinate.
035: */
036: public Double3Vector(final double x, final double y, final double z) {
037: this ();
038: this .x = x;
039: this .y = y;
040: this .z = z;
041: }
042:
043: /**
044: * Constructs a 3-vector.
045: */
046: public Double3Vector(double[] array) {
047: this ();
048: x = array[0];
049: y = array[1];
050: z = array[2];
051: }
052:
053: /**
054: * Compares two double vectors for equality.
055: * @param obj a double 3-vector
056: */
057: public boolean equals(Object obj, double tol) {
058: if (obj != null && (obj instanceof Double3Vector)) {
059: final Double3Vector vec = (Double3Vector) obj;
060: double dx = x - vec.x;
061: double dy = y - vec.y;
062: double dz = z - vec.z;
063: return (dx * dx + dy * dy + dz * dz <= tol * tol);
064: } else
065: return false;
066: }
067:
068: /**
069: * Returns a comma delimited string representing the value of this vector.
070: */
071: public String toString() {
072: final StringBuffer buf = new StringBuffer(15);
073: buf.append(x).append(',').append(y).append(',').append(z);
074: return buf.toString();
075: }
076:
077: /**
078: * Converts this 3-vector to an integer 3-vector.
079: * @return an integer 3-vector
080: */
081: public AbstractIntegerVector toIntegerVector() {
082: return new Integer3Vector(Math.round((float) x), Math
083: .round((float) y), Math.round((float) z));
084: }
085:
086: /**
087: * Converts this 3-vector to a complex 3-vector.
088: * @return a complex 3-vector
089: */
090: public AbstractComplexVector toComplexVector() {
091: return new Complex3Vector(x, 0.0, y, 0.0, z, 0.0);
092: }
093:
094: /**
095: * Returns a component of this vector.
096: * @param n index of the vector component
097: * @exception VectorDimensionException If attempting to access an invalid component.
098: */
099: public double getComponent(final int n) {
100: switch (n) {
101: case 0:
102: return x;
103: case 1:
104: return y;
105: case 2:
106: return z;
107: default:
108: throw new VectorDimensionException("Invalid component.");
109: }
110: }
111:
112: /**
113: * Sets the value of a component of this vector.
114: * Should only be used to initialise this vector.
115: * @param n index of the vector component
116: * @param value a number
117: * @exception VectorDimensionException If attempting to access an invalid component.
118: */
119: public void setComponent(final int n, final double value) {
120: switch (n) {
121: case 0:
122: x = value;
123: break;
124: case 1:
125: y = value;
126: break;
127: case 2:
128: z = value;
129: break;
130: default:
131: throw new VectorDimensionException("Invalid component.");
132: }
133: }
134:
135: /**
136: * Returns the l<sup>n</sup>-norm.
137: */
138: public double norm(final int n) {
139: final double answer = Math.pow(Math.abs(x), n)
140: + Math.pow(Math.abs(y), n) + Math.pow(Math.abs(z), n);
141: return Math.pow(answer, 1.0 / n);
142: }
143:
144: /**
145: * Returns the l<sup>2</sup>-norm (magnitude).
146: */
147: public double norm() {
148: return Math.sqrt(x * x + y * y + z * z);
149: }
150:
151: /**
152: * Returns the l<sup><img border=0 alt="infinity" src="doc-files/infinity.gif"></sup>-norm.
153: * @author Taber Smith
154: */
155: public double infNorm() {
156: double infNorm = 0;
157: double abs;
158: abs = Math.abs(x);
159: if (abs > infNorm)
160: infNorm = abs;
161: abs = Math.abs(y);
162: if (abs > infNorm)
163: infNorm = abs;
164: abs = Math.abs(z);
165: if (abs > infNorm)
166: infNorm = abs;
167: return infNorm;
168: }
169:
170: //============
171: // OPERATIONS
172: //============
173:
174: /**
175: * Returns the negative of this vector.
176: */
177: public AbelianGroup.Member negate() {
178: return new Double3Vector(-x, -y, -z);
179: }
180:
181: // ADDITION
182:
183: /**
184: * Returns the addition of this vector and another.
185: */
186: public AbelianGroup.Member add(final AbelianGroup.Member vec) {
187: if (vec instanceof AbstractDoubleVector)
188: return add((AbstractDoubleVector) vec);
189: else
190: throw new IllegalArgumentException(
191: "Member class not recognised by this method.");
192: }
193:
194: /**
195: * Returns the addition of this vector and another.
196: * @param vec a double 3-vector
197: */
198: public AbstractDoubleVector add(final AbstractDoubleVector vec) {
199: if (vec.N == 3) {
200: return new Double3Vector(x + vec.getComponent(0), y
201: + vec.getComponent(1), z + vec.getComponent(2));
202: } else
203: throw new VectorDimensionException(
204: "Vectors are different sizes.");
205: }
206:
207: // SUBTRACTION
208:
209: /**
210: * Returns the subtraction of this vector by another.
211: */
212: public AbelianGroup.Member subtract(final AbelianGroup.Member vec) {
213: if (vec instanceof AbstractDoubleVector)
214: return subtract((AbstractDoubleVector) vec);
215: else
216: throw new IllegalArgumentException(
217: "Member class not recognised by this method.");
218: }
219:
220: /**
221: * Returns the subtraction of this vector by another.
222: * @param vec a double 3-vector
223: */
224: public AbstractDoubleVector subtract(final AbstractDoubleVector vec) {
225: if (vec.N == 3) {
226: return new Double3Vector(x - vec.getComponent(0), y
227: - vec.getComponent(1), z - vec.getComponent(2));
228: } else
229: throw new VectorDimensionException(
230: "Vectors are different sizes.");
231: }
232:
233: // SCALAR MULTIPLICATION
234:
235: /**
236: * Returns the multiplication of this vector by a scalar.
237: */
238: public Module.Member scalarMultiply(Ring.Member x) {
239: if (x instanceof MathInteger)
240: return scalarMultiply(((MathInteger) x).value());
241: else if (x instanceof MathDouble)
242: return scalarMultiply(((MathDouble) x).value());
243: else
244: throw new IllegalArgumentException(
245: "Member class not recognised by this method.");
246: }
247:
248: /**
249: * Returns the multiplication of this vector by a scalar.
250: * @param k a double
251: * @return a double 3-vector
252: */
253: public AbstractDoubleVector scalarMultiply(final double k) {
254: return new Double3Vector(k * x, k * y, k * z);
255: }
256:
257: // SCALAR DIVISION
258:
259: /**
260: * Returns the division of this vector by a scalar.
261: */
262: public VectorSpace.Member scalarDivide(Field.Member x) {
263: if (x instanceof MathDouble)
264: return scalarDivide(((MathDouble) x).value());
265: else
266: throw new IllegalArgumentException(
267: "Member class not recognised by this method.");
268: }
269:
270: /**
271: * Returns the division of this vector by a scalar.
272: * @param k a double
273: * @return a double 3-vector
274: * @exception ArithmeticException If divide by zero.
275: */
276: public AbstractDoubleVector scalarDivide(final double k) {
277: return new Double3Vector(x / k, y / k, z / k);
278: }
279:
280: // SCALAR PRODUCT
281:
282: /**
283: * Returns the scalar product of this vector and another.
284: * @param vec a double 3-vector
285: */
286: public double scalarProduct(final AbstractDoubleVector vec) {
287: if (vec.N == 3) {
288: return x * vec.getComponent(0) + y * vec.getComponent(1)
289: + z * vec.getComponent(2);
290: } else
291: throw new VectorDimensionException(
292: "Vectors are different sizes.");
293: }
294:
295: // VECTOR PRODUCT
296:
297: /**
298: * Returns the vector product of this vector and another (so(3) algebra).
299: * @param vec a double 3-vector
300: */
301: public Double3Vector multiply(final Double3Vector vec) {
302: return new Double3Vector(y * vec.z - vec.y * z, z * vec.x
303: - vec.z * x, x * vec.y - vec.x * y);
304: }
305:
306: // MAP COMPONENTS
307:
308: /**
309: * Applies a function on all the vector components.
310: * @param mapping a user-defined function
311: * @return a double 3-vector
312: */
313: public AbstractDoubleVector mapComponents(final Mapping mapping) {
314: return new Double3Vector(mapping.map(x), mapping.map(y),
315: mapping.map(z));
316: }
317: }
|