001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math3.linear;
018
019 import org.apache.commons.math3.Field;
020 import org.apache.commons.math3.FieldElement;
021 import org.apache.commons.math3.util.OpenIntToFieldHashMap;
022
023 /**
024 * Sparse matrix implementation based on an open addressed map.
025 *
026 * @param <T> the type of the field elements
027 * @version $Id: SparseFieldMatrix.java 1416643 2012-12-03 19:37:14Z tn $
028 * @since 2.0
029 * @deprecated As of version 3.1, this class is deprecated, for reasons exposed
030 * in this JIRA
031 * <a href="https://issues.apache.org/jira/browse/MATH-870">ticket</a>. This
032 * class will be removed in version 4.0.
033 *
034 */
035 @Deprecated
036 public class SparseFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> {
037
038 /** Storage for (sparse) matrix elements. */
039 private final OpenIntToFieldHashMap<T> entries;
040 /** Row dimension. */
041 private final int rows;
042 /** Column dimension. */
043 private final int columns;
044
045 /**
046 * Create a matrix with no data.
047 *
048 * @param field Field to which the elements belong.
049 */
050 public SparseFieldMatrix(final Field<T> field) {
051 super(field);
052 rows = 0;
053 columns= 0;
054 entries = new OpenIntToFieldHashMap<T>(field);
055 }
056
057 /**
058 * Create a new SparseFieldMatrix<T> with the supplied row and column
059 * dimensions.
060 *
061 * @param field Field to which the elements belong.
062 * @param rowDimension Number of rows in the new matrix.
063 * @param columnDimension Number of columns in the new matrix.
064 * @throws org.apache.commons.math3.exception.NotStrictlyPositiveException
065 * if row or column dimension is not positive.
066 */
067 public SparseFieldMatrix(final Field<T> field,
068 final int rowDimension, final int columnDimension) {
069 super(field, rowDimension, columnDimension);
070 this.rows = rowDimension;
071 this.columns = columnDimension;
072 entries = new OpenIntToFieldHashMap<T>(field);
073 }
074
075 /**
076 * Copy constructor.
077 *
078 * @param other Instance to copy.
079 */
080 public SparseFieldMatrix(SparseFieldMatrix<T> other) {
081 super(other.getField(), other.getRowDimension(), other.getColumnDimension());
082 rows = other.getRowDimension();
083 columns = other.getColumnDimension();
084 entries = new OpenIntToFieldHashMap<T>(other.entries);
085 }
086
087 /**
088 * Generic copy constructor.
089 *
090 * @param other Instance to copy.
091 */
092 public SparseFieldMatrix(FieldMatrix<T> other){
093 super(other.getField(), other.getRowDimension(), other.getColumnDimension());
094 rows = other.getRowDimension();
095 columns = other.getColumnDimension();
096 entries = new OpenIntToFieldHashMap<T>(getField());
097 for (int i = 0; i < rows; i++) {
098 for (int j = 0; j < columns; j++) {
099 setEntry(i, j, other.getEntry(i, j));
100 }
101 }
102 }
103
104 /** {@inheritDoc} */
105 @Override
106 public void addToEntry(int row, int column, T increment) {
107 checkRowIndex(row);
108 checkColumnIndex(column);
109 final int key = computeKey(row, column);
110 final T value = entries.get(key).add(increment);
111 if (getField().getZero().equals(value)) {
112 entries.remove(key);
113 } else {
114 entries.put(key, value);
115 }
116 }
117
118 /** {@inheritDoc} */
119 @Override
120 public FieldMatrix<T> copy() {
121 return new SparseFieldMatrix<T>(this);
122 }
123
124 /** {@inheritDoc} */
125 @Override
126 public FieldMatrix<T> createMatrix(int rowDimension, int columnDimension) {
127 return new SparseFieldMatrix<T>(getField(), rowDimension, columnDimension);
128 }
129
130 /** {@inheritDoc} */
131 @Override
132 public int getColumnDimension() {
133 return columns;
134 }
135
136 /** {@inheritDoc} */
137 @Override
138 public T getEntry(int row, int column) {
139 checkRowIndex(row);
140 checkColumnIndex(column);
141 return entries.get(computeKey(row, column));
142 }
143
144 /** {@inheritDoc} */
145 @Override
146 public int getRowDimension() {
147 return rows;
148 }
149
150 /** {@inheritDoc} */
151 @Override
152 public void multiplyEntry(int row, int column, T factor) {
153 checkRowIndex(row);
154 checkColumnIndex(column);
155 final int key = computeKey(row, column);
156 final T value = entries.get(key).multiply(factor);
157 if (getField().getZero().equals(value)) {
158 entries.remove(key);
159 } else {
160 entries.put(key, value);
161 }
162
163 }
164
165 /** {@inheritDoc} */
166 @Override
167 public void setEntry(int row, int column, T value) {
168 checkRowIndex(row);
169 checkColumnIndex(column);
170 if (getField().getZero().equals(value)) {
171 entries.remove(computeKey(row, column));
172 } else {
173 entries.put(computeKey(row, column), value);
174 }
175 }
176
177 /**
178 * Compute the key to access a matrix element.
179 *
180 * @param row Row index of the matrix element.
181 * @param column Column index of the matrix element.
182 * @return the key within the map to access the matrix element.
183 */
184 private int computeKey(int row, int column) {
185 return row * columns + column;
186 }
187 }