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 #if !defined(AE_NO_EXCEPTIONS)
19 #error "This test should be compiled with AE_NO_EXCEPTIONS defined"
20 #endif
21
22 using namespace alglib;
23
24 const char *fmt_str = "%-29s %s\n";
25
main()26 int main()
27 {
28 printf("Test exception-free error handling:\n");
29
30 #ifdef AE_USE_ALLOC_COUNTER
31 printf("Allocation counter activated...\n");
32 alglib_impl::_use_alloc_counter = ae_true;
33 if( alglib_impl::_alloc_counter!=0 )
34 {
35 printf("FAILURE: alloc_counter is non-zero on start!\n");
36 return 1;
37 }
38 {
39 {
40 alglib::real_1d_array x;
41 x.setlength(1);
42 if( alglib_impl::_alloc_counter==0 )
43 printf(":::: WARNING: ALLOC_COUNTER IS INACTIVE!!! :::::\\n");
44 }
45 if( alglib_impl::_alloc_counter!=0 )
46 {
47 printf("FAILURE: alloc_counter does not decrease!\n");
48 return 1;
49 }
50 }
51 #endif
52
53 //
54 // Test default state of the error flag
55 //
56 {
57 bool passed = true;
58 passed = passed && !alglib::get_error_flag();
59 printf(fmt_str, "* default flag value", passed ? "OK" : "FAILED");
60 fflush(stdout);
61 if( !passed )
62 return 1;
63 }
64
65 //
66 // Test errors during array creation
67 //
68 {
69 bool passed = true;
70 alglib::clear_error_flag();
71
72 // constructors succeeded with working malloc()
73 alglib::clear_error_flag();
74 alglib::real_1d_array r1;
75 passed = passed && !alglib::get_error_flag();
76
77 // even with broken malloc() constructor succeeded()
78 alglib::clear_error_flag();
79 alglib_impl::_force_malloc_failure = true;
80 alglib::real_1d_array r2;
81 passed = passed && !alglib::get_error_flag();
82
83 // but setlength() fails without malloc()
84 alglib::clear_error_flag();
85 r2.setlength(5);
86 passed = passed && alglib::get_error_flag();
87
88 // clear_error_flag() clears error flag
89 alglib::clear_error_flag();
90 passed = passed && !alglib::get_error_flag();
91
92 // without clear_error_flag(), error flag is not reset by successful calls
93 alglib::clear_error_flag();
94 alglib_impl::_force_malloc_failure = true;
95 r2.setlength(5);
96 passed = passed && alglib::get_error_flag() && r2.length()==0;
97 alglib_impl::_force_malloc_failure = false;
98 r2.setlength(6);
99 passed = passed && alglib::get_error_flag() && r2.length()==6;
100 alglib::clear_error_flag();
101 r2.setlength(7);
102 passed = passed && !alglib::get_error_flag() && r2.length()==7;
103
104 // assignment to empty array requires malloc()
105 alglib::clear_error_flag();
106 alglib_impl::_force_malloc_failure = false;
107 alglib::real_1d_array r3;
108 r2.setlength(1);
109 r2[0] = 123.25;
110 alglib_impl::_force_malloc_failure = true;
111 r3 = r2;
112 passed = passed && alglib::get_error_flag() && r3.length()==0;
113 alglib_impl::_force_malloc_failure = false;
114 alglib::clear_error_flag();
115 r3 = r2;
116 passed = passed && !alglib::get_error_flag() && r3.length()==1 && r3[0]==123.25;
117
118 // assignment to non-empty array does NOT require malloc()
119 alglib::clear_error_flag();
120 alglib_impl::_force_malloc_failure = true;
121 r2[0] = 345;
122 r3 = r2;
123 passed = passed && !alglib::get_error_flag() && r3.length()==1 && r3[0]==345;
124 alglib_impl::_force_malloc_failure = false;
125
126 printf(fmt_str, "* 1D arrays", passed ? "OK" : "FAILED");
127 fflush(stdout);
128 if( !passed )
129 return 1;
130 }
131 {
132 bool passed = true;
133 alglib::clear_error_flag();
134
135 // constructors succeeded with working malloc()
136 alglib::clear_error_flag();
137 alglib::real_2d_array r1;
138 passed = passed && !alglib::get_error_flag();
139
140 // even with broken malloc() constructor succeeded()
141 alglib::clear_error_flag();
142 alglib_impl::_force_malloc_failure = true;
143 alglib::real_2d_array r2;
144 passed = passed && !alglib::get_error_flag();
145
146 // but setlength() fails without malloc()
147 alglib::clear_error_flag();
148 r2.setlength(5,6);
149 passed = passed && alglib::get_error_flag();
150
151 // clear_error_flag() clears error flag
152 alglib::clear_error_flag();
153 passed = passed && !alglib::get_error_flag();
154
155 // without clear_error_flag(), error flag is not reset by successful calls
156 alglib::clear_error_flag();
157 alglib_impl::_force_malloc_failure = true;
158 r2.setlength(5,6);
159 passed = passed && alglib::get_error_flag() && r2.rows()==0 && r2.cols()==0;
160 alglib_impl::_force_malloc_failure = false;
161 r2.setlength(6,7);
162 passed = passed && alglib::get_error_flag() && r2.rows()==6 && r2.cols()==7;
163 alglib::clear_error_flag();
164 r2.setlength(7,8);
165 passed = passed && !alglib::get_error_flag() && r2.rows()==7 && r2.cols()==8;
166
167 // assignment to empty array requires malloc()
168 alglib::clear_error_flag();
169 alglib_impl::_force_malloc_failure = false;
170 alglib::real_2d_array r3;
171 r2.setlength(1,1);
172 r2[0][0] = 123.25;
173 alglib_impl::_force_malloc_failure = true;
174 r3 = r2;
175 passed = passed && alglib::get_error_flag() && r3.rows()==0 && r3.cols()==0;
176 alglib_impl::_force_malloc_failure = false;
177 alglib::clear_error_flag();
178 r3 = r2;
179 passed = passed && !alglib::get_error_flag() && r3.rows()==1 && r3.cols()==1 && r3[0][0]==123.25;
180
181 // assignment to non-empty array does NOT require malloc()
182 alglib::clear_error_flag();
183 alglib_impl::_force_malloc_failure = true;
184 r2[0][0] = 345;
185 r3 = r2;
186 passed = passed && !alglib::get_error_flag() && r3.rows()==1 && r3.cols()==1 && r3[0][0]==345;
187 alglib_impl::_force_malloc_failure = false;
188
189 printf(fmt_str, "* 2D arrays", passed ? "OK" : "FAILED");
190 fflush(stdout);
191 if( !passed )
192 return 1;
193 }
194
195 //
196 // Test ALGLIB objects
197 //
198 {
199 bool passed = true;
200 alglib::clear_error_flag();
201
202 // prepare data for tests
203 alglib::real_1d_array x, y;
204 x.setlength(2);
205 x[0] = 0;
206 x[1] = 1;
207 y.setlength(2);
208 y[0] = 2;
209 y[1] = 3;
210
211 // constructors succeeded with working malloc()
212 alglib::clear_error_flag();
213 alglib::spline1dinterpolant s1;
214 passed = passed && !alglib::get_error_flag();
215
216 // with broken malloc() constructor fails()
217 alglib::clear_error_flag();
218 alglib_impl::_force_malloc_failure = true;
219 alglib::spline1dinterpolant s2;
220 passed = passed && alglib::get_error_flag();
221 alglib_impl::_force_malloc_failure = false;
222
223 // construction with correct malloc() succeeds
224 alglib::clear_error_flag();
225 alglib::spline1dbuildlinear(x, y, 2, s1);
226 passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s1,0.5)-2.5)<1.0E-12;
227
228 // assignment with broken malloc() fails
229 alglib::clear_error_flag();
230 alglib::spline1dinterpolant s3;
231 alglib_impl::_force_malloc_failure = true;
232 s3 = s1;
233 alglib_impl::_force_malloc_failure = false;
234 passed = passed && alglib::get_error_flag();
235
236 // assignment with broken object fails, but does not crash
237 alglib::clear_error_flag();
238 alglib_impl::_force_malloc_failure = true;
239 alglib::spline1dinterpolant s3b;
240 passed = passed && s3b.c_ptr()==NULL;
241 s3b = s1;
242 alglib_impl::_force_malloc_failure = false;
243 passed = passed && alglib::get_error_flag();
244
245 // assignment with working malloc() succeeds
246 alglib::clear_error_flag();
247 s3 = s1;
248 passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s3,0.5)-2.5)<1.0E-12;
249
250 // copy constructor with broken malloc fails
251 alglib::clear_error_flag();
252 alglib_impl::_force_malloc_failure = true;
253 alglib::spline1dinterpolant s4(s1);
254 alglib_impl::_force_malloc_failure = false;
255 passed = passed && alglib::get_error_flag();
256
257 // copy constructor with working malloc succeeds
258 alglib::clear_error_flag();
259 alglib::spline1dinterpolant s5(s1);
260 passed = passed && !alglib::get_error_flag() && fabs(alglib::spline1dcalc(s5,0.5)-2.5)<1.0E-12;
261
262 printf(fmt_str, "* ALGLIB objects", passed ? "OK" : "FAILED");
263 fflush(stdout);
264 if( !passed )
265 return 1;
266 }
267
268 //
269 // Test ALGLIB functions
270 //
271 {
272 bool passed = true;
273 //
274 alglib::clear_error_flag();
275 alglib::spline1dinterpolant s1;
276 alglib::real_1d_array x, y;
277 x.setlength(2);
278 x[0] = 0;
279 x[1] = 1;
280 y.setlength(2);
281 y[0] = 2;
282 y[1] = alglib::fp_nan;
283 passed = passed && !alglib::get_error_flag();
284 alglib::spline1dbuildlinear(x, y, 2, s1);
285 passed = passed && alglib::get_error_flag();
286
287 printf(fmt_str, "* ALGLIB functions", passed ? "OK" : "FAILED");
288 fflush(stdout);
289 if( !passed )
290 return 1;
291 }
292
293 //
294 // Allocation counter
295 //
296 #ifdef AE_USE_ALLOC_COUNTER
297 printf("Allocation counter checked... ");
298 if( alglib_impl::_alloc_counter!=0 )
299 {
300 printf("FAILURE: alloc_counter is non-zero on end!\n");
301 return 1;
302 }
303 else
304 printf("OK\n");
305 #endif
306
307 //
308 // Return
309 //
310 return 0;
311 }
312