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
)
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
++;
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
++;
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
)
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
)
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
++;
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
)
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
++;
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
)
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
);
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
)
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
)
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
);
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
)
174 void a_regress_linear_zero(a_regress_linear
*ctx
)
176 a_zero(ctx
->coef_p
, sizeof(a_float
) * ctx
->coef_n
);