001: /*
002: * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
003: * Copyright (C) 2006 - JScience (http://jscience.org/)
004: * All rights reserved.
005: *
006: * Permission to use, copy, modify, and distribute this software is
007: * freely granted, provided that this notice is preserved.
008: */
009: package org.jscience.mathematics.vector;
010:
011: import java.util.List;
012:
013: import javolution.context.ObjectFactory;
014: import javolution.context.StackContext;
015: import javolution.util.FastTable;
016: import javolution.xml.XMLFormat;
017: import javolution.xml.stream.XMLStreamException;
018:
019: import org.jscience.mathematics.structure.Field;
020:
021: /**
022: * <p> This class represents a dense vector.</p>
023: *
024: * @author <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
025: * @version 3.3, January 2, 2007
026: */
027: public final class DenseVector<F extends Field<F>> extends Vector<F> {
028:
029: /**
030: * Holds the default XML representation for dense vectors. For example:
031: * [code]
032: * <DenseVector dimension="2">
033: * <Rational value="1/3" />
034: * <Rational value="3/5" />
035: * </DenseVector>[/code]
036: */
037: protected static final XMLFormat<DenseVector> XML = new XMLFormat<DenseVector>(
038: DenseVector.class) {
039:
040: @Override
041: public DenseVector newInstance(Class<DenseVector> cls,
042: InputElement xml) throws XMLStreamException {
043: return FACTORY.object();
044: }
045:
046: @SuppressWarnings("unchecked")
047: @Override
048: public void read(InputElement xml, DenseVector V)
049: throws XMLStreamException {
050: int dimension = xml.getAttribute("dimension", 0);
051: for (int i = 0; i < dimension; i++) {
052: V._elements.add(xml.getNext());
053: }
054: if (xml.hasNext())
055: throw new XMLStreamException("Too many elements");
056: }
057:
058: @Override
059: public void write(DenseVector V, OutputElement xml)
060: throws XMLStreamException {
061: int dimension = V._elements.size();
062: xml.setAttribute("dimension", dimension);
063: for (int i = 0; i < dimension;) {
064: xml.add(V._elements.get(i++));
065: }
066: }
067: };
068:
069: /**
070: * Holds the elements.
071: */
072: final FastTable<F> _elements = new FastTable<F>();
073:
074: /**
075: * Returns a dense vector holding the specified elements.
076: *
077: * @param elements the vector elements.
078: * @return the vector having the specified elements.
079: */
080: public static <F extends Field<F>> DenseVector<F> valueOf(
081: F... elements) {
082: DenseVector<F> V = DenseVector.newInstance();
083: for (int i = 0, n = elements.length; i < n;) {
084: V._elements.add(elements[i++]);
085: }
086: return V;
087: }
088:
089: /**
090: * Returns a dense vector holding the elements from the specified
091: * collection.
092: *
093: * @param elements the collection of vector elements.
094: * @return the vector having the specified elements.
095: */
096: public static <F extends Field<F>> DenseVector<F> valueOf(
097: List<F> elements) {
098: DenseVector<F> V = DenseVector.newInstance();
099: V._elements.addAll(elements);
100: return V;
101: }
102:
103: /**
104: * Returns a dense vector equivalent to the specified vector.
105: *
106: * @param that the vector to convert.
107: * @return <code>that</code> or a dense vector holding the same elements
108: * as the specified vector.
109: */
110: public static <F extends Field<F>> DenseVector<F> valueOf(
111: Vector<F> that) {
112: if (that instanceof DenseVector)
113: return (DenseVector<F>) that;
114: DenseVector<F> V = DenseVector.newInstance();
115: for (int i = 0, n = that.getDimension(); i < n;) {
116: V._elements.add(that.get(i++));
117: }
118: return V;
119: }
120:
121: @Override
122: public int getDimension() {
123: return _elements.size();
124: }
125:
126: @Override
127: public F get(int i) {
128: return _elements.get(i);
129: }
130:
131: @Override
132: public DenseVector<F> opposite() {
133: DenseVector<F> V = DenseVector.newInstance();
134: for (int i = 0, n = _elements.size(); i < n;) {
135: V._elements.add(_elements.get(i++).opposite());
136: }
137: return V;
138: }
139:
140: @Override
141: public DenseVector<F> plus(Vector<F> that) {
142: final int n = _elements.size();
143: if (that.getDimension() != n)
144: throw new DimensionException();
145: DenseVector<F> V = DenseVector.newInstance();
146: for (int i = 0; i < n; i++) {
147: V._elements.add(_elements.get(i).plus(that.get(i)));
148: }
149: return V;
150: }
151:
152: @Override
153: public DenseVector<F> minus(Vector<F> that) { // Returns more specialized type.
154: return this .plus(that.opposite());
155: }
156:
157: @Override
158: public DenseVector<F> times(F k) {
159: DenseVector<F> V = DenseVector.newInstance();
160: for (int i = 0, n = _elements.size(); i < n;) {
161: V._elements.add(_elements.get(i++).times(k));
162: }
163: return V;
164: }
165:
166: @Override
167: public F times(Vector<F> that) {
168: final int n = _elements.size();
169: if (that.getDimension() != n)
170: throw new DimensionException();
171: StackContext.enter();
172: try { // Reduces memory allocation / garbage collection.
173: F sum = _elements.get(0).times(that.get(0));
174: for (int i = 1; i < n; i++) {
175: sum = sum.plus(_elements.get(i).times(that.get(i)));
176: }
177: return StackContext.outerCopy(sum);
178: } finally {
179: StackContext.exit();
180: }
181: }
182:
183: @SuppressWarnings("unchecked")
184: @Override
185: public DenseVector<F> copy() {
186: DenseVector<F> V = DenseVector.newInstance();
187: for (F e : _elements) {
188: V._elements.add((F) e.copy());
189: }
190: return V;
191: }
192:
193: ///////////////////////
194: // Factory creation. //
195: ///////////////////////
196:
197: @SuppressWarnings("unchecked")
198: static <F extends Field<F>> DenseVector<F> newInstance() {
199: return FACTORY.object();
200: }
201:
202: private static final ObjectFactory<DenseVector> FACTORY = new ObjectFactory<DenseVector>() {
203: @Override
204: protected DenseVector create() {
205: return new DenseVector();
206: }
207:
208: @Override
209: protected void cleanup(DenseVector vector) {
210: vector._elements.reset();
211: }
212: };
213:
214: private DenseVector() {
215: }
216:
217: private static final long serialVersionUID = 1L;
218:
219: }
|