Statistiques
| Révision :

root / tmp / org.txm.analec.rcp / src matt / JamaPlus / SparseMatrix.java @ 1215

Historique | Voir | Annoter | Télécharger (7,71 ko)

1 481 mdecorde
/*
2 481 mdecorde
 * To change this template, choose Tools | Templates
3 481 mdecorde
 * and open the template in the editor.
4 481 mdecorde
 */
5 481 mdecorde
package JamaPlus;
6 481 mdecorde
7 481 mdecorde
import JamaPlus.SparseSVD.SparseSVDException;
8 481 mdecorde
import java.util.*;
9 481 mdecorde
import java.util.logging.Level;
10 481 mdecorde
import java.util.logging.Logger;
11 481 mdecorde
12 481 mdecorde
/**
13 481 mdecorde
 *
14 481 mdecorde
 * @author Bernard Victorri
15 481 mdecorde
 */
16 481 mdecorde
public class SparseMatrix {
17 481 mdecorde
  private int m, n, nnz;
18 481 mdecorde
  private int[] colpts, rowinds;
19 481 mdecorde
  private double[] vals;
20 481 mdecorde
  private double[] tempRow;  // stockage temporaire pour certains calculs (opb)
21 481 mdecorde
22 481 mdecorde
  public SparseMatrix(int m, int n) { // null matrix
23 481 mdecorde
    this.m = m;
24 481 mdecorde
    this.n = n;
25 481 mdecorde
    nnz = 0;
26 481 mdecorde
    colpts = new int[n+1];
27 481 mdecorde
    rowinds = new int[0];
28 481 mdecorde
    vals = new double[0];
29 481 mdecorde
  }
30 481 mdecorde
31 481 mdecorde
   private static class Triple implements Comparable<Triple> {
32 481 mdecorde
    int row;
33 481 mdecorde
    int col;
34 481 mdecorde
    double val;
35 481 mdecorde
36 481 mdecorde
    private Triple(int row, int col, double val) {
37 481 mdecorde
      this.row = row;
38 481 mdecorde
      this.col = col;
39 481 mdecorde
      this.val = val;
40 481 mdecorde
    }
41 481 mdecorde
    private Triple(int row, int col) {
42 481 mdecorde
      this.row = row;
43 481 mdecorde
      this.col = col;
44 481 mdecorde
    }
45 481 mdecorde
    public int compareTo(Triple t) {
46 481 mdecorde
      int res = col - t.col;
47 481 mdecorde
      if(res==0) res = row - t.row;
48 481 mdecorde
      return res;
49 481 mdecorde
    }
50 481 mdecorde
  }
51 481 mdecorde
52 481 mdecorde
 public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
53 481 mdecorde
          ArrayList<Double> values) {
54 481 mdecorde
    this.m = m;
55 481 mdecorde
    this.n = n;
56 481 mdecorde
    nnz = rows.size();
57 481 mdecorde
    if (nnz!=cols.size()||nnz!=rows.size())
58 481 mdecorde
      throw new ArrayIndexOutOfBoundsException(
59 481 mdecorde
              "Size of lines, cols and values don't agree");
60 481 mdecorde
    colpts = new int[n+1];
61 481 mdecorde
    rowinds = new int[nnz];
62 481 mdecorde
    vals = new double[nnz];
63 481 mdecorde
    Triple[] triples = new Triple[nnz];
64 481 mdecorde
    for(int i=0; i<nnz; i++)
65 481 mdecorde
     triples[i] = new Triple(rows.get(i), cols.get(i), values.get(i));
66 481 mdecorde
    Arrays.sort(triples);
67 481 mdecorde
    colpts[0] = 0;
68 481 mdecorde
    int c = 0;
69 481 mdecorde
    for(int i=0; i<nnz; i++) {
70 481 mdecorde
      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col)
71 481 mdecorde
        throw new ArrayIndexOutOfBoundsException(
72 481 mdecorde
              "Two values with same row and column numbers");
73 481 mdecorde
      while(c<triples[i].col) colpts[++c] = i;
74 481 mdecorde
      rowinds[i] = triples[i].row;
75 481 mdecorde
      vals[i] = triples[i].val;
76 481 mdecorde
    }
77 481 mdecorde
    while(c<n) colpts[++c] = nnz;
78 481 mdecorde
  }
79 481 mdecorde
80 481 mdecorde
public SparseMatrix(int m, int n, ArrayList<Integer> rows, ArrayList<Integer> cols,
81 481 mdecorde
          double value) {
82 481 mdecorde
    this.m = m;
83 481 mdecorde
    this.n = n;
84 481 mdecorde
    nnz = rows.size();
85 481 mdecorde
    if (nnz!=cols.size()||nnz!=rows.size())
86 481 mdecorde
      throw new ArrayIndexOutOfBoundsException(
87 481 mdecorde
              "Size of lines, cols and values don't agree");
88 481 mdecorde
    colpts = new int[n+1];
89 481 mdecorde
    rowinds = new int[nnz];
90 481 mdecorde
        vals = new double[nnz];
91 481 mdecorde
    Triple[] triples = new Triple[nnz];
92 481 mdecorde
    for(int i=0; i<nnz; i++)
93 481 mdecorde
     triples[i] = new Triple(rows.get(i), cols.get(i));
94 481 mdecorde
    Arrays.sort(triples);
95 481 mdecorde
    colpts[0] = 0;
96 481 mdecorde
    int c = 0;
97 481 mdecorde
    for(int i=0; i<nnz; i++) {
98 481 mdecorde
      if(i>0 && triples[i].row == triples[i-1].row && triples[i].col == triples[i-1].col)
99 481 mdecorde
        throw new ArrayIndexOutOfBoundsException(
100 481 mdecorde
              "Two values with same row and column numbers");
101 481 mdecorde
      while(c<triples[i].col) colpts[++c] = i;
102 481 mdecorde
      rowinds[i] = triples[i].row;
103 481 mdecorde
      vals[i] = value;
104 481 mdecorde
    }
105 481 mdecorde
    while(c<n) colpts[++c] = nnz;
106 481 mdecorde
  }
107 481 mdecorde
108 481 mdecorde
  private SparseMatrix(int m, int n, int nnz, int[] colpts, int[] rowinds, double[] vals) {
109 481 mdecorde
    this.m = m;
110 481 mdecorde
    this.n = n;
111 481 mdecorde
    this.nnz = nnz;
112 481 mdecorde
    this.colpts = colpts;
113 481 mdecorde
    this.rowinds = rowinds;
114 481 mdecorde
    this.vals = vals;
115 481 mdecorde
  }
116 481 mdecorde
117 481 mdecorde
  public SparseMatrix(Matrix mat) {  // convert a dense matrix
118 481 mdecorde
    m = mat.getRowDimension();
119 481 mdecorde
    n = mat.getColumnDimension();
120 481 mdecorde
    long nbval = mat.getNumberNonZeroValues();
121 481 mdecorde
    if (nbval>Integer.MAX_VALUE) throw new ArrayIndexOutOfBoundsException(
122 481 mdecorde
              "Number of non-zero values exceeds 32 bits integer");
123 481 mdecorde
    nnz = (int) nbval;
124 481 mdecorde
    colpts = new int[n+1];
125 481 mdecorde
    rowinds = new int[nnz];
126 481 mdecorde
    vals = new double[nnz];
127 481 mdecorde
    int nval = 0;
128 481 mdecorde
    for (int j = 0; j<n; j++) {
129 481 mdecorde
      colpts[j] = nval;
130 481 mdecorde
      for (int i = 0; i<m; i++) if (mat.get(i, j)!=0) {
131 481 mdecorde
          rowinds[nval] = i;
132 481 mdecorde
          vals[nval++] = mat.get(i, j);
133 481 mdecorde
        }
134 481 mdecorde
    }
135 481 mdecorde
    colpts[n] = nnz;
136 481 mdecorde
  }
137 481 mdecorde
138 481 mdecorde
  public SparseMatrix copy() {
139 481 mdecorde
    int[] colpts1 = new int[n+1];
140 481 mdecorde
    int[] rowinds1 = new int[nnz];
141 481 mdecorde
    double[] vals1 = new double[nnz];
142 481 mdecorde
    System.arraycopy(colpts, 0, colpts1, 0, n+1);
143 481 mdecorde
    System.arraycopy(rowinds, 0, rowinds1, 0, nnz);
144 481 mdecorde
    System.arraycopy(vals, 0, vals1, 0, nnz);
145 481 mdecorde
    return new SparseMatrix(m, n, nnz, colpts1, rowinds1, vals1);
146 481 mdecorde
  }
147 481 mdecorde
148 481 mdecorde
  public int getRowDimension() {
149 481 mdecorde
    return m;
150 481 mdecorde
  }
151 481 mdecorde
152 481 mdecorde
  public int getColumnDimension() {
153 481 mdecorde
    return n;
154 481 mdecorde
  }
155 481 mdecorde
156 481 mdecorde
  public double get(int i, int j) {
157 481 mdecorde
    try {
158 481 mdecorde
      for (int nval = colpts[j]; nval<colpts[j+1]; nval++)
159 481 mdecorde
        if (rowinds[nval]==i) return vals[nval];
160 481 mdecorde
      return 0;
161 481 mdecorde
    } catch (ArrayIndexOutOfBoundsException ex) {
162 481 mdecorde
      throw new ArrayIndexOutOfBoundsException("Sparse matrix : "
163 481 mdecorde
              +ex.getLocalizedMessage());
164 481 mdecorde
    }
165 481 mdecorde
  }
166 481 mdecorde
167 481 mdecorde
  public SparseMatrix transpose() {
168 481 mdecorde
    int[] colpts1 = new int[m+1];
169 481 mdecorde
    int[] rowinds1 = new int[nnz];
170 481 mdecorde
    double[] vals1 = new double[nnz];
171 481 mdecorde
    for (int v = 0; v<nnz; v++) colpts1[rowinds[v]]++;  // nnz in each row
172 481 mdecorde
    colpts1[m] = nnz-colpts1[m-1];
173 481 mdecorde
    for (int r = m-1; r>0; r--)
174 481 mdecorde
      colpts1[r] = colpts1[r+1]-colpts1[r-1]; // starting point of the previous row
175 481 mdecorde
    colpts1[0] = 0;
176 481 mdecorde
    int i = 0;
177 481 mdecorde
    for (int c = 0; c<n; c++) while (i<colpts[c+1]) {
178 481 mdecorde
        int j = colpts1[rowinds[i]+1]++;  // j : index of the value in the new vectors
179 481 mdecorde
        rowinds1[j] = c;
180 481 mdecorde
        vals1[j] = vals[i++];
181 481 mdecorde
      }
182 481 mdecorde
    return new SparseMatrix(n, m, nnz, colpts1, rowinds1, vals1);
183 481 mdecorde
  }
184 481 mdecorde
185 481 mdecorde
  public void nulColumnSuppression() {
186 481 mdecorde
    ArrayList<Integer> colpts1 = new ArrayList<Integer>();
187 481 mdecorde
    colpts1.add(0);
188 481 mdecorde
    for (int i = 0; i<n; i++) if (colpts[i+1]>colpts[i])
189 481 mdecorde
        colpts1.add(colpts[i+1]);
190 481 mdecorde
    n = colpts1.size()-1;
191 481 mdecorde
    colpts = new int[n+1];
192 481 mdecorde
    for (int i = 0; i<=n; i++) colpts[i] = colpts1.get(i);
193 481 mdecorde
  }
194 481 mdecorde
195 481 mdecorde
  public double elementSum() {
196 481 mdecorde
    double s = 0;
197 481 mdecorde
    for (int i = 0; i<nnz; i++) s += vals[i];
198 481 mdecorde
199 481 mdecorde
    return s;
200 481 mdecorde
  }
201 481 mdecorde
202 481 mdecorde
  public Matrix lineSum() {
203 481 mdecorde
    double[] S = new double[m];
204 481 mdecorde
    for (int i = 0; i<nnz; i++) S[rowinds[i]] += vals[i];
205 481 mdecorde
206 481 mdecorde
    return new Matrix(S, m);
207 481 mdecorde
  }
208 481 mdecorde
209 481 mdecorde
  public Matrix columnSum() {
210 481 mdecorde
    double[] S = new double[n];
211 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
212 481 mdecorde
        S[i] += vals[j];
213 481 mdecorde
214 481 mdecorde
    return new Matrix(S, 1);
215 481 mdecorde
  }
216 481 mdecorde
217 481 mdecorde
  public SparseMatrix timesEquals(double s) {
218 481 mdecorde
    for (int i = 0; i<nnz; i++) {
219 481 mdecorde
      vals[i] *= s;
220 481 mdecorde
    }
221 481 mdecorde
    return this;
222 481 mdecorde
  }
223 481 mdecorde
224 481 mdecorde
  public SparseMatrix firstColumnTimesEqual(Matrix B) {
225 481 mdecorde
    double[][] A = B.getArray();
226 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
227 481 mdecorde
        vals[j] *= A[rowinds[j]][0];
228 481 mdecorde
    return this;
229 481 mdecorde
  }
230 481 mdecorde
231 481 mdecorde
  public SparseMatrix firstLineTimesEqual(Matrix B) {
232 481 mdecorde
    double[][] A = B.getArray();
233 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
234 481 mdecorde
        vals[j] *= A[0][i];
235 481 mdecorde
    return this;
236 481 mdecorde
  }
237 481 mdecorde
238 481 mdecorde
  public void opa(double x[], double y[]) {
239 481 mdecorde
    // Computes y = Ax (x et y : length n)
240 481 mdecorde
    Arrays.fill(y, 0);
241 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
242 481 mdecorde
        y[rowinds[j]] += vals[j]*x[i];
243 481 mdecorde
  }
244 481 mdecorde
245 481 mdecorde
  public void opb(double x[], double y[]) {
246 481 mdecorde
    // Computes y = A'Ax (x et y : length n)
247 481 mdecorde
    if (tempRow==null) tempRow = new double[m];
248 481 mdecorde
    else Arrays.fill(tempRow, 0);
249 481 mdecorde
    Arrays.fill(y, 0);
250 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
251 481 mdecorde
        tempRow[rowinds[j]] += vals[j]*x[i];
252 481 mdecorde
    for (int i = 0; i<n; i++) for (int j = colpts[i]; j<colpts[i+1]; j++)
253 481 mdecorde
        y[i] += vals[j]*tempRow[rowinds[j]];
254 481 mdecorde
  }
255 481 mdecorde
256 481 mdecorde
  public SparseSVD svd(int dim) throws SparseSVD.SparseSVDException {
257 481 mdecorde
    return new SparseSVD(this, dim);
258 481 mdecorde
  }
259 481 mdecorde
260 481 mdecorde
  /** Analyse factorielle de correspondances
261 481 mdecorde
  @return     Analyse factorielle de correspondances
262 481 mdecorde
  @see Analyse factorielle de correspondances
263 481 mdecorde
   */
264 481 mdecorde
  public SparseAFC afc() {
265 481 mdecorde
    try {
266 481 mdecorde
      return new SparseAFC(this);
267 481 mdecorde
    } catch (SparseSVDException ex) {
268 481 mdecorde
      return null;
269 481 mdecorde
    }
270 481 mdecorde
  }
271 481 mdecorde
}