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