-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathbasiclu_factorize.c
More file actions
143 lines (125 loc) · 3.96 KB
/
Copy pathbasiclu_factorize.c
File metadata and controls
143 lines (125 loc) · 3.96 KB
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
/*
* basiclu_factorize.c
*
* Copyright (C) 2016-2018 ERGO-Code
*
*/
#include "lu_internal.h"
#include "lu_timer.h"
lu_int basiclu_factorize
(
lu_int istore[],
double xstore[],
lu_int Li[],
double Lx[],
lu_int Ui[],
double Ux[],
lu_int Wi[],
double Wx[],
const lu_int Bbegin[],
const lu_int Bend[],
const lu_int Bi[],
const double Bx[],
lu_int c0ntinue
)
{
struct lu this;
lu_int status;
double tic[2], elapsed, factor_cost;
lu_tic(tic);
status = lu_load(&this, istore, xstore, Li, Lx, Ui, Ux, Wi, Wx);
if (status != BASICLU_OK)
return status;
if (! (Li && Lx && Ui && Ux && Wi && Wx && Bbegin && Bend && Bi && Bx))
{
status = BASICLU_ERROR_argument_missing;
return lu_save(&this, istore, xstore, status);
}
if (!c0ntinue)
{
lu_reset(&this);
this.task = SINGLETONS;
}
/* continue factorization */
switch (this.task)
{
case SINGLETONS: goto singletons;
case SETUP_BUMP: goto setup_bump;
case FACTORIZE_BUMP: goto factorize_bump;
case BUILD_FACTORS: goto build_factors;
}
status = BASICLU_ERROR_invalid_call;
return lu_save(&this, istore, xstore, status);
/*
* Each of the following four parts of the factorization calls a routine
* lu_do_something() which may request reallocation. In this case return
* to the caller immediately, keeping the entry point in this.task.
*/
singletons:
this.task = SINGLETONS;
status = lu_singletons(&this, Bbegin, Bend, Bi, Bx);
if (status != BASICLU_OK)
goto return_to_caller;
setup_bump:
this.task = SETUP_BUMP;
status = lu_setup_bump(&this, Bbegin, Bend, Bi, Bx);
if (status != BASICLU_OK)
goto return_to_caller;
factorize_bump:
this.task = FACTORIZE_BUMP;
status = lu_factorize_bump(&this);
if (status != BASICLU_OK)
goto return_to_caller;
build_factors:
this.task = BUILD_FACTORS;
status = lu_build_factors(&this);
if (status != BASICLU_OK)
goto return_to_caller;
/* factorization successfully finished */
this.task = NO_TASK;
this.nupdate = 0; /* make factorization valid */
this.ftran_for_update = -1;
this.btran_for_update = -1;
this.nfactorize++;
this.condestL = lu_condest(this.m, this.Lbegin, this.Lindex, this.Lvalue,
NULL, this.p, 0, this.work1,
&this.normL, &this.normestLinv);
this.condestU = lu_condest(this.m, this.Ubegin, this.Uindex, this.Uvalue,
this.row_pivot, this.p, 1, this.work1,
&this.normU, &this.normestUinv);
/* measure numerical stability of the factorization */
lu_residual_test(&this, Bbegin, Bend, Bi, Bx);
/*
* factor_cost is a deterministic measure of the factorization cost.
* The parameters have been adjusted such that (on my computer)
* 1e-6 * factor_cost =~ time_factorize.
*
* update_cost measures the accumulated cost of updates/solves compared
* to the last factorization. It is computed from
*
* update_cost = update_cost_numer / update_cost_denom.
*
* update_cost_denom is fixed here.
* update_cost_numer is zero here and increased by solves/updates.
*
*/
factor_cost =
0.04 * this.m +
0.07 * this.matrix_nz +
0.20 * this.bump_nz +
0.20 * this.nsearch_pivot +
0.008 * this.factor_flops;
this.update_cost_denom = factor_cost * 250;
#if 0
elapsed = this.time_factorize + lu_toc(tic);
printf(" 1e-6 * factor_cost / time_factorize: %.2f\n",
1e-6 * factor_cost / elapsed);
#endif
if (this.rank < this.m)
status = BASICLU_WARNING_singular_matrix;
return_to_caller:
elapsed = lu_toc(tic);
this.time_factorize += elapsed;
this.time_factorize_total += elapsed;
return lu_save(&this, istore, xstore, status);
}