remove warning C6031
[liba.git] / test / regress_linear.h
bloba5a4d2722df5fb9fc84aad3c8981607c6263abe0
1 #define MAIN(x) regress_linear##x
2 #include "test.h"
3 #include "a/regress_linear.h"
4 #include "a/math.h"
5 #include <string.h>
6 #include <time.h>
8 #define RAND_MAX_ 2147483647
9 static unsigned long rand_seed = 1;
10 static void srand_(unsigned long seed)
12 rand_seed = seed;
14 static long rand_(void)
16 rand_seed = (rand_seed * 1103515245 + 12345) % 2147483648;
17 return a_cast_s(long, rand_seed);
20 typedef struct config
22 a_float delta;
23 a_float lrmax;
24 a_float lrmin;
25 a_size lrtim;
26 a_size epoch;
27 a_size batch;
28 } config;
30 static void main_1(int m, a_float a, a_float b, a_size n, config const *cfg)
32 a_float *x = a_new(a_float, A_NULL, n);
33 a_float *y = a_new(a_float, A_NULL, n);
34 a_float *e = a_new(a_float, A_NULL, n);
35 long x_n = a_cast_s(long, n) * 10;
36 long y_n = a_cast_s(long, n) * 2;
37 a_float coef[] = {1};
38 a_regress_linear ctx;
39 a_size i;
41 for (i = 0; i < n; ++i)
43 x[i] = a_cast_s(a_float, rand_() % x_n);
44 y[i] = a * x[i] + b + a_cast_s(a_float, rand_() % y_n) - a_cast_s(a_float, y_n >> 1);
47 a_regress_linear_init(&ctx, coef, 1, 1);
48 a_regress_linear_zero(&ctx);
50 switch (m)
52 default:
53 case 's':
55 a_float r, s, lrcur = 0;
56 a_float const lramp = (cfg->lrmax - cfg->lrmin) / 2;
57 a_float const lrper = A_FLOAT_PI / a_float_c(cfg->lrtim);
58 a_regress_linear_err(&ctx, n, x, y, e);
59 r = a_float_sum2(e, n);
60 for (i = 0; i < cfg->epoch; ++i)
62 a_float alpha = cfg->lrmin + lramp * (a_float_cos(lrcur) + 1);
63 a_regress_linear_sgd(&ctx, n, x, y, alpha);
64 a_regress_linear_err(&ctx, n, x, y, e);
65 s = a_float_sum2(e, n);
66 if (A_ABS_(r, s) < cfg->delta)
68 break;
70 lrcur += lrper;
71 r = s;
73 break;
75 case 'b':
77 a_float r, s, lrcur = 0;
78 a_float const lramp = (cfg->lrmax - cfg->lrmin) / 2;
79 a_float const lrper = A_FLOAT_PI / a_float_c(cfg->lrtim);
80 a_regress_linear_err(&ctx, n, x, y, e);
81 r = a_float_sum2(e, n);
82 for (i = 0; i < cfg->epoch; ++i)
84 a_float alpha = cfg->lrmin + lramp * (a_float_cos(lrcur) + 1);
85 a_regress_linear_bgd(&ctx, n, x, e, alpha);
86 a_regress_linear_err(&ctx, n, x, y, e);
87 s = a_float_sum2(e, n);
88 if (A_ABS_(r, s) < cfg->delta)
90 break;
92 lrcur += lrper;
93 r = s;
95 break;
97 case 'm':
98 a_regress_linear_mgd(&ctx, n, x, y, e, cfg->delta, cfg->lrmax, cfg->lrmin, cfg->lrtim, cfg->epoch, cfg->batch);
101 for (i = 0; i < n; ++i)
103 a_float u = a_cast_s(a_float, i * 10);
104 a_float v = a_regress_linear_eval(&ctx, &u);
105 debug(A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f,")
106 A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f\n"),
107 u, v, x[i], y[i], e[i]);
110 a_regress_linear_zero(&ctx);
112 a_die(x);
113 a_die(y);
114 a_die(e);
117 static void main_2(int m, a_float a, a_float b, a_float c, a_size n, config const *cfg)
119 a_float *x = a_new(a_float, A_NULL, n * 2);
120 a_float *y = a_new(a_float, A_NULL, n);
121 a_float *e = a_new(a_float, A_NULL, n);
122 long x_n = a_cast_s(long, n) * 10;
123 long y_n = a_cast_s(long, n) * 2;
124 a_float coef[2] = {1, 1};
125 a_regress_linear ctx;
126 a_size i, ii;
128 for (i = 0; i < n; ++i)
130 x[i * 2 + 0] = a_cast_s(a_float, rand_() % x_n);
131 x[i * 2 + 1] = a_cast_s(a_float, rand_() % x_n);
132 y[i] = a * x[i * 2 + 0] + b * x[i * 2 + 1] + c +
133 a_cast_s(a_float, rand_() % y_n) - a_cast_s(a_float, y_n >> 1);
136 a_regress_linear_init(&ctx, coef, 2, 1);
137 a_regress_linear_zero(&ctx);
139 switch (m)
141 default:
142 case 's':
144 a_float r, s, lrcur = 0;
145 a_float const lramp = (cfg->lrmax - cfg->lrmin) / 2;
146 a_float const lrper = A_FLOAT_PI / a_float_c(cfg->lrtim);
147 a_regress_linear_err(&ctx, n, x, y, e);
148 r = a_float_sum2(e, n);
149 for (i = 0; i < cfg->epoch; ++i)
151 a_float alpha = cfg->lrmin + lramp * (a_float_cos(lrcur) + 1);
152 a_regress_linear_sgd(&ctx, n, x, y, alpha);
153 a_regress_linear_err(&ctx, n, x, y, e);
154 s = a_float_sum2(e, n);
155 if (A_ABS_(r, s) < cfg->delta)
157 break;
159 lrcur += lrper;
160 r = s;
162 break;
164 case 'b':
166 a_float r, s, lrcur = 0;
167 a_float const lramp = (cfg->lrmax - cfg->lrmin) / 2;
168 a_float const lrper = A_FLOAT_PI / a_float_c(cfg->lrtim);
169 a_regress_linear_err(&ctx, n, x, y, e);
170 r = a_float_sum2(e, n);
171 for (i = 0; i < cfg->epoch; ++i)
173 a_float alpha = cfg->lrmin + lramp * (a_float_cos(lrcur) + 1);
174 a_regress_linear_bgd(&ctx, n, x, e, alpha);
175 a_regress_linear_err(&ctx, n, x, y, e);
176 s = a_float_sum2(e, n);
177 if (A_ABS_(r, s) < cfg->delta)
179 break;
181 lrcur += lrper;
182 r = s;
184 break;
186 case 'm':
187 a_regress_linear_mgd(&ctx, n, x, y, e, cfg->delta, cfg->lrmax, cfg->lrmin, cfg->lrtim, cfg->epoch, cfg->batch);
190 for (i = 0; i < n; ++i)
192 a_float u[2];
193 u[0] = a_cast_s(a_float, i * 10);
194 for (ii = 0; ii < n; ++ii)
196 a_float v;
197 u[1] = a_cast_s(a_float, ii * 10);
198 v = a_regress_linear_eval(&ctx, u);
199 debug(A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f"), u[0], u[1], v);
200 debug("%c", i ? '\n' : ',');
201 if (i == 0)
203 debug(A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f,")
204 A_FLOAT_PRI("+.1", "f,") A_FLOAT_PRI("+.1", "f\n"),
205 x[ii * 2 + 0], x[ii * 2 + 1], y[ii], e[ii]);
208 debug("\n");
211 a_regress_linear_zero(&ctx);
213 a_die(x);
214 a_die(y);
215 a_die(e);
218 int main(int argc, char *argv[]) /* NOLINT(misc-definitions-in-headers) */
220 a_float a = A_FLOAT_C(0.7);
221 a_float b = A_FLOAT_C(1.4);
222 a_float c = 12;
223 a_size n = 100;
224 char *endptr;
225 char m = 'm';
226 int dim = 1;
228 config cfg;
229 cfg.delta = 1;
230 cfg.lrmax = A_FLOAT_C(5e-7);
231 cfg.lrmin = A_FLOAT_C(5e-9);
232 cfg.lrtim = 100;
233 cfg.epoch = 1000;
234 cfg.batch = 16;
236 srand_(a_cast_s(a_ulong, time(A_NULL)));
237 main_init(argc, argv, 1);
239 if (argc > 1)
241 char const *s = strstr(argv[1], "regress_linear_");
242 if (s) { (void)sscanf(s, "regress_linear_%i%c", &dim, &m); } /* NOLINT */
243 else
245 debug("regress_linear_1sgd.csv\n");
246 debug("regress_linear_1bgd.csv\n");
247 debug("regress_linear_1mgd.csv\n");
248 debug("regress_linear_2sgd.csv\n");
249 debug("regress_linear_2bgd.csv\n");
250 debug("regress_linear_2mgd.csv\n");
251 return 0;
255 if (dim == 1)
257 if (argc > 2) { a = strtonum(argv[2], &endptr); }
258 if (argc > 3) { c = strtonum(argv[3], &endptr); }
259 if (argc > 4) { n = strtoul(argv[4], &endptr, 0); }
260 main_1(m, a, c, n, &cfg);
262 if (dim == 2)
264 if (argc > 2) { a = strtonum(argv[2], &endptr); }
265 if (argc > 3) { b = strtonum(argv[3], &endptr); }
266 if (argc > 4) { c = strtonum(argv[4], &endptr); }
267 if (argc > 5) { n = strtoul(argv[5], &endptr, 0); }
268 main_2(m, a, b, c, n, &cfg);
271 #if defined(__cplusplus) && (__cplusplus > 201100L)
272 A_BUILD_ASSERT(std::is_pod<a_regress_linear>::value);
273 #endif /* __cplusplus */
275 return 0;