1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.linear;
23
24 import org.hipparchus.Field;
25 import org.hipparchus.FieldElement;
26 import org.hipparchus.exception.MathIllegalArgumentException;
27 import org.hipparchus.util.OpenIntToFieldHashMap;
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class SparseFieldMatrix<T extends FieldElement<T>> extends AbstractFieldMatrix<T> {
42
43
44 private final OpenIntToFieldHashMap<T> entries;
45
46 private final int rows;
47
48 private final int columns;
49
50
51
52
53
54
55 public SparseFieldMatrix(final Field<T> field) {
56 super(field);
57 rows = 0;
58 columns= 0;
59 entries = new OpenIntToFieldHashMap<>(field);
60 }
61
62
63
64
65
66
67
68
69
70
71
72 public SparseFieldMatrix(final Field<T> field,
73 final int rowDimension, final int columnDimension) {
74 super(field, rowDimension, columnDimension);
75 this.rows = rowDimension;
76 this.columns = columnDimension;
77 entries = new OpenIntToFieldHashMap<>(field);
78 }
79
80
81
82
83
84
85 public SparseFieldMatrix(SparseFieldMatrix<T> other) {
86 super(other.getField(), other.getRowDimension(), other.getColumnDimension());
87 rows = other.getRowDimension();
88 columns = other.getColumnDimension();
89 entries = new OpenIntToFieldHashMap<>(other.entries);
90 }
91
92
93
94
95
96
97 public SparseFieldMatrix(FieldMatrix<T> other){
98 super(other.getField(), other.getRowDimension(), other.getColumnDimension());
99 rows = other.getRowDimension();
100 columns = other.getColumnDimension();
101 entries = new OpenIntToFieldHashMap<>(getField());
102 for (int i = 0; i < rows; i++) {
103 for (int j = 0; j < columns; j++) {
104 setEntry(i, j, other.getEntry(i, j));
105 }
106 }
107 }
108
109
110 @Override
111 public void addToEntry(int row, int column, T increment) {
112 checkRowIndex(row);
113 checkColumnIndex(column);
114 final int key = computeKey(row, column);
115 final T value = entries.get(key).add(increment);
116 if (getField().getZero().equals(value)) {
117 entries.remove(key);
118 } else {
119 entries.put(key, value);
120 }
121 }
122
123
124 @Override
125 public FieldMatrix<T> copy() {
126 return new SparseFieldMatrix<T>(this);
127 }
128
129
130 @Override
131 public FieldMatrix<T> createMatrix(int rowDimension, int columnDimension) {
132 return new SparseFieldMatrix<T>(getField(), rowDimension, columnDimension);
133 }
134
135
136 @Override
137 public int getColumnDimension() {
138 return columns;
139 }
140
141
142 @Override
143 public T getEntry(int row, int column) {
144 checkRowIndex(row);
145 checkColumnIndex(column);
146 return entries.get(computeKey(row, column));
147 }
148
149
150 @Override
151 public int getRowDimension() {
152 return rows;
153 }
154
155
156 @Override
157 public void multiplyEntry(int row, int column, T factor) {
158 checkRowIndex(row);
159 checkColumnIndex(column);
160 final int key = computeKey(row, column);
161 final T value = entries.get(key).multiply(factor);
162 if (getField().getZero().equals(value)) {
163 entries.remove(key);
164 } else {
165 entries.put(key, value);
166 }
167
168 }
169
170
171 @Override
172 public void setEntry(int row, int column, T value) {
173 checkRowIndex(row);
174 checkColumnIndex(column);
175 if (getField().getZero().equals(value)) {
176 entries.remove(computeKey(row, column));
177 } else {
178 entries.put(computeKey(row, column), value);
179 }
180 }
181
182
183
184
185
186
187
188
189 @Override
190 public FieldMatrix<T> multiplyTransposed(final FieldMatrix<T> m)
191 throws MathIllegalArgumentException {
192
193 MatrixUtils.checkSameColumnDimension(this, m);
194
195 final int outCols = m.getRowDimension();
196 final FieldMatrix<T> out = m.createMatrix(rows, outCols);
197 for (OpenIntToFieldHashMap<T>.Iterator iterator = entries.iterator(); iterator.hasNext();) {
198 iterator.advance();
199 final T value = iterator.value();
200 final int key = iterator.key();
201 final int i = key / columns;
202 final int k = key % columns;
203 for (int j = 0; j < outCols; ++j) {
204 out.addToEntry(i, j, value.multiply(m.getEntry(j, k)));
205 }
206 }
207
208 return out;
209
210 }
211
212
213
214
215
216
217
218
219 @Override
220 public FieldMatrix<T> transposeMultiply(final FieldMatrix<T> m)
221 throws MathIllegalArgumentException {
222
223 MatrixUtils.checkSameRowDimension(this, m);
224
225 final int outCols = m.getColumnDimension();
226 final FieldMatrix<T> out = m.createMatrix(columns, outCols);
227 for (OpenIntToFieldHashMap<T>.Iterator iterator = entries.iterator(); iterator.hasNext();) {
228 iterator.advance();
229 final T value = iterator.value();
230 final int key = iterator.key();
231 final int k = key / columns;
232 final int i = key % columns;
233 for (int j = 0; j < outCols; ++j) {
234 out.addToEntry(i, j, value.multiply(m.getEntry(k, j)));
235 }
236 }
237
238 return out;
239
240 }
241
242
243
244
245
246
247
248
249 private int computeKey(int row, int column) {
250 return row * columns + column;
251 }
252 }