線形計画(スパース)及び凸2次計画問題

C言語によるサンプルソースコード : 使用関数名:nag_opt_sparse_convex_qp (e04nkc)

ホーム > 製品 > nAG数値計算ライブラリ > サンプルソースコード集 > 線形計画(スパース)及び凸2次計画問題 (C言語/C++)

Keyword: 線形計画, スパース, 凸2次計画問題

概要

本サンプルは線形計画(スパース)及び凸2次計画問題を解くC言語によるサンプルプログラムです。 本サンプルは以下に示される二次関数を最小化する解を求めて出力します。

線形計画や2次計画問題のデータ 

※本サンプルはnAG Cライブラリに含まれる関数 nag_opt_sparse_convex_qp() のExampleコードです。本サンプル及び関数の詳細情報は nag_opt_sparse_convex_qp のマニュアルページをご参照ください。
ご相談やお問い合わせはこちらまで

入力データ

(本関数の詳細はnag_opt_sparse_convex_qp のマニュアルページを参照)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

このデータをダウンロード
nag_opt_sparse_convex_qp (e04nkc) Example Program Data

Values of n and m
7  8

Values of nnz, iobj and ncolh
48  8  7

Matrix nonzeros: value, row index, column index
    0.02   7   1
    0.02   5   1
    0.03   3   1
    1.00   1   1
    0.70   6   1
    0.02   4   1
    0.15   2   1
 -200.00   8   1
    0.06   7   2
    0.75   6   2
    0.03   5   2
    0.04   4   2
    0.05   3   2
    0.04   2   2
    1.00   1   2
-2000.00   8   2
    0.02   2   3
    1.00   1   3
    0.01   4   3
    0.08   3   3
    0.08   7   3
    0.80   6   3
-2000.00   8   3
    1.00   1   4
    0.12   7   4
    0.02   3   4
    0.02   4   4
    0.75   6   4
    0.04   2   4
-2000.00   8   4
    0.01   5   5
    0.80   6   5
    0.02   7   5
    1.00   1   5
    0.02   2   5
    0.06   3   5
    0.02   4   5
-2000.00   8   5
    1.00   1   6
    0.01   2   6
    0.01   3   6
    0.97   6   6
    0.01   7   6
  400.00   8   6
    0.97   7   7
    0.03   2   7
    1.00   1   7
  400.00   8   7

Lower bounds
 0.0       0.0       4.0e+02   1.0e+02  0.0      0.0      0.0       2.0e+03
-1.0e+25  -1.0e+25  -1.0e+25  -1.0e+25  1.5e+03  2.5e+02 -1.0e+25

Upper bounds
 2.0e+02   2.5e+03   8.0e+02   7.0e+02  1.5e+03  1.0e+25  1.0e+25   2.0e+03
 6.0e+01   1.0e+02   4.0e+01   3.0e+01  1.0e+25  3.0e+02  1.0e+25

Column and row names
'COLUMN 1' 'COLUMN 2' 'COLUMN 3' 'COLUMN 4' 'COLUMN 5' 'COLUMN 6' 'COLUMN 7'
'OBJECTIV' 'ROW    1' 'ROW    2' 'ROW    3' 'ROW    4' 'ROW    5' 'ROW    6'
'ROW    7'

Initial estimate of x
 0.0  0.0  0.0  0.0  0.0  0.0  0.0

Number of hessian nonzeros
9

Hessian nonzeros: value, row index, col index (diagonal/lower triangle elements)
 2.0  1  1
 2.0  2  2
 2.0  3  3
 2.0  4  3
 2.0  4  4
 2.0  5  5
 2.0  6  6
 2.0  7  6
 2.0  7  7

  • 1行目はタイトル行で読み飛ばされます。
  • 4行目に変数の数(n)、一般制約の数(m)を指定しています。
  • 7行目に線形制約行列の非ゼロ要素の数(nnz)、線形目的項cTxのベクトルcの非ゼロ要素の行(iobj)、ヘッセ行列の非ゼロカラムの数(ncolh)を指定しています。
  • 10~57行目に線形制約行列の非ゼロ要素の値(a)、行のインデックス(ha)、列のインデックス(icol)を指定しています。
  • 60~61行目に変数の下限と制約の下限(bl)を指定しています。
  • 64~65行目に変数の上限と制約の上限(bu)を指定しています。
  • 68~70行目に列と行の名前(crnames)を指定しています。
  • 73行目にxの初期推定値を指定しています。
  • 76行目にヘッセ行列の非ゼロ要素の数(nnz_hess)を指定しています。
  • 79~87行目にヘッセ行列の非ゼロ要素の値(hess)、行のインデックス(hhess)、列のインデックス(icol)を指定しています。

出力結果

(本関数の詳細はnag_opt_sparse_convex_qp のマニュアルページを参照)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

この出力例をダウンロード
nag_opt_sparse_convex_qp (e04nkc) Example Program Results

Parameters to e04nkc
--------------------

Problem type............ sparse QP    Number of variables.....         7
Linear constraints......         8    Hessian columns.........         7    

prob_name...............          
obj_name................              rhs_name................          
range_name..............              bnd_name................          
crnames.................  supplied

minimize................  Nag_TRUE    start...................  Nag_Cold
ftol....................  1.00e-06    reset_ftol..............     10000
fcheck..................        60    factor_freq.............       100
scale.............. Nag_ExtraScale    scale_tol...............  9.00e-01
optim_tol...............  1.00e-06    max_iter................        75
crash.............. Nag_CrashTwice    crash_tol...............  1.00e-01
partial_price...........        10    pivot_tol...............  2.04e-11
max_sb..................         7    
inf_bound...............  1.00e+20    inf_step................  1.00e+20
lu_factor_tol...........  1.00e+02    lu_update_tol...........  1.00e+01
lu_sing_tol.............  2.04e-11    machine precision.......  1.11e-16
print_level......... Nag_Soln_Iter
outfile.................    stdout

Memory allocation:
state...................       Nag    lambda..................       Nag

   Itn      Step   Ninf   Sinf/Objective   Norm rg
Itn 0 -- Infeasible
     0   0.0e+00      1     1.152891e+03   0.0e+00
     1   4.3e+02      0     0.000000e+00   0.0e+00
Itn 1 -- Feasible point found (for 1 equality constraints).
     1   0.0e+00      0     0.000000e+00   0.0e+00
     1   0.0e+00      0     1.460000e+06   0.0e+00
Itn 1 -- Feasible QP solution.
     2   8.7e-02      0     9.409959e+05   0.0e+00
     3   5.3e-01      0    -1.056552e+06   0.0e+00
     4   1.0e+00      0    -1.462190e+06   2.3e-12
     5   1.0e+00      0    -1.698092e+06   2.2e-12
     6   4.6e-02      0    -1.764906e+06   7.0e+02
     7   1.0e+00      0    -1.811946e+06   3.1e-12
     8   1.7e-02      0    -1.847325e+06   1.7e+02
     9   1.0e+00      0    -1.847785e+06   1.4e-12

Variable State         Value   Lower Bound  Upper Bound   Lagr Mult    Residual
COLUMN 1    LL   0.00000e+00    0.0000e+00   2.0000e+02   2.361e+03   0.000e+00
COLUMN 2    BS   3.49399e+02    0.0000e+00   2.5000e+03  -3.539e-12   3.494e+02
COLUMN 3   SBS   6.48853e+02    4.0000e+02   8.0000e+02  -1.147e-12   1.511e+02
COLUMN 4   SBS   1.72847e+02    1.0000e+02   7.0000e+02   3.248e-13   7.285e+01
COLUMN 5    BS   4.07521e+02    0.0000e+00   1.5000e+03   8.040e-13   4.075e+02
COLUMN 6    BS   2.71356e+02    0.0000e+00         None  -4.473e-13   2.714e+02
COLUMN 7    BS   1.50023e+02    0.0000e+00         None  -1.413e-12   1.500e+02

Constrnt State         Value   Lower Bound  Upper Bound   Lagr Mult    Residual
OBJECTIV    EQ   2.00000e+03    2.0000e+03   2.0000e+03  -1.290e+04  -0.000e+00
ROW    1    BS   4.92316e+01          None   6.0000e+01   0.000e+00  -1.077e+01
ROW    2    UL   1.00000e+02          None   1.0000e+02  -2.325e+03   0.000e+00
ROW    3    BS   3.20719e+01          None   4.0000e+01   0.000e+00  -7.928e+00
ROW    4    BS   1.45572e+01          None   3.0000e+01   0.000e+00  -1.544e+01
ROW    5    LL   1.50000e+03    1.5000e+03         None   1.445e+04  -0.000e+00
ROW    6    LL   2.50000e+02    2.5000e+02   3.0000e+02   1.458e+04  -0.000e+00
ROW    7    BS  -2.98869e+06          None         None  -1.000e+00  -2.989e+06

Exit after 9 iterations.

Optimal QP solution found.

Final QP objective value =  -1.8477847e+06


Perturb the problem and re-solve with warm start.

Parameters to e04nkc
--------------------

Problem type............ sparse QP    Number of variables.....         7
Linear constraints......         8    Hessian columns.........         7    

prob_name...............          
obj_name................              rhs_name................          
range_name..............              bnd_name................          
crnames.................  supplied

minimize................  Nag_TRUE    start...................  Nag_Warm
ftol....................  1.00e-06    reset_ftol..............     10000
fcheck..................        60    factor_freq.............       100
scale.............. Nag_ExtraScale    scale_tol...............  9.00e-01
optim_tol...............  1.00e-06    max_iter................        75
crash.............. Nag_CrashTwice    crash_tol...............  1.00e-01
partial_price...........        10    pivot_tol...............  2.04e-11
max_sb..................         7    
inf_bound...............  1.00e+20    inf_step................  1.00e+20
lu_factor_tol...........  1.00e+02    lu_update_tol...........  1.00e+01
lu_sing_tol.............  2.04e-11    machine precision.......  1.11e-16
print_level.............  Nag_Soln
outfile.................    stdout

Memory allocation:
state...................       Nag    lambda..................       Nag

Variable State         Value   Lower Bound  Upper Bound   Lagr Mult    Residual
COLUMN 1    LL   0.00000e+00    0.0000e+00   2.0000e+02   2.360e+03   0.000e+00
COLUMN 2   SBS   3.49529e+02    0.0000e+00   2.5000e+03  -2.241e-12   3.495e+02
COLUMN 3    BS   6.48762e+02    4.0000e+02   8.0000e+02  -1.911e-13   1.512e+02
COLUMN 4   SBS   1.72618e+02    1.0000e+02   7.0000e+02  -3.248e-13   7.262e+01
COLUMN 5    BS   4.07596e+02    0.0000e+00   1.5000e+03   3.446e-13   4.076e+02
COLUMN 6    BS   2.71446e+02    0.0000e+00         None   1.640e-12   2.714e+02
COLUMN 7    BS   1.50048e+02    0.0000e+00         None   2.669e-12   1.500e+02

Constrnt State         Value   Lower Bound  Upper Bound   Lagr Mult    Residual
OBJECTIV    EQ   2.00000e+03    2.0000e+03   2.0000e+03  -1.290e+04  -0.000e+00
ROW    1    BS   4.92290e+01          None   6.0000e+01   0.000e+00  -1.077e+01
ROW    2    UL   1.00000e+02          None   1.0000e+02  -2.325e+03   0.000e+00
ROW    3    BS   3.20731e+01          None   4.0000e+01   0.000e+00  -7.927e+00
ROW    4    BS   1.45618e+01          None   3.0000e+01   0.000e+00  -1.544e+01
ROW    5    LL   1.50000e+03    1.5000e+03         None   1.446e+04  -0.000e+00
ROW    6    LL   2.50000e+02    2.5000e+02   3.0000e+02   1.458e+04  -0.000e+00
ROW    7    BS  -2.98841e+06          None         None  -1.000e+00  -2.988e+06

Exit after 1 iterations.

Optimal QP solution found.

Final QP objective value =  -1.8466439e+06


  • 6行目にオプション・パラメータ用のファイルe04nkce.optが読み込まれていることが示されています。
  • 8行目にminor_iter_limに"20"が設定されていることが示されています。
  • 9行目にiter_limに"30"が設定されていることが示されています。
  • 11~58行目に以下に示すプログラムのオプション引数が出力されています。
    Problem tyle 問題の種類。
    Number of variables 変数の数。
    Linear constraints 線形制約の数。
    Hessian columns ヘッセ行列のカラム数。
    obj_name 目的関数の行の名前。
    rhs_name 右辺制約の名前。
    range_name 範囲の名前。
    bnd_name 境界の名前。
    crnames 問題の行や列の名前。
    minimize 最適化の方向。"Nag_TRUE"は最適化の方向が最小化であることを意味します。
    start プログラムがどのように開始するかを示しています。"Nag_Cold"は初期のCrash処理が使用されることを意味します。
    ftol 実行可能点での各制約の許容可能な最大の絶対的違反。
    reset_ftol この数の反復数を超えると実行可能許容値がftolの値に増加します。
    fcheck 直近の主となる反復の後にこの回数の反復ごとに現在の解が一般線形制約を満たしているかを確認するための数値テストが行われます。
    factor_freq 基底行列の因数分解で生じる基底変換の最大数。
    scale 変数と制約のスケーリング。"Nag_ExtraScale"は付加的なスケーリングが実行されることを意味しています。
    scale_tol スケーリングパスの数を制御します。
    optim_tol 縮小勾配の大きさの判断に使用されます。
    max_iter 最大反復数。
    crash 制約行列Aのどの行や列が基底に値するかを決定し、Crash処理が何回呼び出されるかを示します。 "Nag_NoCrash"は基底がB=−Iとなるスラック変数が選択されることを意味します。
    crash_tol Crash処理で三角基底の検索時に行列Aの非ゼロ要素を無視できるようにします。
    part_price プライシングに必要な処理を軽減します。
    pivot_tol Pivot要素がこの値より小さい場合無視されます。
    max_sb 変数の数の上限。
    inf_bound 問題の制約における無限境界。
    inf_step 無限解へのステップと見なされる変数の変化の大きさ。
    lu_factor_tol 再因数分解時の基底因数分解の安定性及びスパース性を制御します。
    lu_update_tol 更新時の基底因数分解の安定性及びスパース性を制御します。
    lu_sing_tol 悪条件の基底行列を防ぐために使用される特異点許容値。
    machine precision マシン精度。
    print_level 出力レベル。"Nag_Soln"は最終解のみ出力されることを意味しています。
    outfile 結果が出力されるファイル名。"stdout"は標準出力を意味しています。
  • 29行目にはオプション引数state、lambdaに必要なメモリがnAGライブラリの関数によって自動的に割り当てられたことを示しています。
  • 31~46行目には以下が出力されています。
    Itn 反復回数。
    Step 探索方向に進んだステップの長さ。
    Ninf 違反した制約の数。
    Sinf/Objective xが実行可能でない場合は制約違反の大きさの合計。実行可能な場合は目的関数の値。
    Norm rg 縮小勾配のユークリッドノルム。
  • 48~55行目には以下が出力されています。
    Variable 変数の名前。
    State 変数の状態(LLは下限での非基底、SBSはsuperbasic、BSは基底であることを意味します)。
    Value 最後の反復の変数の値。
    Lower Bound 下限。
    Upper Bound 上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Residual 残差(変数の値と上限/下限の近いほうとの差)。
  • 57~65行目には以下が出力されています。
    Constrnt 線形制約の名前。
    State 線形制約の状態(ULは上限での非基底、LLは下限での非基底、EQは非基底で固定、BSは基底であることを意味します)。
    Value 最後の反復の制約の値。
    Lower Bound 下限。
    Upper Bound 上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Residual 残差(制約の値と上限/下限の近いほうとの差)。
  • 67行目にはQP問題を解くのに9回の反復が行われたことが示されています。
  • 69行目に最適解が見つかったことが示されています。
  • 71行目に最終的な目的関数値が出力されています。
  • 74行目からはCold startと同じ例を用いたWarm startの場合の実行結果が出力されています。
  • 79~99行目にプログラムのオプション引数が出力されています。
  • 102行目にはオプション引数state、lambdaに必要なメモリがnAGライブラリの関数によって自動的に割り当てられたことを示しています。
  • 104~111行目には以下が出力されています。
    Variable 変数の名前。
    State 変数の状態(LLは下限での非基底、SBSはsuperbasic、BSは基底であることを意味します)。
    Value 最後の反復の変数の値。
    Lower Bound 下限。
    Upper Bound 上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Residual 残差(変数の値と上限/下限の近いほうとの差)。
  • 113~121行目には以下が出力されています。
    Constrnt 線形制約の名前。
    State 線形制約の状態(ULは上限での非基底、LLは下限での非基底、EQは非基底で固定、BSは基底であることを意味します)。
    Value 最後の反復の制約の値。
    Lower Bound 下限。
    Upper Bound 上限。
    Lagr Mult 関連する境界のラグランジュ乗数。
    Residual 残差(制約の値と上限/下限の近いほうとの差)。
  • 123行目にはQP問題を解くのに1回の反復が行われたことが示されています。
  • 125行目に最適解が見つかったことが示されています。
  • 127行目に最終的な目的関数値が出力されています。

ソースコード

(本関数の詳細はnag_opt_sparse_convex_qp のマニュアルページを参照)

※本サンプルソースコードはnAG数値計算ライブラリ(Windows, Linux, MAC等に対応)の関数を呼び出します。
サンプルのコンパイル及び実行方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

このソースコードをダウンロード
/* nag_opt_sparse_convex_qp (e04nkc) Example Program.
 *
 * CLL6I261D/CLL6I261DL Version.
 *
 * Copyright 2017 Numerical Algorithms Group.
 *
 * Mark 26.1, 2017.
 *
 */

#include <nag.h>
#include <stdio.h>
#include <string.h>
#include <nag_stdlib.h>
#include <nage04.h>

#ifdef __cplusplus
extern "C"
{
#endif
  static void nAG_CALL qphess(Integer ncolh, const double x[], double hx[],
                              Nag_Comm *comm);
#ifdef __cplusplus
}
#endif

/* Declare a data structure for passing sparse Hessian data to qphess */
typedef struct
{
  double *hess;
  Integer *khess;
  Integer *hhess;
} HessianData;

#define NAMES(I, J) names[(I)*9+J]

int main(void)
{
  HessianData hess_data;
  Integer exit_status = 0, *ha = 0, *hhess = 0, i, icol, iobj, j, jcol;
  Integer *ka = 0, *khess = 0, m, n, nbnd, ncolh, ninf, nnz, nnz_hess;
  Nag_Comm comm;
  Nag_E04_Opt options;
  char **crnames = 0, *names = 0;
  double *a = 0, *bl = 0, *bu = 0, *hess = 0, obj, sinf, *x = 0;
  NagError fail;

  INIT_FAIL(fail);

  printf("nag_opt_sparse_convex_qp (e04nkc) Example Program Results\n");
  fflush(stdout);

  /* Skip heading in data file */
  scanf(" %*[^\n]");
  /* Read the problem dimensions */
  scanf(" %*[^\n]");
  scanf("%ld%ld", &n, &m);

  /* Read nnz, iobj, ncolh */
  scanf(" %*[^\n]");
  scanf("%ld%ld%ld", &nnz, &iobj, &ncolh);

  if (n >= 1 && m >= 1 && nnz >= 1 && nnz <= n * m) {
    nbnd = n + m;
    if (!(a = nAG_ALLOC(nnz, double)) ||
        !(bl = nAG_ALLOC(nbnd, double)) ||
        !(bu = nAG_ALLOC(nbnd, double)) ||
        !(x = nAG_ALLOC(nbnd, double)) ||
        !(ha = nAG_ALLOC(nnz, Integer)) ||
        !(ka = nAG_ALLOC(n + 1, Integer)) ||
        !(khess = nAG_ALLOC(n + 1, Integer)) ||
        !(crnames = nAG_ALLOC(nbnd, char *)) ||
        !(names = nAG_ALLOC(nbnd * 9, char))
           )
    {
      printf("Allocation failure\n");
      exit_status = -1;
      goto END;
    }
  }
  else {
    printf("Invalid n or m or nnz.\n");
    exit_status = 1;
    return exit_status;
  }

  /* Read the matrix and set up ka */
  jcol = 1;
  ka[jcol - 1] = 0;
  scanf(" %*[^\n]");
  for (i = 0; i < nnz; ++i) {
    /* a[i] stores the (ha[i], icol) element of matrix */
    scanf("%lf%ld%ld", &a[i], &ha[i], &icol);

    /* Check whether we have started a new column */
    if (icol == jcol + 1) {
      ka[icol - 1] = i; /* Start of icol-th column in a */
      jcol = icol;
    }
    else if (icol > jcol + 1) {
      /* Index in a of the start of the icol-th column
       * equals i, but columns jcol+1, jcol+2, ...,
       * icol-1 are empty.  Set the corresponding elements
       * of ka to i.
       */
      for (j = jcol + 1; j < icol; ++j)
        ka[j - 1] = i;

      ka[icol - 1] = i;
      jcol = icol;
    }
  }
  ka[n] = nnz;

  /* If the last columns are empty, set ka accordingly */
  if (n > icol) {
    for (j = icol; j <= n - 1; ++j)
      ka[j] = nnz;
  }

  /* Read the bounds */
  nbnd = n + m;
  scanf(" %*[^\n]"); /* Skip heading in data file */
  for (i = 0; i < nbnd; ++i)
    scanf("%lf", &bl[i]);
  scanf(" %*[^\n]");
  for (i = 0; i < nbnd; ++i)
    scanf("%lf", &bu[i]);

  /* Read the column and row names */
  scanf(" %*[^\n]"); /* Skip heading in data file */
  scanf(" %*[^']");
  for (i = 0; i < nbnd; ++i) {
    scanf(" '%8c'", &NAMES(i, 0));
    NAMES(i, 8) = '\0';
    crnames[i] = &NAMES(i, 0);
  }

  /* Read the initial estimate of x */
  scanf(" %*[^\n]"); /* Skip heading in data file */
  for (i = 0; i < n; ++i)
    scanf("%lf", &x[i]);

  /* Read nnz_hess */
  scanf(" %*[^\n]");
  scanf("%ld", &nnz_hess);

  if (!(hess = nAG_ALLOC(nnz_hess, double)) ||
      !(hhess = nAG_ALLOC(nnz_hess, Integer)))
  {
    printf("Allocation failure\n");
    exit_status = -1;
    goto END;
  }

  /* Read the hessian matrix and set up khess */
  jcol = 1;
  khess[jcol - 1] = 0;
  scanf(" %*[^\n]");
  for (i = 0; i < nnz_hess; ++i) {
    /* hess[i] stores the (hhess[i], icol) element of matrix */
    scanf("%lf%ld%ld", &hess[i], &hhess[i], &icol);

    /* Check whether we have started a new column */
    if (icol == jcol + 1) {
      khess[icol - 1] = i; /* Start of icol-th column in hess */
      jcol = icol;
    }
    else if (icol > jcol + 1) {
      /* Index in hess of the start of the icol-th column
       * equals i, but columns jcol+1, jcol+2, ...,
       * icol-1 are empty.  Set the corresponding elements
       * of khess to i.
       */
      for (j = jcol + 1; j < icol; ++j)
        khess[j - 1] = i;

      khess[icol - 1] = i;
    }
  }
  khess[ncolh] = nnz_hess;

  /* Initialize options structure */
  /* nag_opt_init (e04xxc).
   * Initialization function for option setting
   */
  nag_opt_init(&options);
  options.crnames = crnames;

  /* Package up Hessian data for communication via comm */
  hess_data.hess = hess;
  hess_data.khess = khess;
  hess_data.hhess = hhess;

  comm.p = (Pointer) &hess_data;

  /* Solve the problem */
  /* nag_opt_sparse_convex_qp (e04nkc), see above. */
  nag_opt_sparse_convex_qp(n, m, nnz, iobj, ncolh, qphess, a, ha, ka, bl, bu,
                           x, &ninf, &sinf, &obj, &options, &comm, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_opt_sparse_convex_qp (e04nkc).\n%s\n",
           fail.message);
    exit_status = 1;
    goto END;
  }

  printf("\nPerturb the problem and re-solve with warm start.\n");
  fflush(stdout);
  for (i = 0; i < nnz_hess; ++i)
    hess[i] *= 1.001;

  options.start = Nag_Warm;
  options.print_level = Nag_Soln;
  /* nag_opt_sparse_convex_qp (e04nkc), see above. */
  nag_opt_sparse_convex_qp(n, m, nnz, iobj, ncolh, qphess, a, ha, ka, bl, bu,
                           x, &ninf, &sinf, &obj, &options, &comm, &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_opt_sparse_convex_qp (e04nkc).\n%s\n",
           fail.message);
    exit_status = 1;
    goto END;
  }

  /* Free memory nAG-allocated to members of options */
  /* nag_opt_free (e04xzc).
   * Memory freeing function for use with option setting
   */
  nag_opt_free(&options, "", &fail);
  if (fail.code != NE_NOERROR) {
    printf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message);
    exit_status = 1;
    goto END;
  }

END:
  nAG_FREE(a);
  nAG_FREE(bl);
  nAG_FREE(bu);
  nAG_FREE(x);
  nAG_FREE(hess);
  nAG_FREE(ha);
  nAG_FREE(ka);
  nAG_FREE(hhess);
  nAG_FREE(khess);
  nAG_FREE(crnames);
  nAG_FREE(names);

  return exit_status;
}

static void nAG_CALL qphess(Integer ncolh, const double x[], double hx[],
                            Nag_Comm *comm)
{
  Integer i, j, jrow;
  HessianData *hd = (HessianData *) (comm->p);
  double *hess = hd->hess;
  Integer *hhess = hd->hhess;
  Integer *khess = hd->khess;

  for (i = 0; i < ncolh; ++i)
    hx[i] = 0.0;

  for (i = 0; i < ncolh; ++i) {
    /* For each column of Hessian */
    for (j = khess[i]; j < khess[i + 1]; ++j) {
      /* For each nonzero in column */

      jrow = hhess[j] - 1;

      /* Using symmetry of hessian, add contribution
       * to hx of hess[j] as a diagonal or upper
       * triangular element of hessian.
       */
      hx[i] += hess[j] * x[jrow];

      /* If hess[j] not a diagonal element add its
       * contribution to hx as a lower triangular
       * element of hessian.
       */
      if (jrow != i)
        hx[jrow] += hess[j] * x[i];
    }
  }
} /* qphess */


関連情報
© 日本ニューメリカルアルゴリズムズグループ株式会社 2025
Privacy Policy  /  Trademarks