| 10 | namespace svm_kernel { |
| 11 | |
| 12 | void c_smo_solve_kernel(const int *label, float_type *f_val, float_type *alpha, float_type *alpha_diff, |
| 13 | const int *working_set, |
| 14 | int ws_size, |
| 15 | float_type Cp, float_type Cn, const kernel_type *k_mat_rows, const kernel_type *k_mat_diag, |
| 16 | int row_len, |
| 17 | float_type eps, |
| 18 | float_type *diff, int max_iter) { |
| 19 | //allocate shared memory |
| 20 | float_type alpha_i_diff; //delta alpha_i |
| 21 | float_type alpha_j_diff; |
| 22 | vector<kernel_type> kd(ws_size); // diagonal elements for kernel matrix |
| 23 | |
| 24 | //index, f value and alpha for each instance |
| 25 | vector<float_type> a_old(ws_size); |
| 26 | vector<float_type> kIwsI(ws_size); |
| 27 | vector<float_type> f(ws_size); |
| 28 | vector<float_type> y(ws_size); |
| 29 | vector<float_type> a(ws_size); |
| 30 | for (int tid = 0; tid < ws_size; ++tid) { |
| 31 | int wsi = working_set[tid]; |
| 32 | f[tid] = f_val[wsi]; |
| 33 | a_old[tid] = a[tid] = alpha[wsi]; |
| 34 | y[tid] = label[wsi]; |
| 35 | kd[tid] = k_mat_diag[wsi]; |
| 36 | } |
| 37 | float_type local_eps; |
| 38 | int numOfIter = 0; |
| 39 | while (1) { |
| 40 | //select fUp and fLow |
| 41 | int i = 0; |
| 42 | float_type up_value = INFINITY; |
| 43 | for (int tid = 0; tid < ws_size; ++tid) { |
| 44 | if (is_I_up(a[tid], y[tid], Cp, Cn)) |
| 45 | if (f[tid] < up_value) { |
| 46 | up_value = f[tid]; |
| 47 | i = tid; |
| 48 | } |
| 49 | } |
| 50 | for (int tid = 0; tid < ws_size; ++tid) { |
| 51 | kIwsI[tid] = k_mat_rows[row_len * i + working_set[tid]];//K[i, wsi] |
| 52 | } |
| 53 | float_type low_value = -INFINITY; |
| 54 | for (int tid = 0; tid < ws_size; ++tid) { |
| 55 | if (is_I_low(a[tid], y[tid], Cp, Cn)) |
| 56 | if (f[tid] > low_value) { |
| 57 | low_value = f[tid]; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | // printf("up = %lf, low = %lf\n", up_value, low_value); |
| 62 | float_type local_diff = low_value - up_value; |
| 63 | if (numOfIter == 0) { |
| 64 | local_eps = max(eps, 0.1f * local_diff); |
| 65 | diff[0] = local_diff; |
| 66 | } |
| 67 | |
| 68 | if (numOfIter > max_iter || local_diff < local_eps) { |
| 69 | for (int tid = 0; tid < ws_size; ++tid) { |
no test coverage detected