1 #define MAIN(x) regress_linear##x
3 #include "a/regress_linear.h"
8 #define RAND_MAX_ 2147483647
9 static unsigned long rand_seed
= 1;
10 static void srand_(unsigned long seed
)
14 static long rand_(void)
16 rand_seed
= (rand_seed
* 1103515245UL + 12345) % 2147483648UL;
17 return a_cast_s(long, rand_seed
);
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;
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
);
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
)
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
)
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("%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f\n",
106 u
, v
, x
[i
], y
[i
], e
[i
]);
109 a_regress_linear_zero(&ctx
);
116 static void main_2(int m
, a_float a
, a_float b
, a_float c
, a_size n
, config
const *cfg
)
118 a_float
*x
= a_new(a_float
, A_NULL
, n
* 2);
119 a_float
*y
= a_new(a_float
, A_NULL
, n
);
120 a_float
*e
= a_new(a_float
, A_NULL
, n
);
121 long x_n
= a_cast_s(long, n
) * 10;
122 long y_n
= a_cast_s(long, n
) * 2;
123 a_float coef
[2] = {1, 1};
124 a_regress_linear ctx
;
127 for (i
= 0; i
< n
; ++i
)
129 x
[i
* 2 + 0] = a_cast_s(a_float
, rand_() % x_n
);
130 x
[i
* 2 + 1] = a_cast_s(a_float
, rand_() % x_n
);
131 y
[i
] = a
* x
[i
* 2 + 0] + b
* x
[i
* 2 + 1] + c
+
132 a_cast_s(a_float
, rand_() % y_n
) - a_cast_s(a_float
, y_n
>> 1);
135 a_regress_linear_init(&ctx
, coef
, 2, 1);
136 a_regress_linear_zero(&ctx
);
143 a_float r
, s
, lrcur
= 0;
144 a_float
const lramp
= (cfg
->lrmax
- cfg
->lrmin
) / 2;
145 a_float
const lrper
= A_FLOAT_PI
/ a_float_c(cfg
->lrtim
);
146 a_regress_linear_err(&ctx
, n
, x
, y
, e
);
147 r
= a_float_sum2(e
, n
);
148 for (i
= 0; i
< cfg
->epoch
; ++i
)
150 a_float alpha
= cfg
->lrmin
+ lramp
* (a_float_cos(lrcur
) + 1);
151 a_regress_linear_sgd(&ctx
, n
, x
, y
, alpha
);
152 a_regress_linear_err(&ctx
, n
, x
, y
, e
);
153 s
= a_float_sum2(e
, n
);
154 if (A_ABS_(r
, s
) < cfg
->delta
)
165 a_float r
, s
, lrcur
= 0;
166 a_float
const lramp
= (cfg
->lrmax
- cfg
->lrmin
) / 2;
167 a_float
const lrper
= A_FLOAT_PI
/ a_float_c(cfg
->lrtim
);
168 a_regress_linear_err(&ctx
, n
, x
, y
, e
);
169 r
= a_float_sum2(e
, n
);
170 for (i
= 0; i
< cfg
->epoch
; ++i
)
172 a_float alpha
= cfg
->lrmin
+ lramp
* (a_float_cos(lrcur
) + 1);
173 a_regress_linear_bgd(&ctx
, n
, x
, e
, alpha
);
174 a_regress_linear_err(&ctx
, n
, x
, y
, e
);
175 s
= a_float_sum2(e
, n
);
176 if (A_ABS_(r
, s
) < cfg
->delta
)
186 a_regress_linear_mgd(&ctx
, n
, x
, y
, e
, cfg
->delta
, cfg
->lrmax
, cfg
->lrmin
, cfg
->lrtim
, cfg
->epoch
, cfg
->batch
);
189 for (i
= 0; i
< n
; ++i
)
192 u
[0] = a_cast_s(a_float
, i
* 10);
193 for (ii
= 0; ii
< n
; ++ii
)
196 u
[1] = a_cast_s(a_float
, ii
* 10);
197 v
= a_regress_linear_eval(&ctx
, u
);
198 debug("%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f", u
[0], u
[1], v
);
199 debug("%c", i
? '\n' : ',');
202 debug("%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f,%+.1" A_FLOAT_PRI
"f\n",
203 x
[ii
* 2 + 0], x
[ii
* 2 + 1], y
[ii
], e
[ii
]);
209 a_regress_linear_zero(&ctx
);
216 int main(int argc
, char *argv
[]) /* NOLINT(misc-definitions-in-headers) */
218 a_float a
= A_FLOAT_C(0.7);
219 a_float b
= A_FLOAT_C(1.4);
228 cfg
.lrmax
= A_FLOAT_C(5e-7);
229 cfg
.lrmin
= A_FLOAT_C(5e-9);
234 srand_(a_cast_s(a_ulong
, time(A_NULL
)));
235 main_init(argc
, argv
, 1);
239 char const *s
= strstr(argv
[1], "regress_linear_");
240 if (s
) { (void)sscanf(s
, "regress_linear_%i%c", &dim
, &m
); } /* NOLINT */
243 debug("regress_linear_1sgd.csv\n");
244 debug("regress_linear_1bgd.csv\n");
245 debug("regress_linear_1mgd.csv\n");
246 debug("regress_linear_2sgd.csv\n");
247 debug("regress_linear_2bgd.csv\n");
248 debug("regress_linear_2mgd.csv\n");
255 if (argc
> 2) { a
= strtonum(argv
[2], &endptr
); }
256 if (argc
> 3) { c
= strtonum(argv
[3], &endptr
); }
257 if (argc
> 4) { n
= strtoul(argv
[4], &endptr
, 0); }
258 main_1(m
, a
, c
, n
, &cfg
);
262 if (argc
> 2) { a
= strtonum(argv
[2], &endptr
); }
263 if (argc
> 3) { b
= strtonum(argv
[3], &endptr
); }
264 if (argc
> 4) { c
= strtonum(argv
[4], &endptr
); }
265 if (argc
> 5) { n
= strtoul(argv
[5], &endptr
, 0); }
266 main_2(m
, a
, b
, c
, n
, &cfg
);
269 #if defined(__cplusplus) && (__cplusplus > 201100L)
270 A_BUILD_ASSERT(std::is_pod
<a_regress_linear
>::value
);
271 #endif /* __cplusplus */