Adding sparse field implememtations
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@771132 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
efaead82f7
commit
f479cc70b8
|
@ -0,0 +1,189 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.commons.math.linear;
|
||||||
|
|
||||||
|
import org.apache.commons.math.Field;
|
||||||
|
import org.apache.commons.math.FieldElement;
|
||||||
|
import org.apache.commons.math.util.OpenIntToFieldHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sparse matrix implementation based on an open addressed map.
|
||||||
|
*
|
||||||
|
* @version $Revision: 762117 $ $Date: 2009-04-05 09:53:35 -0700 (Sun, 05 Apr 2009) $
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class SparseFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> {
|
||||||
|
/**
|
||||||
|
* Serial id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 9078068119297757342L;
|
||||||
|
/** Storage for (sparse) matrix elements. */
|
||||||
|
private final OpenIntToFieldHashMap<T> entries;
|
||||||
|
/**
|
||||||
|
* row dimension
|
||||||
|
*/
|
||||||
|
private final int rowDimension;
|
||||||
|
/**
|
||||||
|
* column dimension
|
||||||
|
*/
|
||||||
|
private final int columnDimension;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a matrix with no data
|
||||||
|
* @param field field to which the elements belong
|
||||||
|
*/
|
||||||
|
public SparseFieldMatrix(final Field<T> field) {
|
||||||
|
super(field);
|
||||||
|
rowDimension = 0;
|
||||||
|
columnDimension= 0;
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SparseFieldMatrix<T> with the supplied row and column dimensions.
|
||||||
|
*
|
||||||
|
* @param field field to which the elements belong
|
||||||
|
* @param rowDimension the number of rows in the new matrix
|
||||||
|
* @param columnDimension the number of columns in the new matrix
|
||||||
|
* @throws IllegalArgumentException if row or column dimension is not positive
|
||||||
|
*/
|
||||||
|
public SparseFieldMatrix(final Field<T> field,
|
||||||
|
final int rowDimension, final int columnDimension)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
super(field, rowDimension, columnDimension);
|
||||||
|
this.rowDimension = rowDimension;
|
||||||
|
this.columnDimension = columnDimension;
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy construtor.
|
||||||
|
* @param other The instance to copy
|
||||||
|
*/
|
||||||
|
public SparseFieldMatrix(SparseFieldMatrix<T> other){
|
||||||
|
super(other.getField(), other.getRowDimension(), other.getColumnDimension());
|
||||||
|
rowDimension = other.getRowDimension();
|
||||||
|
columnDimension = other.getColumnDimension();
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(other.entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic copy construtor.
|
||||||
|
* @param other The instance to copy
|
||||||
|
*/
|
||||||
|
public SparseFieldMatrix(FieldMatrix<T> other){
|
||||||
|
super(other.getField(), other.getRowDimension(), other.getColumnDimension());
|
||||||
|
rowDimension = other.getRowDimension();
|
||||||
|
columnDimension = other.getColumnDimension();
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(getField());
|
||||||
|
for(int i=0; i < rowDimension; i++){
|
||||||
|
for(int j=0; j < columnDimension; j++){
|
||||||
|
setEntry(i, j, other.getEntry(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void addToEntry(int row, int column, T increment)
|
||||||
|
throws MatrixIndexException {
|
||||||
|
checkRowIndex(row);
|
||||||
|
checkColumnIndex(column);
|
||||||
|
final int key = computeKey(row, column);
|
||||||
|
final T value = entries.get(key).add(increment);
|
||||||
|
if (getField().getZero().equals(value)) {
|
||||||
|
entries.remove(key);
|
||||||
|
} else {
|
||||||
|
entries.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public FieldMatrix<T> copy() {
|
||||||
|
return new SparseFieldMatrix<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public FieldMatrix<T> createMatrix(int rowDimension, int columnDimension)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
return new SparseFieldMatrix<T>(getField(), rowDimension, columnDimension);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public int getColumnDimension() {
|
||||||
|
return columnDimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public T getEntry(int row, int column) throws MatrixIndexException {
|
||||||
|
checkRowIndex(row);
|
||||||
|
checkColumnIndex(column);
|
||||||
|
return entries.get(computeKey(row, column));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public int getRowDimension() {
|
||||||
|
return rowDimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void multiplyEntry(int row, int column, T factor)
|
||||||
|
throws MatrixIndexException {
|
||||||
|
checkRowIndex(row);
|
||||||
|
checkColumnIndex(column);
|
||||||
|
final int key = computeKey(row, column);
|
||||||
|
final T value = entries.get(key).multiply(factor);
|
||||||
|
if (getField().getZero().equals(value)) {
|
||||||
|
entries.remove(key);
|
||||||
|
} else {
|
||||||
|
entries.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public void setEntry(int row, int column, T value)
|
||||||
|
throws MatrixIndexException {
|
||||||
|
checkRowIndex(row);
|
||||||
|
checkColumnIndex(column);
|
||||||
|
if (getField().getZero().equals(value)) {
|
||||||
|
entries.remove(computeKey(row, column));
|
||||||
|
} else {
|
||||||
|
entries.put(computeKey(row, column), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compute the key to access a matrix element
|
||||||
|
* @param row row index of the matrix element
|
||||||
|
* @param column column index of the matrix element
|
||||||
|
* @return key within the map to access the matrix element
|
||||||
|
*/
|
||||||
|
private int computeKey(int row, int column) {
|
||||||
|
return row * columnDimension + column;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,585 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.commons.math.linear;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
|
import org.apache.commons.math.Field;
|
||||||
|
import org.apache.commons.math.FieldElement;
|
||||||
|
import org.apache.commons.math.MathRuntimeException;
|
||||||
|
import org.apache.commons.math.util.OpenIntToFieldHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implements the {@link FieldVector} interface with a {@link OpenIntToFieldHashMap} backing store.
|
||||||
|
* @version $Revision: 728186 $ $Date: 2009-04-25 12:39:38 -0700 (Sat, 25 Apr 2009) $
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class SparseFieldVector<T extends FieldElement<T>> implements FieldVector<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serial version id
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 7841233292190413362L;
|
||||||
|
/** Field to which the elements belong. */
|
||||||
|
private final Field<T> field;
|
||||||
|
/** Entries of the vector. */
|
||||||
|
private final OpenIntToFieldHashMap<T> entries;
|
||||||
|
/** Dimension of the vector. */
|
||||||
|
private final int virtualSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a 0-length vector.
|
||||||
|
* <p>Zero-length vectors may be used to initialized construction of vectors
|
||||||
|
* by data gathering. We start with zero-length and use either the {@link
|
||||||
|
* #SparseFieldVector(SparseFieldVector<T>, int)} constructor
|
||||||
|
* or one of the <code>append</code> method ({@link #append(Field<T>)}, {@link
|
||||||
|
* #append(Field<T>[])}, {@link #append(FieldVector)}) to gather data
|
||||||
|
* into this vector.</p>
|
||||||
|
*/
|
||||||
|
public SparseFieldVector(Field<T> field) {
|
||||||
|
this(field, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a (dimension)-length vector of zeros.
|
||||||
|
* @param dimension Size of the vector
|
||||||
|
* @param epsilon The tolerance for having a value considered zero
|
||||||
|
*/
|
||||||
|
public SparseFieldVector(Field<T> field, int dimension) {
|
||||||
|
this.field = field;
|
||||||
|
virtualSize = dimension;
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a resized vector, for use with append.
|
||||||
|
* @param v The original vector
|
||||||
|
* @param resize The amount to resize it
|
||||||
|
*/
|
||||||
|
protected SparseFieldVector(SparseFieldVector<T> v, int resize) {
|
||||||
|
field = v.field;
|
||||||
|
virtualSize = v.getDimension() + resize;
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(v.entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a vector with known the sparseness (for advanced use only).
|
||||||
|
* @param dimension The size of the vector
|
||||||
|
* @param expectedSize The expected number of non-zero entries
|
||||||
|
* @param epsilon The tolerance for having a value considered zero
|
||||||
|
*/
|
||||||
|
public SparseFieldVector(Field<T> field, int dimension, int expectedSize) {
|
||||||
|
this.field = field;
|
||||||
|
virtualSize = dimension;
|
||||||
|
entries = new OpenIntToFieldHashMap<T> (field,expectedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create from a Field array.
|
||||||
|
* Only non-zero entries will be stored
|
||||||
|
* @param values The set of values to create from
|
||||||
|
* @param epsilon The tolerance for having a value considered zero
|
||||||
|
*/
|
||||||
|
public SparseFieldVector(Field<T> field, T[] values) {
|
||||||
|
this.field = field;
|
||||||
|
virtualSize = values.length;
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(field);
|
||||||
|
for (int key = 0; key < values.length; key++) {
|
||||||
|
T value = values[key];
|
||||||
|
entries.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor.
|
||||||
|
* @param v The instance to copy from
|
||||||
|
*/
|
||||||
|
public SparseFieldVector(SparseFieldVector<T> v) {
|
||||||
|
field = v.field;
|
||||||
|
virtualSize = v.getDimension();
|
||||||
|
entries = new OpenIntToFieldHashMap<T>(v.getEntries());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the entries of this instance.
|
||||||
|
* @return entries of this instance
|
||||||
|
*/
|
||||||
|
private OpenIntToFieldHashMap<T> getEntries() {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimzed method to add sparse vectors
|
||||||
|
* @return The sum of <code>this</code> and <code>v</code>
|
||||||
|
* @throws IllegalArgumentException If the dimensions don't match
|
||||||
|
*/
|
||||||
|
public FieldVector<T> add(SparseFieldVector<T> v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
int key = iter.key();
|
||||||
|
T value = iter.value();
|
||||||
|
if (entries.containsKey(key)) {
|
||||||
|
res.setEntry(key, entries.get(key).add(value));
|
||||||
|
} else {
|
||||||
|
res.setEntry(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> add(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(field,getDimension());
|
||||||
|
for (int i = 0; i < v.length; i++) {
|
||||||
|
res.setEntry(i, v[i].add(getEntry(i)));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> append(SparseFieldVector<T> v) {
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this, v.getDimension());
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = v.entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res.setEntry(iter.key() + virtualSize, iter.value());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> append(FieldVector<T> v) {
|
||||||
|
if(v instanceof SparseFieldVector)
|
||||||
|
return append((SparseFieldVector<T>)v);
|
||||||
|
else
|
||||||
|
return append(v.toArray());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> append(T d) {
|
||||||
|
FieldVector<T> res = new SparseFieldVector<T>(this, 1);
|
||||||
|
res.setEntry(virtualSize, d);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> append(T[] a) {
|
||||||
|
FieldVector<T> res = new SparseFieldVector<T>(this, a.length);
|
||||||
|
for (int i = 0; i < a.length; i++) {
|
||||||
|
res.setEntry(i + virtualSize, a[i]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> copy() {
|
||||||
|
return new SparseFieldVector<T>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public T dotProduct(FieldVector<T> v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
T res = field.getZero();
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res = res.add(v.getEntry(iter.key()).multiply(iter.value()));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public T dotProduct(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
T res = field.getZero();
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
int idx = iter.key();
|
||||||
|
T value = field.getZero();
|
||||||
|
if (idx < v.length) {
|
||||||
|
value = v[idx];
|
||||||
|
}
|
||||||
|
res = res.add(value.multiply(iter.value()));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> ebeDivide(FieldVector<T> v)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res.setEntry(iter.key(), iter.value().divide(v.getEntry(iter.key())));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> ebeDivide(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res.setEntry(iter.key(), iter.value().divide(v[iter.key()]));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> ebeMultiply(FieldVector<T> v)throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res.setEntry(iter.key(), iter.value().multiply(v.getEntry(iter.key())));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> ebeMultiply(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = res.entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res.setEntry(iter.key(), iter.value().multiply(v[iter.key()]));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public T[] getData() {
|
||||||
|
T[] res = buildArray(virtualSize);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
res[iter.key()] = iter.value();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public int getDimension() {
|
||||||
|
return virtualSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public T getEntry(int index) throws MatrixIndexException {
|
||||||
|
checkIndex(index);
|
||||||
|
return entries.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public Field<T> getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> getSubVector(int index, int n)
|
||||||
|
throws MatrixIndexException {
|
||||||
|
checkIndex(index);
|
||||||
|
checkIndex(index + n - 1);
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(field,n);
|
||||||
|
int end = index + n;
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
int key = iter.key();
|
||||||
|
if (key >= index && key < end) {
|
||||||
|
res.setEntry(key - index, iter.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapAdd(T d) {
|
||||||
|
return copy().mapAddToSelf(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapAddToSelf(T d) {
|
||||||
|
for (int i = 0; i < virtualSize; i++) {
|
||||||
|
setEntry(i, getEntry(i).add(d));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapDivide(T d) {
|
||||||
|
return copy().mapDivideToSelf(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapDivideToSelf(T d) {
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
entries.put(iter.key(), iter.value().divide(d));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapInv() {
|
||||||
|
return copy().mapInvToSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapInvToSelf() {
|
||||||
|
for (int i = 0; i < virtualSize; i++) {
|
||||||
|
setEntry(i, field.getOne().divide(getEntry(i)));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapMultiply(T d) {
|
||||||
|
return copy().mapMultiplyToSelf(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapMultiplyToSelf(T d) {
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
entries.put(iter.key(), iter.value().multiply(d));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapSubtract(T d) {
|
||||||
|
return copy().mapSubtractToSelf(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> mapSubtractToSelf(T d) {
|
||||||
|
return mapAddToSelf(field.getZero().subtract(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimized method to compute outer product when both vectors are sparse
|
||||||
|
* @param v vector with which outer product should be computed
|
||||||
|
* @return the square matrix outer product between instance and v
|
||||||
|
* @throws IllegalArgumentException if v is not the same size as {@code this}
|
||||||
|
*/
|
||||||
|
public FieldMatrix<T> outerProduct(SparseFieldVector<T> v)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
SparseFieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter2 = v.entries.iterator();
|
||||||
|
while (iter2.hasNext()) {
|
||||||
|
iter2.advance();
|
||||||
|
res.setEntry(iter.key(), iter2.key(), iter.value().multiply(iter2.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldMatrix<T> outerProduct(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
FieldMatrix<T> res = new SparseFieldMatrix<T>(field, virtualSize, virtualSize);
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = entries.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
int row = iter.key();
|
||||||
|
FieldElement<T>value = iter.value();
|
||||||
|
for (int col = 0; col < virtualSize; col++) {
|
||||||
|
res.setEntry(row, col, value.multiply(v[col]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldMatrix<T> outerProduct(FieldVector<T> v)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
if(v instanceof SparseFieldVector)
|
||||||
|
return outerProduct((SparseFieldVector<T>)v);
|
||||||
|
else
|
||||||
|
return outerProduct(v.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldVector<T> projection(FieldVector<T> v)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
return v.mapMultiply(dotProduct(v).divide(v.dotProduct(v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> projection(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
return projection(new SparseFieldVector<T>(field,v));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public void set(T value) {
|
||||||
|
for (int i = 0; i < virtualSize; i++) {
|
||||||
|
setEntry(i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public void setEntry(int index, T value) throws MatrixIndexException {
|
||||||
|
checkIndex(index);
|
||||||
|
entries.put(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public void setSubVector(int index, FieldVector<T> v)
|
||||||
|
throws MatrixIndexException {
|
||||||
|
checkIndex(index);
|
||||||
|
checkIndex(index + v.getDimension() - 1);
|
||||||
|
setSubVector(index, v.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public void setSubVector(int index, T[] v) throws MatrixIndexException {
|
||||||
|
checkIndex(index);
|
||||||
|
checkIndex(index + v.length - 1);
|
||||||
|
for (int i = 0; i < v.length; i++) {
|
||||||
|
setEntry(i + index, v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimized method to subtract SparseRealVectors.
|
||||||
|
* @param v The vector to subtract from <code>this</code>
|
||||||
|
* @return The difference of <code>this</code> and <code>v</code>
|
||||||
|
* @throws IllegalArgumentException If the dimensions don't match
|
||||||
|
*/
|
||||||
|
public SparseFieldVector<T> subtract(SparseFieldVector<T> v) throws IllegalArgumentException{
|
||||||
|
checkVectorDimensions(v.getDimension());
|
||||||
|
SparseFieldVector<T> res = (SparseFieldVector<T>)copy();
|
||||||
|
OpenIntToFieldHashMap<T>.Iterator iter = v.getEntries().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.advance();
|
||||||
|
int key = iter.key();
|
||||||
|
if (entries.containsKey(key)) {
|
||||||
|
res.setEntry(key, entries.get(key).subtract(iter.value()));
|
||||||
|
} else {
|
||||||
|
res.setEntry(key, field.getZero().subtract(iter.value()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> subtract(FieldVector<T> v)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
if(v instanceof SparseFieldVector)
|
||||||
|
return subtract((SparseFieldVector<T>)v);
|
||||||
|
else
|
||||||
|
return subtract(v.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> subtract(T[] v) throws IllegalArgumentException {
|
||||||
|
checkVectorDimensions(v.length);
|
||||||
|
SparseFieldVector<T> res = new SparseFieldVector<T>(this);
|
||||||
|
for (int i = 0; i < v.length; i++) {
|
||||||
|
if (entries.containsKey(i)) {
|
||||||
|
res.setEntry(i, entries.get(i).subtract(v[i]));
|
||||||
|
} else {
|
||||||
|
res.setEntry(i, field.getZero().subtract(v[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public T[] toArray() {
|
||||||
|
return getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an index is valid.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* index to check
|
||||||
|
* @exception MatrixIndexException
|
||||||
|
* if index is not valid
|
||||||
|
*/
|
||||||
|
private void checkIndex(final int index) throws MatrixIndexException {
|
||||||
|
if (index < 0 || index >= getDimension()) {
|
||||||
|
throw new MatrixIndexException(
|
||||||
|
"index {0} out of allowed range [{1}, {2}]",
|
||||||
|
index, 0, getDimension() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if instance dimension is equal to some expected value.
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* expected dimension.
|
||||||
|
* @exception IllegalArgumentException
|
||||||
|
* if the dimension is inconsistent with vector size
|
||||||
|
*/
|
||||||
|
protected void checkVectorDimensions(int n) throws IllegalArgumentException {
|
||||||
|
if (getDimension() != n) {
|
||||||
|
throw MathRuntimeException.createIllegalArgumentException(
|
||||||
|
"vector length mismatch: got {0} but expected {1}",
|
||||||
|
getDimension(), n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
public FieldVector<T> add(FieldVector<T> v) throws IllegalArgumentException {
|
||||||
|
if(v instanceof SparseFieldVector)
|
||||||
|
return add((SparseFieldVector<T>)v);
|
||||||
|
else
|
||||||
|
return add(v.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Build an array of elements.
|
||||||
|
* @param length size of the array to build
|
||||||
|
* @return a new array
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private T[] buildArray(final int length) {
|
||||||
|
return (T[]) Array.newInstance(field.getZero().getClass(), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ public class SparseRealMatrix extends AbstractRealMatrix {
|
||||||
private final int columnDimension;
|
private final int columnDimension;
|
||||||
|
|
||||||
/** Storage for (sparse) matrix elements. */
|
/** Storage for (sparse) matrix elements. */
|
||||||
private OpenIntToDoubleHashMap entries;
|
private final OpenIntToDoubleHashMap entries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a sparse matrix with the supplied row and column dimensions.
|
* Build a sparse matrix with the supplied row and column dimensions.
|
||||||
|
|
|
@ -353,7 +353,7 @@ public class SparseRealVector implements RealVector {
|
||||||
iter.advance();
|
iter.advance();
|
||||||
res.setEntry(iter.key(), iter.value() / v[iter.key()]);
|
res.setEntry(iter.key(), iter.value() / v[iter.key()]);
|
||||||
}
|
}
|
||||||
return null;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|
Loading…
Reference in New Issue