b4e62e2104f220f9a662f7c591e13a6494e6bf2f
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / ScilabBooleanSparse.java
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2011-2011 - DIGITEO - Calixte DENIZET
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
7  * This file is hereby licensed under the terms of the GNU GPL v2.0,
8  * pursuant to article 5.3.4 of the CeCILL v.2.1.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16 package org.scilab.modules.types;
17
18 import java.io.IOException;
19 import java.io.ObjectInput;
20 import java.io.ObjectOutput;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24
25 /**
26  * This class provides a representation on the Scilab Boolean Sparse datatype<br>
27  * <br>
28  * This class is {@link java.io.Serializable} and any modification could impact
29  * load and store of data (Xcos files, Javasci saved data, etc...).<br>
30  * <br>
31  * //TODO Sly : ajouter de la doc
32  *
33  * @see org.scilab.modules.javasci.Scilab
34  */
35 public class ScilabBooleanSparse implements ScilabType {
36
37     private static final long serialVersionUID = 879625048944109684L;
38     private static final ScilabTypeEnum type = ScilabTypeEnum.sci_boolean_sparse;
39
40     private static final int VERSION = 0;
41
42     private int rows;
43     private int cols;
44     private int nbItem;
45     private int[] nbItemRow;
46     private int[] colPos;
47     private String varName;
48
49     /**
50      * Default constructor
51      */
52     public ScilabBooleanSparse() {
53     }
54
55     /**
56      * Constructor with a unique value.
57      *
58      * @param data
59      *            the unique value
60      */
61     public ScilabBooleanSparse(boolean data) {
62         if (data) {
63             nbItem = 1;
64             rows = cols = 1;
65             nbItemRow = new int[] { 1 };
66             colPos = new int[] { 0 };
67         }
68     }
69
70     /**
71      * Constructor
72      *
73      * @param rows
74      *            the number of rows
75      * @param cols
76      *            the number of cols
77      * @param nbItem
78      *            the number of true items
79      * @param nbItemRow
80      *            contains the number of true in each rows
81      * @param colPos
82      *            the column position of each true
83      * @param check
84      *            if true the parameters validity is checked
85      */
86     public ScilabBooleanSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, boolean check) throws ScilabSparseException {
87         this(rows, cols, nbItem, nbItemRow, colPos);
88         if (check) {
89             ScilabSparse.checkValidity(rows, cols, nbItem, nbItemRow, colPos);
90         }
91     }
92
93     /**
94      * Constructor
95      *
96      * @param rows
97      *            the number of rows
98      * @param cols
99      *            the number of cols
100      * @param nbItem
101      *            the number of true items
102      * @param nbItemRow
103      *            contains the number of true in each rows
104      * @param colPos
105      *            the column position of each true
106      */
107     public ScilabBooleanSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos) {
108         this.rows = rows;
109         this.cols = cols;
110         this.nbItem = nbItem;
111         this.nbItemRow = nbItemRow;
112         this.colPos = colPos;
113     }
114
115     /**
116      * Constructor with a matrix of real data.
117      *
118      * @param data
119      *            the data
120      */
121     public ScilabBooleanSparse(boolean[][] data) {
122         if (data.length != 0 && data[0].length != 0) {
123             rows = data.length;
124             cols = data[0].length;
125             nbItemRow = new int[rows];
126             List<Integer> listCol = new ArrayList<Integer>();
127
128             for (int i = 0; i < rows; i++) {
129                 for (int j = 0; j < cols; j++) {
130                     if (data[i][j]) {
131                         ++nbItem;
132                         ++nbItemRow[i];
133                         listCol.add(j);
134                     }
135                 }
136             }
137
138             colPos = new int[listCol.size()];
139             int i = 0;
140             for (Integer c : listCol) {
141                 colPos[i++] = c;
142             }
143         }
144     }
145
146     /**
147      * Constructor
148      *
149      * @param varName
150      *            the variable name
151      * @param rows
152      *            the number of rows
153      * @param cols
154      *            the number of cols
155      * @param nbItem
156      *            the number of true items
157      * @param nbItemRow
158      *            contains the number of true in each rows
159      * @param colPos
160      *            the column position of each true
161      */
162     public ScilabBooleanSparse(String varName, int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos) {
163         this(rows, cols, nbItem, nbItemRow, colPos);
164         this.varName = varName;
165     }
166
167     /**
168      * {@inheritDoc}
169      */
170     public boolean isReference() {
171         return false;
172     }
173
174     /**
175      * Return the type of Scilab
176      *
177      * @return the type of Scilab
178      * @since 5.4.0
179      */
180     @Override
181     public ScilabTypeEnum getType() {
182         return type;
183     }
184
185     /**
186      * Check the emptiness of the associated data.
187      *
188      * @return true, if the associated data array is empty.
189      */
190     @Override
191     public boolean isEmpty() {
192         return rows == 0 && cols == 0;
193     }
194
195     /**
196      * Get the real part of the data.
197      *
198      * @return the real part.
199      */
200     public int getNbNonNullItems() {
201         return nbItem;
202     }
203
204     /**
205      * Set the real part of the data.
206      *
207      * @param nbItem
208      *            the real part.
209      */
210     public void setNbNonNullItems(int nbItem) {
211         this.nbItem = nbItem;
212     }
213
214     /**
215      * Get the real part of the data.
216      *
217      * @return the real part.
218      */
219     public int[] getNbItemRow() {
220         return nbItemRow;
221     }
222
223     /**
224      * Set the real part of the data.
225      *
226      * @param nbItemRow
227      *            the real part.
228      */
229     public void setNbItemRow(int[] nbItemRow) {
230         this.nbItemRow = nbItemRow;
231     }
232
233     /**
234      * Get the column positions of the non null items.
235      *
236      * @return an integer array.
237      */
238     public int[] getScilabColPos() {
239         int[] cp = new int[colPos.length];
240         for (int i = 0; i < colPos.length; i++) {
241             cp[i] = colPos[i] + 1;
242         }
243         return cp;
244     }
245
246     /**
247      * Get the real part of the data.
248      *
249      * @return the real part.
250      */
251     public int[] getColPos() {
252         return colPos;
253     }
254
255     /**
256      * Set the real part of the data.
257      *
258      * @param colPos
259      *            the real part.
260      */
261     public void setColPos(int[] colPos) {
262         this.colPos = colPos;
263     }
264
265     /**
266      * {@inheritDoc}
267      */
268     public String getVarName() {
269         return varName;
270     }
271
272     /**
273      * {@inheritDoc}
274      */
275     public boolean isSwaped() {
276         return false;
277     }
278
279     /**
280      * Get the real part of the full sparse matrix
281      *
282      * @return the full real matrix
283      */
284     public boolean[][] getFullMatrix() {
285         int prev = 0;
286         int j = 0;
287         boolean[][] b = new boolean[rows][cols];
288         for (int i = 0; i < nbItemRow.length; i++) {
289             for (; j < prev + nbItemRow[i]; j++) {
290                 b[i][colPos[j]] = true;
291             }
292             prev += nbItemRow[i];
293         }
294
295         return b;
296     }
297
298     /**
299      * Get complex matrix as a serialized form
300      *
301      * @return the serialized matrix with complex values
302      */
303     // TODO Sly : faire qque chose ici...
304     public boolean[] getSerializedBooleanSparseMatrix() {
305         return new boolean[0];
306     }
307
308     /**
309      * @return the height of the data matrix
310      * @see org.scilab.modules.types.ScilabType#getHeight()
311      */
312     @Override
313     public int getHeight() {
314         return rows;
315     }
316
317     /**
318      * @return the width of the data matrix
319      * @see org.scilab.modules.types.ScilabType#getWidth()
320      */
321     @Override
322     public int getWidth() {
323         return cols;
324     }
325
326
327
328
329     @Override
330     public int hashCode() {
331         final int prime = 31;
332         int result = 1;
333         result = prime * result + Arrays.hashCode(colPos);
334         result = prime * result + cols;
335         result = prime * result + nbItem;
336         result = prime * result + Arrays.hashCode(nbItemRow);
337         result = prime * result + rows;
338         return result;
339     }
340
341     /**
342      * @see org.scilab.modules.types.ScilabType#equals(Object)
343      */
344     @Override
345     public boolean equals(Object obj) {
346         if (obj instanceof ScilabBooleanSparse) {
347             ScilabBooleanSparse sciSparse = (ScilabBooleanSparse) obj;
348             return this.getNbNonNullItems() == sciSparse.getNbNonNullItems() && ScilabSparse.compareNbItemRow(this.getNbItemRow(), sciSparse.getNbItemRow())
349                    && Arrays.equals(this.getColPos(), sciSparse.getColPos());
350         } else {
351             return false;
352         }
353     }
354
355     /**
356      * {@inheritDoc}
357      */
358     public Object getSerializedObject() {
359         return new Object[] { new int[] { rows, cols }, nbItemRow, getScilabColPos() };
360     }
361
362     @Override
363     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
364         int version = in.readInt();
365         switch (version) {
366             case 0:
367                 rows = in.readInt();
368                 cols = in.readInt();
369                 nbItem = in.readInt();
370                 nbItemRow = (int[]) in.readObject();
371                 colPos = (int[]) in.readObject();
372                 varName = (String) in.readObject();
373                 break;
374             default:
375                 throw new ClassNotFoundException("A class ScilabBooleanSparse with a version " + version + " does not exists");
376         }
377     }
378
379     @Override
380     public void writeExternal(ObjectOutput out) throws IOException {
381         out.writeInt(VERSION);
382         out.writeInt(rows);
383         out.writeInt(cols);
384         out.writeInt(nbItem);
385         out.writeObject(nbItemRow);
386         out.writeObject(colPos);
387         out.writeObject(varName);
388     }
389
390     /**
391      * Display the representation in the Scilab language of the type<BR>
392      * Note that the representation can be copied/pasted straight into Scilab
393      *
394      * @return a Scilab-like String representation of the data.
395      * @see java.lang.Object#toString()
396      */
397     @Override
398     public String toString() {
399         StringBuilder result = new StringBuilder();
400
401         if (isEmpty()) {
402             result.append("[]");
403             return result.toString();
404         }
405
406         result.append("sparse([");
407         int j = 0;
408         int prev = 0;
409         for (int i = 0; i < nbItemRow.length; i++) {
410             for (; j < prev + nbItemRow[i]; j++) {
411                 result.append(Integer.toString(i + 1));
412                 result.append(", ");
413                 result.append(Integer.toString(colPos[j] + 1));
414                 if (j < nbItem - 1) {
415                     result.append(" ; ");
416                 }
417             }
418             prev += nbItemRow[i];
419         }
420
421         result.append("], [");
422         for (int i = 0; i < nbItem; i++) {
423             result.append("%t");
424             if (i < nbItem - 1) {
425                 result.append(", ");
426             }
427         }
428
429         result.append("], [");
430         result.append(Integer.toString(rows));
431         result.append(", ");
432         result.append(Integer.toString(cols));
433
434         result.append("])");
435
436         return result.toString();
437     }
438 }