1 /*************************************************************************************
2 * Copyright (C) 2014 by Percy Camilo T. Aucahuasi <percy.camilo.ta@gmail.com> *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License *
6 * as published by the Free Software Foundation; either version 2 *
7 * of the License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
17 *************************************************************************************/
18
19 #include "commandstest.h"
20
21 #include <QTest>
22
23 #include "analyzer.h"
24 #include <config-analitza.h>
25
26 using Analitza::Expression;
27
QTEST_MAIN(CommandsTest)28 QTEST_MAIN( CommandsTest )
29
30 CommandsTest::CommandsTest(QObject *parent)
31 : QObject(parent)
32 {}
33
~CommandsTest()34 CommandsTest::~CommandsTest()
35 {}
36
initTestCase()37 void CommandsTest::initTestCase()
38 {
39 a=new Analitza::Analyzer;
40 }
41
cleanupTestCase()42 void CommandsTest::cleanupTestCase()
43 {
44 delete a;
45 }
46
testCorrect_data()47 void CommandsTest::testCorrect_data()
48 {
49 QTest::addColumn<QStringList>("expression");
50 QTest::addColumn<QString>("result");
51
52 QStringList script;
53
54 script.clear();
55 script << QStringLiteral("range(10)");
56 QTest::newRow("simple range") << script << "list { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }";
57
58 script.clear();
59 script << QStringLiteral("range(-1.5, 2)");
60 QTest::newRow("range(-1.5, 2)") << script << "list { -1.5, -0.5, 0.5, 1.5 }";
61
62 script.clear();
63 script << QStringLiteral("range(0, 1, 0.2)");
64 QTest::newRow("range(0, 1, 0.2)") << script << "list { 0, 0.2, 0.4, 0.6, 0.8, 1 }";
65
66 script.clear();
67 script << QStringLiteral("vector(3, -2.3)");
68 QTest::newRow("simple fill vector") << script << "vector { -2.3, -2.3, -2.3 }";
69
70 script.clear();
71 script << QStringLiteral("7*vector(34, 14.2)[23]");
72 QTest::newRow("select fill vector") << script << "99.4";
73
74 script.clear();
75 script << QStringLiteral("seq := range(14, 20, 2)");
76 script << QStringLiteral("vector(seq)");
77 QTest::newRow("vector by range/seq") << script << "vector { 14, 16, 18, 20 }";
78
79 script.clear();
80 script << QStringLiteral("matrix(3, 2, -15.7)");
81 QTest::newRow("simple fill matrix") << script << "matrix { matrixrow { -15.7, -15.7 }, matrixrow { -15.7, -15.7 }, matrixrow { -15.7, -15.7 } }";
82
83 script.clear();
84 script << QStringLiteral("matrix(2)");
85 QTest::newRow("simple fill square matrix") << script << "matrix { matrixrow { 0, 0 }, matrixrow { 0, 0 } }";
86
87 script.clear();
88 script << QStringLiteral("matrix(3, 2)");
89 QTest::newRow("simple matrix") << script << "matrix { matrixrow { 0, 0 }, matrixrow { 0, 0 }, matrixrow { 0, 0 } }";
90
91 script.clear();
92 script << QStringLiteral("matrix(3, 2, -9.8)[2][1]");
93 QTest::newRow("select simple matrix") << script << "-9.8";
94
95 script.clear();
96 script << QStringLiteral("matrix(vector{2,3}, vector{7, 4})");
97 QTest::newRow("matrix by vectors/columns") << script << "matrix { matrixrow { 2, 7 }, matrixrow { 3, 4 } }";
98
99 script.clear();
100 script << QStringLiteral("matrix(matrixrow{2,3}, matrixrow{7, 4})");
101 QTest::newRow("matrix by rows") << script << "matrix { matrixrow { 2, 3 }, matrixrow { 7, 4 } }";
102
103 script.clear();
104 script << QStringLiteral("A := matrix{matrixrow{13,6}, matrixrow{-2,5}}");
105 script << QStringLiteral("matrix(vector{2,3}, vector{7, 4}) + A");
106 QTest::newRow("matrix by vectors/columns + A") << script << "matrix { matrixrow { 15, 13 }, matrixrow { 1, 9 } }";
107
108 script.clear();
109 script << QStringLiteral("A := matrix{matrixrow{2, 3, 6}, matrixrow{-5, 0, 2.3}}");
110 script << QStringLiteral("matrix(2, 3, -9) + A");
111 QTest::newRow("fill + A") << script << "matrix { matrixrow { -7, -6, -3 }, matrixrow { -14, -9, -6.7 } }";
112
113 script.clear();
114 script << QStringLiteral("A := matrix{matrixrow{2, 3}, matrixrow{-5, 1}}");
115 script << QStringLiteral("B := matrix{matrixrow{12, 13}, matrixrow{-15, 11}}");
116 script << QStringLiteral("blockmatrix(matrixrow{A, B})");
117 QTest::newRow("simple block matrix") << script << "matrix { matrixrow { 2, 3, 12, 13 }, matrixrow { -5, 1, -15, 11 } }";
118
119 const QString resultblockmatrix = QStringLiteral("matrix { matrixrow { 1, 8, 7, 6 }, matrixrow { 3, 5, 0, 2 }, matrixrow { 1, 4, 9, 3 } }");
120
121 script.clear();
122 script << QStringLiteral("A := matrix(vector{1,3}, vector{8,5})");
123 script << QStringLiteral("B := matrix{matrixrow{7,6}, matrixrow{0,2}}");
124 script << QStringLiteral("C := matrix(matrixrow{1,4})");
125 script << QStringLiteral("D := matrix(vector{9}, vector{3})");
126 script << QStringLiteral("blockmatrix(matrixrow{A, B}, matrixrow{C, D})");
127 QTest::newRow("block matrix 4 blocks conf 1") << script << resultblockmatrix;
128
129 script.clear();
130 script << QStringLiteral("A := matrix{matrixrow{1,8,7}, matrixrow{3,5,0}}");
131 script << QStringLiteral("B := matrix(vector{6,2})");
132 script << QStringLiteral("C := matrix(matrixrow{1,4,9})");
133 script << QStringLiteral("D := matrix(1,1,3)");
134 script << QStringLiteral("blockmatrix(matrixrow{A, B}, matrixrow{C, D})");
135 QTest::newRow("block matrix by rows, conf 2") << script << resultblockmatrix;
136
137 script.clear();
138 script << QStringLiteral("A := matrix(matrixrow{1,8})");
139 script << QStringLiteral("B := transpose(matrix(diag(diag(7,6))))");
140 script << QStringLiteral("C := matrix{matrixrow{3,5}}");
141 script << QStringLiteral("D := matrix(matrixrow{0,2})");
142 script << QStringLiteral("E := matrix(vector{1},vector{4})");
143 script << QStringLiteral("F := matrix{matrixrow{9,3}}");
144 script << QStringLiteral("blockmatrix(matrixrow{A, B}, matrixrow{C, D}, matrixrow{E, F})");
145 QTest::newRow("block matrix by rows, conf 3") << script << resultblockmatrix;
146
147 script.clear();
148 script << QStringLiteral("A := matrix(vector{1,3}, vector{8,5})");
149 script << QStringLiteral("B := matrix(matrixrow{1,4})");
150 script << QStringLiteral("C := matrix{matrixrow{7,6}, matrixrow{0,2}}");
151 script << QStringLiteral("D := matrix(vector{9}, vector{3})");
152 script << QStringLiteral("blockmatrix(vector{A, B}, vector{C, D})");
153 QTest::newRow("block matrix by cols, conf 1") << script << resultblockmatrix;
154
155 script.clear();
156 script << QStringLiteral("A := matrix{matrixrow{1,8}}");
157 script << QStringLiteral("B := matrix(matrixrow{3,5})");
158 script << QStringLiteral("C := matrix(matrixrow{1,4})");
159 script << QStringLiteral("D := matrix{matrixrow{7,6}}");
160 script << QStringLiteral("E := matrix(matrixrow{0,2})");
161 script << QStringLiteral("F := matrix(matrixrow{9,3})");
162 script << QStringLiteral("blockmatrix(vector{A, B, C}, vector{D, E, F})");
163 QTest::newRow("block matrix by cols, conf 2") << script << resultblockmatrix;
164
165 script.clear();
166 script << QStringLiteral("matrix(2,5)");
167 QTest::newRow("simple 0") << script << "matrix { matrixrow { 0, 0, 0, 0, 0 }, matrixrow { 0, 0, 0, 0, 0 } }";
168
169 script.clear();
170 script << QStringLiteral("identitymatrix(3)");
171 QTest::newRow("simple I") << script << "matrix { matrixrow { 1, 0, 0 }, matrixrow { 0, 1, 0 }, matrixrow { 0, 0, 1 } }";
172
173 script.clear();
174 script << QStringLiteral("identitymatrix(3)-identitymatrix(3)");
175 QTest::newRow("I - I") << script << "matrix { matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 } }";
176
177 script.clear();
178 script << QStringLiteral("0*identitymatrix(3)");
179 QTest::newRow("0*I") << script << "matrix { matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 } }";
180
181 script.clear();
182 script << QStringLiteral("matrix(3,3) + identitymatrix(3)");
183 QTest::newRow("0 + I") << script << "matrix { matrixrow { 1, 0, 0 }, matrixrow { 0, 1, 0 }, matrixrow { 0, 0, 1 } }";
184
185 script.clear();
186 script << QStringLiteral("diag(5, 3.2, 6, -9)");
187 QTest::newRow("simple diag") << script << "matrix { matrixrow { 5, 0, 0, 0 }, matrixrow { 0, 3.2, 0, 0 }, matrixrow { 0, 0, 6, 0 }, matrixrow { 0, 0, 0, -9 } }";
188
189 script.clear();
190 script << QStringLiteral("diag(vector{5, 3.2, 6, -9})");
191 QTest::newRow("simple diag by vector") << script << "matrix { matrixrow { 5, 0, 0, 0 }, matrixrow { 0, 3.2, 0, 0 }, matrixrow { 0, 0, 6, 0 }, matrixrow { 0, 0, 0, -9 } }";
192
193 script.clear();
194 script << QStringLiteral("diag(1, 1, 1) - identitymatrix(3)");
195 QTest::newRow("zeromatrix: diag - I") << script << "matrix { matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 } }";
196
197 script.clear();
198 script << QStringLiteral("diag(vector{1, 1, 1}) - identitymatrix(3)");
199 QTest::newRow("zeromatrix: diag by vector - I") << script << "matrix { matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 }, matrixrow { 0, 0, 0 } }";
200
201 script.clear();
202 script << QStringLiteral("diag(5, 7.8, -0.6, 3.5)[3][3] + diag(5, 7.8, -0.6, 3.5)[2][3]");
203 QTest::newRow("selector diag") << script << "-0.6";
204
205 script.clear();
206 script << QStringLiteral("v := vector{5, 7.8, -0.6, 3.5}");
207 script << QStringLiteral("diag(v)[3][3] + diag(v)[2][3]");
208 QTest::newRow("selector diag by vector") << script << "-0.6";
209
210 script.clear();
211 script << QStringLiteral("blockdiag(matrix{matrixrow{1, 3}, matrixrow{-6, 8}}, matrix{matrixrow{5, 6}, matrixrow{14, -1.2}})");
212 QTest::newRow("simple block diagonal") << script << "matrix { matrixrow { 1, 3, 0, 0 }, matrixrow { -6, 8, 0, 0 }, matrixrow { 0, 0, 5, 6 }, matrixrow { 0, 0, 14, -1.2 } }";
213
214 script.clear();
215 script << QStringLiteral("I := identitymatrix(3)");
216 script << QStringLiteral("A := matrix(2,3, -6)");
217 script << QStringLiteral("B := 3*I");
218 script << QStringLiteral("blockdiag(I, A, B)");
219 QTest::newRow("block diagonal") << script << "matrix { matrixrow { 1, 0, 0, 0, 0, 0, 0, 0, 0 }, matrixrow { 0, 1, 0, 0, 0, 0, 0, 0, 0 }, matrixrow { 0, 0, 1, 0, 0, 0, 0, 0, 0 }, matrixrow { 0, 0, 0, -6, -6, -6, 0, 0, 0 }, matrixrow { 0, 0, 0, -6, -6, -6, 0, 0, 0 }, matrixrow { 0, 0, 0, 0, 0, 0, 3, 0, 0 }, matrixrow { 0, 0, 0, 0, 0, 0, 0, 3, 0 }, matrixrow { 0, 0, 0, 0, 0, 0, 0, 0, 3 } }";
220
221 script.clear();
222 script << QStringLiteral("tridiag(-2.1, 3.6, 48, 5)");
223 QTest::newRow("simple tridiag") << script << "matrix { matrixrow { 3.6, 48, 0, 0, 0 }, matrixrow { -2.1, 3.6, 48, 0, 0 }, matrixrow { 0, -2.1, 3.6, 48, 0 }, matrixrow { 0, 0, -2.1, 3.6, 48 }, matrixrow { 0, 0, 0, -2.1, 3.6 } }";
224
225 script.clear();
226 script << QStringLiteral("A := matrix{matrixrow{-7.8, 2.3, 5}, matrixrow{0, -1.2, cos(pi)}, matrixrow{-45, 9.6, -2.3}}");
227 script << QStringLiteral("tridiag(-8, 10, 7.2, 3) - identitymatrix(3) + A");
228 QTest::newRow("tridiag - I + A") << script << "matrix { matrixrow { 1.2, 9.5, 5 }, matrixrow { -8, 7.8, 6.2 }, matrixrow { -45, 1.6, 6.7 } }";
229
230 script.clear();
231 script << QStringLiteral("A := matrix{matrixrow{-7.8, 2.3, 5}, matrixrow{0, -12, 1}, matrixrow{-45, 9.6, cos(pi)}}");
232 script << QStringLiteral("diag(A)");
233 QTest::newRow("simple diag(A)") << script << "vector { -7.8, -12, -1 }";
234
235 script.clear();
236 script << QStringLiteral("A := matrix{matrixrow{8, 2.3, 5}, matrixrow{-45, -cos(pi), 12}}");
237 script << QStringLiteral("diag(A)");
238 QTest::newRow("getdiag fat") << script << "vector { 8, 1 }";
239
240 script.clear();
241 script << QStringLiteral("A := matrix{matrixrow{8, 2.3, 1}, matrixrow{3, 32, 2}, matrixrow{-45, 12, 3}, matrixrow{1, 0, 3}, matrixrow{-5, 1, 0}}");
242 script << QStringLiteral("diag(A)");
243 QTest::newRow("getdiag skinny") << script << "vector { 8, 32, 3 }";
244
245 script.clear();
246 script << QStringLiteral("A := matrix{matrixrow{-7.8, 2.3, 5}, matrixrow{0, -12, 1}, matrixrow{-45, 9.6, cos(pi)}}");
247 script << QStringLiteral("diag(A)[2]");
248 QTest::newRow("selector getdiag") << script << "-12";
249
250 script.clear();
251 script << QStringLiteral("v := vector{5,5,0}");
252 script << QStringLiteral("A := matrix{matrixrow{0, -1, 2}, matrixrow{4, 0, -3.2}, matrixrow{5.8, -15, 0}}");
253 script << QStringLiteral("B := matrix(3,3, 4.5)");
254 script << QStringLiteral("D := diag(v)");
255 script << QStringLiteral("I := identitymatrix(3)");
256 script << QStringLiteral("O := matrix(3,3)");
257 script << QStringLiteral("T := tridiag(2,1,8,3)");
258 script << QStringLiteral("A + B + D - cos(pi)*I + O + T");
259 QTest::newRow("complex exp") << script << "matrix { matrixrow { 11.5, 11.5, 6.5 }, matrixrow { 10.5, 11.5, 9.3 }, matrixrow { 10.3, -8.5, 6.5 } }";
260
261 // 3.6 48 0 9 80
262 // 2.1 3.2 49 20 100
263 // 1 -2.1 3.6 47 90
264 // 0 -7 -2.1 3.3 42
265 // 5 4 3 -2.1 3.5
266 const QString square = QStringLiteral("A := matrix{matrixrow{3.6, 48, 0, 9, 80}, matrixrow {2.1, 3.2, 49, 20, 100}, matrixrow{1, -2.1, 3.6, 47, 90}, matrixrow{0, -7, -2.1, 3.3, 42}, matrixrow{5, 4, 3, -2.1, 3.5}}");
267
268 script.clear();
269 script << square;
270 script << QStringLiteral("diag(A,2)");
271 QTest::newRow("getndiag square +2") << script << "vector { 0, 20, 90 }";
272
273 script.clear();
274 script << square;
275 script << QStringLiteral("diag(A,-2)");
276 QTest::newRow("getndiag square -2") << script << "vector { 1, -7, 3 }";
277
278 script.clear();
279 script << square;
280 script << QStringLiteral("diag(A,-3)");
281 QTest::newRow("getndiag square -3") << script << "vector { 0, 4 }";
282
283 script.clear();
284 script << square;
285 script << QStringLiteral("diag(A,3)");
286 QTest::newRow("getndiag square +3") << script << "vector { 9, 100 }";
287
288 script.clear();
289 script << square;
290 script << QStringLiteral("diag(A,-3)");
291 QTest::newRow("getndiag square -3") << script << "vector { 0, 4 }";
292
293 script.clear();
294 script << square;
295 script << QStringLiteral("diag(A,4)[1]");
296 QTest::newRow("selector getndiag square corner +") << script << "80";
297
298 script.clear();
299 script << square;
300 script << QStringLiteral("diag(A,-4)[1]");
301 QTest::newRow("selector getndiag square corner -") << script << "5";
302
303 // 3.6 42 0 9 80 4 15
304 // -4.1 7.8 45 0 100 6 7
305 // 1 2.2 3.6 47 0 8 9
306 // 0 0 -2.3 5.6 48 2 1
307 // 2 4 3 -2.1 3.6 3 5
308 const QString fat = QStringLiteral("A := matrix{matrixrow{3.6, 42, 0, 9, 80, 4, 15}, matrixrow{-4.1, 7.8, 45, 0, 100, 6,7}, matrixrow{1, 2.2, 5.6, 47, 0 , 8, 9}, matrixrow{0, 0, -2.3, 3.6, 48, 2,1}, matrixrow{2, 4, 3, -2.1, 3.6, 3,5}}");
309
310 script.clear();
311 script << fat;
312 script << QStringLiteral("diag(A,5)");
313 QTest::newRow("getndiag fat +5") << script << "vector { 4, 7 }";
314
315 script.clear();
316 script << fat;
317 script << QStringLiteral("diag(A,1)");
318 QTest::newRow("getndiag fat +1") << script << "vector { 42, 45, 47, 48, 3 }";
319
320 script.clear();
321 script << fat;
322 script << QStringLiteral("diag(A,-1)");
323 QTest::newRow("getndiag fat -1") << script << "vector { -4.1, 2.2, -2.3, -2.1 }";
324
325 script.clear();
326 script << fat;
327 script << QStringLiteral("diag(A,6)[1]");
328 QTest::newRow("selector getndiag fat corner +") << script << "15";
329
330 script.clear();
331 script << fat;
332 script << QStringLiteral("diag(A,-4)[1]");
333 QTest::newRow("selector getndiag fat corner -") << script << "2";
334
335 // 3.6 42
336 // -4.1 7.8
337 // 1 2.2
338 // 0 1
339 // 2 4
340 const QString skinny = QStringLiteral("A := matrix{matrixrow{3.6, 42}, matrixrow{-4.1, 7.8}, matrixrow{1, 2.2}, matrixrow{0, 1}, matrixrow{2, 4}}");
341
342 script.clear();
343 script << fat;
344 script << QStringLiteral("diag(A,1)[1]");
345 QTest::newRow("selector getndiag skinny corner +") << script << "42";
346
347 script.clear();
348 script << skinny;
349 script << QStringLiteral("diag(A,-1)");
350 QTest::newRow("getndiag skinny -1") << script << "vector { -4.1, 2.2 }";
351
352 script.clear();
353 script << skinny;
354 script << QStringLiteral("diag(A,-3)");
355 QTest::newRow("getndiag skinny -3") << script << "vector { 0, 4 }";
356
357 script.clear();
358 script << skinny;
359 script << QStringLiteral("diag(A,-4)");
360 QTest::newRow("getndiag skinny -4") << script << "vector { 2 }";
361
362 script.clear();
363 script << skinny;
364 script << QStringLiteral("isdiag(A)");
365 QTest::newRow("is not diag") << script << "false";
366
367 script.clear();
368 script << QStringLiteral("iszeromatrix(matrix(8,5))");
369 QTest::newRow("is zero matrix") << script << "true";
370
371 script.clear();
372 script << QStringLiteral("isidentitymatrix(identitymatrix(5))");
373 QTest::newRow("Id is identity matrix") << script << "true";
374
375 script.clear();
376 script << QStringLiteral("isidentitymatrix(blockdiag(identitymatrix(3), matrix{matrixrow{1}}, identitymatrix(2)))");
377 QTest::newRow("block of Id is Id matrix") << script << "true";
378
379 script.clear();
380 script << QStringLiteral("isdiag(identitymatrix(4))");
381 QTest::newRow("Id is diag matrix") << script << "true";
382
383 #ifdef HAVE_EIGEN3
384 script.clear();
385 script << QStringLiteral("eigenvalues(identitymatrix(4))");
386 QTest::newRow("eigenvalues: from Id") << script << "list { 1, 1, 1, 1 }";
387
388 script.clear();
389 script << QStringLiteral("eigenvalues(matrix(vector{3,4}, vector{-2, -1}))");
390 QTest::newRow("eigenvalues: full complex") << script << "list { 1+2*i, 1-2*i }";
391
392 script.clear();
393 script << QStringLiteral("eigenvectors(identitymatrix(4))");
394 QTest::newRow("eigenvectors: from Id") << script << "list { vector { 1, 0, 0, 0 }, vector { 0, 1, 0, 0 }, vector { 0, 0, 1, 0 }, vector { 0, 0, 0, 1 } }";
395
396 script.clear();
397 script << QStringLiteral("eigenvectors(matrix(vector{3,4}, vector{-2, -1}))");
398 QTest::newRow("complex eigenvectors") << script << "list { vector { -0.408248290464+0.408248290464*i, 0.816496580928*i }, vector { -0.408248290464-0.408248290464*i, -0.816496580928*i } }";
399 #endif
400 }
401
testCorrect()402 void CommandsTest::testCorrect()
403 {
404 QFETCH(QStringList, expression);
405 QFETCH(QString, result);
406
407 Expression last;
408 Analitza::Analyzer b1;
409 foreach(const QString &exp, expression) {
410 Expression e(exp, false);
411 if(!e.isCorrect()) qDebug() << "error:" << e.error();
412 QVERIFY(e.isCorrect());
413
414 b1.setExpression(e);
415
416 if(!b1.isCorrect()) qDebug() << "errors: " << b1.errors();
417 QVERIFY(b1.isCorrect());
418 last = b1.calculate();
419 if(!b1.isCorrect()) qDebug() << "errors:" << e.toString() << b1.errors();
420 QVERIFY(b1.isCorrect());
421 }
422 QCOMPARE(last.toString(), result);
423
424 QString script = expression.join(QStringLiteral("\n"));
425 script+=QLatin1String("\n\n\n");
426 QTextStream stream(&script);
427 a->importScript(&stream);
428 QVERIFY(a->isCorrect());
429 }
430
testIncorrect_data()431 void CommandsTest::testIncorrect_data()
432 {
433 QTest::addColumn<QString>("expression");
434
435 QTest::newRow("range: bad input") << "range(list{3,4}-9)";
436 QTest::newRow("range: bad arg type") << "range(list{3}, 31, true)";
437 QTest::newRow("range: bad arg type2") << "range(list{3}, 31)";
438 QTest::newRow("range: bad arg count") << "range(2,3,vector{3}, list{2}, 4)";
439 QTest::newRow("range: bad args1") << "range(2,3,9, list{2}, 4)";
440 QTest::newRow("range: bad args2") << "range(2,3,9, 9, vector{4})";
441 QTest::newRow("range: bad args3") << "range(2,3,9, 9, 3,4,5,5)";
442
443 QTest::newRow("vector: bad arg type") << "vector(list{23},4)";
444 QTest::newRow("vector: bad number of args") << "vector(4, list{23}, 44)";
445
446 QTest::newRow("matrix: 0 args") << "matrix()";
447 QTest::newRow("matrix: bad args") << "matrix(list{3}, 31)";
448 QTest::newRow("matrix: invalid parameter") << "matrix(range(list{matrix{2}}))";
449 QTest::newRow("matrix: empty matrix result") << "matrix(0, 0)";
450 QTest::newRow("matrix: fill empty matrix result") << "matrix(0, 0, sin(1))";
451 QTest::newRow("matrix: not all vectors") << "matrix(vector{1}, 3)";
452 QTest::newRow("matrix: not all matrixrow elements") << "matrix(matrixrow{1}, list{2})";
453 QTest::newRow("matrix: not all matrixrow elements 2") << "matrix(matrixrow{1}, vector{2})";
454 QTest::newRow("matrix: neg square") << "matrix(-9)";
455
456 QTest::newRow("zero matrix: empty matrix result") << "matrix(0, 0)";
457 QTest::newRow("zero matrix: bad number of args") << "matrix()";
458 QTest::newRow("zero matrix: bad number of args") << "matrix(3,list{3},4,6)";
459 QTest::newRow("zero matrix: bad dim") << "matrix(23, -3.5)";
460 QTest::newRow("zero matrix: bad dim2") << "matrix(-23, 5)";
461
462 QTest::newRow("identity matrix: bad arg") << "identitymatrix(-98)";
463 QTest::newRow("identity matrix: empty matrix result") << "identitymatrix(0)";
464
465 QTest::newRow("diag: 0 args") << "diag()";
466 QTest::newRow("diag: bad arg, one empty matrix") << "diag(identitymatrix(0))";
467 QTest::newRow("diag: bad arg, one empty matrix2") << "diag(matrix{matrixrow{}})";
468 QTest::newRow("diag: bad diag index") << "diag(matrix(4,6,3.2), -98)";
469 QTest::newRow("diag: bad diag index type") << "diag(matrix(4,6,3.2), list{-98})";
470 QTest::newRow("diag: invalid parameter") << "diag(matrix(-8,5))";
471
472 QTest::newRow("tridiag: empty matrix result") << "tridiag(1,2,3,0)";
473 QTest::newRow("tridiag: bad number of args") << "tridiag(1,2,2)";
474 QTest::newRow("tridiag: bad number of args2") << "tridiag(1,2,2, 4, list{2})";
475
476 QTest::newRow("iszeromatrix: bad number of args") << "iszeromatrix()";
477 QTest::newRow("iszeromatrix: empty matrix") << "iszeromatrix(matrix{})";
478 QTest::newRow("iszeromatrix: invalid parameter") << "iszeromatrix(matrix(-8,5))";
479
480 QTest::newRow("isidentitymatrix: bad number of args") << "isidentitymatrix(matrix{matrixrow{1}}, 2)";
481 QTest::newRow("isidentitymatrix: bad number of args2") << "isidentitymatrix()";
482 QTest::newRow("isidentitymatrix: empty matrix") << "isidentitymatrix(matrix{})";
483 QTest::newRow("isidentitymatrix: empty matrix2") << "isidentitymatrix(matrix{matrixrow{}})";
484 QTest::newRow("isidentitymatrix: invalid parameter") << "isidentitymatrix(matrix(-8,5))";
485 QTest::newRow("isidentitymatrix: invalid parameter2") << "isidentitymatrix(matrix(list{},5))";
486
487 QTest::newRow("isdiag: bad number of args") << "isdiag(matrix{matrixrow{1}}, 2)";
488 QTest::newRow("isdiag: bad number of args2") << "isdiag()";
489 QTest::newRow("isdiag: empty matrix") << "isdiag(matrix{})";
490 QTest::newRow("isdiag: empty matrix2") << "isdiag(matrix{matrixrow{}})";
491 QTest::newRow("isdiag: invalid parameter") << "isdiag(matrix(-8,5))";
492
493 QTest::newRow("blockmatrix: bad block matrix size") << "blockmatrix(vector{matrix(1,2), matrix(32,13)})";
494 QTest::newRow("blockmatrix: empty matrix1") << "blockmatrix(vector{matrix{}}, vector{matrix{matrixrow{}}})";
495 QTest::newRow("blockmatrix: empty matrix2") << "blockmatrix(vector{identitymatrix(0)})";
496 QTest::newRow("blockmatrix: bad arg type") << "blockmatrix(vector{-5})";
497 QTest::newRow("blockmatrix: err arg") << "blockmatrix(vector{matrix{-98}})";
498 QTest::newRow("blockmatrix: bad block matrix args size") << "blockmatrix(vector{matrix(1,2), matrix(32,13)}, vector{matrix(7,13)})";
499 QTest::newRow("blockmatrix: bad block matrix args type 1") << "blockmatrix(vector{matrix(32,13), list{23}}, vector{matrix(7,13), matrix(32,1)})";
500 QTest::newRow("blockmatrix: bad block matrix args type 2") << "matrix(vector{list{23}, zeromatrix(32,13)}, vector{zeromatrix(7,13), zeromatrix(32,1)})";
501
502 QTest::newRow("blockdiag: bad block diag, empty matrix 1") << "blockdiag(matrix(0,0), matrix(2,2,1))";
503 QTest::newRow("blockdiag: empty matrix1") << "blockdiag(matrix{})";
504 QTest::newRow("blockdiag: empty matrix2") << "blockdiag(identitymatrix(0))";
505 QTest::newRow("blockdiag: bad arg type") << "blockdiag(vector{-5})";
506 QTest::newRow("blockdiag: bad block diag, empty matrix 2") << "blockdiag(matrix{matrixrow{1}}, tridiag(1,2,3,0))";
507 QTest::newRow("blockdiag: invalid parameter") << "blockdiag(matrix(-8,5))";
508
509 QTest::newRow("bad dimensions:2x2identitymatrix and 2x1zeromatrix") << "2*(identitymatrix(2) + matrix(2,1))";
510 QTest::newRow("bad dimensions:2x2identitymatrix and -2x2matrix") << "2*(identitymatrix(2) + matrix(-2, 2,1))";
511
512 #ifdef HAVE_EIGEN3
513 QTest::newRow("eigenvalues: bad args type1") << "eigenvalues(list{23},4)";
514 QTest::newRow("eigenvalues: bad args type2") << "eigenvalues(list{23})";
515 QTest::newRow("eigenvalues: empty matrix2") << "eigenvalues(matrix{})";
516 QTest::newRow("eigenvalues: empty invalid matrix2") << "eigenvalues(matrix{1}, matrix{})";
517 QTest::newRow("eigenvalues: bad numbe of args") << "eigenvalues(identitymatrix(3), zeromatrix(4,5))";
518 QTest::newRow("eigenvalues: empty matrix") << "eigenvalues(matrix{matrixrow{1,2}}, matrix{})";
519 QTest::newRow("eigenvalues: invalid arg types1") << "eigenvalues(matrix{matrixrow{1,2}}, matrix{matrixrow{list{5},6}})";
520 QTest::newRow("eigenvalues: invalid arg types2") << "eigenvalues(matrix{matrixrow{1,list{2}}})";
521 QTest::newRow("eigenvalues: non square matrix") << "eigenvalues(matrix{matrixrow{1,2,3}})";
522 //TODO nan and inf cases
523 #endif
524 }
525
testIncorrect()526 void CommandsTest::testIncorrect()
527 {
528 QFETCH(QString, expression);
529
530 Expression exp(expression, false);
531
532 if (exp.isCorrect()) {
533 Analitza::Analyzer a;
534 a.setExpression(exp);
535
536 if (a.isCorrect()) {
537 Expression calc = a.calculate();
538 QVERIFY(!a.isCorrect());
539 QCOMPARE(calc.toString(), QString());
540 qDebug() << "calc errors:" << a.errors();
541
542 Expression eval = a.evaluate();
543 QVERIFY(!a.isCorrect());
544 QCOMPARE(eval.toString(), QString());
545 qDebug() << "eval errors:" << a.errors();
546 } else {
547 QVERIFY(!a.isCorrect());
548 qDebug() << "set expression errors:" << a.errors();
549 }
550 } else {
551 qDebug() << "expression errors:" << exp.error();
552 }
553 }
554
555
556