Javasci: fix java build, javadoc warnings
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / ScilabSparse.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 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  *
32  * @see org.scilab.modules.javasci.Scilab
33  */
34 public class ScilabSparse implements ScilabType {
35
36     private static final long serialVersionUID = 879625048944109684L;
37
38     private static final int VERSION = 0;
39
40     protected int rows;
41     protected int cols;
42     protected int nbItem;
43     protected int[] nbItemRow;
44     protected int[] colPos;
45     protected double[] realPart;
46     protected double[] imaginaryPart;
47     protected String varName;
48     protected boolean byref;
49
50     /**
51      * Default constructor
52      */
53     public ScilabSparse() {
54     }
55
56     /**
57      * Constructor with a unique value.
58      *
59      * @param data
60      *            the unique value
61      */
62     public ScilabSparse(double data) {
63         if (data != 0) {
64             nbItem = 1;
65             rows = cols = 1;
66             nbItemRow = new int[] { 1 };
67             colPos = new int[] { 0 };
68             realPart = new double[] { data };
69         }
70     }
71
72     /**
73      * Constructor with a unique complex value.
74      *
75      * @param realData
76      *            the real part
77      * @param imagData
78      *            the complex part
79      */
80     public ScilabSparse(double realData, double imagData) {
81         if (realData != 0 || imagData != 0) {
82             nbItem = 1;
83             rows = cols = 1;
84             nbItemRow = new int[] { 1 };
85             colPos = new int[] { 0 };
86             realPart = new double[] { realData };
87             imaginaryPart = new double[] { imagData };
88         }
89     }
90
91     /**
92      * Constructor
93      *
94      * @param rows
95      *            the number of rows
96      * @param cols
97      *            the number of cols
98      * @param nbItem
99      *            the number of non null items
100      * @param nbItemRow
101      *            contains the number of true in each rows
102      * @param colPos
103      *            the column position of each non null item
104      * @param data
105      *            the non null data
106      * @param check
107      *            if true the parameters validity is checked
108      * @throws ScilabSparseException if the passed arguments are not a valid sparse representation
109      */
110     public ScilabSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, double[] data, boolean check) throws ScilabSparseException {
111         this(rows, cols, nbItem, nbItemRow, colPos, data);
112         if (check) {
113             checkValidity(rows, cols, nbItem, nbItemRow, colPos);
114
115             if (realPart.length != nbItem) {
116                 throw new ScilabSparseException("Invalid length for the array realPart: its length must be equal to the number of non-null items.");
117             }
118         }
119     }
120
121     /**
122      * Constructor
123      *
124      * @param rows
125      *            the number of rows
126      * @param cols
127      *            the number of cols
128      * @param nbItem
129      *            the number of non null items
130      * @param nbItemRow
131      *            contains the number of true in each rows
132      * @param colPos
133      *            the column position of each non null item
134      * @param real
135      *            the non null real data
136      */
137     public ScilabSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, double[] real) {
138         this.rows = rows;
139         this.cols = cols;
140         this.nbItem = nbItem;
141         this.nbItemRow = nbItemRow;
142         this.colPos = colPos;
143         this.realPart = real;
144     }
145
146     /**
147      * Constructor
148      *
149      * @param rows
150      *            the number of rows
151      * @param cols
152      *            the number of cols
153      * @param nbItem
154      *            the number of non null items
155      * @param nbItemRow
156      *            contains the number of true in each rows
157      * @param colPos
158      *            the column position of each non null item
159      * @param real
160      *            the non null real data
161      * @param imag
162      *            the non null imaginary data
163      * @param check
164      *            if true the parameters validity is checked
165      * @throws ScilabSparseException if the passed arguments are not a valid sparse representation
166      */
167     public ScilabSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, double[] real, double[] imag, boolean check)
168     throws ScilabSparseException {
169         this(rows, cols, nbItem, nbItemRow, colPos, real, imag);
170         if (check) {
171             checkValidity(rows, cols, nbItem, nbItemRow, colPos);
172
173             if (realPart.length != nbItem) {
174                 throw new ScilabSparseException("Invalid length for the array realPart: its length must be equal to the number of non-null items.");
175             }
176
177             if (imaginaryPart.length != nbItem) {
178                 throw new ScilabSparseException("Invalid length for the array imaginaryPart: its length must be equal to the number of non-null items.");
179             }
180         }
181     }
182
183     /**
184      * Constructor
185      *
186      * @param rows
187      *            the number of rows
188      * @param cols
189      *            the number of cols
190      * @param nbItem
191      *            the number of non null items
192      * @param nbItemRow
193      *            contains the number of true in each rows
194      * @param colPos
195      *            the column position of each non null item
196      * @param real
197      *            the non null real data
198      * @param imag
199      *            the non null imaginary data
200      */
201     public ScilabSparse(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, double[] real, double[] imag) {
202         this(rows, cols, nbItem, nbItemRow, colPos, real);
203         this.imaginaryPart = imag;
204     }
205
206     /**
207      * Constructor
208      *
209      * @param rows
210      *            the number of rows
211      * @param cols
212      *            the number of cols
213      * @param nbItem
214      *            the number of non null items
215      * @param nbItemRow
216      *            contains the number of true in each rows
217      * @param colPos
218      *            the column position of each non null item
219      */
220     static final void checkValidity(int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos) throws ScilabSparseException {
221         if (nbItem > rows * cols || nbItem < 0) {
222             throw new ScilabSparseException("Invalid number of items: between 0 and " + rows * cols + " expected.");
223         }
224
225         if (nbItemRow.length > rows) {
226             throw new ScilabSparseException("Invalid length for the array nbItemRow: a length between 0 and " + rows + " expected.");
227         }
228
229         int s = 0;
230         for (int i = 0; i < nbItemRow.length; i++) {
231             if (nbItemRow[i] > cols) {
232                 throw new ScilabSparseException("Invalid number of non-null items in nbItemRow at position " + i + ".");
233             }
234             s += nbItemRow[i];
235         }
236
237         if (s != nbItem) {
238             throw new ScilabSparseException("Invalid array nbItemRow: the total sum is not equal to the number of non-null items.");
239         }
240
241         if (colPos.length != nbItem) {
242             throw new ScilabSparseException("Invalid length for the array colPos: its length must be equal to the number of non-null items.");
243         }
244
245         for (int i = 0; i < nbItem; i++) {
246             if (colPos[i] >= cols || colPos[i] < 0) {
247                 throw new ScilabSparseException("Invalid column position at position " + i + ".");
248             }
249         }
250     }
251
252     /**
253      * Constructor with a matrix of real data.
254      *
255      * @param data
256      *            the data
257      */
258     public ScilabSparse(double[][] data) {
259         if (data.length != 0 && data[0].length != 0) {
260             rows = data.length;
261             cols = data[0].length;
262             nbItemRow = new int[rows];
263             List<Integer> listCol = new ArrayList<Integer>();
264             List<Double> listVal = new ArrayList<Double>();
265
266             for (int i = 0; i < rows; i++) {
267                 for (int j = 0; j < cols; j++) {
268                     if (data[i][j] != 0) {
269                         ++nbItem;
270                         ++nbItemRow[i];
271                         listCol.add(j);
272                         listVal.add(data[i][j]);
273                     }
274                 }
275             }
276
277             colPos = new int[listCol.size()];
278             realPart = new double[colPos.length];
279             int i = 0;
280             for (Integer c : listCol) {
281                 colPos[i++] = c;
282             }
283             i = 0;
284             for (Double x : listVal) {
285                 realPart[i++] = x;
286             }
287         }
288     }
289
290     /**
291      * Constructor with a matrix of complex numbers
292      *
293      * @param realData
294      *            the real part of the data
295      * @param imagData
296      *            the imaginary part of the data
297      */
298     public ScilabSparse(double[][] realData, double[][] imagData) {
299         if (realData.length != 0 && realData[0].length != 0) {
300             rows = realData.length;
301             cols = realData[0].length;
302             nbItemRow = new int[rows];
303             List<Integer> listCol = new ArrayList<Integer>();
304             List<Double> listReal = new ArrayList<Double>();
305             List<Double> listImag = new ArrayList<Double>();
306
307             for (int i = 0; i < rows; i++) {
308                 for (int j = 0; j < cols; j++) {
309                     if (realData[i][j] != 0 || imagData[i][j] != 0) {
310                         ++nbItem;
311                         ++nbItemRow[i];
312                         listCol.add(j);
313                         listReal.add(realData[i][j]);
314                         listImag.add(imagData[i][j]);
315                     }
316                 }
317             }
318
319             colPos = new int[listCol.size()];
320             this.realPart = new double[colPos.length];
321             this.imaginaryPart = new double[colPos.length];
322             int i = 0;
323             for (Integer c : listCol) {
324                 colPos[i++] = c;
325             }
326             i = 0;
327             for (Double x : listReal) {
328                 this.realPart[i++] = x;
329             }
330             i = 0;
331             for (Double x : listImag) {
332                 this.imaginaryPart[i++] = x;
333             }
334         }
335     }
336
337     /**
338      * Constructor
339      *
340      * @param varName
341      *            the variable name
342      * @param rows
343      *            the number of rows
344      * @param cols
345      *            the number of cols
346      * @param nbItem
347      *            the number of non null items
348      * @param nbItemRow
349      *            contains the number of true in each rows
350      * @param colPos
351      *            the column position of each non null item
352      * @param real
353      *            the non null real data
354      * @param imag
355      *            the non null imaginary data
356      */
357     public ScilabSparse(String varName, int rows, int cols, int nbItem, int[] nbItemRow, int[] colPos, double[] real, double[] imag) {
358         this(rows, cols, nbItem, nbItemRow, colPos, real, imag);
359         this.varName = varName;
360     }
361
362     /**
363      * {@inheritDoc}
364      */
365     @Override
366     public boolean isReference() {
367         return false;
368     }
369
370     /**
371      * Return the type of Scilab
372      *
373      * @return the type of Scilab
374      * @since 5.4.0
375      */
376     @Override
377     public ScilabTypeEnum getType() {
378         return ScilabTypeEnum.sci_sparse;
379     }
380
381     /**
382      * Check the emptiness of the associated data.
383      *
384      * @return true, if the associated data array is empty.
385      */
386     @Override
387     public boolean isEmpty() {
388         return rows == 0 && cols == 0;
389     }
390
391     /**
392      * Check if the current data doesn't have an imaginary part.
393      *
394      * @return true, if the data are real only.
395      */
396     public boolean isReal() {
397         return imaginaryPart == null;
398     }
399
400     /**
401      * Get the element in column position
402      * @param i the position
403      * @return the column position
404      */
405     public int getColPosElement(final int i) {
406         return colPos[i];
407     }
408
409     /**
410      * Set the element in column position
411      * @param i the position
412      * @param x the column position
413      */
414     public void setColPosElement(final int i, final int x) {
415         colPos[i] = x;
416     }
417
418     /**
419      * Get the number of non-null item in row i
420      * @param i the row
421      * @return the number of non-null items
422      */
423     public int getNbItemElement(final int i) {
424         return nbItemRow[i];
425     }
426
427     /**
428      * Set the number of non-null item in row i
429      * @param i the row
430      * @param x the number of non-null items
431      */
432     public void setNbItemElement(final int i, final int x) {
433         nbItemRow[i] = x;
434     }
435
436     /**
437      * Get the real element at position i
438      * @param i the position
439      * @return a real
440      */
441     public double getRealElement(final int i) {
442         return realPart[i];
443     }
444
445     /**
446      * Get the real element at position (i, j) in the sparse matrix
447      * @param i the row index
448      * @param j the column index
449      * @return a real
450      */
451     public double getRealElement(final int i, final int j) {
452         if (getNbItemElement(i) == 0) {
453             return 0;
454         }
455
456         int prev = 0;
457         for (int k = 0; k < i; k++) {
458             prev += getNbItemElement(k);
459         }
460
461         for (int k = prev; k < prev + getNbItemElement(i); k++) {
462             if (getColPosElement(k) == j) {
463                 return getRealElement(k);
464             }
465         }
466
467         return 0;
468     }
469
470     /**
471      * Get the imaginary element at position i
472      * @param i the position
473      * @return a real
474      */
475     public double getImaginaryElement(final int i) {
476         return imaginaryPart[i];
477     }
478
479     /**
480      * Get the imanginary element at position (i, j) in the sparse matrix
481      * @param i the row index
482      * @param j the column index
483      * @return a real
484      */
485     public double getImaginaryElement(final int i, final int j) {
486         if (getNbItemElement(i) == 0) {
487             return 0;
488         }
489
490         int prev = 0;
491         for (int k = 0; k < i; k++) {
492             prev += getNbItemElement(k);
493         }
494
495         for (int k = prev; k < prev + getNbItemElement(i); k++) {
496             if (getColPosElement(k) == j) {
497                 return getImaginaryElement(k);
498             }
499         }
500
501         return 0;
502     }
503
504     /**
505      * Get the real and imaginary elements at position i
506      * @param i the position
507      * @return a 2-array containing real and imaginary part
508      */
509     public double[] getElement(final int i) {
510         if (isReal()) {
511             return new double[] {realPart[i], 0};
512         } else {
513             return new double[] {realPart[i], imaginaryPart[i]};
514         }
515     }
516
517     /**
518      * Get the real and imanginary element at position (i, j) in the sparse matrix
519      * @param i the row index
520      * @param j the column index
521      * @return a 2-array containing real and imaginary parts
522      */
523     public double[] getElement(final int i, final int j) {
524         if (isReal()) {
525             return new double[] {getRealElement(i, j), 0};
526         } else {
527             if (getNbItemElement(i) == 0) {
528                 return new double[] {0, 0};
529             }
530
531             int prev = 0;
532             for (int k = 0; k < i; k++) {
533                 prev += getNbItemElement(k);
534             }
535
536             for (int k = prev; k < prev + getNbItemElement(i); k++) {
537                 if (getColPosElement(k) == j) {
538                     return new double[] {getRealElement(k), getImaginaryElement(k)};
539                 }
540             }
541
542             return new double[] {0, 0};
543         }
544     }
545
546     /**
547      * Set the real element at position i
548      * @param i the position
549      * @param x the value to set
550      */
551     public void setRealElement(final int i, final double x) {
552         realPart[i] = x;
553     }
554
555     /**
556      * Set the real element at position (i, j) in sparse matrix
557      * Take care only an already non-null element can be set
558      * @param i the row index
559      * @param j the column index
560      * @param x the value to set
561      */
562     public void setRealElement(final int i, final int j, final double x) {
563         if (getNbItemElement(i) == 0) {
564             return;
565         }
566
567         int prev = 0;
568         for (int k = 0; k < i; k++) {
569             prev += getNbItemElement(k);
570         }
571
572         for (int k = prev; k < prev + getNbItemElement(i); k++) {
573             if (getColPosElement(k) == j) {
574                 setRealElement(k, x);
575                 break;
576             }
577         }
578     }
579
580     /**
581      * Set the imaginary element at position i
582      * @param i the position
583      * @param x the value to set
584      */
585     public void setImaginaryElement(final int i, final double x) {
586         imaginaryPart[i] = x;
587     }
588
589     /**
590      * Set the imaginary element at position (i, j) in sparse matrix
591      * Take care only an already non-null element can be set
592      * @param i the row index
593      * @param j the column index
594      * @param x the value to set
595      */
596     public void setImaginaryElement(final int i, final int j, final double x) {
597         if (getNbItemElement(i) == 0) {
598             return;
599         }
600
601         int prev = 0;
602         for (int k = 0; k < i; k++) {
603             prev += getNbItemElement(k);
604         }
605
606         for (int k = prev; k < prev + getNbItemElement(i); k++) {
607             if (getColPosElement(k) == j) {
608                 setImaginaryElement(k, x);
609                 break;
610             }
611         }
612     }
613
614     /**
615      * Set the real and imaginary elements at position i
616      * @param i the position
617      * @param x the real part to set
618      * @param y the imaginary part to set
619      */
620     public void setElement(final int i, final double x, final double y) {
621         setRealElement(i, x);
622         setImaginaryElement(i, y);
623     }
624
625     /**
626      * Get the real part of the data.
627      *
628      * @return the real part.
629      */
630     public double[] getRealPart() {
631         return realPart;
632     }
633
634     /**
635      * Set the real part of the data.
636      *
637      * @param realPart
638      *            the real part.
639      */
640     public void setRealPart(double[] realPart) {
641         this.realPart = realPart;
642     }
643
644     /**
645      * Get the imaginary part of the data.
646      *
647      * @return the imaginary part.
648      */
649     public double[] getImaginaryPart() {
650         return imaginaryPart;
651     }
652
653     /**
654      * Set the imaginary part of the data.
655      *
656      * @param imaginaryPart
657      *            the imaginary part.
658      */
659     public void setImaginaryPart(double[] imaginaryPart) {
660         this.imaginaryPart = imaginaryPart;
661     }
662
663     /**
664      * Get the number of non null items in the matrix.
665      *
666      * @return the number of non null items.
667      */
668     public int getNbNonNullItems() {
669         return nbItem;
670     }
671
672     /**
673      * Set the number of non null items in the matrix.
674      *
675      * @param nbItem
676      *            the number of non null items.
677      */
678     public void setNbNonNullItems(int nbItem) {
679         this.nbItem = nbItem;
680     }
681
682     /**
683      * Get the number of non null items by row.
684      *
685      * @return an integer array.
686      */
687     public int[] getNbItemRow() {
688         return nbItemRow;
689     }
690
691     /**
692      * Set the number of non null items by row.
693      *
694      * @param nbItemRow
695      *            an integer array.
696      */
697     public void setNbItemRow(int[] nbItemRow) {
698         this.nbItemRow = nbItemRow;
699     }
700
701     /**
702      * Get the column positions of the non null items.
703      *
704      * @return an integer array.
705      */
706     public int[] getScilabColPos() {
707         int[] cp = new int[colPos.length];
708         for (int i = 0; i < colPos.length; i++) {
709             cp[i] = colPos[i] + 1;
710         }
711         return cp;
712     }
713
714     /**
715      * Get the column positions of the non null items.
716      *
717      * @return an integer array.
718      */
719     public int[] getColPos() {
720         return colPos;
721     }
722
723     /**
724      * Set the column positions of the non null items.
725      *
726      * @param colPos
727      *            an integer array.
728      */
729     public void setColPos(int[] colPos) {
730         this.colPos = colPos;
731     }
732
733     /**
734      * {@inheritDoc}
735      */
736     @Override
737     public String getVarName() {
738         return varName;
739     }
740
741     /**
742      * {@inheritDoc}
743      */
744     @Override
745     public boolean isSwaped() {
746         return false;
747     }
748
749     /**
750      * Get the real part of the full sparse matrix
751      *
752      * @return the full real matrix
753      */
754     public double[][] getFullRealPart() {
755         int prev = 0;
756         int j = 0;
757         double[][] d = new double[rows][cols];
758         for (int i = 0; i < nbItemRow.length; i++) {
759             for (; j < prev + nbItemRow[i]; j++) {
760                 d[i][colPos[j]] = realPart[j];
761             }
762             prev += nbItemRow[i];
763         }
764
765         return d;
766     }
767
768     /**
769      * Get the imaginary part of the full sparse matrix
770      *
771      * @return the full imaginary matrix
772      */
773     public double[][] getFullImaginaryPart() {
774         int prev = 0;
775         int j = 0;
776         double[][] d = new double[rows][cols];
777         for (int i = 0; i < nbItemRow.length; i++) {
778             for (; j < prev + nbItemRow[i]; j++) {
779                 d[i][colPos[j]] = imaginaryPart[j];
780             }
781             prev += nbItemRow[i];
782         }
783
784         return d;
785     }
786
787     /**
788      * Get the full sparse matrix representation as an array 2 x rows x cols If
789      * d = getFullMatrix(), then d[0] contains realpart and d[1] the imaginary
790      * one.
791      *
792      * @return the full matrix components
793      */
794     public double[][][] getFullMatrix() {
795         int prev = 0;
796         int j = 0;
797         double[][][] d = new double[2][rows][cols];
798         for (int i = 0; i < nbItemRow.length; i++) {
799             for (; j < prev + nbItemRow[i]; j++) {
800                 d[0][i][colPos[j]] = realPart[j];
801                 d[1][i][colPos[j]] = imaginaryPart[j];
802             }
803             prev += nbItemRow[i];
804         }
805
806         return d;
807     }
808
809     /**
810      * Get complex matrix as a serialized form
811      *
812      * @return the serialized matrix with complex values
813      */
814     // TODO Sly : faire qque chose ici...
815     public double[] getSerializedSparseMatrix() {
816         return new double[0];
817     }
818
819     /**
820      * @return the height of the data matrix
821      * @see org.scilab.modules.types.ScilabType#getHeight()
822      */
823     @Override
824     public int getHeight() {
825         return rows;
826     }
827
828     /**
829      * @return the width of the data matrix
830      * @see org.scilab.modules.types.ScilabType#getWidth()
831      */
832     @Override
833     public int getWidth() {
834         return cols;
835     }
836
837     @Override
838     public int hashCode() {
839         final int prime = 31;
840         int result = 1;
841         result = prime * result + Arrays.hashCode(colPos);
842         result = prime * result + cols;
843         result = prime * result + Arrays.hashCode(imaginaryPart);
844         result = prime * result + nbItem;
845         result = prime * result + Arrays.hashCode(nbItemRow);
846         result = prime * result + Arrays.hashCode(realPart);
847         result = prime * result + rows;
848         return result;
849     }
850
851     /**
852      * @see org.scilab.modules.types.ScilabType#equals(Object)
853      */
854     @Override
855     public boolean equals(Object obj) {
856         if (obj instanceof ScilabSparse) {
857             ScilabSparse sciSparse = (ScilabSparse) obj;
858             if (isEmpty() && sciSparse.isEmpty()) {
859                 return true;
860             }
861
862             if (this.getWidth() != sciSparse.getWidth() || this.getHeight() != sciSparse.getHeight()) {
863                 return false;
864             }
865
866             if (this.getNbNonNullItems() == sciSparse.getNbNonNullItems() && compareNbItemRow(this.getNbItemRow(), sciSparse.getNbItemRow())
867                     && Arrays.equals(this.getColPos(), sciSparse.getColPos())) {
868                 if (this.isReal() && sciSparse.isReal()) {
869                     return Arrays.equals(this.getRealPart(), sciSparse.getRealPart());
870                 } else {
871                     /* Complex */
872                     return Arrays.equals(this.getRealPart(), sciSparse.getRealPart()) && Arrays.equals(this.getImaginaryPart(), sciSparse.getImaginaryPart());
873                 }
874             } else {
875                 return false;
876             }
877         } else {
878             return false;
879         }
880     }
881
882     /**
883      * Compare two arrays containing the number of items by row. For example {1,
884      * 2, 3, 4} is equal to {1, 2, 3, 4, 0, 0, 0, 0}/
885      *
886      * @param a
887      *            an array
888      * @param b
889      *            an other array
890      * @return true if the arrays are equal
891      */
892     static final boolean compareNbItemRow(final int[] a, final int[] b) {
893         if (Arrays.equals(a, b)) {
894             return true;
895         }
896
897         if (a.length == b.length) {
898             return false;
899         }
900
901         int[] c, d;
902         if (a.length < b.length) {
903             c = a;
904             d = b;
905         } else {
906             c = b;
907             d = a;
908         }
909
910         int i = 0;
911         for (; i < c.length; i++) {
912             if (c[i] != d[i]) {
913                 return false;
914             }
915         }
916
917         for (; i < d.length; i++) {
918             if (d[i] != 0) {
919                 return false;
920             }
921         }
922
923         return true;
924     }
925
926     /**
927      * {@inheritDoc}
928      */
929     @Override
930     public Object getSerializedObject() {
931         if (isReal()) {
932             return new Object[] { new int[] { getHeight(), getWidth() }, getNbItemRow(), getScilabColPos(), getRealPart() };
933         } else {
934             return new Object[] { new int[] { getHeight(), getWidth() }, getNbItemRow(), getScilabColPos(), getRealPart(), getImaginaryPart() };
935         }
936     }
937
938     @Override
939     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
940         int version = in.readInt();
941         switch (version) {
942             case 0:
943                 rows = in.readInt();
944                 cols = in.readInt();
945                 nbItem = in.readInt();
946                 nbItemRow = (int[]) in.readObject();
947                 colPos = (int[]) in.readObject();
948                 realPart = (double[]) in.readObject();
949                 imaginaryPart = (double[]) in.readObject();
950                 varName = (String) in.readObject();
951                 break;
952             default:
953                 throw new ClassNotFoundException("A class ScilabSparse with a version " + version + " does not exists");
954         }
955     }
956
957     @Override
958     public void writeExternal(ObjectOutput out) throws IOException {
959         out.writeInt(VERSION);
960         out.writeInt(rows);
961         out.writeInt(cols);
962         out.writeInt(nbItem);
963         out.writeObject(nbItemRow);
964         out.writeObject(colPos);
965         out.writeObject(realPart);
966         out.writeObject(imaginaryPart);
967         out.writeObject(varName);
968     }
969
970     /**
971      * Display the representation in the Scilab language of the type<BR>
972      * Note that the representation can be copied/pasted straight into Scilab
973      *
974      * @return a Scilab-like String representation of the data.
975      * @see java.lang.Object#toString()
976      */
977     @Override
978     public String toString() {
979         StringBuilder result = new StringBuilder();
980
981         if (isEmpty()) {
982             return "[]";
983         }
984
985         result.append("sparse([");
986         int j = 0;
987         int prev = 0;
988         int[] nbItemRow = getNbItemRow();
989         int[] colPos = getColPos();
990         for (int i = 0; i < nbItemRow.length; i++) {
991             for (; j < prev + nbItemRow[i]; j++) {
992                 result.append(Integer.toString(i + 1));
993                 result.append(", ");
994                 result.append(Integer.toString(colPos[j] + 1));
995                 if (j < nbItem - 1) {
996                     result.append(" ; ");
997                 }
998             }
999             prev += nbItemRow[i];
1000         }
1001
1002         result.append("], [");
1003         boolean real = isReal();
1004         for (int i = 0; i < nbItem; i++) {
1005             result.append(Double.toString(getRealElement(i)));
1006             if (!real) {
1007                 final double y = getImaginaryElement(i);
1008                 if (y != 0) {
1009                     if (y > 0) {
1010                         result.append("+");
1011                     }
1012                     result.append(Double.toString(y));
1013                     result.append("*%i");
1014                 }
1015             }
1016             if (i < nbItem - 1) {
1017                 result.append(" ; ");
1018             } else {
1019                 result.append("]");
1020             }
1021         }
1022
1023         result.append(", [");
1024         result.append(Integer.toString(rows));
1025         result.append(", ");
1026         result.append(Integer.toString(cols));
1027
1028         result.append("])");
1029
1030         return result.toString();
1031     }
1032 }