Javasci: fix java build, javadoc warnings
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / ScilabDouble.java
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2009-2009 - DIGITEO - Bruno JOFRET
4  *  Copyright (C) 2010-2010 - DIGITEO - Clement DAVID
5  *  Copyright (C) 2011-2011 - DIGITEO - Calixte DENIZET
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 package org.scilab.modules.types;
19
20 import java.io.IOException;
21 import java.io.ObjectInput;
22 import java.io.ObjectOutput;
23 import java.util.Arrays;
24
25 /**
26  * This class provides a representation on the Scilab Double datatype<br>
27  * Note that double is the default datatype in Scilab.<br>
28  * <br>
29  * This class is {@link java.io.Serializable} and any modification could impact
30  * load and store of data (Xcos files, Javasci saved data, etc...).<br>
31  * <br>
32  * Example (real):<BR>
33  * <code>
34  * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
35  * ScilabDouble aMatrix = new ScilabDouble(a);<BR>
36  * </code> <br>
37  * Example (complex):<BR>
38  * <code>
39  * double [][]a={{21.2, 22.0, 42.0, 39.0},{23.2, 24.0, 44.0, 40.0}};<BR>
40  * double [][]aImg={{210.2, 220.0, 420.0, 390.0},{230.2, 240.0, 440.0, 400.0}};<BR>
41  * ScilabDouble aMatrix = new ScilabDouble(a, aImg);
42  * </code>
43  *
44  * @see org.scilab.modules.javasci.Scilab
45  */
46 public class ScilabDouble implements ScilabType {
47
48     private static final long serialVersionUID = 879624048944109684L;
49
50     private static final int VERSION = 0;
51
52     protected double[][] realPart;
53     protected double[][] imaginaryPart;
54     protected String varName;
55     protected boolean swaped;
56     transient protected boolean byref;
57
58     /**
59      * Default constructor
60      */
61     public ScilabDouble() {
62         realPart = new double[0][];
63         imaginaryPart = new double[0][];
64     }
65
66     /**
67      * Constructor with a unique value.
68      *
69      * @param data
70      *            the unique value
71      */
72     public ScilabDouble(double data) {
73         realPart = new double[1][1];
74         realPart[0][0] = data;
75         imaginaryPart = new double[0][];
76     }
77
78     /**
79      * Constructor with a unique complex value.
80      *
81      * @param realData
82      *            the real part
83      * @param imagData
84      *            the complex part
85      */
86     public ScilabDouble(double realData, double imagData) {
87         realPart = new double[1][1];
88         realPart[0][0] = realData;
89         imaginaryPart = new double[1][1];
90         imaginaryPart[0][0] = imagData;
91     }
92
93     /**
94      * Constructor with a matrix of real data.
95      *
96      * @param data
97      *            the data
98      */
99     public ScilabDouble(double[][] data) {
100         this(data, new double[0][]);
101     }
102
103     /**
104      * Constructor with a matrix of complex numbers
105      *
106      * @param realData
107      *            the real part of the data
108      * @param imagData
109      *            the imaginary part of the data
110      */
111     public ScilabDouble(double[][] realData, double[][] imagData) {
112         if (realData == null) {
113             realPart = new double[0][];
114             imaginaryPart = new double[0][];
115         } else {
116             realPart = realData;
117             if (imagData == null) {
118                 imaginaryPart = new double[0][];
119             } else {
120                 imaginaryPart = imagData;
121             }
122         }
123     }
124
125     /**
126      * Constructor with a matrix of complex numbers
127      *
128      * @param varName the variable name
129      * @param realData
130      *            the real part of the data
131      * @param imagData
132      *            the imaginary part of the data
133      * @param swaped true if the matrices are stored row by row
134      */
135     public ScilabDouble(String varName, double[][] realData, double[][] imagData, boolean swaped) {
136         this(realData, imagData);
137         this.varName = varName;
138         this.swaped = swaped;
139     }
140
141     /**
142      * Return the type of Scilab
143      *
144      * @return the type of Scilab
145      * @since 5.4.0
146      */
147     @Override
148     public ScilabTypeEnum getType() {
149         return ScilabTypeEnum.sci_matrix;
150     }
151
152     /**
153      * Check the emptiness of the associated data.
154      *
155      * @return true, if the associated data array is empty.
156      */
157     @Override
158     public boolean isEmpty() {
159         return realPart == null || realPart.length == 0;
160     }
161
162     /**
163      * {@inheritDoc}
164      */
165     @Override
166     public boolean isReference() {
167         return byref;
168     }
169
170     /**
171      * Check if the current data doesn't have an imaginary part.
172      *
173      * @return true, if the data are real only.
174      */
175     public boolean isReal() {
176         return imaginaryPart == null || imaginaryPart.length == 0;
177     }
178
179     /**
180      * Get the real part of the data.
181      *
182      * @return the real part.
183      */
184     public double[][] getRealPart() {
185         return realPart;
186     }
187
188     /**
189      * Set the real part of the data.
190      *
191      * @param realPart
192      *            the real part.
193      */
194     public void setRealPart(double[][] realPart) {
195         this.realPart = realPart;
196     }
197
198     /**
199      * Get the imaginary part of the data.
200      *
201      * @return the imaginary part.
202      */
203     public double[][] getImaginaryPart() {
204         return imaginaryPart;
205     }
206
207     /**
208      * Set the imaginary part of the data.
209      *
210      * @param imaginaryPart
211      *            the imaginary part.
212      */
213     public void setImaginaryPart(double[][] imaginaryPart) {
214         this.imaginaryPart = imaginaryPart;
215     }
216
217     /**
218      * {@inheritDoc}
219      */
220     @Override
221     public String getVarName() {
222         return varName;
223     }
224
225     /**
226      * {@inheritDoc}
227      */
228     @Override
229     public boolean isSwaped() {
230         return swaped;
231     }
232
233     /**
234      * Get the element at position (i, j) in the real part
235      * @param i the first coordinate
236      * @param j the second coordinate
237      * @return the corresponding double
238      */
239     public double getRealElement(final int i, final int j) {
240         return realPart[i][j];
241     }
242
243     /**
244      * Get the element at position (i, j) in the imaginary part
245      * @param i the first coordinate
246      * @param j the second coordinate
247      * @return the corresponding double
248      */
249     public double getImaginaryElement(final int i, final int j) {
250         return imaginaryPart[i][j];
251     }
252
253     /**
254      * Get the complex at position (i, j) as a 2-length row-vector
255      * @param i the first coordinate
256      * @param j the second coordinate
257      * @return the corresponding complex
258      */
259     public double[] getElement(final int i, final int j) {
260         return new double[] {getRealElement(i, j), getImaginaryElement(i, j)};
261     }
262
263     /**
264      * Set the element at position (i, j) in the real part
265      * @param i the first coordinate
266      * @param j the second coordinate
267      * @param x the new value
268      */
269     public void setRealElement(final int i, final int j, final double x) {
270         realPart[i][j] = x;
271     }
272
273     /**
274      * Set the element at position (i, j) in the imaginary part
275      * @param i the first coordinate
276      * @param j the second coordinate
277      * @param x the new value
278      */
279     public void setImaginaryElement(final int i, final int j, final double x) {
280         imaginaryPart[i][j] = x;
281     }
282
283     /**
284      * Set the element at position (i, j)
285      * @param i the first coordinate
286      * @param j the second coordinate
287      * @param x the new value for real part
288      * @param y the new value for imaginary part
289      */
290     public void setElement(final int i, final int j, final double x, final double y) {
291         realPart[i][j] = x;
292         imaginaryPart[i][j] = y;
293     }
294
295     /**
296      * Get the raw data
297      * @return the real part
298      */
299     public Object getRawRealPart() {
300         return realPart;
301     }
302
303     /**
304      * Get the raw data
305      * @return the imaginary part
306      */
307     public Object getRawImaginaryPart() {
308         return imaginaryPart;
309     }
310
311     /**
312      * Get complex matrix as a serialized form
313      *
314      * @return the serialized matrix with complex values
315      */
316     public double[] getSerializedComplexMatrix() {
317         int size = this.getHeight() * this.getWidth();
318         double[] serializedComplexMatrix = new double[size * 2];
319         for (int i = 0; i < this.getHeight(); i++) {
320             for (int j = 0; j < this.getWidth(); j++) {
321                 serializedComplexMatrix[j * this.getHeight() + i] = getRealElement(i, j);
322                 serializedComplexMatrix[size + j * this.getHeight() + i] = getImaginaryElement(i, j);
323             }
324         }
325
326         return serializedComplexMatrix;
327     }
328
329     /**
330      * {@inheritDoc}
331      */
332     @Override
333     public Object getSerializedObject() {
334         if (isReal()) {
335             return new Object[] { getRealPart() };
336         } else {
337             return new Object[] { getRealPart(), getImaginaryPart() };
338         }
339     }
340
341     /**
342      * @return the height of the data matrix
343      * @see org.scilab.modules.types.ScilabType#getHeight()
344      */
345     @Override
346     public int getHeight() {
347         if (isEmpty()) {
348             return 0;
349         }
350         return realPart.length;
351     }
352
353     /**
354      * @return the width of the data matrix
355      * @see org.scilab.modules.types.ScilabType#getWidth()
356      */
357     @Override
358     public int getWidth() {
359         if (isEmpty()) {
360             return 0;
361         }
362
363         return realPart[0].length;
364     }
365
366     @Override
367     public int hashCode() {
368         final int prime = 31;
369         int result = 1;
370         result = prime * result + Arrays.deepHashCode(imaginaryPart);
371         result = prime * result + Arrays.deepHashCode(realPart);
372         return result;
373     }
374
375     /**
376      * @see org.scilab.modules.types.ScilabType#equals(Object)
377      */
378     @Override
379     public boolean equals(Object obj) {
380         if (obj instanceof ScilabDouble) {
381             ScilabDouble sciDouble = (ScilabDouble) obj;
382             if (isEmpty() && sciDouble.isEmpty()) {
383                 return true;
384             }
385
386             if (this.getWidth() != sciDouble.getWidth() || this.getHeight() != sciDouble.getHeight()) {
387                 return false;
388             }
389
390             if (this.isReal() && sciDouble.isReal()) {
391                 return ScilabTypeUtils.equalsDouble(this.getRawRealPart(), this.isSwaped(), sciDouble.getRawRealPart(), sciDouble.isSwaped());
392             } else if (!this.isReal() && !sciDouble.isReal()) {
393                 /* Complex */
394                 return ScilabTypeUtils.equalsDouble(this.getRawRealPart(), this.isSwaped(), sciDouble.getRawRealPart(), sciDouble.isSwaped())
395                        && ScilabTypeUtils.equalsDouble(this.getRawImaginaryPart(), this.isSwaped(), sciDouble.getRawImaginaryPart(), sciDouble.isSwaped());
396             }
397         }
398
399         return false;
400     }
401
402     @Override
403     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
404         int version = in.readInt();
405         switch (version) {
406             case 0:
407                 realPart = (double[][]) in.readObject();
408                 imaginaryPart = (double[][]) in.readObject();
409                 varName = (String) in.readObject();
410                 swaped = in.readBoolean();
411                 break;
412             default:
413                 throw new ClassNotFoundException("A class ScilabDouble with a version " + version + " does not exists");
414         }
415     }
416
417     @Override
418     public void writeExternal(ObjectOutput out) throws IOException {
419         out.writeInt(VERSION);
420         out.writeObject(getRealPart());
421         out.writeObject(getImaginaryPart());
422         out.writeObject(varName);
423         out.writeBoolean(swaped);
424     }
425
426     /**
427      * Display the representation in the Scilab language of the type<BR>
428      * Note that the representation can be copied/pasted straight into Scilab
429      *
430      * @return a Scilab-like String representation of the data.
431      * @see java.lang.Object#toString()
432      */
433     @Override
434     public String toString() {
435         StringBuilder result = new StringBuilder();
436
437         if (isEmpty()) {
438             return "[]";
439         }
440
441         result.append("[");
442         final boolean real = isReal();
443         for (int i = 0; i < getHeight(); ++i) {
444             for (int j = 0; j < getWidth(); ++j) {
445                 result.append(Double.toString(getRealElement(i, j)));
446                 if (!real) {
447                     final double y = getImaginaryElement(i, j);
448                     if (y != 0) {
449                         if (y > 0) {
450                             result.append(" + ");
451                         }
452                         result.append(Double.toString(y));
453                         result.append(" * %i");
454                     }
455                 }
456                 if (j != getWidth() - 1) {
457                     result.append(", ");
458                 }
459             }
460             if (i != getHeight() - 1) {
461                 result.append(" ; ");
462             }
463         }
464         result.append("]");
465
466         return result.toString();
467     }
468 }