change e,y,x,n to n,x,y,e for regress
[liba.git] / src / regress_linear.c
blob94bee7879459758815b7317b6897aefd9a8cb5cf
1 #include "a/regress_linear.h"
3 void a_regress_linear_init(a_regress_linear *ctx, a_float *coef_p, a_size coef_n, a_float bias)
5 ctx->coef_p = coef_p;
6 ctx->coef_n = coef_n;
7 ctx->bias = bias;
10 a_float a_regress_linear_eval(a_regress_linear const *ctx, a_float const *val)
12 a_float res = ctx->bias;
13 a_float const *coef = ctx->coef_p;
14 for (a_size n = ctx->coef_n; n; --n)
16 res += *coef++ * *val++;
18 return res;
21 void a_regress_linear_err1(a_regress_linear const *ctx, a_size n, a_float const *x, a_float const *y, a_float *err)
23 for (; n; --n, x += ctx->coef_n) { *err++ = *y++ - a_regress_linear_eval(ctx, x); }
26 void a_regress_linear_err2(a_regress_linear const *ctx, a_size n, a_float const *const *x, a_float const *y, a_float *err)
28 for (; n; --n) { *err++ = *y++ - a_regress_linear_eval(ctx, *x++); }
31 void a_regress_linear_pdm1(a_regress_linear const *ctx, a_size n, a_float const *x, a_float *pdm, a_float y_mean)
33 for (; n; --n, x += ctx->coef_n) { *pdm++ = a_regress_linear_eval(ctx, x) - y_mean; }
36 void a_regress_linear_pdm2(a_regress_linear const *ctx, a_size n, a_float const *const *x, a_float *pdm, a_float y_mean)
38 for (; n; --n) { *pdm++ = a_regress_linear_eval(ctx, *x++) - y_mean; }
41 void a_regress_linear_sgd_(a_regress_linear *ctx, a_float const *input, a_float error, a_float alpha)
43 a_float delta = alpha * error;
44 a_float *coef = ctx->coef_p;
45 for (a_size n = ctx->coef_n; n; --n)
47 *coef++ += delta * *input++;
49 ctx->bias += delta;
52 void a_regress_linear_sgd(a_regress_linear *ctx, a_float const *x, a_float y, a_float alpha)
54 a_float error = y - a_regress_linear_eval(ctx, x);
55 a_regress_linear_sgd_(ctx, x, error, alpha);
58 void a_regress_linear_sgd1(a_regress_linear *ctx, a_size n, a_float const *x, a_float const *y, a_float alpha)
60 for (; n; --n, x += ctx->coef_n)
62 a_float error = *y++ - a_regress_linear_eval(ctx, x);
63 a_regress_linear_sgd_(ctx, x, error, alpha);
67 void a_regress_linear_sgd2(a_regress_linear *ctx, a_size n, a_float const *const *x, a_float const *y, a_float alpha)
69 for (; n; --n, ++x)
71 a_float error = *y++ - a_regress_linear_eval(ctx, *x);
72 a_regress_linear_sgd_(ctx, *x, error, alpha);
76 void a_regress_linear_bgd1(a_regress_linear *ctx, a_size n, a_float const *x, a_float const *err, a_float alpha)
78 for (; n; --n)
80 a_float *coef = ctx->coef_p;
81 a_float delta = alpha * *err++;
82 for (a_size c = ctx->coef_n; c; --c)
84 *coef++ += delta * *x++;
86 ctx->bias += delta;
90 void a_regress_linear_bgd2(a_regress_linear *ctx, a_size n, a_float const *const *x, a_float const *err, a_float alpha)
92 for (; n; --n)
94 a_float const *p = *x++;
95 a_float *coef = ctx->coef_p;
96 a_float delta = alpha * *err++;
97 for (a_size c = ctx->coef_n; c; --c)
99 *coef++ += delta * *p++;
101 ctx->bias += delta;
105 int a_regress_linear_mgd1(a_regress_linear *ctx, a_size n, a_float const *x_, a_float const *y_,
106 a_float *err, a_float alpha, a_float delta, a_size count, a_size batch)
108 a_float r, s;
109 a_size q_ = n / batch;
110 a_size r_ = n % batch;
111 a_size c, xoffset = ctx->coef_n;
112 q_ ? (xoffset *= batch) : (batch = n);
113 a_regress_linear_err1(ctx, n, x_, y_, err);
114 r = a_float_sum2(err, n);
115 for (c = 0; c < count; ++c)
117 a_float const *y = y_;
118 a_float const *x = x_;
119 for (a_size q = q_; q; --q, y += batch, x += xoffset)
121 a_regress_linear_err1(ctx, batch, x, y, err);
122 a_regress_linear_bgd1(ctx, batch, x, err, alpha);
124 if (r_)
126 a_regress_linear_err1(ctx, r_, x, y, err);
127 a_regress_linear_bgd1(ctx, r_, x, err, alpha);
129 a_regress_linear_err1(ctx, n, x_, y_, err);
130 s = a_float_sum2(err, n);
131 if (A_ABS_(r, s) < delta)
133 break;
135 r = s;
137 return c < count;
140 int a_regress_linear_mgd2(a_regress_linear *ctx, a_size n, a_float const *const *x_, a_float const *y_,
141 a_float *err, a_float alpha, a_float delta, a_size count, a_size batch)
143 a_float r, s;
144 a_size q_ = n / batch;
145 a_size r_ = n % batch, c;
146 if (q_ == 0) { batch = n; }
147 a_regress_linear_err2(ctx, n, x_, y_, err);
148 r = a_float_sum2(err, n);
149 for (c = 0; c < count; ++c)
151 a_float const *y = y_;
152 a_float const *const *x = x_;
153 for (a_size q = q_; q; --q, y += batch, x += batch)
155 a_regress_linear_err2(ctx, batch, x, y, err);
156 a_regress_linear_bgd2(ctx, batch, x, err, alpha);
158 if (r_)
160 a_regress_linear_err2(ctx, r_, x, y, err);
161 a_regress_linear_bgd2(ctx, r_, x, err, alpha);
163 a_regress_linear_err2(ctx, n, x_, y_, err);
164 s = a_float_sum2(err, n);
165 if (A_ABS_(r, s) < delta)
167 break;
169 r = s;
171 return c < count;
174 void a_regress_linear_zero(a_regress_linear *ctx)
176 a_zero(ctx->coef_p, sizeof(a_float) * ctx->coef_n);
177 ctx->bias = 0;