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
* 1103515245 + 12345) % 2147483648;
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(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
);
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
;
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
);
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
)
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
)
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
)
193 u
[0] = a_cast_s(a_float
, i
* 10);
194 for (ii
= 0; ii
< n
; ++ii
)
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' : ',');
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
]);
211 a_regress_linear_zero(&ctx
);
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);
230 cfg
.lrmax
= A_FLOAT_C(5e-7);
231 cfg
.lrmin
= A_FLOAT_C(5e-9);
236 srand_(a_cast_s(a_ulong
, time(A_NULL
)));
237 main_init(argc
, argv
, 1);
241 char const *s
= strstr(argv
[1], "regress_linear_");
242 if (s
) { (void)sscanf(s
, "regress_linear_%i%c", &dim
, &m
); } /* NOLINT */
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");
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
);
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 */