| 7 | using namespace svm_kernel; |
| 8 | |
| 9 | float_type |
| 10 | NuSMOSolver::calculate_rho(const SyncArray<float_type> &f_val, const SyncArray<int> &y, SyncArray<float_type> &alpha, |
| 11 | float_type Cp, |
| 12 | float_type Cn) const { |
| 13 | int n_free_p = 0, n_free_n = 0; |
| 14 | float_type sum_free_p = 0, sum_free_n = 0; |
| 15 | float_type up_value_p = INFINITY, up_value_n = INFINITY; |
| 16 | float_type low_value_p = -INFINITY, low_value_n = -INFINITY; |
| 17 | const float_type *f_val_data = f_val.host_data(); |
| 18 | const int *y_data = y.host_data(); |
| 19 | float_type *alpha_data = alpha.host_data(); |
| 20 | for (int i = 0; i < alpha.size(); ++i) { |
| 21 | if (y_data[i] > 0) { |
| 22 | if (alpha_data[i] > 0 && alpha_data[i] < Cp) { |
| 23 | n_free_p++; |
| 24 | sum_free_p += f_val_data[i]; |
| 25 | } |
| 26 | if (is_I_up(alpha_data[i], y_data[i], Cp, Cn)) up_value_p = min(up_value_p, -f_val_data[i]); |
| 27 | if (is_I_low(alpha_data[i], y_data[i], Cp, Cn)) low_value_p = max(low_value_p, -f_val_data[i]); |
| 28 | } else { |
| 29 | if (alpha_data[i] > 0 && alpha_data[i] < Cn) { |
| 30 | n_free_n++; |
| 31 | sum_free_n += -f_val_data[i]; |
| 32 | } |
| 33 | if (is_I_up(alpha_data[i], y_data[i], Cp, Cn)) up_value_n = min(up_value_n, -f_val_data[i]); |
| 34 | if (is_I_low(alpha_data[i], y_data[i], Cp, Cn)) low_value_n = max(low_value_n, -f_val_data[i]); |
| 35 | } |
| 36 | } |
| 37 | float_type r1 = n_free_p != 0 ? sum_free_p / n_free_p : (-(up_value_p + low_value_p) / 2); |
| 38 | float_type r2 = n_free_n != 0 ? sum_free_n / n_free_n : (-(up_value_n + low_value_n) / 2); |
| 39 | float_type rho = (r1 - r2) / 2; |
| 40 | //not scale for svr, scale for nu-svc |
| 41 | if (!for_svr) { |
| 42 | float_type r = (r1 + r2) / 2; |
| 43 | scale_alpha_rho(alpha, rho, r); |
| 44 | } |
| 45 | return rho; |
| 46 | } |
| 47 | |
| 48 | void |
| 49 | NuSMOSolver::select_working_set(vector<int> &ws_indicator, const SyncArray<int> &f_idx2sort, const SyncArray<int> &y, |