/*
 * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
 * Copyright (C) 2006 - JScience (http://jscience.org/)
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software is
 * freely granted, provided that this notice is preserved.
 */
package org.jscience.mathematics.vector;

import java.util.Iterator;
import java.util.List;
import javolution.context.ArrayFactory;
import javolution.xml.XMLFormat;
import javolution.xml.stream.XMLStreamException;

import org.jscience.mathematics.number.Complex;
import org.jscience.mathematics.structure.VectorSpaceNormed;

/**
 * 

This class represents an optimized {@link Vector vector} implementation * for {@link Complex complex} numbers elements.

* * @author Jean-Marie Dautelle * @version 3.3, January 2, 2007 */ public final class ComplexVector extends Vector implements VectorSpaceNormed, Complex> { /** * Holds the default XML representation. For example: * [code] * * * * [/code] */ protected static final XMLFormat XML = new XMLFormat( ComplexVector.class) { @Override public ComplexVector newInstance(Class cls, InputElement xml) throws XMLStreamException { int dimension = xml.getAttribute("dimension", 0); ComplexVector V = FACTORY.array(dimension); V._dimension = dimension; return V; } @SuppressWarnings("unchecked") @Override public void read(InputElement xml, ComplexVector V) throws XMLStreamException { for (int i = 0, n = V._dimension; i < n;) { V._reals[i++] = ((Complex) xml.getNext()).doubleValue(); } if (xml.hasNext()) throw new XMLStreamException("Too many elements"); } @Override public void write(ComplexVector V, OutputElement xml) throws XMLStreamException { xml.setAttribute("dimension", V._dimension); for (int i = 0, n = V._dimension; i < n;) { xml.add(V.get(i++)); } } }; /** * Holds factory for vectors with variable size arrays. */ private static final ArrayFactory FACTORY = new ArrayFactory() { @Override protected ComplexVector create(int capacity) { return new ComplexVector(capacity); } }; /** * Holds the dimension. */ private int _dimension; /** * Holds the real values. */ private final double[] _reals; /** * Holds the imaginary values. */ private double[] _imags; /** * Creates a vector of specified capacity. */ private ComplexVector(int capacity) { _reals = new double[capacity]; _imags = new double[capacity]; } /** * Returns a new vector holding the specified complex numbers. * * @param elements the complex numbers elements. * @return the vector having the specified complex numbers. */ public static ComplexVector valueOf(Complex... elements) { int n = elements.length; ComplexVector V = FACTORY.array(n); V._dimension = n; for (int i = 0; i < n; i++) { Complex complex = elements[i]; V._reals[i] = complex.getReal(); V._imags[i] = complex.getImaginary(); } return V; } /** * Returns a new vector holding the elements from the specified * collection. * * @param elements the collection of floating-points numbers. * @return the vector having the specified elements. */ public static ComplexVector valueOf(List elements) { int n = elements.size(); ComplexVector V = FACTORY.array(n); V._dimension = n; Iterator iterator = elements.iterator(); for (int i = 0; i < n; i++) { Complex complex = iterator.next(); V._reals[i] = complex.getReal(); V._imags[i] = complex.getImaginary(); } return V; } /** * Returns a {@link ComplexVector} instance equivalent to the * specified vector. * * @param that the vector to convert. * @return that or new equivalent ComplexVector. */ public static ComplexVector valueOf(Vector that) { if (that instanceof ComplexVector) return (ComplexVector) that; int n = that.getDimension(); ComplexVector V = FACTORY.array(n); V._dimension = n; for (int i = 0; i < n; i++) { Complex complex = that.get(i); V._reals[i] = complex.getReal(); V._imags[i] = complex.getImaginary(); } return V; } /** * Returns the real value of a complex number from this vector (fast). * * @param i the complex number index. * @return the real value of complex at i. * @throws IndexOutOfBoundsException (i < 0) || (i >= dimension()) */ public double getReal(int i) { if (i >= _dimension) throw new ArrayIndexOutOfBoundsException(); return _reals[i]; } /** * Returns the imaginary value of a complex number from this vector (fast). * * @param i the complex number index. * @return the real value of complex at i. * @throws IndexOutOfBoundsException (i < 0) || (i >= dimension()) */ public double getImaginary(int i) { if (i >= _dimension) throw new ArrayIndexOutOfBoundsException(); return _imags[i]; } /** * Returns the Euclidian norm of this vector (square root of the * dot product of this vector and itself). * * @return sqrt(this ยท this). */ public Complex norm() { double normSquaredReal = 0; double normSquaredImag = 0; for (int i = _dimension; --i >= 0;) { double real = _reals[i]; double imag = _imags[i]; normSquaredReal += real * real - imag * imag; normSquaredImag += real * imag * 2.0; } return Complex.valueOf(normSquaredReal, normSquaredImag).sqrt(); } @Override public int getDimension() { return _dimension; } @Override public Complex get(int i) { if (i >= _dimension) throw new IndexOutOfBoundsException(); return Complex.valueOf(_reals[i], _imags[i]); } @Override public ComplexVector opposite() { ComplexVector V = FACTORY.array(_dimension); V._dimension = _dimension; for (int i = 0; i < _dimension; i++) { V._reals[i] = -_reals[i]; V._imags[i] = -_imags[i]; } return V; } @Override public ComplexVector plus(Vector that) { ComplexVector T = ComplexVector.valueOf(that); if (T._dimension != _dimension) throw new DimensionException(); ComplexVector V = FACTORY.array(_dimension); V._dimension = _dimension; for (int i = 0; i < _dimension; i++) { V._reals[i] = _reals[i] + T._reals[i]; V._imags[i] = _imags[i] + T._imags[i]; } return V; } @Override public ComplexVector minus(Vector that) { ComplexVector T = ComplexVector.valueOf(that); if (T._dimension != _dimension) throw new DimensionException(); ComplexVector V = FACTORY.array(_dimension); V._dimension = _dimension; for (int i = 0; i < _dimension; i++) { V._reals[i] = _reals[i] - T._reals[i]; V._imags[i] = _imags[i] - T._imags[i]; } return V; } @Override public ComplexVector times(Complex k) { ComplexVector V = FACTORY.array(_dimension); V._dimension = _dimension; for (int i = 0; i < _dimension; i++) { double real = _reals[i]; double imag = _imags[i]; V._reals[i] = real * k.getReal() - imag * k.getImaginary(); V._imags[i] = real * k.getImaginary() + imag * k.getReal(); } return V; } @Override public Complex times(Vector that) { ComplexVector T = ComplexVector.valueOf(that); if (T._dimension != _dimension) throw new DimensionException(); double sumReal = _reals[0] * T._reals[0] - _imags[0] * T._imags[0]; double sumImag = _reals[0] * T._imags[0] + _imags[0] * T._reals[0]; for (int i = 1; i < _dimension; i++) { sumReal += _reals[i] * T._reals[i] - _imags[i] * T._imags[i]; sumImag += _reals[i] * T._imags[i] + _imags[i] * T._reals[i]; } return Complex.valueOf(sumReal, sumImag); } @Override public ComplexVector copy() { ComplexVector V = FACTORY.array(_dimension); V._dimension = _dimension; for (int i = 0; i < _dimension; i++) { V._reals[i] = _reals[i]; V._imags[i] = _imags[i]; } return V; } /////////////////////////////// // Package Private Utilities // /////////////////////////////// void set(int i, Complex c) { _reals[i] = c.getReal(); _imags[i] = c.getImaginary(); } static ComplexVector newInstance(int n) { ComplexVector V = FACTORY.array(n); V._dimension = n; return V; } private static final long serialVersionUID = 1L; }

Ads help maintain this website.