KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > maths > vectors > ComplexVector


1 package JSci.maths.vectors;
2
3 import JSci.maths.Complex;
4 import JSci.maths.ComplexMapping;
5 import JSci.maths.MathDouble;
6 import JSci.maths.MathInteger;
7 import JSci.maths.algebras.Module;
8 import JSci.maths.algebras.VectorSpace;
9 import JSci.maths.algebras.HilbertSpace;
10 import JSci.maths.fields.Ring;
11 import JSci.maths.fields.Field;
12 import JSci.maths.groups.AbelianGroup;
13
14 /**
15 * An array-based implementation of a complex vector.
16 * @version 2.2
17 * @author Mark Hale
18 */

19 public class ComplexVector extends AbstractComplexVector {
20         /**
21         * Arrays containing the components of the vector.
22         */

23         protected double vectorRe[];
24         protected double vectorIm[];
25         /**
26         * Constructs an empty vector.
27         * @param dim the dimension of the vector.
28         */

29         public ComplexVector(final int dim) {
30                 super(dim);
31                 vectorRe=new double[dim];
32                 vectorIm=new double[dim];
33         }
34         /**
35         * Constructs a vector by wrapping two arrays.
36         * @param real an array of real values
37         * @param imag an array of imaginary values
38         */

39         public ComplexVector(final double real[],final double imag[]) {
40                 super(real.length);
41                 vectorRe=real;
42                 vectorIm=imag;
43         }
44         /**
45         * Constructs a vector from an array.
46         * @param array an assigned value
47         */

48         public ComplexVector(final Complex array[]) {
49                 this(array.length);
50                 for(int i=0;i<N;i++) {
51                         vectorRe[i]=array[i].real();
52                         vectorIm[i]=array[i].imag();
53                 }
54         }
55         /**
56         * Compares two complex vectors for equality.
57         * @param a a complex vector
58         */

59         public boolean equals(Object JavaDoc a, double tol) {
60                 if(a!=null && (a instanceof ComplexVector) && N==((ComplexVector)a).N) {
61                         final ComplexVector cv=(ComplexVector)a;
62             double sumSqr = 0.0;
63                         for(int i=0;i<N;i++) {
64                                 double deltaRe = vectorRe[i]-cv.getRealComponent(i);
65                                 double deltaIm = vectorIm[i]-cv.getImagComponent(i);
66                                 sumSqr += deltaRe*deltaRe + deltaIm*deltaIm;
67                         }
68                         return (sumSqr <= tol*tol);
69                 } else
70                         return false;
71         }
72         /**
73         * Returns a comma delimited string representing the value of this vector.
74         */

75         public String JavaDoc toString() {
76                 final StringBuffer JavaDoc buf=new StringBuffer JavaDoc(8*N);
77                 int i;
78                 for(i=0;i<N-1;i++) {
79                         buf.append(Complex.toString(vectorRe[i],vectorIm[i]));
80                         buf.append(',');
81                 }
82                 buf.append(Complex.toString(vectorRe[i],vectorIm[i]));
83                 return buf.toString();
84         }
85         /**
86         * Returns the real part of this complex vector.
87         */

88         public AbstractDoubleVector real() {
89                 return new DoubleVector(vectorRe);
90         }
91         /**
92         * Returns the imaginary part of this complex vector.
93         */

94         public AbstractDoubleVector imag() {
95                 return new DoubleVector(vectorIm);
96         }
97         /**
98         * Returns a component of this vector.
99         * @param n index of the vector component
100         * @exception VectorDimensionException If attempting to access an invalid component.
101         */

102         public Complex getComponent(final int n) {
103                 if(n>=0 && n<N)
104                         return new Complex(vectorRe[n],vectorIm[n]);
105                 else
106                         throw new VectorDimensionException(getInvalidComponentMsg(n));
107         }
108         public double getRealComponent(final int n) {
109                 if(n>=0 && n<N)
110                         return vectorRe[n];
111                 else
112                         throw new VectorDimensionException(getInvalidComponentMsg(n));
113         }
114         public double getImagComponent(final int n) {
115                 if(n>=0 && n<N)
116                         return vectorIm[n];
117                 else
118                         throw new VectorDimensionException(getInvalidComponentMsg(n));
119         }
120         /**
121         * Sets the value of a component of this vector.
122         * Should only be used to initialise this vector.
123         * @param n index of the vector component
124         * @param z a complex number
125         * @exception VectorDimensionException If attempting to access an invalid component.
126         */

127         public void setComponent(final int n, final Complex z) {
128                 if(n>=0 && n<N) {
129                         vectorRe[n]=z.real();
130                         vectorIm[n]=z.imag();
131                 } else
132                         throw new VectorDimensionException(getInvalidComponentMsg(n));
133         }
134         /**
135         * Sets the value of a component of this vector.
136         * Should only be used to initialise this vector.
137         * @param n index of the vector component
138         * @param x the real part of a complex number
139         * @param y the imaginary part of a complex number
140         * @exception VectorDimensionException If attempting to access an invalid component.
141         */

142         public void setComponent(final int n, final double x, final double y) {
143                 if(n>=0 && n<N) {
144                         vectorRe[n]=x;
145                         vectorIm[n]=y;
146                 } else
147                         throw new VectorDimensionException(getInvalidComponentMsg(n));
148         }
149         /**
150         * Returns the l<sup>2</sup>-norm (magnitude).
151         */

152         public double norm() {
153                 double answer=vectorRe[0]*vectorRe[0]+vectorIm[0]*vectorIm[0];
154                 for(int i=1;i<N;i++)
155                         answer+=vectorRe[i]*vectorRe[i]+vectorIm[i]*vectorIm[i];
156                 return Math.sqrt(answer);
157         }
158         /**
159         * Returns the l<sup><img border=0 alt="infinity" SRC="doc-files/infinity.gif"></sup>-norm.
160         */

161         public double infNorm() {
162                 double infNorm=vectorRe[0]*vectorRe[0]+vectorIm[0]*vectorIm[0];
163                 for(int i=1;i<N;i++) {
164                         double mod=vectorRe[i]*vectorRe[i]+vectorIm[i]*vectorIm[i];
165                         if(mod>infNorm)
166                                 infNorm=mod;
167                 }
168                 return Math.sqrt(infNorm);
169         }
170
171 //============
172
// OPERATIONS
173
//============
174

175         /**
176         * Returns the negative of this vector.
177         */

178         public AbelianGroup.Member negate() {
179                 final double arrayRe[]=new double[N];
180                 final double arrayIm[]=new double[N];
181                 arrayRe[0]=-vectorRe[0];
182                 arrayIm[0]=-vectorIm[0];
183                 for(int i=1;i<N;i++) {
184                         arrayRe[i]=-vectorRe[i];
185                         arrayIm[i]=-vectorIm[i];
186                 }
187                 return new ComplexVector(arrayRe,arrayIm);
188         }
189
190 // COMPLEX CONJUGATE
191

192         /**
193         * Returns the complex conjugate of this vector.
194         */

195         public AbstractComplexVector conjugate() {
196                 final double arrayIm[]=new double[N];
197                 arrayIm[0]=-vectorIm[0];
198                 for(int i=1;i<N;i++)
199                         arrayIm[i]=-vectorIm[i];
200                 return new ComplexVector(vectorRe,arrayIm);
201         }
202
203 // ADDITION
204

205         /**
206         * Returns the addition of this vector and another.
207         */

208         public AbelianGroup.Member add(final AbelianGroup.Member v) {
209                 if(v instanceof ComplexVector)
210                         return add((ComplexVector)v);
211                 else if(v instanceof DoubleVector)
212                         return add((DoubleVector)v);
213                 else if(v instanceof IntegerVector)
214                         return add((IntegerVector)v);
215                 else
216                         throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
217         }
218         /**
219         * Returns the addition of this vector and another.
220         * @param v a complex vector
221         * @exception VectorDimensionException If the vectors are different sizes.
222         */

223         public AbstractComplexVector add(final AbstractComplexVector v) {
224                 if(v instanceof ComplexVector)
225                         return add((ComplexVector)v);
226                 else {
227                         if(N==v.N) {
228                                 final double arrayRe[]=new double[N];
229                                 final double arrayIm[]=new double[N];
230                                 arrayRe[0]=vectorRe[0]+v.getComponent(0).real();
231                                 arrayIm[0]=vectorIm[0]+v.getComponent(0).imag();
232                                 for(int i=1;i<N;i++) {
233                                         arrayRe[i]=vectorRe[i]+v.getComponent(i).real();
234                                         arrayIm[i]=vectorIm[i]+v.getComponent(i).imag();
235                                 }
236                                 return new ComplexVector(arrayRe,arrayIm);
237                         } else
238                                 throw new VectorDimensionException("Vectors are different sizes.");
239                 }
240         }
241         public ComplexVector add(final ComplexVector v) {
242                 if(N==v.N) {
243                         final double arrayRe[]=new double[N];
244                         final double arrayIm[]=new double[N];
245                         arrayRe[0]=vectorRe[0]+v.vectorRe[0];
246                         arrayIm[0]=vectorIm[0]+v.vectorIm[0];
247                         for(int i=1;i<N;i++) {
248                                 arrayRe[i]=vectorRe[i]+v.vectorRe[i];
249                                 arrayIm[i]=vectorIm[i]+v.vectorIm[i];
250                         }
251                         return new ComplexVector(arrayRe,arrayIm);
252                 } else
253                         throw new VectorDimensionException("Vectors are different sizes.");
254         }
255         /**
256         * Returns the addition of this vector and another.
257         * @param v a double vector
258         * @exception VectorDimensionException If the vectors are different sizes.
259         */

260         public AbstractComplexVector add(final AbstractDoubleVector v) {
261                 if(v instanceof DoubleVector)
262                         return add((DoubleVector)v);
263                 else {
264                         if(N==v.N) {
265                                 final double arrayRe[]=new double[N];
266                                 arrayRe[0]=vectorRe[0]+v.getComponent(0);
267                                 for(int i=1;i<N;i++)
268                                         arrayRe[i]=vectorRe[i]+v.getComponent(i);
269                                 return new ComplexVector(arrayRe,vectorIm);
270                         } else
271                                 throw new VectorDimensionException("Vectors are different sizes.");
272                 }
273         }
274         public ComplexVector add(final DoubleVector v) {
275                 if(N==v.N) {
276                         final double arrayRe[]=new double[N];
277                         arrayRe[0]=vectorRe[0]+v.vector[0];
278                         for(int i=1;i<N;i++)
279                                 arrayRe[i]=vectorRe[i]+v.vector[i];
280                         return new ComplexVector(arrayRe,vectorIm);
281                 } else
282                         throw new VectorDimensionException("Vectors are different sizes.");
283         }
284         /**
285         * Returns the addition of this vector and another.
286         * @param v an integer vector
287         * @exception VectorDimensionException If the vectors are different sizes.
288         */

289         public AbstractComplexVector add(final AbstractIntegerVector v) {
290                 if(v instanceof IntegerVector)
291                         return add((IntegerVector)v);
292                 else {
293                         if(N==v.N) {
294                                 final double arrayRe[]=new double[N];
295                                 arrayRe[0]=vectorRe[0]+v.getComponent(0);
296                                 for(int i=1;i<N;i++)
297                                         arrayRe[i]=vectorRe[i]+v.getComponent(i);
298                                 return new ComplexVector(arrayRe,vectorIm);
299                         } else
300                                 throw new VectorDimensionException("Vectors are different sizes.");
301                 }
302         }
303         public ComplexVector add(final IntegerVector v) {
304                 if(N==v.N) {
305                         final double arrayRe[]=new double[N];
306                         arrayRe[0]=vectorRe[0]+v.vector[0];
307                         for(int i=1;i<N;i++)
308                                 arrayRe[i]=vectorRe[i]+v.vector[i];
309                         return new ComplexVector(arrayRe,vectorIm);
310                 } else
311                         throw new VectorDimensionException("Vectors are different sizes.");
312         }
313
314 // SUBTRACTION
315

316         /**
317         * Returns the subtraction of this vector by another.
318         */

319         public AbelianGroup.Member subtract(final AbelianGroup.Member v) {
320                 if(v instanceof ComplexVector)
321                         return subtract((ComplexVector)v);
322                 else if(v instanceof DoubleVector)
323                         return subtract((DoubleVector)v);
324                 else if(v instanceof IntegerVector)
325                         return subtract((IntegerVector)v);
326                 else
327                         throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
328         }
329         /**
330         * Returns the subtraction of this vector by another.
331         * @param v a complex vector
332         * @exception VectorDimensionException If the vectors are different sizes.
333         */

334         public AbstractComplexVector subtract(final AbstractComplexVector v) {
335                 if(v instanceof ComplexVector)
336                         return subtract((ComplexVector)v);
337                 else {
338                         if(N==v.N) {
339                                 final double arrayRe[]=new double[N];
340                                 final double arrayIm[]=new double[N];
341                                 arrayRe[0]=vectorRe[0]-v.getComponent(0).real();
342                                 arrayIm[0]=vectorIm[0]-v.getComponent(0).imag();
343                                 for(int i=1;i<N;i++) {
344                                         arrayRe[i]=vectorRe[i]-v.getComponent(i).real();
345                                         arrayIm[i]=vectorIm[i]-v.getComponent(i).imag();
346                                 }
347                                 return new ComplexVector(arrayRe,arrayIm);
348                         } else
349                                 throw new VectorDimensionException("Vectors are different sizes.");
350                 }
351         }
352         public ComplexVector subtract(final ComplexVector v) {
353                 if(N==v.N) {
354                         final double arrayRe[]=new double[N];
355                         final double arrayIm[]=new double[N];
356                         arrayRe[0]=vectorRe[0]-v.vectorRe[0];
357                         arrayIm[0]=vectorIm[0]-v.vectorIm[0];
358                         for(int i=1;i<N;i++) {
359                                 arrayRe[i]=vectorRe[i]-v.vectorRe[i];
360                                 arrayIm[i]=vectorIm[i]-v.vectorIm[i];
361                         }
362                         return new ComplexVector(arrayRe,arrayIm);
363                 } else
364                         throw new VectorDimensionException("Vectors are different sizes.");
365         }
366         /**
367         * Returns the subtraction of this vector by another.
368         * @param v a double vector
369         * @exception VectorDimensionException If the vectors are different sizes.
370         */

371         public AbstractComplexVector subtract(final AbstractDoubleVector v) {
372                 if(v instanceof DoubleVector)
373                         return subtract((DoubleVector)v);
374                 else {
375                         if(N==v.N) {
376                                 final double arrayRe[]=new double[N];
377                                 arrayRe[0]=vectorRe[0]-v.getComponent(0);
378                                 for(int i=1;i<N;i++)
379                                         arrayRe[i]=vectorRe[i]-v.getComponent(i);
380                                 return new ComplexVector(arrayRe,vectorIm);
381                         } else
382                                 throw new VectorDimensionException("Vectors are different sizes.");
383                 }
384         }
385         public ComplexVector subtract(final DoubleVector v) {
386                 if(N==v.N) {
387                         final double arrayRe[]=new double[N];
388                         arrayRe[0]=vectorRe[0]-v.vector[0];
389                         for(int i=1;i<N;i++)
390                                 arrayRe[i]=vectorRe[i]-v.vector[i];
391                         return new ComplexVector(arrayRe,vectorIm);
392                 } else
393                         throw new VectorDimensionException("Vectors are different sizes.");
394         }
395         /**
396         * Returns the subtraction of this vector by another.
397         * @param v an integer vector
398         * @exception VectorDimensionException If the vectors are different sizes.
399         */

400         public AbstractComplexVector subtract(final AbstractIntegerVector v) {
401                 if(v instanceof IntegerVector)
402                         return subtract((IntegerVector)v);
403                 else {
404                         if(N==v.N) {
405                                 final double arrayRe[]=new double[N];
406                                 arrayRe[0]=vectorRe[0]-v.getComponent(0);
407                                 for(int i=1;i<N;i++)
408                                         arrayRe[i]=vectorRe[i]-v.getComponent(i);
409                                 return new ComplexVector(arrayRe,vectorIm);
410                         } else
411                                 throw new VectorDimensionException("Vectors are different sizes.");
412                 }
413         }
414         public ComplexVector subtract(final IntegerVector v) {
415                 if(N==v.N) {
416                         final double arrayRe[]=new double[N];
417                         arrayRe[0]=vectorRe[0]-v.vector[0];
418                         for(int i=1;i<N;i++)
419                                 arrayRe[i]=vectorRe[i]-v.vector[i];
420                         return new ComplexVector(arrayRe,vectorIm);
421                 } else
422                         throw new VectorDimensionException("Vectors are different sizes.");
423         }
424
425 // SCALAR MULTIPLICATION
426

427         /**
428         * Returns the multiplication of this vector by a scalar.
429         */

430         public Module.Member scalarMultiply(Ring.Member x) {
431                 if(x instanceof Complex)
432                         return scalarMultiply((Complex)x);
433                 else if(x instanceof MathDouble)
434                         return scalarMultiply(((MathDouble)x).value());
435                 else if(x instanceof MathInteger)
436                         return scalarMultiply(((MathInteger)x).value());
437                 else
438                         throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
439         }
440         /**
441         * Returns the multiplication of this vector by a scalar.
442         * @param z a complex number
443         */

444         public AbstractComplexVector scalarMultiply(final Complex z) {
445                 final double real=z.real();
446                 final double imag=z.imag();
447                 final double arrayRe[]=new double[N];
448                 final double arrayIm[]=new double[N];
449                 arrayRe[0]=vectorRe[0]*real-vectorIm[0]*imag;
450                 arrayIm[0]=vectorRe[0]*imag+vectorIm[0]*real;
451                 for(int i=1;i<N;i++) {
452                         arrayRe[i]=vectorRe[i]*real-vectorIm[i]*imag;
453                         arrayIm[i]=vectorRe[i]*imag+vectorIm[i]*real;
454                 }
455                 return new ComplexVector(arrayRe,arrayIm);
456         }
457         /**
458         * Returns the multiplication of this vector by a scalar.
459         * @param x a double
460         */

461         public AbstractComplexVector scalarMultiply(final double x) {
462                 final double arrayRe[]=new double[N];
463                 final double arrayIm[]=new double[N];
464                 arrayRe[0]=x*vectorRe[0];
465                 arrayIm[0]=x*vectorIm[0];
466                 for(int i=1;i<N;i++) {
467                         arrayRe[i]=x*vectorRe[i];
468                         arrayIm[i]=x*vectorIm[i];
469                 }
470                 return new ComplexVector(arrayRe,arrayIm);
471         }
472
473 // SCALAR DIVISION
474

475         /**
476         * Returns the division of this vector by a scalar.
477         */

478         public VectorSpace.Member scalarDivide(Field.Member x) {
479                 if(x instanceof Complex)
480                         return scalarDivide((Complex)x);
481                 else if(x instanceof MathDouble)
482                         return scalarDivide(((MathDouble)x).value());
483                 else
484                         throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
485         }
486         /**
487         * Returns the division of this vector by a scalar.
488         * @param z a complex number
489         * @exception ArithmeticException If divide by zero.
490         */

491         public AbstractComplexVector scalarDivide(final Complex z) {
492                 final double real=z.real();
493                 final double imag=z.imag();
494                 final double arrayRe[]=new double[N];
495                 final double arrayIm[]=new double[N];
496                 final double a,denom;
497                 if(Math.abs(real)<Math.abs(imag)) {
498                         a=real/imag;
499                         denom=real*a+imag;
500                         for(int i=0;i<N;i++) {
501                                 arrayRe[i]=(vectorRe[i]*a+vectorIm[i])/denom;
502                                 arrayIm[i]=(vectorIm[i]*a-vectorRe[i])/denom;
503                         }
504                 } else {
505                         a=imag/real;
506                         denom=real+imag*a;
507                         for(int i=0;i<N;i++) {
508                                 arrayRe[i]=(vectorRe[i]+vectorIm[i]*a)/denom;
509                                 arrayIm[i]=(vectorIm[i]-vectorRe[i]*a)/denom;
510                         }
511                 }
512                 return new ComplexVector(arrayRe,arrayIm);
513         }
514         /**
515         * Returns the division of this vector by a scalar.
516         * @param x a double
517         * @exception ArithmeticException If divide by zero.
518         */

519         public AbstractComplexVector scalarDivide(final double x) {
520                 final double arrayRe[]=new double[N];
521                 final double arrayIm[]=new double[N];
522                 arrayRe[0]=vectorRe[0]/x;
523                 arrayIm[0]=vectorIm[0]/x;
524                 for(int i=1;i<N;i++) {
525                         arrayRe[i]=vectorRe[i]/x;
526                         arrayIm[i]=vectorIm[i]/x;
527                 }
528                 return new ComplexVector(arrayRe,arrayIm);
529         }
530
531 // SCALAR PRODUCT
532

533         /**
534         * Returns the scalar product of this vector and another.
535         */

536         public Complex scalarProduct(HilbertSpace.Member v) {
537                 if(v instanceof ComplexVector)
538                         return scalarProduct((ComplexVector)v);
539                 else
540                         throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
541         }
542         /**
543         * Returns the scalar product of this vector and another.
544         * @param v a complex vector
545         * @exception VectorDimensionException If the vectors are different sizes.
546         */

547         public Complex scalarProduct(final AbstractComplexVector v) {
548                 if(v instanceof ComplexVector)
549                         return rawScalarProduct((ComplexVector)v);
550                 else {
551                         if(N==v.N) {
552                                 Complex comp=v.getComponent(0);
553                                 double real=vectorRe[0]*comp.real()+vectorIm[0]*comp.imag();
554                                 double imag=vectorIm[0]*comp.real()-vectorRe[0]*comp.imag();
555                                 for(int i=1;i<N;i++) {
556                                         comp=v.getComponent(i);
557                                         real+=vectorRe[i]*comp.real()+vectorIm[i]*comp.imag();
558                                         imag+=vectorIm[i]*comp.real()-vectorRe[i]*comp.imag();
559                                 }
560                                 return new Complex(real,imag);
561                         } else
562                                 throw new VectorDimensionException("Vectors are different sizes.");
563                 }
564         }
565         private Complex rawScalarProduct(final ComplexVector v) {
566                 if(N==v.N) {
567                         double real=vectorRe[0]*v.vectorRe[0]+vectorIm[0]*v.vectorIm[0];
568                         double imag=vectorIm[0]*v.vectorRe[0]-vectorRe[0]*v.vectorIm[0];
569                         for(int i=1;i<N;i++) {
570                                 real+=vectorRe[i]*v.vectorRe[i]+vectorIm[i]*v.vectorIm[i];
571                                 imag+=vectorIm[i]*v.vectorRe[i]-vectorRe[i]*v.vectorIm[i];
572                         }
573                         return new Complex(real,imag);
574                 } else
575                         throw new VectorDimensionException("Vectors are different sizes.");
576         }
577
578 // MAP COMPONENTS
579

580         /**
581         * Applies a function on all the vector components.
582         * @param f a user-defined function
583         * @return a complex vector
584         */

585         public AbstractComplexVector mapComponents(final ComplexMapping f) {
586                 final Complex array[]=new Complex[N];
587                 array[0]=f.map(vectorRe[0],vectorIm[0]);
588                 for(int i=1;i<N;i++)
589                         array[i]=f.map(vectorRe[i],vectorIm[i]);
590                 return new ComplexVector(array);
591         }
592 }
593
594
Popular Tags