1 #include "stdafx.h"
2 #include <sstream>
3 #include <math.h>
4
5 #include "alglibmisc.h"
6 #include "alglibinternal.h"
7 #include "linalg.h"
8 #include "statistics.h"
9 #include "dataanalysis.h"
10 #include "specialfunctions.h"
11 #include "solvers.h"
12 #include "optimization.h"
13 #include "diffequations.h"
14 #include "fasttransforms.h"
15 #include "integration.h"
16 #include "interpolation.h"
17
18 using namespace alglib;
19
20 const char *fmt_str = "%-29s %s\n";
21 const char *fmt_speedup = "%-25s %5.1fx\n";
22
23 //
24 // Flag variables
25 //
26 bool issue505_passed = true;
27 bool issue478_passed = true;
28 bool issue528_passed = true;
29 bool issue591_passed = true;
30 bool issue594_passed = true;
31 bool issue764_passed = true;
32 bool issue813_passed = true;
33
34 //
35 // Service datatypes
36 //
37 typedef struct
38 {
39 alglib_impl::ae_complex cval;
40 double rval;
41 alglib_impl::ae_int_t ival;
42 ae_bool bval;
43 alglib_impl::ae_vector i1val;
44 } innerrec;
45
46
47 typedef struct
48 {
49 ae_bool bval;
50 innerrec recval;
51 alglib_impl::ae_shared_pool pool;
52 } seedrec;
53
_innerrec_init(void * _p,alglib_impl::ae_state * _state,ae_bool make_automatic)54 void _innerrec_init(void* _p, alglib_impl::ae_state *_state, ae_bool make_automatic)
55 {
56 innerrec *p = (innerrec*)_p;
57 alglib_impl::ae_touch_ptr((void*)p);
58 alglib_impl::ae_vector_init(&p->i1val, 0, alglib_impl::DT_INT, _state, make_automatic);
59 }
60
61
_innerrec_init_copy(void * _dst,void * _src,alglib_impl::ae_state * _state,ae_bool make_automatic)62 void _innerrec_init_copy(void* _dst, void* _src, alglib_impl::ae_state *_state, ae_bool make_automatic)
63 {
64 innerrec *dst = (innerrec*)_dst;
65 innerrec *src = (innerrec*)_src;
66 dst->cval = src->cval;
67 dst->rval = src->rval;
68 dst->ival = src->ival;
69 dst->bval = src->bval;
70 alglib_impl::ae_vector_init_copy(&dst->i1val, &src->i1val, _state, make_automatic);
71 }
72
73
_innerrec_clear(void * _p)74 void _innerrec_clear(void* _p)
75 {
76 innerrec *p = (innerrec*)_p;
77 alglib_impl::ae_touch_ptr((void*)p);
78 alglib_impl::ae_vector_clear(&p->i1val);
79 }
80
81
_innerrec_destroy(void * _p)82 void _innerrec_destroy(void* _p)
83 {
84 innerrec *p = (innerrec*)_p;
85 alglib_impl::ae_touch_ptr((void*)p);
86 alglib_impl::ae_vector_destroy(&p->i1val);
87 }
88
89
_seedrec_init(void * _p,alglib_impl::ae_state * _state,ae_bool make_automatic)90 void _seedrec_init(void* _p, alglib_impl::ae_state *_state, ae_bool make_automatic)
91 {
92 seedrec *p = (seedrec*)_p;
93 alglib_impl::ae_touch_ptr((void*)p);
94 _innerrec_init(&p->recval, _state, make_automatic);
95 alglib_impl::ae_shared_pool_init(&p->pool, _state, make_automatic);
96 }
97
98
_seedrec_init_copy(void * _dst,void * _src,alglib_impl::ae_state * _state,ae_bool make_automatic)99 void _seedrec_init_copy(void* _dst, void* _src, alglib_impl::ae_state *_state, ae_bool make_automatic)
100 {
101 seedrec *dst = (seedrec*)_dst;
102 seedrec *src = (seedrec*)_src;
103 dst->bval = src->bval;
104 _innerrec_init_copy(&dst->recval, &src->recval, _state, make_automatic);
105 alglib_impl::ae_shared_pool_init_copy(&dst->pool, &src->pool, _state, make_automatic);
106 }
107
108
_seedrec_clear(void * _p)109 void _seedrec_clear(void* _p)
110 {
111 seedrec *p = (seedrec*)_p;
112 alglib_impl::ae_touch_ptr((void*)p);
113 _innerrec_clear(&p->recval);
114 alglib_impl::ae_shared_pool_clear(&p->pool);
115 }
116
117
_seedrec_destroy(void * _p)118 void _seedrec_destroy(void* _p)
119 {
120 seedrec *p = (seedrec*)_p;
121 alglib_impl::ae_touch_ptr((void*)p);
122 _innerrec_destroy(&p->recval);
123 alglib_impl::ae_shared_pool_destroy(&p->pool);
124 }
125
func505_grad(const real_1d_array & x,double & func,real_1d_array & grad,void * ptr)126 void func505_grad(const real_1d_array &x, double &func, real_1d_array &grad, void *ptr)
127 {
128 double x0 = *((double*)ptr);
129
130 //
131 // This block assigns zero vector to gradient. Because gradient is a proxy vector
132 // (vector which uses another object as storage), sizes of gradient and vector being
133 // assigned must be equal. In this case data are copied in the memory linked with
134 // proxy.
135 //
136 // Early versions of ALGLIB failed to handle such assignment (it discrupted link
137 // between proxy vector and actual gradient stored in the internals of ALGLIB).
138 //
139 real_1d_array z = "[0]";
140 grad = "[0]";
141 grad = z;
142
143 //
144 // This block tries to perform operations which are forbidden for proxy vector:
145 // * assign vector of non-matching size
146 // * change length of the vector
147 // Correct implementation must throw an exception without breaking a link between
148 // proxy object and actual vector.
149 //
150 z = "[0,1]";
151 try
152 {
153 grad = "[0,1]";
154 issue505_passed = false;
155 }
156 catch(...) {}
157 try
158 {
159 grad = z;
160 issue505_passed = false;
161 }
162 catch(...) {}
163 try
164 {
165 grad.setlength(10);
166 issue505_passed = false;
167 }
168 catch(...) {}
169 try
170 {
171 grad.setlength(1);
172 issue505_passed = false;
173 }
174 catch(...) {}
175
176 //
177 // This block actually calculates function/gradient
178 //
179 func = pow(x[0]-x0,4);
180 grad[0] = 4*pow(x[0]-x0,3);
181 }
182
func505_vec(const real_1d_array & x,real_1d_array & fi,void * ptr)183 void func505_vec(const real_1d_array &x, real_1d_array &fi, void *ptr)
184 {
185 double x0 = *((double*)ptr);
186 fi[0] = x[0]-x0;
187 fi[1] = pow(x[0]-x0,2);
188 }
189
func505_jac(const real_1d_array & x,real_1d_array & fi,real_2d_array & jac,void * ptr)190 void func505_jac(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr)
191 {
192 double x0 = *((double*)ptr);
193
194 //
195 // This block assigns zero matrix to Jacobian. Because Jacobian is a proxy matrix
196 // (matrix which uses another object as storage), sizes of Jacobian and matrix being
197 // assigned must be equal. In this case data are copied in the memory linked with
198 // proxy.
199 //
200 // Early versions of ALGLIB failed to handle such assignment (it discrupted link
201 // between proxy and actual matrix stored in the internals of ALGLIB).
202 //
203 real_2d_array z = "[[0],[0]]";
204 jac = "[[0],[0]]";
205 jac = z;
206
207 //
208 // This block tries to perform operations which are forbidden for proxy vector:
209 // * assign vector of non-matching size
210 // * change length of the vector
211 // Correct implementation must throw an exception without breaking a link between
212 // proxy object and actual vector.
213 //
214 try
215 {
216 jac = "[[0]]";
217 issue505_passed = false;
218 }
219 catch(...) {}
220 try
221 {
222 jac = "[[0,0],[1,1]]";
223 issue505_passed = false;
224 }
225 catch(...) {}
226 try
227 {
228 z = "[[0,1]]";
229 jac = z;
230 issue505_passed = false;
231 }
232 catch(...) {}
233 try
234 {
235 jac.setlength(10,6);
236 issue505_passed = false;
237 }
238 catch(...) {}
239 try
240 {
241 jac.setlength(2,1);
242 issue505_passed = false;
243 }
244 catch(...) {}
245
246 //
247 // This block actually calculates function/gradient
248 //
249 fi[0] = x[0]-x0;
250 fi[1] = pow(x[0]-x0,2);
251 jac[0][0] = 1.0;
252 jac[1][0] = 2*(x[0]-x0);
253 }
254
issue813_callback(const alglib::real_1d_array &,alglib::real_1d_array &,void *)255 void issue813_callback(const alglib::real_1d_array&, alglib::real_1d_array&, void*)
256 {
257 throw 0;
258 }
259
file_put_contents(const char * filename,const char * contents)260 void file_put_contents(const char *filename, const char *contents)
261 {
262 FILE *f = fopen(filename, "wb");
263 if( f==NULL )
264 throw alglib::ap_error("file_put_contents: failed opening file");
265 if( fwrite((void*)contents, 1, strlen(contents), f)!=strlen(contents) )
266 throw alglib::ap_error("file_put_contents: failed writing to file");
267 fclose(f);
268 }
269
main()270 int main()
271 {
272 //
273 // Report system properties
274 //
275 printf("System:\n");
276 #ifdef AE_HPC
277 printf("* cores count %3ld\n", (long)alglib_impl::ae_cores_count());
278 #else
279 printf("* cores count %3ld\n", (long)1);
280 #endif
281
282 //
283 // Check status of allocation counter
284 //
285 #ifdef AE_USE_ALLOC_COUNTER
286 printf("Allocation counter activated...\n");
287 alglib_impl::_use_alloc_counter = ae_true;
288 if( alglib_impl::_alloc_counter!=0 )
289 {
290 printf("FAILURE: alloc_counter is non-zero on start!\n");
291 return 1;
292 }
293 {
294 alglib::real_1d_array x;
295 x.setlength(1);
296 if( alglib_impl::_alloc_counter==0 )
297 printf(":::: WARNING: ALLOC_COUNTER IS INACTIVE!!! :::::\n");
298 }
299 if( alglib_impl::_alloc_counter!=0 )
300 {
301 printf("FAILURE: alloc_counter does not decrease!\n");
302 return 1;
303 }
304 #else
305 printf("No alloc counter.\nSome tests are skipped.\n");
306 #endif
307
308 //
309 // Testing basic functionality
310 //
311 printf("Basic functions:\n");
312 {
313 //
314 // Testing 1D array functionality
315 //
316 bool passed = true;
317 try
318 {
319 //
320 // 1D boolean
321 //
322 // Default constructor, string constructor, copy constructor, assignment constructors:
323 // * test that array sizes as reported by length match to what was specified
324 // * test item-by-item access
325 // * test to_string()
326 // * test that modification of the copied array does not change original
327 // * test that setlength() changes length
328 // * test setcontent/getcontent
329 // * test getcontent(), operator() and operator[] on constant arrays
330 // (in this case distinct implementation is used which must be tested separately)
331 //
332 alglib::boolean_1d_array arr_0, arr_1("[]"), arr_2("[true,false,true]"), arr_3(arr_2), arr_4, arr_5;
333 arr_4 = arr_2;
334 arr_5 = "[true,true,false]";
335 passed = passed && (arr_0.length()==0);
336 passed = passed && (arr_1.length()==0);
337 passed = passed && (arr_2.length()==3);
338 passed = passed && (arr_3.length()==3);
339 passed = passed && (arr_2[0]==arr_2(0)) && (arr_2[1]==arr_2(1)) && (arr_2[2]==arr_2(2));
340 passed = passed && arr_2[0] && !arr_2[1] && arr_2[2];
341 passed = passed && arr_3[0] && !arr_3[1] && arr_3[2];
342 passed = passed && arr_4[0] && !arr_4[1] && arr_4[2];
343 passed = passed && arr_5[0] && arr_5[1] && !arr_5[2];
344 passed = passed && (arr_2.tostring()=="[true,false,true]");
345 passed = passed && (arr_3.tostring()=="[true,false,true]");
346 passed = passed && (arr_4.tostring()=="[true,false,true]");
347 passed = passed && (arr_5.tostring()=="[true,true,false]");
348 arr_2[0] = false;
349 passed = passed && !arr_2[0] && arr_3[0] && arr_4[0];
350 arr_5.setlength(99);
351 passed = passed && (arr_5.length()==99);
352
353 // setcontent/getcontent
354 bool a0[] = {true, false, true, false, false};
355 bool a0_mod = false;
356 bool a0_orig = true;
357 bool *p6;
358 alglib::boolean_1d_array arr_6;
359 arr_6.setcontent(5, a0);
360 passed = passed && (arr_6[0]==a0[0]) && (arr_6[1]==a0[1]) && (arr_6[2]==a0[2]) && (arr_6[3]==a0[3]) && (arr_6[4]==a0[4]);
361 p6 = arr_6.getcontent();
362 passed = passed && (p6!=a0);
363 passed = passed && (p6[0]==a0[0]) && (p6[1]==a0[1]) && (p6[2]==a0[2]) && (p6[3]==a0[3]) && (p6[4]==a0[4]);
364 a0[0] = a0_mod;
365 passed = passed && (arr_6[0]!=a0[0]);
366 a0[0] = a0_orig;
367
368 // operations on constant arrays
369 {
370 const alglib::boolean_1d_array &ac = arr_6;
371 passed = passed && (ac[0]==a0[0]) && (ac[1]==a0[1]) && (ac[2]==a0[2]) && (ac[3]==a0[3]) && (ac[4]==a0[4]);
372 passed = passed && (ac(0)==a0[0]) && (ac(1)==a0[1]) && (ac(2)==a0[2]) && (ac(3)==a0[3]) && (ac(4)==a0[4]);
373 const bool *p = ac.getcontent();
374 passed = passed && (p[0]==a0[0]) && (p[1]==a0[1]) && (p[2]==a0[2]) && (p[3]==a0[3]) && (p[4]==a0[4]);
375 }
376
377 //
378 // Operations with proxy arrays:
379 // * changes in target are propagated to proxy and vice versa
380 // * assignments where proxy is source create new independent copy
381 // * assignments to proxy are checked (their size must match to that of the target)
382 // * incorrect assignments or attempts to change length must generate exception
383 // * attempts to call setlength() must fail even when new size match original size
384 // of the array
385 //
386 alglib::boolean_1d_array targt, acopy;
387 targt = "[true,false,false,true]";
388 alglib::boolean_1d_array proxy(targt.c_ptr());
389 acopy = proxy;
390 passed = passed && targt[0] && !targt[1] && !targt[2] && targt[3];
391 passed = passed && proxy[0] && !proxy[1] && !proxy[2] && proxy[3];
392 passed = passed && acopy[0] && !acopy[1] && !acopy[2] && acopy[3];
393
394 targt[0] = false;
395 passed = passed && !targt[0] && !proxy[0] && acopy[0];
396 proxy[0] = true;
397 passed = passed && targt[0] && proxy[0] && acopy[0];
398
399 acopy = "[false,true,true,true]";
400 proxy = acopy;
401 passed = passed && !targt[0] && targt[1] && targt[2] && targt[3];
402 passed = passed && !proxy[0] && proxy[1] && proxy[2] && proxy[3];
403 proxy = "[true,false,true,true]";
404 passed = passed && targt[0] && !targt[1] && targt[2] && targt[3];
405 passed = passed && proxy[0] && !proxy[1] && proxy[2] && proxy[3];
406
407 try
408 {
409 acopy = "[false,true,true]";
410 proxy = acopy;
411 passed = false;
412 }
413 catch(alglib::ap_error e)
414 { }
415 catch(...)
416 { passed = false; }
417
418 try
419 {
420 proxy = "[true,true,true]";
421 passed = false;
422 }
423 catch(alglib::ap_error e)
424 { }
425 catch(...)
426 { passed = false; }
427
428 try
429 {
430 proxy.setlength(100);
431 passed = false;
432 }
433 catch(alglib::ap_error e)
434 { }
435 catch(...)
436 { passed = false; }
437
438 try
439 {
440 proxy.setlength(proxy.length());
441 passed = false;
442 }
443 catch(alglib::ap_error e)
444 { }
445 catch(...)
446 { passed = false; }
447 }
448 catch(...)
449 { passed = false; }
450 try
451 {
452 //
453 // 1D integer
454 //
455 // Default constructor, string constructor, copy constructor, assignment constructors:
456 // * test that array sizes as reported by length match to what was specified
457 // * test item-by-item access
458 // * test to_string()
459 // * test that modification of the copied array does not change original
460 // * test that setlength() changes length
461 //
462 const char *s1 = "[2,3,-1]";
463 const char *s2 = "[5,4,3]";
464 const char *s3 = "[6,7,3,-4]";
465 const char *s4 = "[9,5,-12,-0]";
466 const char *s5 = "[1,7,2,1]";
467 const char *s6 = "[7,7,7]";
468 int v10 = 2, v11 = 3, v12 = -1, v10_mod = 9;
469 int v20 = 5, v21 = 4, v22 = 3;
470 int v30 = 6, v31 = 7, v32 = 3, v33 = -4, v30_mod = -6;
471 int v40 = 9, v41 = 5, v42 =-12, v43 = 0;
472 int v50 = 1, v51 = 7, v52 = 2, v53 = 1;
473
474 alglib::integer_1d_array arr_0, arr_1("[]"), arr_2(s1), arr_3(arr_2), arr_4, arr_5;
475 arr_4 = arr_2;
476 arr_5 = s2;
477 passed = passed && (arr_0.length()==0);
478 passed = passed && (arr_1.length()==0);
479 passed = passed && (arr_2.length()==3);
480 passed = passed && (arr_3.length()==3);
481 passed = passed && (arr_2[0]==arr_2(0)) && (arr_2[1]==arr_2(1)) && (arr_2[2]==arr_2(2));
482 passed = passed && (arr_2[0]==v10) && (arr_2[1]==v11) && (arr_2[2]==v12);
483 passed = passed && (arr_3[0]==v10) && (arr_3[1]==v11) && (arr_3[2]==v12);
484 passed = passed && (arr_4[0]==v10) && (arr_4[1]==v11) && (arr_4[2]==v12);
485 passed = passed && (arr_5[0]==v20) && (arr_5[1]==v21) && (arr_5[2]==v22);
486 passed = passed && (arr_2.tostring()==s1);
487 passed = passed && (arr_3.tostring()==s1);
488 passed = passed && (arr_4.tostring()==s1);
489 passed = passed && (arr_5.tostring()==s2);
490 arr_2[0] = v10_mod;
491 passed = passed && (arr_2[0]==v10_mod) && (arr_3[0]==v10) && (arr_4[0]==v10);
492 arr_5.setlength(99);
493 passed = passed && (arr_5.length()==99);
494
495 // setcontent/getcontent
496 alglib::ae_int_t a0[] = {2, 3, 1, 9, 2};
497 alglib::ae_int_t a0_mod = 7;
498 alglib::ae_int_t a0_orig = 2;
499 alglib::ae_int_t *p6;
500 alglib::integer_1d_array arr_6;
501 arr_6.setcontent(5, a0);
502 passed = passed && (arr_6[0]==a0[0]) && (arr_6[1]==a0[1]) && (arr_6[2]==a0[2]) && (arr_6[3]==a0[3]) && (arr_6[4]==a0[4]);
503 p6 = arr_6.getcontent();
504 passed = passed && (p6!=a0);
505 passed = passed && (p6[0]==a0[0]) && (p6[1]==a0[1]) && (p6[2]==a0[2]) && (p6[3]==a0[3]) && (p6[4]==a0[4]);
506 a0[0] = a0_mod;
507 passed = passed && (arr_6[0]!=a0[0]);
508 a0[0] = a0_orig;
509
510 // operations on constant arrays
511 {
512 const alglib::integer_1d_array &ac = arr_6;
513 passed = passed && (ac[0]==a0[0]) && (ac[1]==a0[1]) && (ac[2]==a0[2]) && (ac[3]==a0[3]) && (ac[4]==a0[4]);
514 passed = passed && (ac(0)==a0[0]) && (ac(1)==a0[1]) && (ac(2)==a0[2]) && (ac(3)==a0[3]) && (ac(4)==a0[4]);
515 const alglib::ae_int_t *p = ac.getcontent();
516 passed = passed && (p[0]==a0[0]) && (p[1]==a0[1]) && (p[2]==a0[2]) && (p[3]==a0[3]) && (p[4]==a0[4]);
517 }
518
519 //
520 // Operations with proxy arrays:
521 // * changes in target are propagated to proxy and vice versa
522 // * assignments where proxy is source create new independent copy
523 // * assignments to proxy are checked (their size must match to that of the target)
524 // * incorrect assignments or attempts to change length must generate exception
525 // * attempts to call setlength() must fail even when new size match original size
526 // of the array
527 //
528 alglib::integer_1d_array targt, acopy;
529 targt = s3;
530 alglib::integer_1d_array proxy(targt.c_ptr());
531 acopy = proxy;
532 passed = passed && (targt[0]==v30) && (targt[1]==v31) && (targt[2]==v32) && (targt[3]==v33);
533 passed = passed && (proxy[0]==v30) && (proxy[1]==v31) && (proxy[2]==v32) && (proxy[3]==v33);
534 passed = passed && (acopy[0]==v30) && (acopy[1]==v31) && (acopy[2]==v32) && (acopy[3]==v33);
535
536 targt[0] = v30_mod;
537 passed = passed && (targt[0]==v30_mod) && (proxy[0]==v30_mod) && (acopy[0]==v30);
538 proxy[0] = v30;
539 passed = passed && (targt[0]==v30) && (proxy[0]==v30) && (acopy[0]==v30);
540
541 acopy = s4;
542 proxy = acopy;
543 passed = passed && (targt[0]==v40) && (targt[1]==v41) && (targt[2]==v42) && (targt[3]==v43);
544 passed = passed && (proxy[0]==v40) && (proxy[1]==v41) && (proxy[2]==v42) && (proxy[3]==v43);
545 proxy = s5;
546 passed = passed && (targt[0]==v50) && (targt[1]==v51) && (targt[2]==v52) && (targt[3]==v53);
547 passed = passed && (proxy[0]==v50) && (proxy[1]==v51) && (proxy[2]==v52) && (proxy[3]==v53);
548
549 try
550 {
551 acopy = s6;
552 proxy = acopy;
553 passed = false;
554 }
555 catch(alglib::ap_error e)
556 { }
557 catch(...)
558 { passed = false; }
559
560 try
561 {
562 proxy = s6;
563 passed = false;
564 }
565 catch(alglib::ap_error e)
566 { }
567 catch(...)
568 { passed = false; }
569
570 try
571 {
572 proxy.setlength(100);
573 passed = false;
574 }
575 catch(alglib::ap_error e)
576 { }
577 catch(...)
578 { passed = false; }
579
580 try
581 {
582 proxy.setlength(proxy.length());
583 passed = false;
584 }
585 catch(alglib::ap_error e)
586 { }
587 catch(...)
588 { passed = false; }
589 }
590 catch(...)
591 { passed = false; }
592 try
593 {
594 //
595 // 1D real
596 //
597 // Default constructor, string constructor, copy constructor, assignment constructors:
598 // * test that array sizes as reported by length match to what was specified
599 // * test item-by-item access
600 // * test to_string()
601 // * test that modification of the copied array does not change original
602 // * test that setlength() changes length
603 //
604 const char *s1 = "[2,3.5,-2.5E-1]";
605 const char *s1_fmt = "[2.00,3.50,-0.25]";
606 const char *s2 = "[5,4,3.126]";
607 const char *s2_fmt = "[5.00,4.00,3.13]";
608 const char *s3 = "[6,7,3,-4E2]";
609 const char *s4 = "[9,5,-12,-0.01]";
610 const char *s5 = "[1,7,2,1]";
611 const char *s6 = "[7,7,7]";
612 const int dps = 2;
613 const double v10 = 2, v11 = 3.5, v12 = -0.25, v10_mod = 9;
614 const double v20 = 5, v21 = 4, v22 = 3.126;
615 const double v30 = 6, v31 = 7, v32 = 3, v33 = -400, v30_mod = -6;
616 const double v40 = 9, v41 = 5, v42 =-12, v43 = -0.01;
617 const double v50 = 1, v51 = 7, v52 = 2, v53 = 1;
618
619 alglib::real_1d_array arr_0, arr_1("[]"), arr_2(s1), arr_3(arr_2), arr_4, arr_5;
620 arr_4 = arr_2;
621 arr_5 = s2;
622 passed = passed && (arr_0.length()==0);
623 passed = passed && (arr_1.length()==0);
624 passed = passed && (arr_2.length()==3);
625 passed = passed && (arr_3.length()==3);
626 passed = passed && (arr_2[0]==arr_2(0)) && (arr_2[1]==arr_2(1)) && (arr_2[2]==arr_2(2));
627 passed = passed && (arr_2[0]==v10) && (arr_2[1]==v11) && (arr_2[2]==v12);
628 passed = passed && (arr_3[0]==v10) && (arr_3[1]==v11) && (arr_3[2]==v12);
629 passed = passed && (arr_4[0]==v10) && (arr_4[1]==v11) && (arr_4[2]==v12);
630 passed = passed && (arr_5[0]==v20) && (arr_5[1]==v21) && (arr_5[2]==v22);
631 passed = passed && (arr_2.tostring(dps)==s1_fmt);
632 passed = passed && (arr_3.tostring(dps)==s1_fmt);
633 passed = passed && (arr_4.tostring(dps)==s1_fmt);
634 passed = passed && (arr_5.tostring(dps)==s2_fmt);
635 arr_2[0] = v10_mod;
636 passed = passed && (arr_2[0]==v10_mod) && (arr_3[0]==v10) && (arr_4[0]==v10);
637 arr_5.setlength(99);
638 passed = passed && (arr_5.length()==99);
639
640 // setcontent/getcontent
641 double a0[] = {2, 3.5, 1, 9.125, 2};
642 double a0_mod = 7;
643 double a0_orig = 2;
644 double *p6;
645 alglib::real_1d_array arr_6;
646 arr_6.setcontent(5, a0);
647 passed = passed && (arr_6[0]==a0[0]) && (arr_6[1]==a0[1]) && (arr_6[2]==a0[2]) && (arr_6[3]==a0[3]) && (arr_6[4]==a0[4]);
648 p6 = arr_6.getcontent();
649 passed = passed && (p6!=a0);
650 passed = passed && (p6[0]==a0[0]) && (p6[1]==a0[1]) && (p6[2]==a0[2]) && (p6[3]==a0[3]) && (p6[4]==a0[4]);
651 a0[0] = a0_mod;
652 passed = passed && (arr_6[0]!=a0[0]);
653 a0[0] = a0_orig;
654
655 // operations on constant arrays
656 {
657 const alglib::real_1d_array &ac = arr_6;
658 passed = passed && (ac[0]==a0[0]) && (ac[1]==a0[1]) && (ac[2]==a0[2]) && (ac[3]==a0[3]) && (ac[4]==a0[4]);
659 passed = passed && (ac(0)==a0[0]) && (ac(1)==a0[1]) && (ac(2)==a0[2]) && (ac(3)==a0[3]) && (ac(4)==a0[4]);
660 const double *p = ac.getcontent();
661 passed = passed && (p[0]==a0[0]) && (p[1]==a0[1]) && (p[2]==a0[2]) && (p[3]==a0[3]) && (p[4]==a0[4]);
662 }
663
664 //
665 // Operations with proxy arrays attached via attach_to(ae_vector*):
666 // * changes in target are propagated to proxy and vice versa
667 // * assignments where proxy is source create new independent copy
668 // * assignments to proxy are checked (their size must match to that of the target)
669 // * incorrect assignments or attempts to change length must generate exception
670 // * attempts to call setlength() must fail even when new size match original size
671 // of the array
672 //
673 {
674 alglib::real_1d_array targt, acopy;
675 targt = s3;
676 alglib::real_1d_array proxy(targt.c_ptr());
677 acopy = proxy;
678 passed = passed && (targt[0]==v30) && (targt[1]==v31) && (targt[2]==v32) && (targt[3]==v33);
679 passed = passed && (proxy[0]==v30) && (proxy[1]==v31) && (proxy[2]==v32) && (proxy[3]==v33);
680 passed = passed && (acopy[0]==v30) && (acopy[1]==v31) && (acopy[2]==v32) && (acopy[3]==v33);
681
682 targt[0] = v30_mod;
683 passed = passed && (targt[0]==v30_mod) && (proxy[0]==v30_mod) && (acopy[0]==v30);
684 proxy[0] = v30;
685 passed = passed && (targt[0]==v30) && (proxy[0]==v30) && (acopy[0]==v30);
686
687 acopy = s4;
688 proxy = acopy;
689 passed = passed && (targt[0]==v40) && (targt[1]==v41) && (targt[2]==v42) && (targt[3]==v43);
690 passed = passed && (proxy[0]==v40) && (proxy[1]==v41) && (proxy[2]==v42) && (proxy[3]==v43);
691 proxy = s5;
692 passed = passed && (targt[0]==v50) && (targt[1]==v51) && (targt[2]==v52) && (targt[3]==v53);
693 passed = passed && (proxy[0]==v50) && (proxy[1]==v51) && (proxy[2]==v52) && (proxy[3]==v53);
694
695 try
696 {
697 acopy = s6;
698 proxy = acopy;
699 passed = false;
700 }
701 catch(alglib::ap_error e)
702 { }
703 catch(...)
704 { passed = false; }
705
706 try
707 {
708 proxy = s6;
709 passed = false;
710 }
711 catch(alglib::ap_error e)
712 { }
713 catch(...)
714 { passed = false; }
715
716 try
717 {
718 proxy.setlength(100);
719 passed = false;
720 }
721 catch(alglib::ap_error e)
722 { }
723 catch(...)
724 { passed = false; }
725
726 try
727 {
728 proxy.setlength(proxy.length());
729 passed = false;
730 }
731 catch(alglib::ap_error e)
732 { }
733 catch(...)
734 { passed = false; }
735 }
736
737 //
738 // >>> Unique for real_1d_array >>>
739 //
740 // Operations with proxy arrays attached via attach_to(double*):
741 // * changes in target are propagated to proxy and vice versa
742 // * assignments where proxy is source create new independent copy
743 // * assignments to proxy are checked (their size must match to that of the target)
744 // * incorrect assignments or attempts to change length must generate exception
745 // * attempts to call setlength() must fail even when new size match original size
746 // of the array
747 //
748 {
749 alglib::real_1d_array proxy, acopy;
750 double targt[] = {v30, v31, v32, v33};
751 proxy.attach_to_ptr(4, targt);
752 acopy = proxy;
753 passed = passed && (targt[0]==v30) && (targt[1]==v31) && (targt[2]==v32) && (targt[3]==v33);
754 passed = passed && (proxy[0]==v30) && (proxy[1]==v31) && (proxy[2]==v32) && (proxy[3]==v33);
755 passed = passed && (acopy[0]==v30) && (acopy[1]==v31) && (acopy[2]==v32) && (acopy[3]==v33);
756
757 targt[0] = v30_mod;
758 passed = passed && (targt[0]==v30_mod) && (proxy[0]==v30_mod) && (acopy[0]==v30);
759 proxy[0] = v30;
760 passed = passed && (targt[0]==v30) && (proxy[0]==v30) && (acopy[0]==v30);
761
762 acopy = s4;
763 proxy = acopy;
764 passed = passed && (targt[0]==v40) && (targt[1]==v41) && (targt[2]==v42) && (targt[3]==v43);
765 passed = passed && (proxy[0]==v40) && (proxy[1]==v41) && (proxy[2]==v42) && (proxy[3]==v43);
766 proxy = s5;
767 passed = passed && (targt[0]==v50) && (targt[1]==v51) && (targt[2]==v52) && (targt[3]==v53);
768 passed = passed && (proxy[0]==v50) && (proxy[1]==v51) && (proxy[2]==v52) && (proxy[3]==v53);
769
770 try
771 {
772 acopy = s6;
773 proxy = acopy;
774 passed = false;
775 }
776 catch(alglib::ap_error e)
777 { }
778 catch(...)
779 { passed = false; }
780
781 try
782 {
783 proxy = s6;
784 passed = false;
785 }
786 catch(alglib::ap_error e)
787 { }
788 catch(...)
789 { passed = false; }
790
791 try
792 {
793 proxy.setlength(100);
794 passed = false;
795 }
796 catch(alglib::ap_error e)
797 { }
798 catch(...)
799 { passed = false; }
800
801 try
802 {
803 proxy.setlength(proxy.length());
804 passed = false;
805 }
806 catch(alglib::ap_error e)
807 { }
808 catch(...)
809 { passed = false; }
810 }
811 }
812 catch(...)
813 { passed = false; }
814 try
815 {
816 //
817 // 1D complex
818 //
819 // Default constructor, string constructor, copy constructor, assignment constructors:
820 // * test that array sizes as reported by length match to what was specified
821 // * test item-by-item access
822 // * test to_string()
823 // * test that modification of the copied array does not change original
824 // * test that setlength() changes length
825 //
826 const char *s1 = "[2,3.5i,1-2.5E-1i]";
827 const char *s1_fmt = "[2.00,3.50i,1.00-0.25i]";
828 const char *s2 = "[5,-4+1i,3.126]";
829 const char *s2_fmt = "[5.00,-4.00+1.00i,3.13]";
830 const char *s3 = "[6,7,3,-4E2]";
831 const char *s4 = "[9,5,-12,-0.01]";
832 const char *s5 = "[1,7,2,1]";
833 const char *s6 = "[7,7,7]";
834 const int dps = 2;
835 alglib::complex v10 = 2, v11 = alglib::complex(0,3.5), v12 = alglib::complex(1,-0.25), v10_mod = 9;
836 alglib::complex v20 = 5, v21 = alglib::complex(-4,1), v22 = 3.126;
837 alglib::complex v30 = 6, v31 = 7, v32 = 3, v33 = -400, v30_mod = -6;
838 alglib::complex v40 = 9, v41 = 5, v42 =-12, v43 = -0.01;
839 alglib::complex v50 = 1, v51 = 7, v52 = 2, v53 = 1;
840
841 alglib::complex_1d_array arr_0, arr_1("[]"), arr_2(s1), arr_3(arr_2), arr_4, arr_5;
842 arr_4 = arr_2;
843 arr_5 = s2;
844 passed = passed && (arr_0.length()==0);
845 passed = passed && (arr_1.length()==0);
846 passed = passed && (arr_2.length()==3);
847 passed = passed && (arr_3.length()==3);
848 passed = passed && (arr_2[0]==arr_2(0)) && (arr_2[1]==arr_2(1)) && (arr_2[2]==arr_2(2));
849 passed = passed && (arr_2[0]==v10) && (arr_2[1]==v11) && (arr_2[2]==v12);
850 passed = passed && (arr_3[0]==v10) && (arr_3[1]==v11) && (arr_3[2]==v12);
851 passed = passed && (arr_4[0]==v10) && (arr_4[1]==v11) && (arr_4[2]==v12);
852 passed = passed && (arr_5[0]==v20) && (arr_5[1]==v21) && (arr_5[2]==v22);
853 passed = passed && (arr_2.tostring(dps)==s1_fmt);
854 passed = passed && (arr_3.tostring(dps)==s1_fmt);
855 passed = passed && (arr_4.tostring(dps)==s1_fmt);
856 passed = passed && (arr_5.tostring(dps)==s2_fmt);
857 arr_2[0] = v10_mod;
858 passed = passed && (arr_2[0]==v10_mod) && (arr_3[0]==v10) && (arr_4[0]==v10);
859 arr_5.setlength(99);
860 passed = passed && (arr_5.length()==99);
861
862 // setcontent/getcontent
863 alglib::complex a0[] = {2, 3.5, 1, 9.125, 2};
864 alglib::complex a0_mod = 7;
865 alglib::complex a0_orig = 2;
866 alglib::complex *p6;
867 alglib::complex_1d_array arr_6;
868 arr_6.setcontent(5, a0);
869 passed = passed && (arr_6[0]==a0[0]) && (arr_6[1]==a0[1]) && (arr_6[2]==a0[2]) && (arr_6[3]==a0[3]) && (arr_6[4]==a0[4]);
870 p6 = arr_6.getcontent();
871 passed = passed && (p6!=a0);
872 passed = passed && (p6[0]==a0[0]) && (p6[1]==a0[1]) && (p6[2]==a0[2]) && (p6[3]==a0[3]) && (p6[4]==a0[4]);
873 a0[0] = a0_mod;
874 passed = passed && (arr_6[0]!=a0[0]);
875 a0[0] = a0_orig;
876
877 // operations on constant arrays
878 {
879 const alglib::complex_1d_array &ac = arr_6;
880 passed = passed && (ac[0]==a0[0]) && (ac[1]==a0[1]) && (ac[2]==a0[2]) && (ac[3]==a0[3]) && (ac[4]==a0[4]);
881 passed = passed && (ac(0)==a0[0]) && (ac(1)==a0[1]) && (ac(2)==a0[2]) && (ac(3)==a0[3]) && (ac(4)==a0[4]);
882 const alglib::complex *p = ac.getcontent();
883 passed = passed && (p[0]==a0[0]) && (p[1]==a0[1]) && (p[2]==a0[2]) && (p[3]==a0[3]) && (p[4]==a0[4]);
884 }
885
886 //
887 // Operations with proxy arrays:
888 // * changes in target are propagated to proxy and vice versa
889 // * assignments where proxy is source create new independent copy
890 // * assignments to proxy are checked (their size must match to that of the target)
891 // * incorrect assignments or attempts to change length must generate exception
892 // * attempts to call setlength() must fail even when new size match original size
893 // of the array
894 //
895 alglib::complex_1d_array targt, acopy;
896 targt = s3;
897 alglib::complex_1d_array proxy(targt.c_ptr());
898 acopy = proxy;
899 passed = passed && (targt[0]==v30) && (targt[1]==v31) && (targt[2]==v32) && (targt[3]==v33);
900 passed = passed && (proxy[0]==v30) && (proxy[1]==v31) && (proxy[2]==v32) && (proxy[3]==v33);
901 passed = passed && (acopy[0]==v30) && (acopy[1]==v31) && (acopy[2]==v32) && (acopy[3]==v33);
902
903 targt[0] = v30_mod;
904 passed = passed && (targt[0]==v30_mod) && (proxy[0]==v30_mod) && (acopy[0]==v30);
905 proxy[0] = v30;
906 passed = passed && (targt[0]==v30) && (proxy[0]==v30) && (acopy[0]==v30);
907
908 acopy = s4;
909 proxy = acopy;
910 passed = passed && (targt[0]==v40) && (targt[1]==v41) && (targt[2]==v42) && (targt[3]==v43);
911 passed = passed && (proxy[0]==v40) && (proxy[1]==v41) && (proxy[2]==v42) && (proxy[3]==v43);
912 proxy = s5;
913 passed = passed && (targt[0]==v50) && (targt[1]==v51) && (targt[2]==v52) && (targt[3]==v53);
914 passed = passed && (proxy[0]==v50) && (proxy[1]==v51) && (proxy[2]==v52) && (proxy[3]==v53);
915
916 try
917 {
918 acopy = s6;
919 proxy = acopy;
920 passed = false;
921 }
922 catch(alglib::ap_error e)
923 { }
924 catch(...)
925 { passed = false; }
926
927 try
928 {
929 proxy = s6;
930 passed = false;
931 }
932 catch(alglib::ap_error e)
933 { }
934 catch(...)
935 { passed = false; }
936
937 try
938 {
939 proxy.setlength(100);
940 passed = false;
941 }
942 catch(alglib::ap_error e)
943 { }
944 catch(...)
945 { passed = false; }
946
947 try
948 {
949 proxy.setlength(proxy.length());
950 passed = false;
951 }
952 catch(alglib::ap_error e)
953 { }
954 catch(...)
955 { passed = false; }
956 }
957 catch(...)
958 { passed = false; }
959
960 //
961 // Report
962 //
963 printf(fmt_str, "* 1D arrays", passed ? "OK" : "FAILED");
964 fflush(stdout);
965 if( !passed )
966 return 1;
967 }
968
969 {
970 //
971 // Testing 2D array functionality
972 //
973 bool passed = true;
974 try
975 {
976 //
977 // 2D real
978 //
979 // Default constructor, string constructor, copy constructor, assignment constructors:
980 // * test that array sizes as reported by length match to what was specified
981 // * test item-by-item access
982 // * test to_string()
983 // * test that modification of the copied array does not change original
984 // * test that setlength() changes length
985 //
986 const char *s1 = "[[2,3.5,-2.5E-1],[1,2,3]]";
987 const char *s1_fmt = "[[2.00,3.50,-0.25],[1.00,2.00,3.00]]";
988 const char *s2 = "[[5],[4],[3.126]]";
989 const char *s2_fmt = "[[5.00],[4.00],[3.13]]";
990 const char *s3 = "[[6,7],[3,-4E2],[-3,-1]]";
991 const char *s4 = "[[9,5],[-12,-0.01],[-1,-2]]";
992 const char *s5 = "[[1,7],[2,1],[0,4]]";
993 const char *s60 = "[[7,7],[7,7]]";
994 const char *s61 = "[[7],[7],[7]]";
995 const int dps = 2;
996 const double v10 = 2, v11 = 3.5, v12 = -0.25, v13=1, v14 = 2, v15 = 3, v10_mod = 9;
997 const double v20 = 5, v21 = 4, v22 = 3.126;
998 const double v30 = 6, v31 = 7, v32 = 3, v33 = -400, v34=-3, v35=-1, v30_mod = -6;
999 /*double v40 = 9, v41 = 5, v42 =-12, v43 = -0.01;
1000 double v50 = 1, v51 = 7, v52 = 2, v53 = 1;*/
1001 double r;
1002
1003 alglib::real_2d_array arr_0, arr_1("[[]]"), arr_2(s1), arr_3(arr_2), arr_4, arr_5;
1004 arr_4 = arr_2;
1005 arr_5 = s2;
1006 passed = passed && (arr_0.rows()==0) && (arr_0.cols()==0) && (arr_0.getstride()==0);
1007 passed = passed && (arr_1.rows()==0) && (arr_1.cols()==0) && (arr_1.getstride()==0);
1008 passed = passed && (arr_2.rows()==2) && (arr_2.cols()==3) && (arr_2.getstride()>=arr_2.cols());
1009 passed = passed && (arr_3.rows()==2) && (arr_3.cols()==3) && (arr_3.getstride()>=arr_3.cols());
1010 passed = passed && (arr_4.rows()==2) && (arr_4.cols()==3) && (arr_4.getstride()>=arr_4.cols());
1011 passed = passed && (arr_5.rows()==3) && (arr_5.cols()==1) && (arr_5.getstride()>=arr_5.cols());
1012 passed = passed && (arr_2[0][0]==arr_2(0,0)) && (arr_2[0][1]==arr_2(0,1)) && (arr_2[0][2]==arr_2(0,2));
1013 passed = passed && (arr_2[1][0]==arr_2(1,0)) && (arr_2[1][1]==arr_2(1,1)) && (arr_2[1][2]==arr_2(1,2));
1014 passed = passed && (arr_2[0][0]==v10) && (arr_2[0][1]==v11) && (arr_2[0][2]==v12);
1015 passed = passed && (arr_2[1][0]==v13) && (arr_2[1][1]==v14) && (arr_2[1][2]==v15);
1016 passed = passed && (arr_3[0][0]==v10) && (arr_3[0][1]==v11) && (arr_3[0][2]==v12);
1017 passed = passed && (arr_3[1][0]==v13) && (arr_3[1][1]==v14) && (arr_3[1][2]==v15);
1018 passed = passed && (arr_4[0][0]==v10) && (arr_4[0][1]==v11) && (arr_4[0][2]==v12);
1019 passed = passed && (arr_4[1][0]==v13) && (arr_4[1][1]==v14) && (arr_4[1][2]==v15);
1020 passed = passed && (arr_5[0][0]==v20) && (arr_5[1][0]==v21) && (arr_5[2][0]==v22);
1021 passed = passed && (arr_2.tostring(dps)==s1_fmt);
1022 passed = passed && (arr_3.tostring(dps)==s1_fmt);
1023 passed = passed && (arr_4.tostring(dps)==s1_fmt);
1024 passed = passed && (arr_5.tostring(dps)==s2_fmt);
1025 arr_2[0][0] = v10_mod;
1026 passed = passed && (arr_2[0][0]==v10_mod) && (arr_3[0][0]==v10) && (arr_4[0][0]==v10);
1027 arr_5.setlength(99,97);
1028 passed = passed && (arr_5.rows()==99) && (arr_5.cols()==97);
1029
1030 //
1031 // setcontent/elementwise access/constant arrays
1032 //
1033 ae_int_t n, m, i, j;
1034 for(n=1; n<=10; n++)
1035 for(m=1; m<=10; m++)
1036 {
1037 alglib::real_2d_array arr_6;
1038 double a0[100];
1039
1040 // fill array by random values, test setcontent(0
1041 for(i=0; i<m*n; i++)
1042 a0[i] = alglib::randomreal();
1043 arr_6.setcontent(m, n, a0);
1044 for(i=0; i<m; i++)
1045 for(j=0; j<n; j++)
1046 {
1047 passed = passed && (arr_6[i][j]==a0[i*n+j]);
1048 passed = passed && (arr_6(i,j)==a0[i*n+j]);
1049 }
1050
1051 // test that setcontent() actually copies data instead of creating just reference
1052 r = a0[0];
1053 a0[0] = a0[0]+1;
1054 passed = passed && (arr_6[0][0]!=a0[0]);
1055 a0[0] = r;
1056
1057 // operations on constant arrays
1058 {
1059 const alglib::real_2d_array &ac = arr_6;
1060 for(i=0; i<m; i++)
1061 for(j=0; j<n; j++)
1062 {
1063 passed = passed && (ac[i][j]==a0[i*n+j]);
1064 passed = passed && (ac(i,j)==a0[i*n+j]);
1065 }
1066 }
1067 }
1068
1069
1070 //
1071 // Operations with proxy arrays:
1072 // * changes in target are propagated to proxy and vice versa
1073 // * assignments where proxy is source create new independent copy
1074 // * assignments to proxy are checked (their size must match to that of the target)
1075 // * incorrect assignments or attempts to change length must generate exception
1076 // * attempts to call setlength() must fail even when new size match original size
1077 // of the array
1078 //
1079 { // test attach_to(ae_matrix*)
1080 // subtest 0
1081 alglib::real_2d_array targt, acopy, acopy2;
1082 targt = s3;
1083 alglib::real_2d_array proxy(targt.c_ptr());
1084 acopy = proxy;
1085 for(i=0; i<targt.rows(); i++)
1086 for(j=0; j<targt.cols(); j++)
1087 {
1088 passed = passed && (proxy[i][j]==targt[i][j]);
1089 passed = passed && (acopy[i][j]==targt[i][j]);
1090 }
1091 r = targt[0][0];
1092 targt[0][0] = r+1;
1093 passed = passed && (targt[0][0]!=r) && (proxy[0][0]!=r) && (acopy[0][0]==r);
1094 proxy[0][0] = r;
1095 passed = passed && (targt[0][0]==r) && (proxy[0][0]==r) && (acopy[0][0]==r);
1096
1097 // subtest 1
1098 acopy = s4;
1099 proxy = acopy;
1100 for(i=0; i<acopy.rows(); i++)
1101 for(j=0; j<acopy.cols(); j++)
1102 {
1103 passed = passed && (proxy[i][j]==acopy[i][j]);
1104 passed = passed && (targt[i][j]==acopy[i][j]);
1105 }
1106 r = targt[0][0];
1107 targt[0][0] = r+1;
1108 passed = passed && (targt[0][0]!=r) && (proxy[0][0]!=r) && (acopy[0][0]==r);
1109 proxy[0][0] = r;
1110 passed = passed && (targt[0][0]==r) && (proxy[0][0]==r) && (acopy[0][0]==r);
1111
1112 // subtest 2
1113 acopy2 = s5;
1114 proxy = s5;
1115 for(i=0; i<acopy.rows(); i++)
1116 for(j=0; j<acopy.cols(); j++)
1117 {
1118 passed = passed && (proxy[i][j]==acopy2[i][j]);
1119 passed = passed && (targt[i][j]==acopy2[i][j]);
1120 }
1121
1122 // error handling test 0
1123 try
1124 {
1125 acopy = s60;
1126 proxy = acopy;
1127 passed = false;
1128 }
1129 catch(alglib::ap_error e)
1130 { }
1131 catch(...)
1132 { passed = false; }
1133
1134 // error handling test 1
1135 try
1136 {
1137 acopy = s61;
1138 proxy = acopy;
1139 passed = false;
1140 }
1141 catch(alglib::ap_error e)
1142 { }
1143 catch(...)
1144 { passed = false; }
1145
1146 // error handling test 2
1147 try
1148 {
1149 proxy = s60;
1150 passed = false;
1151 }
1152 catch(alglib::ap_error e)
1153 { }
1154 catch(...)
1155 { passed = false; }
1156
1157 // error handling test 3
1158 try
1159 {
1160 proxy = s61;
1161 passed = false;
1162 }
1163 catch(alglib::ap_error e)
1164 { }
1165 catch(...)
1166 { passed = false; }
1167
1168 // error handling test 4
1169 try
1170 {
1171 proxy.setlength(100,99);
1172 passed = false;
1173 }
1174 catch(alglib::ap_error e)
1175 { }
1176 catch(...)
1177 { passed = false; }
1178
1179 // error handling test 5
1180 try
1181 {
1182 proxy.setlength(proxy.rows(),proxy.cols());
1183 passed = false;
1184 }
1185 catch(alglib::ap_error e)
1186 { }
1187 catch(...)
1188 { passed = false; }
1189 }
1190 { // test attach_to(double*)
1191 // subtest 0
1192 alglib::real_2d_array proxy, acopy, acopy2;
1193 double targt[] = {v30, v31, v32, v33, v34, v35};
1194 const int NCOLS = 2;
1195 proxy.attach_to_ptr(3, 2, targt);
1196 acopy = proxy;
1197 for(i=0; i<proxy.rows(); i++)
1198 for(j=0; j<proxy.cols(); j++)
1199 {
1200 passed = passed && (proxy[i][j]==targt[i*NCOLS+j]);
1201 passed = passed && (acopy[i][j]==targt[i*NCOLS+j]);
1202 }
1203 r = targt[0*NCOLS+0];
1204 targt[0*NCOLS+0] = r+1;
1205 passed = passed && (targt[0*NCOLS+0]!=r) && (proxy[0][0]!=r) && (acopy[0][0]==r);
1206 proxy[0][0] = r;
1207 passed = passed && (targt[0*NCOLS+0]==r) && (proxy[0][0]==r) && (acopy[0][0]==r);
1208
1209 // subtest 1
1210 acopy = s4;
1211 proxy = acopy;
1212 for(i=0; i<acopy.rows(); i++)
1213 for(j=0; j<acopy.cols(); j++)
1214 {
1215 passed = passed && (proxy[i][j]==acopy[i][j]);
1216 passed = passed && (targt[i*NCOLS+j]==acopy[i][j]);
1217 }
1218 r = targt[0*NCOLS+0];
1219 targt[0*NCOLS+0] = r+1;
1220 passed = passed && (targt[0*NCOLS+0]!=r) && (proxy[0][0]!=r) && (acopy[0][0]==r);
1221 proxy[0][0] = r;
1222 passed = passed && (targt[0*NCOLS+0]==r) && (proxy[0][0]==r) && (acopy[0][0]==r);
1223
1224 // subtest 2
1225 acopy2 = s5;
1226 proxy = s5;
1227 for(i=0; i<acopy.rows(); i++)
1228 for(j=0; j<acopy.cols(); j++)
1229 {
1230 passed = passed && (proxy[i][j]==acopy2[i][j]);
1231 passed = passed && (targt[i*NCOLS+j]==acopy2[i][j]);
1232 }
1233
1234 // error handling test 0
1235 try
1236 {
1237 acopy = s60;
1238 proxy = acopy;
1239 passed = false;
1240 }
1241 catch(alglib::ap_error e)
1242 { }
1243 catch(...)
1244 { passed = false; }
1245
1246 // error handling test 1
1247 try
1248 {
1249 acopy = s61;
1250 proxy = acopy;
1251 passed = false;
1252 }
1253 catch(alglib::ap_error e)
1254 { }
1255 catch(...)
1256 { passed = false; }
1257
1258 // error handling test 2
1259 try
1260 {
1261 proxy = s60;
1262 passed = false;
1263 }
1264 catch(alglib::ap_error e)
1265 { }
1266 catch(...)
1267 { passed = false; }
1268
1269 // error handling test 3
1270 try
1271 {
1272 proxy = s61;
1273 passed = false;
1274 }
1275 catch(alglib::ap_error e)
1276 { }
1277 catch(...)
1278 { passed = false; }
1279
1280 // error handling test 4
1281 try
1282 {
1283 proxy.setlength(100,99);
1284 passed = false;
1285 }
1286 catch(alglib::ap_error e)
1287 { }
1288 catch(...)
1289 { passed = false; }
1290
1291 // error handling test 5
1292 try
1293 {
1294 proxy.setlength(proxy.rows(),proxy.cols());
1295 passed = false;
1296 }
1297 catch(alglib::ap_error e)
1298 { }
1299 catch(...)
1300 { passed = false; }
1301 }
1302 }
1303 catch(...)
1304 { passed = false; }
1305
1306 //
1307 // Report
1308 //
1309 printf(fmt_str, "* 2D arrays", passed ? "OK" : "FAILED");
1310 fflush(stdout);
1311 if( !passed )
1312 return 1;
1313 }
1314
1315 {
1316 //
1317 // Testing CSV functionality
1318 //
1319 const char *csv_name = "alglib-tst-35252-ndg4sf.csv";
1320 bool passed = true;
1321 try
1322 {
1323 // CSV_DEFAULT must be zero
1324 passed = passed && alglib::CSV_DEFAULT==0;
1325
1326 // absent file - must fail
1327 try
1328 {
1329 alglib::real_2d_array arr;
1330 read_csv("nonexistent123foralgtestinglib", '\t', alglib::CSV_DEFAULT, arr);
1331 passed = false;
1332 }
1333 catch(alglib::ap_error)
1334 { }
1335 catch(...)
1336 { passed = false; }
1337
1338 // non-rectangular file - must fail
1339 try
1340 {
1341 alglib::real_2d_array arr;
1342 file_put_contents(csv_name, "a,b,c\r\n1,2");
1343 read_csv(csv_name, ',', alglib::CSV_SKIP_HEADERS, arr);
1344 remove(csv_name);
1345 passed = false;
1346 }
1347 catch(alglib::ap_error)
1348 { }
1349 catch(...)
1350 { passed = false; }
1351 try
1352 {
1353 alglib::real_2d_array arr;
1354 file_put_contents(csv_name, "a,b,c\r\n1,2,3,4");
1355 read_csv(csv_name, ',', alglib::CSV_SKIP_HEADERS, arr);
1356 remove(csv_name);
1357 passed = false;
1358 }
1359 catch(alglib::ap_error)
1360 { }
1361 catch(...)
1362 { passed = false; }
1363 try
1364 {
1365 alglib::real_2d_array arr;
1366 file_put_contents(csv_name, "1,2,3,4\n1,2,3\n1,2,3");
1367 read_csv(csv_name, ',', alglib::CSV_DEFAULT, arr);
1368 remove(csv_name);
1369 passed = false;
1370 }
1371 catch(alglib::ap_error)
1372 { }
1373 catch(...)
1374 { passed = false; }
1375
1376 // empty file
1377 try
1378 {
1379 alglib::real_2d_array arr;
1380 file_put_contents(csv_name, "");
1381 read_csv(csv_name, '\t', alglib::CSV_DEFAULT, arr);
1382 remove(csv_name);
1383 passed = passed && arr.rows()==0 && arr.cols()==0;
1384 }
1385 catch(...)
1386 { passed = false; }
1387
1388 // one row with header, tab separator
1389 try
1390 {
1391 alglib::real_2d_array arr;
1392 file_put_contents(csv_name, "a\tb\tc\n");
1393 read_csv(csv_name, '\t', alglib::CSV_SKIP_HEADERS, arr);
1394 remove(csv_name);
1395 passed = passed && arr.rows()==0 && arr.cols()==0;
1396 }
1397 catch(...)
1398 { passed = false; }
1399
1400 // no header, comma-separated, full stop as decimal point
1401 try
1402 {
1403 alglib::real_2d_array arr;
1404 file_put_contents(csv_name, "1.5,2,3.25\n4,5,6");
1405 read_csv(csv_name, ',', alglib::CSV_DEFAULT, arr);
1406 remove(csv_name);
1407 passed = passed && arr.tostring(2)=="[[1.50,2.00,3.25],[4.00,5.00,6.00]]";
1408 }
1409 catch(...)
1410 { passed = false; }
1411
1412 // header, tab-separated, mixed use of comma and full stop as decimal points
1413 try
1414 {
1415 alglib::real_2d_array arr;
1416 file_put_contents(csv_name, "a\tb\tc\n1.5\t2\t3,25\n4\t5.25\t6,1\n");
1417 read_csv(csv_name, '\t', alglib::CSV_SKIP_HEADERS, arr);
1418 remove(csv_name);
1419 passed = passed && arr.tostring(2)=="[[1.50,2.00,3.25],[4.00,5.25,6.10]]";
1420 }
1421 catch(...)
1422 { passed = false; }
1423
1424 // header, tab-separated, fixed/exponential, spaces, mixed use of comma and full stop as decimal points
1425 try
1426 {
1427 alglib::real_2d_array arr;
1428 file_put_contents(csv_name, " a\t b \tc\n1,1\t 2.9\t -3.5 \n 1.1E1 \t 2.0E-1 \t-3E+1 \n+1 \t -2\t 3. \n.1\t-.2\t+.3\n");
1429 read_csv(csv_name, '\t', alglib::CSV_SKIP_HEADERS, arr);
1430 remove(csv_name);
1431 passed = passed && arr.tostring(2)=="[[1.10,2.90,-3.50],[11.00,0.20,-30.00],[1.00,-2.00,3.00],[0.10,-0.20,0.30]]";
1432 }
1433 catch(...)
1434 { passed = false; }
1435 }
1436 catch(...)
1437 { passed = false; }
1438
1439 //
1440 // Report
1441 //
1442 printf(fmt_str, "* CSV support", passed ? "OK" : "FAILED");
1443 fflush(stdout);
1444 if( !passed )
1445 return 1;
1446 }
1447
1448
1449 //
1450 // Serialization properties
1451 //
1452 {
1453 //
1454 // Test kd-tree serialization
1455 //
1456 bool passed = true;
1457 alglib::hqrndstate rs;
1458 alglib::kdtree tree0;
1459 alglib::real_2d_array xy, rxy0, rxy1;
1460 alglib::real_1d_array qx;
1461 const int npts = 50;
1462 const int nx = 2;
1463 const int ny = 1;
1464 int cnt0, cnt1;
1465 alglib::hqrndrandomize(rs);
1466 xy.setlength(npts, nx+ny);
1467 for(int i=0; i<npts; i++)
1468 for(int j=0; j<nx+ny; j++)
1469 xy[i][j] = alglib::hqrndnormal(rs);
1470 alglib::kdtreebuild(xy, npts, nx, ny, 2, tree0);
1471 qx.setlength(nx);
1472
1473 try
1474 {
1475 // test string serialization/unserialization
1476 alglib::kdtree tree1;
1477 std::string s;
1478 alglib::kdtreeserialize(tree0, s);
1479 alglib::kdtreeunserialize(s, tree1);
1480 for(int i=0; i<100; i++)
1481 {
1482 for(int j=0; j<nx; j++)
1483 qx[j] = alglib::hqrndnormal(rs);
1484 cnt0 = alglib::kdtreequeryknn(tree0, qx, 1, true);
1485 cnt1 = alglib::kdtreequeryknn(tree1, qx, 1, true);
1486 if( (cnt0!=1) || (cnt1!=1) )
1487 {
1488 passed = false;
1489 break;
1490 }
1491 alglib::kdtreequeryresultsxy(tree0, rxy0);
1492 alglib::kdtreequeryresultsxy(tree1, rxy1);
1493 for(int j=0; j<nx+ny; j++)
1494 passed = passed && (rxy0[0][j]==rxy1[0][j]);
1495 }
1496 }
1497 catch(...)
1498 { passed = false; }
1499
1500 try
1501 {
1502 // test stream serialization/unserialization
1503 //
1504 // NOTE: we add a few symbols at the beginning and after the end of the data
1505 // in order to test algorithm ability to work in the middle of the stream
1506 alglib::kdtree tree1;
1507 std::stringstream s;
1508 s.put('b');
1509 s.put('e');
1510 s.put('g');
1511 alglib::kdtreeserialize(tree0, s);
1512 s.put('e');
1513 s.put('n');
1514 s.put('d');
1515 s.seekg(0);
1516 passed = passed && (s.get()=='b');
1517 passed = passed && (s.get()=='e');
1518 passed = passed && (s.get()=='g');
1519 alglib::kdtreeunserialize(s, tree1);
1520 passed = passed && (s.get()=='e');
1521 passed = passed && (s.get()=='n');
1522 passed = passed && (s.get()=='d');
1523 for(int i=0; i<100; i++)
1524 {
1525 for(int j=0; j<nx; j++)
1526 qx[j] = alglib::hqrndnormal(rs);
1527 cnt0 = alglib::kdtreequeryknn(tree0, qx, 1, true);
1528 cnt1 = alglib::kdtreequeryknn(tree1, qx, 1, true);
1529 if( (cnt0!=1) || (cnt1!=1) )
1530 {
1531 passed = false;
1532 break;
1533 }
1534 alglib::kdtreequeryresultsxy(tree0, rxy0);
1535 alglib::kdtreequeryresultsxy(tree1, rxy1);
1536 for(int j=0; j<nx+ny; j++)
1537 passed = passed && (rxy0[0][j]==rxy1[0][j]);
1538 }
1539 }
1540 catch(...)
1541 { passed = false; }
1542
1543 try
1544 {
1545 // test string-to-stream serialization/unserialization
1546 alglib::kdtree tree1;
1547 std::string s0;
1548 alglib::kdtreeserialize(tree0, s0);
1549 std::stringstream s1(s0);
1550 alglib::kdtreeunserialize(s1, tree1);
1551 for(int i=0; i<100; i++)
1552 {
1553 for(int j=0; j<nx; j++)
1554 qx[j] = alglib::hqrndnormal(rs);
1555 cnt0 = alglib::kdtreequeryknn(tree0, qx, 1, true);
1556 cnt1 = alglib::kdtreequeryknn(tree1, qx, 1, true);
1557 if( (cnt0!=1) || (cnt1!=1) )
1558 {
1559 passed = false;
1560 break;
1561 }
1562 alglib::kdtreequeryresultsxy(tree0, rxy0);
1563 alglib::kdtreequeryresultsxy(tree1, rxy1);
1564 for(int j=0; j<nx+ny; j++)
1565 passed = passed && (rxy0[0][j]==rxy1[0][j]);
1566 }
1567 }
1568 catch(...)
1569 { passed = false; }
1570
1571 try
1572 {
1573 // test stream-to-string serialization/unserialization
1574 alglib::kdtree tree1;
1575 std::stringstream s0;
1576 alglib::kdtreeserialize(tree0, s0);
1577 std::string s1 = s0.str();
1578 alglib::kdtreeunserialize(s1, tree1);
1579 for(int i=0; i<100; i++)
1580 {
1581 for(int j=0; j<nx; j++)
1582 qx[j] = alglib::hqrndnormal(rs);
1583 cnt0 = alglib::kdtreequeryknn(tree0, qx, 1, true);
1584 cnt1 = alglib::kdtreequeryknn(tree1, qx, 1, true);
1585 if( (cnt0!=1) || (cnt1!=1) )
1586 {
1587 passed = false;
1588 break;
1589 }
1590 alglib::kdtreequeryresultsxy(tree0, rxy0);
1591 alglib::kdtreequeryresultsxy(tree1, rxy1);
1592 for(int j=0; j<nx+ny; j++)
1593 passed = passed && (rxy0[0][j]==rxy1[0][j]);
1594 }
1595 }
1596 catch(...)
1597 { passed = false; }
1598
1599 //
1600 // Report
1601 //
1602 printf(fmt_str, "* Serialization (kd-tree)", passed ? "OK" : "FAILED");
1603 fflush(stdout);
1604 if( !passed )
1605 return 1;
1606 }
1607 {
1608 //
1609 // Test legacy RBF interface
1610 //
1611 const char *pc_str = "50000000000 00000000000 20000000000 10000000000 A0000000000 \
1612 30000000000 20000000000 00000000000 A0000000000 30000000000\r\
1613 00000000000 20000000000 A0000000000 60000000000 00000000000\n\
1614 00000000000 00000000000 00000000000 00000000000 00000000000\r\n\
1615 00000000m_3 00000000000 00000000000 00000000m_3 00000000000\n\r\
1616 00000000000 00000000004 00000000000 00000000000\t00000000004 \
1617 00000000000 00000000000 00000000804 00000000000 00000000000 \
1618 00000000804 00000000000 00000000000 00000000G04 00000000000 \
1619 00000000000 00000000G04 00000000000 00000000000 00000000O04 \
1620 00000000000 00000000000 00000000O04 00000000000 00000000000 \
1621 00000000S04 00000000000 00000000000 00000000S04 00000000000 \
1622 00000000000 00000000W04 00000000000 00000000000 00000000W04 \
1623 00000000000 00000000000 00000000Y04 00000000000 00000000000 \
1624 00000000Y04 00000000000 00000000000 00000000K04 00000000000 \
1625 00000000000 00000000K04 00000000000 00000000000 A0000000000 \
1626 00000000000 10000000000 20000000000 30000000000 40000000000 \
1627 60000000000 70000000000 80000000000 90000000000 50000000000 \
1628 30000000000 00000000000 00000000000 00000000000 30000000000 \
1629 00000000Y04 00000000000 00000000000 u1000000000 00000000000 \
1630 00000000000 00000000000 60000000000 80000000000 00000000000 \
1631 50000000000 00000000000 50000000000 50000000000 00000000000 \
1632 00000000000 00000000000 00000000000 00000000000 00000000000 \
1633 00000000000 00000000000 00000000000 00000000000 00000000000 \
1634 00000000000 00000000000 00000000000 00000000000 00000000000 \
1635 00000000000 00000000000 00000000000 00000000000 00000000000 \
1636 00000000000 00000000000 00000000000 00000000000 00000000000 \
1637 00000000000 00000000000 00000000000 00000000000 00000000000 \
1638 00000000000 00000000000 00000000000 00000000000 00000000000 \
1639 00000000000 00000000000 00000000000 00000000000 00000000000 \
1640 00000000000 00000000000 00000000000 00000000000 00000000000 \
1641 00000000000 00000000000 00000000000 00000000000 00000000000 \
1642 00000000000 00000000000 00000000000 00000000000 00000000000 \
1643 00000000000 00000000000 00000000000 00000000000 00000000000 \
1644 00000000000 00000000000 00000000000 00000000000 00000000000 \
1645 00000000000 00000000000 00000000000 00000000000 00000000000 \
1646 00000000000 00000000000 00000000000 00000000000 00000000000 \
1647 00000000000 00000000000 00000000000 00000000000 00000000000 \
1648 00000000000 00000000000 00000000000 00000000000 00000000000 \
1649 00000000000 00000000000 00000000000 00000000000 00000000000 \
1650 00000000000 00000000000 00000000000 00000000000 00000000000 \
1651 00000000000 00000000000 00000000000 00000000000 00000000000 \
1652 00000000000 00000000000 00000000000 00000000000 00000000000 \
1653 00000000000 00000000000 00000000000 00000000000 K0000000000 \
1654 00000000I04 00000000000 00000000000 00000000000 00000000000 \
1655 00000000000 00000000000 00000000000 00000000000 00000000000 \
1656 00000000000 00000000000 00000000000 00000000000 00000000000 \
1657 00000000000 00000000000 00000000000 00000000000 00000000000 \
1658 A0000000000 30000000000 00000000000 00000000000 00000000000 \
1659 00000000m_3 00000000000 00000000000 00000000004 00000000000 \
1660 00000000000 00000000804 00000000000 00000000000 00000000G04 \
1661 00000000000 00000000000 00000000K04 00000000000 00000000000 \
1662 00000000O04 00000000000 00000000000 00000000S04 00000000000 \
1663 00000000000 00000000W04 00000000000 00000000000 00000000Y04 \
1664 00000000000 00000000000 A0000000000 40000000000 00000000q04 \
1665 -pAGQnQBI14 UqUWierJ91C esm8ag6G61C 00000000q04 4wcFMyCtu04 \
1666 oPDvwHqst04 CExQXp8Ct04 00000000q04 litzPFhRb0C oKJvjcct314 \
1667 5-fT-X8w614 00000000q04 3HSOsPVH11C vZWf4dgfv04 GbZg4MTJn04 \
1668 00000000q04 iv7rMhuR71C hRtixp15r_3 EvCEDtLu-0C 00000000q04 \
1669 41CXzA_q71C umRYLK2yp0C 1zzY3Zqd91C 00000000q04 JvxJzDeI21C \
1670 TVbyd7Ygz0C JLywRdR1n0C 00000000q04 KmFarhc4g0C 1ehrn2tUt0C \
1671 AECfwTIX814 00000000q04 Big__6hwt04 nSPzmAQrh_B 2H3o-KftH14 \
1672 00000000q04 n1b9361vI14 mhJhviUE114 54a_qyBrH1C 00000000q04 \
1673 10000000000 40000000000 StLCgor39-3 00000000000 00000000000 \
1674 6qTG7Ae-1_3\n";
1675 alglib::real_1d_array ref_val("[-0.042560546916643, 0.942523544654062, 0.875197036560778, 0.0656948997826632, -0.743065973803404, -0.8903682039297, -0.26994815318748, 0.602248517290195, 0.980011992233124, 0.436594293214176]");
1676 bool passed = true;
1677
1678 try
1679 {
1680 // test unserialization from string without trailing end-of-stream symbol (dot)
1681 // this test is necessary for backward compatibility
1682 double eps = 0.0000000001;
1683 alglib::rbfmodel model;
1684 alglib::rbfunserialize(std::string(pc_str), model);
1685 for(int i=0; i<ref_val.length(); i++)
1686 passed = passed && (fabs(alglib::rbfcalc2(model,i,0)-ref_val[i])<eps);
1687 }
1688 catch(...)
1689 { passed = false; }
1690
1691 try
1692 {
1693 // test unserialization from string with trailing end-of-stream symbol (dot)
1694 // this test is necessary for forward compatibility
1695 double eps = 0.0000000001;
1696 alglib::rbfmodel model;
1697 alglib::rbfunserialize(std::string(pc_str)+".", model);
1698 for(int i=0; i<ref_val.length(); i++)
1699 passed = passed && (fabs(alglib::rbfcalc2(model,i,0)-ref_val[i])<eps);
1700 }
1701 catch(...)
1702 { passed = false; }
1703
1704 try
1705 {
1706 // test unserialization from stream WITHOUT trailing end-of-stream symbol (dot)
1707 // this test MUST fail
1708 double eps = 0.0000000001;
1709 std::string _s(pc_str);
1710 std::istringstream stream(_s);
1711 alglib::rbfmodel model;
1712 alglib::rbfunserialize(stream, model);
1713 passed = false;
1714 }
1715 catch(...)
1716 { /* do nothing, it is expected to fail */ }
1717
1718 try
1719 {
1720 // test unserialization from stream WITH trailing end-of-stream symbol (dot)
1721 // this test must succeed
1722 double eps = 0.0000000001;
1723 std::string _s = std::string(pc_str)+".";
1724 std::istringstream stream(_s);
1725 alglib::rbfmodel model;
1726 alglib::rbfunserialize(stream, model);
1727 for(int i=0; i<ref_val.length(); i++)
1728 passed = passed && (fabs(alglib::rbfcalc2(model,i,0)-ref_val[i])<eps);
1729 }
1730 catch(...)
1731 { passed = false; }
1732
1733 try
1734 {
1735 // test that we can read from the stream after unserialization
1736 double eps = 0.0000000001;
1737 std::string _s = std::string(pc_str)+".<az>";
1738 std::istringstream stream(_s);
1739 alglib::rbfmodel model;
1740 alglib::rbfunserialize(stream, model);
1741 for(int i=0; i<ref_val.length(); i++)
1742 passed = passed && (fabs(alglib::rbfcalc2(model,i,0)-ref_val[i])<eps);
1743 passed = passed && (stream.get()=='<');
1744 passed = passed && (stream.get()=='a');
1745 passed = passed && (stream.get()=='z');
1746 passed = passed && (stream.get()=='>');
1747 }
1748 catch(...)
1749 { passed = false; }
1750
1751 //
1752 // Report
1753 //
1754 printf(fmt_str, "* Serialization (RBF)", passed ? "OK" : "FAILED");
1755 fflush(stdout);
1756 if( !passed )
1757 return 1;
1758 }
1759 {
1760 //
1761 // Test malloc() exceptions in constructors
1762 //
1763 #ifdef AE_USE_ALLOC_COUNTER
1764 bool passed = true;
1765 bool were_exceptions = false;
1766 for(int eidx=0; ; eidx++) // loop is terminated when we survive through all the tests
1767 {
1768 //
1769 // Select moment when we generate exception in the constructor
1770 //
1771 alglib_impl::_malloc_failure_after = alglib_impl::_alloc_counter_total+eidx;
1772
1773 //
1774 // Perform many activities with ALGLIB, catch exceptions.
1775 // It is survival test, it checks that we survive exceptions.
1776 // If it fails, we are likely to end with abort().
1777 //
1778 try
1779 {
1780 {
1781 real_1d_array x0 = "[1,2,3]";
1782 real_1d_array x1(x0);
1783 real_1d_array x2;
1784 x2 = x1;
1785 real_1d_array *p = new real_1d_array("[1]");
1786 delete p;
1787 }
1788 {
1789 real_2d_array x0 = "[[1,2,3],[0,0,0]]";
1790 real_2d_array x1(x0);
1791 real_2d_array x2;
1792 x2 = x1;
1793 real_2d_array *p = new real_2d_array("[[1],[5]]");
1794 delete p;
1795 }
1796 {
1797 sparsematrix s;
1798 sparsecreate(2, 2, s);
1799 sparseset(s, 0, 0, 2.0);
1800 sparseset(s, 1, 1, 1.0);
1801 sparseset(s, 0, 1, 1.0);
1802 sparseadd(s, 1, 1, 4.0);
1803 sparsematrix s2(s), s3;
1804 s3 = s;
1805 double v;
1806 v = sparseget(s, 0, 0);
1807 v = sparseget(s, 0, 1);
1808 v = sparseget(s, 1, 0);
1809 v = sparseget(s, 1, 1);
1810 sparseconverttocrs(s);
1811 real_1d_array x = "[1,-1]";
1812 real_1d_array y = "[]";
1813 sparsemv(s, x, y);
1814 }
1815 {
1816 real_1d_array x = "[0,0]";
1817 double epsg = 0.0000000001;
1818 double epsf = 0;
1819 double epsx = 0;
1820 double stpmax = 0.1;
1821 ae_int_t maxits = 0;
1822 mincgstate state;
1823 mincgreport rep;
1824 mincgcreate(x, state);
1825 mincgsetcond(state, epsg, epsf, epsx, maxits);
1826 mincgsetstpmax(state, stpmax);
1827 mincgstate state2;
1828 state2 = state;
1829 mincgstate state3(state2);
1830 mincgrestartfrom(state, x);
1831 }
1832 {
1833 mlptrainer trn;
1834 multilayerperceptron network;
1835 mlpreport rep;
1836 real_2d_array xy = "[[1,1,1],[1,2,2],[2,1,2],[2,2,4]]";
1837 mlpcreatetrainer(2, 1, trn);
1838 mlpcreate1(2, 5, 1, network);
1839 mlpsetdataset(trn, xy, 4);
1840 mlptrainnetwork(trn, network, 5, rep);
1841 real_1d_array x = "[2,2]";
1842 real_1d_array y = "[0]";
1843 mlpprocess(network, x, y);
1844 }
1845 {
1846 std::string s;
1847 double v;
1848 rbfmodel model0;
1849 rbfmodel model1;
1850 real_2d_array xy = "[[-1,0,2],[+1,0,3]]";
1851 rbfreport rep;
1852 rbfcreate(2, 1, model0);
1853 rbfsetpoints(model0, xy);
1854 rbfsetalgohierarchical(model0, 1.0, 3, 0.0);
1855 rbfbuildmodel(model0, rep);
1856 alglib::rbfserialize(model0, s);
1857 alglib::rbfunserialize(s, model1);
1858 v = rbfcalc2(model0, 0.0, 0.0);
1859 v = rbfcalc2(model1, 0.0, 0.0);
1860 rbfbuildmodel(model0, rep);
1861 v = rbfcalc2(model0, 0.0, 0.0);
1862 rbfbuildmodel(model1, rep);
1863 v = rbfcalc2(model1, 0.0, 0.0);
1864 }
1865
1866 //
1867 // We survived all tests, next iteration will bring no changed, terminate loop!
1868 //
1869 break;
1870 }
1871 catch(ap_error)
1872 { were_exceptions = true; }
1873 }
1874 alglib_impl::_malloc_failure_after = 0; // turn off artificial malloc failures
1875 printf(fmt_str, "* Exceptions in constructors", were_exceptions ? (passed ? "OK" : "FAILED") : "..");
1876 fflush(stdout);
1877 if( !passed )
1878 return 1;
1879 #else
1880 printf(fmt_str, "* Exceptions in constructors", "??");
1881 fflush(stdout);
1882 #endif
1883 }
1884 {
1885 //
1886 // Test multithreading-related settings
1887 //
1888 // For this test we measure performance of large NxNxN GEMMs
1889 // with different threading settings.
1890 //
1891 printf("SMP settings vs GEMM speedup:\n");
1892 if( alglib::_ae_cores_count()>1 )
1893 {
1894 bool passed = true;
1895 alglib_impl::ae_uint64_t default_global_threading = alglib::_ae_get_global_threading();
1896 alglib::ae_int_t default_nworkers = alglib::getnworkers();
1897 double time_default = 0,
1898 time_glob_ser = 0,
1899 time_glob_smp = 0,
1900 time_glob_ser_loc_ser = 0,
1901 time_glob_ser_loc_smp = 0,
1902 time_glob_smp_loc_ser = 0,
1903 time_glob_smp_loc_smp = 0,
1904 time_glob_smp_nw1 = 0;
1905 alglib::ae_int_t n = 800, mintime = 2000, cnt, t0;
1906 try
1907 {
1908 // allocate temporary matrices
1909 alglib::real_2d_array a, b, c;
1910 int i, j;
1911 a.setlength(n, n);
1912 b.setlength(n, n);
1913 c.setlength(n, n);
1914 for(i=0; i<n; i++)
1915 for(j=0; j<n; j++)
1916 {
1917 a[i][j] = alglib::randomreal()-0.5;
1918 b[i][j] = alglib::randomreal()-0.5;
1919 c[i][j] = 0.0;
1920 }
1921
1922 // measure time; interleave measurements with different settings in order to
1923 // reduce variance of results
1924 while(time_default<mintime)
1925 {
1926 // default threading
1927 t0 = alglib_impl::_tickcount();
1928 alglib::rmatrixgemm(
1929 n, n, n,
1930 1.0,
1931 a, 0, 0, 0,
1932 b, 0, 0, 0,
1933 0.0,
1934 c, 0, 0);
1935 time_default += alglib_impl::_tickcount()-t0;
1936 alglib::_ae_set_global_threading(default_global_threading); // restore
1937
1938 // global serial
1939 t0 = alglib_impl::_tickcount();
1940 alglib::setglobalthreading(alglib::serial);
1941 alglib::rmatrixgemm(
1942 n, n, n,
1943 1.0,
1944 a, 0, 0, 0,
1945 b, 0, 0, 0,
1946 0.0,
1947 c, 0, 0);
1948 time_glob_ser += alglib_impl::_tickcount()-t0;
1949 alglib::_ae_set_global_threading(default_global_threading); // restore
1950
1951 // global parallel
1952 t0 = alglib_impl::_tickcount();
1953 alglib::setglobalthreading(alglib::parallel);
1954 alglib::rmatrixgemm(
1955 n, n, n,
1956 1.0,
1957 a, 0, 0, 0,
1958 b, 0, 0, 0,
1959 0.0,
1960 c, 0, 0);
1961 time_glob_smp += alglib_impl::_tickcount()-t0;
1962 alglib::_ae_set_global_threading(default_global_threading); // restore
1963
1964 // global serial, local serial
1965 t0 = alglib_impl::_tickcount();
1966 alglib::setglobalthreading(alglib::serial);
1967 alglib::rmatrixgemm(
1968 n, n, n,
1969 1.0,
1970 a, 0, 0, 0,
1971 b, 0, 0, 0,
1972 0.0,
1973 c, 0, 0,
1974 alglib::serial);
1975 time_glob_ser_loc_ser += alglib_impl::_tickcount()-t0;
1976 alglib::_ae_set_global_threading(default_global_threading); // restore
1977
1978 // global serial, local parallel
1979 t0 = alglib_impl::_tickcount();
1980 alglib::setglobalthreading(alglib::serial);
1981 alglib::rmatrixgemm(
1982 n, n, n,
1983 1.0,
1984 a, 0, 0, 0,
1985 b, 0, 0, 0,
1986 0.0,
1987 c, 0, 0,
1988 alglib::parallel);
1989 time_glob_ser_loc_smp += alglib_impl::_tickcount()-t0;
1990 alglib::_ae_set_global_threading(default_global_threading); // restore
1991
1992 // global parallel, local serial
1993 t0 = alglib_impl::_tickcount();
1994 alglib::setglobalthreading(alglib::parallel);
1995 alglib::rmatrixgemm(
1996 n, n, n,
1997 1.0,
1998 a, 0, 0, 0,
1999 b, 0, 0, 0,
2000 0.0,
2001 c, 0, 0,
2002 alglib::serial);
2003 time_glob_smp_loc_ser += alglib_impl::_tickcount()-t0;
2004 alglib::_ae_set_global_threading(default_global_threading); // restore
2005
2006 // global parallel, local parallel
2007 t0 = alglib_impl::_tickcount();
2008 alglib::setglobalthreading(alglib::parallel);
2009 alglib::rmatrixgemm(
2010 n, n, n,
2011 1.0,
2012 a, 0, 0, 0,
2013 b, 0, 0, 0,
2014 0.0,
2015 c, 0, 0,
2016 alglib::parallel);
2017 time_glob_smp_loc_smp += alglib_impl::_tickcount()-t0;
2018 alglib::_ae_set_global_threading(default_global_threading); // restore
2019
2020 // global parallel, nworkers=1
2021 t0 = alglib_impl::_tickcount();
2022 alglib::setglobalthreading(alglib::parallel);
2023 alglib::setnworkers(1);
2024 alglib::rmatrixgemm(
2025 n, n, n,
2026 1.0,
2027 a, 0, 0, 0,
2028 b, 0, 0, 0,
2029 0.0,
2030 c, 0, 0);
2031 time_glob_smp_nw1 += alglib_impl::_tickcount()-t0;
2032 alglib::_ae_set_global_threading(default_global_threading); // restore
2033 alglib::setnworkers(default_nworkers);
2034 }
2035 }
2036 catch(ap_error)
2037 { passed = false; }
2038 printf(fmt_speedup, "* default speedup", time_glob_ser/time_glob_ser);
2039 printf(fmt_speedup, "* serial (global)", time_glob_ser/time_default);
2040 printf(fmt_speedup, "* serial (local)", time_glob_ser/time_glob_ser_loc_ser);
2041 printf(fmt_speedup, "* serial (nworkers=1)", time_glob_ser/time_glob_smp_nw1);
2042 printf(fmt_speedup, "* parallel (global)", time_glob_ser/time_glob_smp);
2043 printf(fmt_speedup, "* parallel (local) v1", time_glob_ser/time_glob_ser_loc_smp);
2044 passed = passed && (time_glob_ser/time_default >0.85) && (time_glob_ser/time_default <1.15);
2045 passed = passed && (time_glob_ser/time_glob_ser >0.85) && (time_glob_ser/time_glob_ser <1.15);
2046 passed = passed && (time_glob_ser/time_glob_ser_loc_ser>0.85) && (time_glob_ser/time_glob_ser_loc_ser<1.15);
2047 passed = passed && (time_glob_ser/time_glob_smp_loc_ser>0.85) && (time_glob_ser/time_glob_smp_loc_ser<1.15);
2048 passed = passed && (time_glob_ser/time_glob_smp_nw1 >0.85) && (time_glob_ser/time_glob_smp_nw1 <1.15);
2049 passed = passed && (time_glob_ser/time_glob_smp >1.30);
2050 passed = passed && (time_glob_ser/time_glob_ser_loc_smp>1.30);
2051 passed = passed && (time_glob_ser/time_glob_smp_loc_smp>1.30);
2052 printf(fmt_str, "* test result", passed ? "OK" : "FAILED (soft failure)");
2053 fflush(stdout);
2054 //
2055 // soft failure:
2056 // // if( !passed )
2057 // // return 1;
2058 //
2059 }
2060 else
2061 {
2062 printf(fmt_str, "* test skipped (no SMP)", "??");
2063 fflush(stdout);
2064 }
2065 }
2066
2067 //
2068 // Testing issues which must be fixed
2069 //
2070 printf("Issues:\n");
2071 {
2072 //
2073 // Testing issue #505 (http://bugs.alglib.net/view.php?id=505) in optimizers.
2074 // This issue was present in ALL optimizers, but we test it only on two: CG and LM.
2075 //
2076 try
2077 {
2078 //
2079 // Test CG
2080 // Stopping criteria - EpsX
2081 //
2082 mincgstate state;
2083 mincgreport rep;
2084 real_1d_array x = "[0.0]";
2085 double x0 = 20*alglib::randomreal()-10;
2086 double epsx = 1.0E-9;
2087 mincgcreate(1, x, state);
2088 mincgsetcond(state, 0.0, 0.0, epsx, 0);
2089 mincgoptimize(state, func505_grad, NULL, &x0);
2090 mincgresults(state, x, rep);
2091 issue505_passed = issue505_passed && (fabs(4*pow(x[0]-x0,3))<1.0E-3);
2092 }
2093 catch(...)
2094 { issue505_passed = false; }
2095 try
2096 {
2097 //
2098 // Test LM
2099 // Stopping criteria - after |grad|<epsG
2100 //
2101 minlmstate state;
2102 minlmreport rep;
2103 real_1d_array x = "[0.0]";
2104 double x0 = 20*alglib::randomreal()-10;
2105 double epsx = 1.0E-9;
2106 minlmcreatevj(1, 2, x, state);
2107 minlmsetcond(state, epsx, 0);
2108 minlmoptimize(state, func505_vec, func505_jac, NULL, &x0);
2109 minlmresults(state, x, rep);
2110 issue505_passed = issue505_passed && (fabs(x[0]-x0)<1.0E-3);
2111 }
2112 catch(...)
2113 { issue505_passed = false; }
2114 printf(fmt_str, "* issue 505", issue505_passed ? "OK" : "FAILED");
2115 fflush(stdout);
2116 if( !issue505_passed )
2117 return 1;
2118
2119 //
2120 // Testing issue #478 (http://bugs.alglib.net/view.php?id=478)
2121 // in high-quality RNG. It have to correctly handle random numbers
2122 // larger than 2^31.
2123 //
2124 // This test is performed only in 64-bit mode.
2125 //
2126 if( sizeof(alglib::ae_int_t)>4 )
2127 {
2128 //
2129 // 64-bit mode, perform test:
2130 // * use large NMax>2^31
2131 // * generate 1.000.000 random numbers
2132 // * use two bins - one for numbers less then NMax/2,
2133 // another one for the rest of them
2134 // * bin sizes are equal to n0, n1
2135 // * both bins should be approximately equal, we use
2136 // ad hoc threshold 0.45 < n0,n1 < 0.55.
2137 //
2138 try
2139 {
2140 alglib::hqrndstate rs;
2141 alglib::ae_int_t nmax[3];
2142 alglib::ae_int_t ncnt = 3, nidx;
2143 double n0, n1;
2144 alglib::hqrndrandomize(rs);
2145
2146 //
2147 // nmax:
2148 // * first nmax is just large value to test basic uniformity of generator
2149 //
2150 nmax[0] = 1000000;
2151 nmax[0] = nmax[0]*nmax[0];
2152 nmax[1] = 2147483562;
2153 nmax[1] *= 1.5;
2154 nmax[2] = 2147483562;
2155 nmax[2] *= 3;
2156
2157 for(nidx=0; nidx<ncnt; nidx++)
2158 {
2159 n0 = 0;
2160 n1 = 0;
2161 for(int i=0; i<1000000; i++)
2162 {
2163 alglib::ae_int_t v = alglib::hqrnduniformi(rs, nmax[nidx]);
2164 if( v<nmax[nidx]/2 )
2165 n0++;
2166 else
2167 n1++;
2168 issue478_passed = issue478_passed && (v>=0) && (v<nmax[nidx]);
2169 }
2170 issue478_passed = issue478_passed && (n0/(n0+n1)>0.45);
2171 issue478_passed = issue478_passed && (n0/(n0+n1)<0.55);
2172 issue478_passed = issue478_passed && (n1/(n0+n1)>0.45);
2173 issue478_passed = issue478_passed && (n1/(n0+n1)<0.55);
2174 }
2175 }
2176 catch(...)
2177 { issue478_passed = false; }
2178 printf(fmt_str, "* issue 478", issue478_passed ? "OK" : "FAILED");
2179 fflush(stdout);
2180 if( !issue478_passed )
2181 return 1;
2182 }
2183 else
2184 {
2185 //
2186 // 32-bit mode, skip test
2187 //
2188 printf(fmt_str, "* issue 478", "OK (skipped in 32-bit mode)");
2189 fflush(stdout);
2190 }
2191
2192 //
2193 // Testing issue #528 (http://bugs.alglib.net/view.php?id=528)
2194 // in shared pool and smart pointer which leak memory.
2195 //
2196 // In order to test it we create pool, seed it with specially
2197 // created structure, perform several operations, then clear it.
2198 // We test allocation counter before and after this operation.
2199 //
2200 #ifdef AE_USE_ALLOC_COUNTER
2201 try
2202 {
2203 int alloc_cnt;
2204 alglib_impl::ae_state _alglib_env_state;
2205 alglib_impl::ae_frame _frame_block;
2206 alglib_impl::ae_shared_pool pool;
2207 alglib_impl::ae_smart_ptr ptr0, ptr1;
2208 void *p0, *p1;
2209 seedrec seed;
2210
2211 // case #0: just seeding the pool
2212 alloc_cnt = alglib_impl::_alloc_counter;
2213 alglib_impl::ae_state_init(&_alglib_env_state);
2214 alglib_impl::ae_frame_make(&_alglib_env_state, &_frame_block);
2215 memset(&pool, 0, sizeof(pool));
2216 memset(&seed, 0, sizeof(seed));
2217 alglib_impl::ae_shared_pool_init(&pool, &_alglib_env_state, true);
2218 _seedrec_init(&seed, &_alglib_env_state, ae_true);
2219 alglib_impl::ae_shared_pool_set_seed(&pool, &seed, sizeof(seed), _seedrec_init, _seedrec_init_copy, _seedrec_destroy, &_alglib_env_state);
2220 alglib_impl::ae_state_clear(&_alglib_env_state);
2221 issue528_passed = issue528_passed && (alloc_cnt==alglib_impl::_alloc_counter);
2222
2223 // case #1: seeding and retrieving, not recycling
2224 alloc_cnt = alglib_impl::_alloc_counter;
2225 alglib_impl::ae_state_init(&_alglib_env_state);
2226 alglib_impl::ae_frame_make(&_alglib_env_state, &_frame_block);
2227 memset(&seed, 0, sizeof(seed));
2228 memset(&pool, 0, sizeof(pool));
2229 memset(&ptr0, 0, sizeof(ptr0));
2230 alglib_impl::ae_smart_ptr_init(&ptr0, (void**)&p0, &_alglib_env_state, true);
2231 alglib_impl::ae_shared_pool_init(&pool, &_alglib_env_state, true);
2232 _seedrec_init(&seed, &_alglib_env_state, true);
2233 alglib_impl::ae_shared_pool_set_seed(&pool, &seed, sizeof(seed), _seedrec_init, _seedrec_init_copy, _seedrec_destroy, &_alglib_env_state);
2234 alglib_impl::ae_shared_pool_retrieve(&pool, &ptr0, &_alglib_env_state);
2235 alglib_impl::ae_state_clear(&_alglib_env_state);
2236 issue528_passed = issue528_passed && (alloc_cnt==alglib_impl::_alloc_counter);
2237
2238 // case #2: seeding and retrieving twice to different pointers, recycling both
2239 alloc_cnt = alglib_impl::_alloc_counter;
2240 alglib_impl::ae_state_init(&_alglib_env_state);
2241 alglib_impl::ae_frame_make(&_alglib_env_state, &_frame_block);
2242 memset(&ptr0, 0, sizeof(ptr0));
2243 memset(&ptr1, 0, sizeof(ptr1));
2244 memset(&pool, 0, sizeof(pool));
2245 memset(&seed, 0, sizeof(seed));
2246 alglib_impl::ae_smart_ptr_init(&ptr0, (void**)&p0, &_alglib_env_state, true);
2247 alglib_impl::ae_smart_ptr_init(&ptr1, (void**)&p1, &_alglib_env_state, true);
2248 alglib_impl::ae_shared_pool_init(&pool, &_alglib_env_state, true);
2249 _seedrec_init(&seed, &_alglib_env_state, true);
2250 alglib_impl::ae_shared_pool_set_seed(&pool, &seed, sizeof(seed), _seedrec_init, _seedrec_init_copy, _seedrec_destroy, &_alglib_env_state);
2251 alglib_impl::ae_shared_pool_retrieve(&pool, &ptr0, &_alglib_env_state);
2252 alglib_impl::ae_shared_pool_retrieve(&pool, &ptr1, &_alglib_env_state);
2253 alglib_impl::ae_shared_pool_recycle(&pool, &ptr0, &_alglib_env_state);
2254 alglib_impl::ae_shared_pool_recycle(&pool, &ptr1, &_alglib_env_state);
2255 alglib_impl::ae_state_clear(&_alglib_env_state);
2256 issue528_passed = issue528_passed && (alloc_cnt==alglib_impl::_alloc_counter);
2257 }
2258 catch(...)
2259 { issue528_passed = false; }
2260 printf(fmt_str, "* issue 528", issue528_passed ? "OK" : "FAILED");
2261 fflush(stdout);
2262 if( !issue528_passed )
2263 return 1;
2264 #else
2265 printf(fmt_str, "* issue 528", "??");
2266 fflush(stdout);
2267 #endif
2268
2269 //
2270 // Testing issue #591 (http://bugs.alglib.net/view.php?id=591)
2271 // in copying of object containing shared pool as one of its
2272 // fields.
2273 //
2274 // Unfixed ALGLIB crashes because of unneeded assertion in the
2275 // ae_shared_pool_init_copy() function.
2276 //
2277 try
2278 {
2279 alglib::multilayerperceptron net0, net1;
2280 alglib::real_1d_array x("[1,2]"), y0("[0,0]"), y1("[0,0]"), y2("[0,0]");
2281 alglib::mlpcreate0(2, 2, net0);
2282 alglib::mlpprocess(net0, x, y0);
2283
2284 //
2285 // Test assignment constructor
2286 //
2287 net1 = net0;
2288 alglib::mlpprocess(net1, x, y1);
2289 issue591_passed = issue591_passed && (fabs(y0[0]-y1[0])<1.0E-9) && (fabs(y0[1]-y1[1])<1.0E-9);
2290
2291 //
2292 // Test copy constructor
2293 //
2294 alglib::multilayerperceptron net2(net0);
2295 alglib::mlpprocess(net2, x, y2);
2296 issue591_passed = issue591_passed && (fabs(y0[0]-y2[0])<1.0E-9) && (fabs(y0[1]-y2[1])<1.0E-9);
2297 }
2298 catch(...)
2299 { issue591_passed = false; }
2300 printf(fmt_str, "* issue 591", issue591_passed ? "OK" : "FAILED");
2301 fflush(stdout);
2302 if( !issue591_passed )
2303 return 1;
2304
2305 //
2306 // Task #594 (http://bugs.alglib.net/view.php?id=594) - additional
2307 // test for correctness of copying of objects. When we copy ALGLIB
2308 // object, indenendent new copy is created.
2309 //
2310 // This test checks both copying with copy constructor and assignment
2311 // constructor
2312 //
2313 try
2314 {
2315 alglib::multilayerperceptron net0, net1;
2316 alglib::real_1d_array x("[1,2]"), y0("[0,0]"), y1("[0,0]"), y2("[0,0]");
2317 alglib::mlpcreate0(2, 2, net0);
2318 alglib::mlpprocess(net0, x, y0);
2319
2320 //
2321 // Test assignment and copy constructors:
2322 // * copy object with one of the constructors
2323 // * process vector with original network
2324 // * randomize original network
2325 // * process vector with copied networks and compare
2326 //
2327 net1 = net0;
2328 alglib::multilayerperceptron net2(net0);
2329 alglib::mlprandomize(net0);
2330 alglib::mlpprocess(net1, x, y1);
2331 alglib::mlpprocess(net2, x, y2);
2332 issue594_passed = issue594_passed && (fabs(y0[0]-y1[0])<1.0E-9) && (fabs(y0[1]-y1[1])<1.0E-9);
2333 issue594_passed = issue594_passed && (fabs(y0[0]-y2[0])<1.0E-9) && (fabs(y0[1]-y2[1])<1.0E-9);
2334 }
2335 catch(...)
2336 { issue594_passed = false; }
2337 printf(fmt_str, "* issue 594", issue594_passed ? "OK" : "FAILED");
2338 fflush(stdout);
2339 if( !issue594_passed )
2340 return 1;
2341
2342 //
2343 // Issue 764#, potential memory leak in the smart pointer
2344 //
2345 #ifdef AE_USE_ALLOC_COUNTER
2346 try
2347 {
2348 int alloc_cnt;
2349 alglib_impl::ae_state _alglib_env_state;
2350 alglib_impl::ae_frame _frame_block;
2351 alglib_impl::ae_shared_pool pool;
2352 alglib_impl::ae_smart_ptr ptr0;
2353 void *p0, *p1;
2354 seedrec seed;
2355
2356 // seeding shared pool and retrieving twice to same pointer, no recycling
2357 alloc_cnt = alglib_impl::_alloc_counter;
2358 alglib_impl::ae_state_init(&_alglib_env_state);
2359 alglib_impl::ae_frame_make(&_alglib_env_state, &_frame_block);
2360 memset(&ptr0, 0, sizeof(ptr0));
2361 memset(&pool, 0, sizeof(pool));
2362 memset(&seed, 0, sizeof(seed));
2363 alglib_impl::ae_smart_ptr_init(&ptr0, (void**)&p0, &_alglib_env_state, true);
2364 alglib_impl::ae_shared_pool_init(&pool, &_alglib_env_state, true);
2365 _seedrec_init(&seed, &_alglib_env_state, true);
2366 alglib_impl::ae_shared_pool_set_seed(&pool, &seed, sizeof(seed), _seedrec_init, _seedrec_init_copy, _seedrec_destroy, &_alglib_env_state);
2367 alglib_impl::ae_shared_pool_retrieve(&pool, &ptr0, &_alglib_env_state);
2368 alglib_impl::ae_shared_pool_retrieve(&pool, &ptr0, &_alglib_env_state);
2369 alglib_impl::ae_state_clear(&_alglib_env_state);
2370 issue764_passed = issue764_passed && (alloc_cnt==alglib_impl::_alloc_counter);
2371 }
2372 catch(...)
2373 { issue764_passed = false; }
2374 printf(fmt_str, "* issue 764", issue764_passed ? "OK" : "FAILED");
2375 fflush(stdout);
2376 if( !issue764_passed )
2377 return 1;
2378 #else
2379 printf(fmt_str, "* issue 764", "??");
2380 fflush(stdout);
2381 #endif
2382
2383 //
2384 // Issue 813: MSVC is unable to handle longjmp() from catch() block; the code
2385 // cycles forever.
2386 //
2387 {
2388 alglib::minlmstate state;
2389 alglib::real_1d_array x;
2390 x.setlength(1);
2391 alglib::minlmcreatev(1, x, 1e-5, state);
2392 issue813_passed = false;
2393 try
2394 {
2395 alglib::minlmoptimize(state, &issue813_callback);
2396 }
2397 catch(...)
2398 {
2399 issue813_passed = true;
2400 }
2401 printf(fmt_str, "* issue 813", issue813_passed ? "OK" : "FAILED");
2402 fflush(stdout);
2403 if( !issue813_passed )
2404 return 1;
2405 }
2406 }
2407
2408 //
2409 // Performance testing
2410 //
2411 printf("Performance:\n");
2412 {
2413 {
2414 int _n[] = { 16, 32, 64, 1024, 0};
2415 int i, j, k, t, nidx;
2416 for(nidx=0; _n[nidx]!=0; nidx++)
2417 {
2418 //
2419 // Settings:
2420 // * n - matrix size
2421 // * nrepeat - number of repeated multiplications, always divisible by 4
2422 //
2423 int n = _n[nidx];
2424 double desiredflops = n>64 ? 1.0E10 : 1.0E9;
2425 int nrepeat = (int)(desiredflops/(2*pow((double)n,3.0)));
2426 nrepeat = 4*(nrepeat/4+1);
2427
2428 //
2429 // Actual processing
2430 //
2431 alglib::real_2d_array a, b, c;
2432 double perf0, perf1, perf2;
2433 a.setlength(n, n);
2434 b.setlength(n, n);
2435 c.setlength(n, n);
2436 for(i=0; i<n; i++)
2437 for(j=0; j<n; j++)
2438 {
2439 a[i][j] = alglib::randomreal()-0.5;
2440 b[i][j] = alglib::randomreal()-0.5;
2441 c[i][j] = 0.0;
2442 }
2443
2444 t = alglib_impl::_tickcount();
2445 for(k=0; k<nrepeat; k++)
2446 alglib::rmatrixgemm(
2447 n, n, n,
2448 1.0,
2449 a, 0, 0, k%2,
2450 b, 0, 0, (k/2)%2,
2451 0.0,
2452 c, 0, 0);
2453 t = alglib_impl::_tickcount()-t;
2454 perf0 = 1.0E-6*pow((double)n,3)*2.0*nrepeat/(0.001*t);
2455 printf("* RGEMM-SEQ-%-4ld (MFLOPS) %5.0lf\n", (long)n, (double)perf0);
2456
2457 alglib::setnworkers(0);
2458 t = alglib_impl::_tickcount();
2459 for(k=0; k<nrepeat; k++)
2460 alglib::rmatrixgemm(
2461 n, n, n,
2462 1.0,
2463 a, 0, 0, k%2,
2464 b, 0, 0, (k/2)%2,
2465 0.0,
2466 c, 0, 0, alglib::parallel);
2467 t = alglib_impl::_tickcount()-t;
2468 perf2 = 1.0E-6*pow((double)n,3)*2.0*nrepeat/(0.001*t);
2469 printf("* RGEMM-MTN-%-4ld %4.1lfx\n", (long)n, (double)(perf2/perf0));
2470 alglib::setnworkers(1);
2471
2472 }
2473 }
2474 }
2475
2476 //
2477 // Check allocation counter on exit
2478 //
2479 #ifdef AE_USE_ALLOC_COUNTER
2480 printf("Allocation counter checked... ");
2481 #ifdef _ALGLIB_HAS_WORKSTEALING
2482 alglib_impl::ae_free_disposed_items();
2483 #endif
2484 if( alglib_impl::_alloc_counter!=0 )
2485 {
2486 printf("FAILURE: alloc_counter is non-zero on end!\n");
2487 return 1;
2488 }
2489 else
2490 printf("OK\n");
2491 #endif
2492
2493 //
2494 // Return
2495 //
2496 return 0;
2497 }
2498