9f4d7ac607bc24609235c456278db76ed45a73ee
[scilab.git] / scilab / modules / types / src / java / org / scilab / modules / types / ScilabPolynomial.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.Arrays;
22
23 /**
24  * This class provides a representation on the Scilab Polynomial datatype<br>
25  * <br>
26  * This class is {@link java.io.Serializable} and any modification could impact
27  * load and store of data (Xcos files, Javasci saved data, etc...).<br>
28  * <br>
29  * TODO Sly: faire de la doc
30  *
31  * @see org.scilab.modules.javasci.Scilab
32  */
33 public class ScilabPolynomial implements ScilabType {
34
35     private static final long serialVersionUID = 870624048944109684L;
36     private static final ScilabTypeEnum type = ScilabTypeEnum.sci_poly;
37
38     private static final int VERSION = 0;
39
40     private double[][][] realPart;
41     private double[][][] imaginaryPart;
42
43     private String varName;
44     private String polyVarName = "x";
45     private boolean swaped;
46
47     /**
48      * Default constructor
49      */
50     public ScilabPolynomial() {
51         realPart = null;
52         imaginaryPart = null;
53     }
54
55     /**
56      * Constructor with a unique polynomial.
57      *
58      * @param data
59      *            the unique polynomial
60      */
61     public ScilabPolynomial(double[] data) {
62         realPart = new double[1][1][];
63         realPart[0][0] = data;
64         imaginaryPart = null;
65     }
66
67     /**
68      * Constructor with a unique polynomial.
69      *
70      * @param data
71      *            the unique polynomial
72      */
73     public ScilabPolynomial(double[] data, String polyVarName) {
74         this(data);
75         setPolyVarName(polyVarName);
76     }
77
78     /**
79      * Constructor with a unique complex polynomial.
80      *
81      * @param realData
82      *            the real part
83      * @param imagData
84      *            the complex part
85      */
86     public ScilabPolynomial(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 unique complex polynomial.
95      *
96      * @param realData
97      *            the real part
98      * @param imagData
99      *            the complex part
100      */
101     public ScilabPolynomial(double[] realData, double[] imagData, String polyVarName) {
102         this(realData, imagData);
103         setPolyVarName(polyVarName);
104     }
105
106     /**
107      * Constructor with a matrix of real polynomials.
108      *
109      * @param data
110      *            the data
111      */
112     public ScilabPolynomial(double[][][] data) {
113         realPart = data;
114         imaginaryPart = null;
115     }
116
117     /**
118      * Constructor with a matrix of real polynomials.
119      *
120      * @param data
121      *            the data
122      */
123     public ScilabPolynomial(double[][][] data, String polyVarName) {
124         this(data);
125         setPolyVarName(polyVarName);
126     }
127
128     /**
129      * Constructor with a matrix of complex polynomials
130      *
131      * @param realData
132      *            the real part of the data
133      * @param imagData
134      *            the imaginary part of the data
135      */
136     public ScilabPolynomial(double[][][] realData, double[][][] imagData) {
137         realPart = realData;
138         imaginaryPart = imagData;
139     }
140
141     /**
142      * Constructor with a matrix of complex polynomials
143      *
144      * @param realData
145      *            the real part of the data
146      * @param imagData
147      *            the imaginary part of the data
148      */
149     public ScilabPolynomial(double[][][] realData, double[][][] imagData, String polyVarName) {
150         this(realData, imagData);
151         setPolyVarName(polyVarName);
152     }
153
154     /**
155      * Constructor with a matrix of complex polynomials
156      *
157      * @param varName
158      *            the variable name
159      * @param polyVarName
160      *            the polynomial variable name
161      * @param realData
162      *            the real part of the data
163      * @param imagData
164      *            the imaginary part of the data
165      * @param swaped
166      *            if true the matrix is stored row by row
167      */
168     public ScilabPolynomial(String varName, String polyVarName, double[][][] realData, double[][][] imagData, boolean swaped) {
169         this.varName = varName;
170         this.polyVarName = polyVarName;
171         this.swaped = swaped;
172         realPart = realData;
173         imaginaryPart = imagData;
174     }
175
176     /**
177      * {@inheritDoc}
178      */
179     public boolean isReference() {
180         return false;
181     }
182
183     /**
184      * Return the type of Scilab
185      *
186      * @return the type of Scilab
187      * @since 5.4.0
188      */
189     @Override
190     public ScilabTypeEnum getType() {
191         return type;
192     }
193
194     /**
195      * Check the emptiness of the associated data.
196      *
197      * @return true, if the associated data array is empty.
198      */
199     @Override
200     public boolean isEmpty() {
201         return (realPart == null && imaginaryPart == null);
202     }
203
204     /**
205      * Check if the current data doesn't have an imaginary part.
206      *
207      * @return true, if the data are real only.
208      */
209     public boolean isReal() {
210         return (imaginaryPart == null);
211     }
212
213     /**
214      * Get the real part of the data.
215      *
216      * @return the real part.
217      */
218     public double[][][] getRealPart() {
219         return realPart;
220     }
221
222     /**
223      * Set the real part of the data.
224      *
225      * @param realPart
226      *            the real part.
227      */
228     public void setRealPart(double[][][] realPart) {
229         this.realPart = realPart;
230     }
231
232     /**
233      * Get the imaginary part of the data.
234      *
235      * @return the imaginary part.
236      */
237     public double[][][] getImaginaryPart() {
238         return imaginaryPart;
239     }
240
241     /**
242      * Set the imaginary part of the data.
243      *
244      * @param imaginaryPart
245      *            the imaginary part.
246      */
247     public void setImaginaryPart(double[][][] imaginaryPart) {
248         this.imaginaryPart = imaginaryPart;
249     }
250
251     /**
252      * Get the polynomila variable name
253      *
254      * @return the name
255      */
256     public String getPolyVarName() {
257         return polyVarName;
258     }
259
260     public void setPolyVarName(String polyVarName) {
261         this.polyVarName = polyVarName;
262     }
263
264     /**
265      * {@inheritDoc}
266      */
267     public String getVarName() {
268         return varName;
269     }
270
271     /**
272      * {@inheritDoc}
273      */
274     public boolean isSwaped() {
275         return swaped;
276     }
277
278     /**
279      * Get complex matrix as a serialized form
280      *
281      * @return the serialized matrix with complex values
282      */
283     // TODO Sly : serializer ce machin
284     public double[][] getSerializedComplexPolynomial() {
285         return new double[0][0];
286     }
287
288     /**
289      * @return the height of the data matrix
290      * @see org.scilab.modules.types.ScilabType#getHeight()
291      */
292     @Override
293     public int getHeight() {
294         if (isEmpty()) {
295             return 0;
296         }
297         return realPart.length;
298     }
299
300     /**
301      * @return the width of the data matrix
302      * @see org.scilab.modules.types.ScilabType#getWidth()
303      */
304     @Override
305     public int getWidth() {
306         if (isEmpty() || realPart.length == 0) {
307             return 0;
308         }
309
310         return realPart[0].length;
311     }
312
313
314     @Override
315     public int hashCode() {
316         final int prime = 31;
317         int result = 1;
318         result = prime * result + Arrays.deepHashCode(imaginaryPart);
319         result = prime * result + ((polyVarName == null) ? 0 : polyVarName.hashCode());
320         result = prime * result + Arrays.deepHashCode(realPart);
321         return result;
322     }
323
324     /**
325      * @see org.scilab.modules.types.ScilabType#equals(Object)
326      */
327     @Override
328     public boolean equals(Object obj) {
329         if (obj instanceof ScilabPolynomial) {
330             ScilabPolynomial sciPoly = ((ScilabPolynomial) obj);
331             if (sciPoly.getPolyVarName().equals(getPolyVarName())) {
332                 if (this.isReal() && sciPoly.isReal()) {
333                     return Arrays.deepEquals(this.getRealPart(), sciPoly.getRealPart());
334                 } else {
335                     /* Complex */
336                     return Arrays.deepEquals(this.getRealPart(), sciPoly.getRealPart())
337                            && Arrays.deepEquals(this.getImaginaryPart(), sciPoly.getImaginaryPart());
338                 }
339             } else {
340                 return false;
341             }
342         } else {
343             return false;
344         }
345     }
346
347     /**
348      * {@inheritDoc}
349      */
350     public Object getSerializedObject() {
351         if (isReal()) {
352             return new Object[] { polyVarName, realPart };
353         } else {
354             return new Object[] { polyVarName, realPart, imaginaryPart };
355         }
356     }
357
358     @Override
359     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
360         int version = in.readInt();
361         switch (version) {
362             case 0:
363                 realPart = (double[][][]) in.readObject();
364                 imaginaryPart = (double[][][]) in.readObject();
365                 varName = (String) in.readObject();
366                 polyVarName = in.readUTF();
367                 swaped = in.readBoolean();
368                 break;
369             default:
370                 throw new ClassNotFoundException("A class ScilabPolynomial with a version " + version + " does not exists");
371         }
372     }
373
374     @Override
375     public void writeExternal(ObjectOutput out) throws IOException {
376         out.writeInt(VERSION);
377         out.writeObject(realPart);
378         out.writeObject(imaginaryPart);
379         out.writeObject(varName);
380         out.writeUTF(polyVarName);
381         out.writeBoolean(swaped);
382     }
383
384     /**
385      * Display the representation in the Scilab language of the type<BR>
386      * Note that the representation can be copied/pasted straight into Scilab
387      *
388      * @return a Scilab-like String representation of the data.
389      * @see java.lang.Object#toString()
390      */
391     @Override
392     public String toString() {
393         StringBuilder result = new StringBuilder();
394
395         if (isEmpty()) {
396             result.append("[]");
397             return result.toString();
398         }
399
400         result.append("[");
401
402         for (int i = 0; i < getHeight(); ++i) {
403             for (int j = 0; j < getWidth(); ++j) {
404                 result.append("poly([");
405                 for (int k = 0; k < realPart[i][j].length; k++) {
406                     if (isReal()) {
407                         result.append(Double.toString(realPart[i][j][k]));
408                     } else {
409                         result.append(Double.toString(realPart[i][j][k]));
410                         if (imaginaryPart[i][j][k] != 0) {
411                             result.append("+");
412                             result.append(Double.toString(imaginaryPart[i][j][k]));
413                             result.append("*%i");
414                         }
415                     }
416                     if (k < realPart[i][j].length - 1) {
417                         result.append(", ");
418                     }
419                 }
420                 result.append("], \"");
421                 result.append(getPolyVarName());
422                 result.append("\", \"coeff\")");
423
424                 if (j < getWidth() - 1) {
425                     result.append(", ");
426                 }
427             }
428             if (i < getHeight() - 1) {
429                 result.append(" ; ");
430             }
431         }
432         result.append("]");
433
434         return result.toString();
435     }
436 }