numo-liblinear 1.0.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/build.yml +28 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +1 -1
- data/README.md +5 -10
- data/Steepfile +20 -0
- data/ext/numo/liblinear/converter.c +6 -0
- data/ext/numo/liblinear/extconf.rb +1 -1
- data/ext/numo/liblinear/liblinear/linear.cpp +779 -257
- data/ext/numo/liblinear/liblinear/linear.h +7 -2
- data/ext/numo/liblinear/liblinear/newton.cpp +245 -0
- data/ext/numo/liblinear/liblinear/{tron.h → newton.h} +11 -10
- data/ext/numo/liblinear/liblinearext.c +16 -0
- data/ext/numo/liblinear/model.c +3 -0
- data/ext/numo/liblinear/parameter.c +36 -29
- data/ext/numo/liblinear/problem.c +3 -0
- data/ext/numo/liblinear/solver_type.c +8 -6
- data/lib/numo/liblinear/version.rb +1 -1
- data/numo-liblinear.gemspec +2 -7
- data/sig/numo/liblinear.rbs +52 -0
- data/sig/patch.rbs +8 -0
- metadata +11 -65
- data/.travis.yml +0 -13
- data/ext/numo/liblinear/liblinear/tron.cpp +0 -288
@@ -17,18 +17,20 @@ void rb_init_solver_type_module()
|
|
17
17
|
rb_define_const(mSolverType, "L2R_L2LOSS_SVC", INT2NUM(L2R_L2LOSS_SVC));
|
18
18
|
/* L2-regularized L1-loss support vector classification (dual) */
|
19
19
|
rb_define_const(mSolverType, "L2R_L1LOSS_SVC_DUAL", INT2NUM(L2R_L1LOSS_SVC_DUAL));
|
20
|
-
|
20
|
+
/* support vector classification by Crammer and Singer */
|
21
21
|
rb_define_const(mSolverType, "MCSVM_CS", INT2NUM(MCSVM_CS));
|
22
|
-
|
22
|
+
/* L1-regularized L2-loss support vector classification */
|
23
23
|
rb_define_const(mSolverType, "L1R_L2LOSS_SVC", INT2NUM(L1R_L2LOSS_SVC));
|
24
|
-
|
24
|
+
/* L1-regularized logistic regression */
|
25
25
|
rb_define_const(mSolverType, "L1R_LR", INT2NUM(L1R_LR));
|
26
26
|
/* L2-regularized logistic regression (dual) */
|
27
27
|
rb_define_const(mSolverType, "L2R_LR_DUAL", INT2NUM(L2R_LR_DUAL));
|
28
|
-
|
28
|
+
/* L2-regularized L2-loss support vector regression (primal) */
|
29
29
|
rb_define_const(mSolverType, "L2R_L2LOSS_SVR", INT2NUM(L2R_L2LOSS_SVR));
|
30
|
-
|
30
|
+
/* L2-regularized L2-loss support vector regression (dual) */
|
31
31
|
rb_define_const(mSolverType, "L2R_L2LOSS_SVR_DUAL", INT2NUM(L2R_L2LOSS_SVR_DUAL));
|
32
|
-
|
32
|
+
/* L2-regularized L1-loss support vector regression (dual) */
|
33
33
|
rb_define_const(mSolverType, "L2R_L1LOSS_SVR_DUAL", INT2NUM(L2R_L1LOSS_SVR_DUAL));
|
34
|
+
/* one-class support vector machine (dual) */
|
35
|
+
rb_define_const(mSolverType, "ONECLASS_SVM", INT2NUM(ONECLASS_SVM));
|
34
36
|
}
|
data/numo-liblinear.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
gem_dir = File.expand_path(__dir__) + '/'
|
32
32
|
submodule_path = `git submodule --quiet foreach pwd`.split($OUTPUT_RECORD_SEPARATOR).first
|
33
33
|
submodule_relative_path = submodule_path.sub gem_dir, ''
|
34
|
-
liblinear_files = %w[linear.cpp linear.h
|
34
|
+
liblinear_files = %w[linear.cpp linear.h newton.cpp newton.h blas/blas.h blas/blasp.h blas/daxpy.c blas/ddot.c blas/dnrm2.c blas/dscal.c]
|
35
35
|
liblinear_files.each { |liblinf| spec.files << "#{submodule_relative_path}/#{liblinf}" }
|
36
36
|
|
37
37
|
spec.bindir = 'exe'
|
@@ -45,10 +45,5 @@ Gem::Specification.new do |spec|
|
|
45
45
|
'documentation_uri' => 'https://yoshoku.github.io/numo-liblinear/doc/'
|
46
46
|
}
|
47
47
|
|
48
|
-
spec.add_runtime_dependency 'numo-narray', '
|
49
|
-
|
50
|
-
spec.add_development_dependency 'bundler', '~> 2.0'
|
51
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
52
|
-
spec.add_development_dependency 'rake-compiler', '~> 1.0'
|
53
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
48
|
+
spec.add_runtime_dependency 'numo-narray', '>= 0.9.1'
|
54
49
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Numo
|
2
|
+
module Liblinear
|
3
|
+
module SolverType
|
4
|
+
L2R_LR: Integer
|
5
|
+
L2R_L2LOSS_SVC_DUAL: Integer
|
6
|
+
L2R_L2LOSS_SVC: Integer
|
7
|
+
L2R_L1LOSS_SVC_DUAL: Integer
|
8
|
+
MCSVM_CS: Integer
|
9
|
+
L1R_L2LOSS_SVC: Integer
|
10
|
+
L1R_LR: Integer
|
11
|
+
L2R_LR_DUAL: Integer
|
12
|
+
L2R_L2LOSS_SVR: Integer
|
13
|
+
L2R_L2LOSS_SVR_DUAL: Integer
|
14
|
+
L2R_L1LOSS_SVR_DUAL: Integer
|
15
|
+
ONECLASS_SVM: Integer
|
16
|
+
end
|
17
|
+
|
18
|
+
LIBLINEAR_VERSION: Integer
|
19
|
+
VERSION: String
|
20
|
+
|
21
|
+
type model = {
|
22
|
+
nr_class: Integer,
|
23
|
+
nr_feature: Integer,
|
24
|
+
w: Numo::DFloat,
|
25
|
+
label: Numo::Int32,
|
26
|
+
bias: Float,
|
27
|
+
rho: Float
|
28
|
+
}
|
29
|
+
|
30
|
+
type param = {
|
31
|
+
solver_type: Integer?,
|
32
|
+
eps: Float?,
|
33
|
+
C: Float?,
|
34
|
+
nr_weight: Integer?,
|
35
|
+
weight_label: Numo::Int32?,
|
36
|
+
weight: Numo::DFloat?,
|
37
|
+
p: Float?,
|
38
|
+
nu: Float?,
|
39
|
+
verbose: bool?,
|
40
|
+
random_seed: Integer?
|
41
|
+
}
|
42
|
+
|
43
|
+
def self?.cv: (Numo::DFloat x, Numo::DFloat y, param, Integer n_folds) -> Numo::DFloat
|
44
|
+
def self?.train: (Numo::DFloat x, Numo::DFloat y, param) -> model
|
45
|
+
def self?.predict: (Numo::DFloat x, param, model) -> Numo::DFloat
|
46
|
+
def self?.predict_proba: (Numo::DFloat x, param, model) -> Numo::DFloat
|
47
|
+
def self?.decision_function: (Numo::DFloat x, param, model) -> Numo::DFloat
|
48
|
+
def self?.save_model: (String filename, param, model) -> bool
|
49
|
+
def self?.load_model: (String filename) -> [param, model]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/sig/patch.rbs
ADDED
metadata
CHANGED
@@ -1,85 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numo-liblinear
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshoku
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 0.9.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.9.1
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: bundler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '2.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '2.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '10.0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '10.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake-compiler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: rspec
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '3.0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '3.0'
|
83
27
|
description: |
|
84
28
|
Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library.
|
85
29
|
LIBLINEAR is one of the famous libraries for large-scale regularized linear classification and regression.
|
@@ -91,16 +35,17 @@ extensions:
|
|
91
35
|
- ext/numo/liblinear/extconf.rb
|
92
36
|
extra_rdoc_files: []
|
93
37
|
files:
|
38
|
+
- ".github/workflows/build.yml"
|
94
39
|
- ".gitignore"
|
95
40
|
- ".gitmodules"
|
96
41
|
- ".rspec"
|
97
|
-
- ".travis.yml"
|
98
42
|
- CHANGELOG.md
|
99
43
|
- CODE_OF_CONDUCT.md
|
100
44
|
- Gemfile
|
101
45
|
- LICENSE.txt
|
102
46
|
- README.md
|
103
47
|
- Rakefile
|
48
|
+
- Steepfile
|
104
49
|
- ext/numo/liblinear/converter.c
|
105
50
|
- ext/numo/liblinear/converter.h
|
106
51
|
- ext/numo/liblinear/extconf.rb
|
@@ -112,8 +57,8 @@ files:
|
|
112
57
|
- ext/numo/liblinear/liblinear/blas/dscal.c
|
113
58
|
- ext/numo/liblinear/liblinear/linear.cpp
|
114
59
|
- ext/numo/liblinear/liblinear/linear.h
|
115
|
-
- ext/numo/liblinear/liblinear/
|
116
|
-
- ext/numo/liblinear/liblinear/
|
60
|
+
- ext/numo/liblinear/liblinear/newton.cpp
|
61
|
+
- ext/numo/liblinear/liblinear/newton.h
|
117
62
|
- ext/numo/liblinear/liblinearext.c
|
118
63
|
- ext/numo/liblinear/liblinearext.h
|
119
64
|
- ext/numo/liblinear/model.c
|
@@ -127,6 +72,8 @@ files:
|
|
127
72
|
- lib/numo/liblinear.rb
|
128
73
|
- lib/numo/liblinear/version.rb
|
129
74
|
- numo-liblinear.gemspec
|
75
|
+
- sig/numo/liblinear.rbs
|
76
|
+
- sig/patch.rbs
|
130
77
|
homepage: https://github.com/yoshoku/numo-liblinear
|
131
78
|
licenses:
|
132
79
|
- BSD-3-Clause
|
@@ -149,8 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
96
|
- !ruby/object:Gem::Version
|
150
97
|
version: '0'
|
151
98
|
requirements: []
|
152
|
-
|
153
|
-
rubygems_version: 2.6.14.4
|
99
|
+
rubygems_version: 3.2.21
|
154
100
|
signing_key:
|
155
101
|
specification_version: 4
|
156
102
|
summary: Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library. Numo::Liblinear
|
data/.travis.yml
DELETED
@@ -1,288 +0,0 @@
|
|
1
|
-
#include <math.h>
|
2
|
-
#include <stdio.h>
|
3
|
-
#include <string.h>
|
4
|
-
#include <stdarg.h>
|
5
|
-
#include "tron.h"
|
6
|
-
|
7
|
-
#ifndef min
|
8
|
-
template <class T> static inline T min(T x,T y) { return (x<y)?x:y; }
|
9
|
-
#endif
|
10
|
-
|
11
|
-
#ifndef max
|
12
|
-
template <class T> static inline T max(T x,T y) { return (x>y)?x:y; }
|
13
|
-
#endif
|
14
|
-
|
15
|
-
#ifdef __cplusplus
|
16
|
-
extern "C" {
|
17
|
-
#endif
|
18
|
-
|
19
|
-
extern double dnrm2_(int *, double *, int *);
|
20
|
-
extern double ddot_(int *, double *, int *, double *, int *);
|
21
|
-
extern int daxpy_(int *, double *, double *, int *, double *, int *);
|
22
|
-
extern int dscal_(int *, double *, double *, int *);
|
23
|
-
|
24
|
-
#ifdef __cplusplus
|
25
|
-
}
|
26
|
-
#endif
|
27
|
-
|
28
|
-
static void default_print(const char *buf)
|
29
|
-
{
|
30
|
-
fputs(buf,stdout);
|
31
|
-
fflush(stdout);
|
32
|
-
}
|
33
|
-
|
34
|
-
static double uTMv(int n, double *u, double *M, double *v)
|
35
|
-
{
|
36
|
-
const int m = n-4;
|
37
|
-
double res = 0;
|
38
|
-
int i;
|
39
|
-
for (i=0; i<m; i+=5)
|
40
|
-
res += u[i]*M[i]*v[i]+u[i+1]*M[i+1]*v[i+1]+u[i+2]*M[i+2]*v[i+2]+
|
41
|
-
u[i+3]*M[i+3]*v[i+3]+u[i+4]*M[i+4]*v[i+4];
|
42
|
-
for (; i<n; i++)
|
43
|
-
res += u[i]*M[i]*v[i];
|
44
|
-
return res;
|
45
|
-
}
|
46
|
-
|
47
|
-
void TRON::info(const char *fmt,...)
|
48
|
-
{
|
49
|
-
char buf[BUFSIZ];
|
50
|
-
va_list ap;
|
51
|
-
va_start(ap,fmt);
|
52
|
-
vsprintf(buf,fmt,ap);
|
53
|
-
va_end(ap);
|
54
|
-
(*tron_print_string)(buf);
|
55
|
-
}
|
56
|
-
|
57
|
-
TRON::TRON(const function *fun_obj, double eps, double eps_cg, int max_iter)
|
58
|
-
{
|
59
|
-
this->fun_obj=const_cast<function *>(fun_obj);
|
60
|
-
this->eps=eps;
|
61
|
-
this->eps_cg=eps_cg;
|
62
|
-
this->max_iter=max_iter;
|
63
|
-
tron_print_string = default_print;
|
64
|
-
}
|
65
|
-
|
66
|
-
TRON::~TRON()
|
67
|
-
{
|
68
|
-
}
|
69
|
-
|
70
|
-
void TRON::tron(double *w)
|
71
|
-
{
|
72
|
-
// Parameters for updating the iterates.
|
73
|
-
double eta0 = 1e-4, eta1 = 0.25, eta2 = 0.75;
|
74
|
-
|
75
|
-
// Parameters for updating the trust region size delta.
|
76
|
-
double sigma1 = 0.25, sigma2 = 0.5, sigma3 = 4;
|
77
|
-
|
78
|
-
int n = fun_obj->get_nr_variable();
|
79
|
-
int i, cg_iter;
|
80
|
-
double delta=0, sMnorm, one=1.0;
|
81
|
-
double alpha, f, fnew, prered, actred, gs;
|
82
|
-
int search = 1, iter = 1, inc = 1;
|
83
|
-
double *s = new double[n];
|
84
|
-
double *r = new double[n];
|
85
|
-
double *g = new double[n];
|
86
|
-
|
87
|
-
const double alpha_pcg = 0.01;
|
88
|
-
double *M = new double[n];
|
89
|
-
|
90
|
-
// calculate gradient norm at w=0 for stopping condition.
|
91
|
-
double *w0 = new double[n];
|
92
|
-
for (i=0; i<n; i++)
|
93
|
-
w0[i] = 0;
|
94
|
-
fun_obj->fun(w0);
|
95
|
-
fun_obj->grad(w0, g);
|
96
|
-
double gnorm0 = dnrm2_(&n, g, &inc);
|
97
|
-
delete [] w0;
|
98
|
-
|
99
|
-
f = fun_obj->fun(w);
|
100
|
-
fun_obj->grad(w, g);
|
101
|
-
double gnorm = dnrm2_(&n, g, &inc);
|
102
|
-
|
103
|
-
if (gnorm <= eps*gnorm0)
|
104
|
-
search = 0;
|
105
|
-
|
106
|
-
fun_obj->get_diag_preconditioner(M);
|
107
|
-
for(i=0; i<n; i++)
|
108
|
-
M[i] = (1-alpha_pcg) + alpha_pcg*M[i];
|
109
|
-
delta = sqrt(uTMv(n, g, M, g));
|
110
|
-
|
111
|
-
double *w_new = new double[n];
|
112
|
-
bool reach_boundary;
|
113
|
-
bool delta_adjusted = false;
|
114
|
-
while (iter <= max_iter && search)
|
115
|
-
{
|
116
|
-
cg_iter = trpcg(delta, g, M, s, r, &reach_boundary);
|
117
|
-
|
118
|
-
memcpy(w_new, w, sizeof(double)*n);
|
119
|
-
daxpy_(&n, &one, s, &inc, w_new, &inc);
|
120
|
-
|
121
|
-
gs = ddot_(&n, g, &inc, s, &inc);
|
122
|
-
prered = -0.5*(gs-ddot_(&n, s, &inc, r, &inc));
|
123
|
-
fnew = fun_obj->fun(w_new);
|
124
|
-
|
125
|
-
// Compute the actual reduction.
|
126
|
-
actred = f - fnew;
|
127
|
-
|
128
|
-
// On the first iteration, adjust the initial step bound.
|
129
|
-
sMnorm = sqrt(uTMv(n, s, M, s));
|
130
|
-
if (iter == 1 && !delta_adjusted)
|
131
|
-
{
|
132
|
-
delta = min(delta, sMnorm);
|
133
|
-
delta_adjusted = true;
|
134
|
-
}
|
135
|
-
|
136
|
-
// Compute prediction alpha*sMnorm of the step.
|
137
|
-
if (fnew - f - gs <= 0)
|
138
|
-
alpha = sigma3;
|
139
|
-
else
|
140
|
-
alpha = max(sigma1, -0.5*(gs/(fnew - f - gs)));
|
141
|
-
|
142
|
-
// Update the trust region bound according to the ratio of actual to predicted reduction.
|
143
|
-
if (actred < eta0*prered)
|
144
|
-
delta = min(alpha*sMnorm, sigma2*delta);
|
145
|
-
else if (actred < eta1*prered)
|
146
|
-
delta = max(sigma1*delta, min(alpha*sMnorm, sigma2*delta));
|
147
|
-
else if (actred < eta2*prered)
|
148
|
-
delta = max(sigma1*delta, min(alpha*sMnorm, sigma3*delta));
|
149
|
-
else
|
150
|
-
{
|
151
|
-
if (reach_boundary)
|
152
|
-
delta = sigma3*delta;
|
153
|
-
else
|
154
|
-
delta = max(delta, min(alpha*sMnorm, sigma3*delta));
|
155
|
-
}
|
156
|
-
|
157
|
-
info("iter %2d act %5.3e pre %5.3e delta %5.3e f %5.3e |g| %5.3e CG %3d\n", iter, actred, prered, delta, f, gnorm, cg_iter);
|
158
|
-
|
159
|
-
if (actred > eta0*prered)
|
160
|
-
{
|
161
|
-
iter++;
|
162
|
-
memcpy(w, w_new, sizeof(double)*n);
|
163
|
-
f = fnew;
|
164
|
-
fun_obj->grad(w, g);
|
165
|
-
fun_obj->get_diag_preconditioner(M);
|
166
|
-
for(i=0; i<n; i++)
|
167
|
-
M[i] = (1-alpha_pcg) + alpha_pcg*M[i];
|
168
|
-
|
169
|
-
gnorm = dnrm2_(&n, g, &inc);
|
170
|
-
if (gnorm <= eps*gnorm0)
|
171
|
-
break;
|
172
|
-
}
|
173
|
-
if (f < -1.0e+32)
|
174
|
-
{
|
175
|
-
info("WARNING: f < -1.0e+32\n");
|
176
|
-
break;
|
177
|
-
}
|
178
|
-
if (prered <= 0)
|
179
|
-
{
|
180
|
-
info("WARNING: prered <= 0\n");
|
181
|
-
break;
|
182
|
-
}
|
183
|
-
if (fabs(actred) <= 1.0e-12*fabs(f) &&
|
184
|
-
fabs(prered) <= 1.0e-12*fabs(f))
|
185
|
-
{
|
186
|
-
info("WARNING: actred and prered too small\n");
|
187
|
-
break;
|
188
|
-
}
|
189
|
-
}
|
190
|
-
|
191
|
-
delete[] g;
|
192
|
-
delete[] r;
|
193
|
-
delete[] w_new;
|
194
|
-
delete[] s;
|
195
|
-
delete[] M;
|
196
|
-
}
|
197
|
-
|
198
|
-
int TRON::trpcg(double delta, double *g, double *M, double *s, double *r, bool *reach_boundary)
|
199
|
-
{
|
200
|
-
int i, inc = 1;
|
201
|
-
int n = fun_obj->get_nr_variable();
|
202
|
-
double one = 1;
|
203
|
-
double *d = new double[n];
|
204
|
-
double *Hd = new double[n];
|
205
|
-
double zTr, znewTrnew, alpha, beta, cgtol;
|
206
|
-
double *z = new double[n];
|
207
|
-
|
208
|
-
*reach_boundary = false;
|
209
|
-
for (i=0; i<n; i++)
|
210
|
-
{
|
211
|
-
s[i] = 0;
|
212
|
-
r[i] = -g[i];
|
213
|
-
z[i] = r[i] / M[i];
|
214
|
-
d[i] = z[i];
|
215
|
-
}
|
216
|
-
|
217
|
-
zTr = ddot_(&n, z, &inc, r, &inc);
|
218
|
-
cgtol = eps_cg*sqrt(zTr);
|
219
|
-
int cg_iter = 0;
|
220
|
-
int max_cg_iter = max(n, 5);
|
221
|
-
|
222
|
-
while (cg_iter < max_cg_iter)
|
223
|
-
{
|
224
|
-
if (sqrt(zTr) <= cgtol)
|
225
|
-
break;
|
226
|
-
cg_iter++;
|
227
|
-
fun_obj->Hv(d, Hd);
|
228
|
-
|
229
|
-
alpha = zTr/ddot_(&n, d, &inc, Hd, &inc);
|
230
|
-
daxpy_(&n, &alpha, d, &inc, s, &inc);
|
231
|
-
|
232
|
-
double sMnorm = sqrt(uTMv(n, s, M, s));
|
233
|
-
if (sMnorm > delta)
|
234
|
-
{
|
235
|
-
info("cg reaches trust region boundary\n");
|
236
|
-
*reach_boundary = true;
|
237
|
-
alpha = -alpha;
|
238
|
-
daxpy_(&n, &alpha, d, &inc, s, &inc);
|
239
|
-
|
240
|
-
double sTMd = uTMv(n, s, M, d);
|
241
|
-
double sTMs = uTMv(n, s, M, s);
|
242
|
-
double dTMd = uTMv(n, d, M, d);
|
243
|
-
double dsq = delta*delta;
|
244
|
-
double rad = sqrt(sTMd*sTMd + dTMd*(dsq-sTMs));
|
245
|
-
if (sTMd >= 0)
|
246
|
-
alpha = (dsq - sTMs)/(sTMd + rad);
|
247
|
-
else
|
248
|
-
alpha = (rad - sTMd)/dTMd;
|
249
|
-
daxpy_(&n, &alpha, d, &inc, s, &inc);
|
250
|
-
alpha = -alpha;
|
251
|
-
daxpy_(&n, &alpha, Hd, &inc, r, &inc);
|
252
|
-
break;
|
253
|
-
}
|
254
|
-
alpha = -alpha;
|
255
|
-
daxpy_(&n, &alpha, Hd, &inc, r, &inc);
|
256
|
-
|
257
|
-
for (i=0; i<n; i++)
|
258
|
-
z[i] = r[i] / M[i];
|
259
|
-
znewTrnew = ddot_(&n, z, &inc, r, &inc);
|
260
|
-
beta = znewTrnew/zTr;
|
261
|
-
dscal_(&n, &beta, d, &inc);
|
262
|
-
daxpy_(&n, &one, z, &inc, d, &inc);
|
263
|
-
zTr = znewTrnew;
|
264
|
-
}
|
265
|
-
|
266
|
-
if (cg_iter == max_cg_iter)
|
267
|
-
info("WARNING: reaching maximal number of CG steps\n");
|
268
|
-
|
269
|
-
delete[] d;
|
270
|
-
delete[] Hd;
|
271
|
-
delete[] z;
|
272
|
-
|
273
|
-
return(cg_iter);
|
274
|
-
}
|
275
|
-
|
276
|
-
double TRON::norm_inf(int n, double *x)
|
277
|
-
{
|
278
|
-
double dmax = fabs(x[0]);
|
279
|
-
for (int i=1; i<n; i++)
|
280
|
-
if (fabs(x[i]) >= dmax)
|
281
|
-
dmax = fabs(x[i]);
|
282
|
-
return(dmax);
|
283
|
-
}
|
284
|
-
|
285
|
-
void TRON::set_print_string(void (*print_string) (const char *buf))
|
286
|
-
{
|
287
|
-
tron_print_string = print_string;
|
288
|
-
}
|