solver_mlmtiluc2.hpp 15.4 KB
Newer Older
Kirill Terekhov's avatar
Kirill Terekhov committed
1
2
3
4
5
6
7
8

#ifndef __SOLVER_MLMTILUC2__
#define __SOLVER_MLMTILUC2__
#include <iomanip>

#include "inmost_solver.h"
#include "../solver_prototypes.hpp"

9

Kirill Terekhov's avatar
Kirill Terekhov committed
10
11
class MLMTILUC_preconditioner : public Method
{
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
	typedef struct Block_t
	{
		INMOST_DATA_ENUM_TYPE row_start, row_end;
		INMOST_DATA_ENUM_TYPE col_start, col_end;
		bool separator;
		Block_t(INMOST_DATA_ENUM_TYPE rows, 
				INMOST_DATA_ENUM_TYPE rowe,
				INMOST_DATA_ENUM_TYPE cols,
				INMOST_DATA_ENUM_TYPE cole,
				bool separator)
		: row_start(rows), row_end(rowe),
		  col_start(cols), col_end(cole),
		  separator(separator) {}
		Block_t(INMOST_DATA_ENUM_TYPE rows, 
				INMOST_DATA_ENUM_TYPE rowe,
				INMOST_DATA_ENUM_TYPE cols,
				INMOST_DATA_ENUM_TYPE cole)
		: row_start(rows), row_end(rowe),
		  col_start(cols), col_end(cole),
		  separator(false) {}
		INMOST_DATA_ENUM_TYPE RowSize() const {return row_end - row_start;}
		INMOST_DATA_ENUM_TYPE ColSize() const {return col_end - col_start;}
		// Block_t(const Block_t & b)
		// : row_start(b.row_start), row_end(b.row_end),
		//   col_start(b.col_start), col_end(b.col_end) {}
		// Block_t & operator =(Block_t const & b)
		// {
		// 	row_start = b.row_start;
		// 	row_end = b.row_end;
		// 	col_start = b.col_start;
		// 	col_end = b.col_end;
		// 	return *this;
		// }
	} Block;
Kirill Terekhov's avatar
Kirill Terekhov committed
46
47
48
	typedef struct Interval_t
	{
		INMOST_DATA_ENUM_TYPE first, last;
49
		INMOST_DATA_ENUM_TYPE Size() const { return last - first; }
Kirill Terekhov's avatar
Kirill Terekhov committed
50
	} Interval;
51
	typedef std::vector<INMOST_DATA_ENUM_TYPE> levels_t;
52
	std::vector<Sparse::Row::entry> L_Entries, U_Entries;
Kirill Terekhov's avatar
Kirill Terekhov committed
53
	interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> LU_Diag;
54
	interval<INMOST_DATA_ENUM_TYPE, Interval> U_Address, L_Address;
Kirill Terekhov's avatar
Kirill Terekhov committed
55
56
57
58
59
60
61
62
63
64
65
66
67
	std::vector<interval<INMOST_DATA_ENUM_TYPE, Interval> *> F_Address, E_Address;
	std::vector<Sparse::Row::entry> E_Entries, F_Entries;
	levels_t level_size; //remember size of each level
	std::vector<Interval> level_interval;
	interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> temp; // temporal place for solve phase
	//reordering information
	interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE > ddP,ddQ;
	INMOST_DATA_REAL_TYPE condestL, condestU;	
	INMOST_DATA_ENUM_TYPE estimator;
	INMOST_DATA_REAL_TYPE iluc2_tau;
	INMOST_DATA_REAL_TYPE pivot_cond;
	INMOST_DATA_REAL_TYPE pivot_diag;
	INMOST_DATA_REAL_TYPE tau, eps;
68
	INMOST_DATA_ENUM_TYPE sciters, verbosity;
Kirill Terekhov's avatar
Kirill Terekhov committed
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
	Sparse::Matrix * Alink;
	Solver::OrderInfo * info;
	bool init;
	void DumpMatrix(interval<INMOST_DATA_ENUM_TYPE, Interval> & Address, 
					std::vector<Sparse::Row::entry> & Entries,
					INMOST_DATA_ENUM_TYPE wmbeg, INMOST_DATA_ENUM_TYPE wmend,
					std::string file_name);
	void CheckOrder(interval<INMOST_DATA_ENUM_TYPE, Interval> & Address, 
					std::vector<Sparse::Row::entry> & Entries,
					INMOST_DATA_ENUM_TYPE rbeg, INMOST_DATA_ENUM_TYPE rend);
	void inversePQ(INMOST_DATA_ENUM_TYPE wbeg,
				   INMOST_DATA_ENUM_TYPE wend, 
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invP,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invQ);

	void applyPQ(INMOST_DATA_ENUM_TYPE wbeg,
				 INMOST_DATA_ENUM_TYPE wend,
				 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
				 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invP,
				 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invQ);
	void ReorderEF(INMOST_DATA_ENUM_TYPE wbeg,
				   INMOST_DATA_ENUM_TYPE wend,
				   interval<INMOST_DATA_ENUM_TYPE, bool> & donePQ,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ);
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
	INMOST_DATA_REAL_TYPE AddListOrdered(INMOST_DATA_ENUM_TYPE cbeg,
										 Interval & Address,
										 std::vector<Sparse::Row::entry> & Entries,
										 INMOST_DATA_REAL_TYPE coef,
										 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
										 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues,
										 INMOST_DATA_REAL_TYPE droptol);
	INMOST_DATA_REAL_TYPE AddListUnordered(INMOST_DATA_ENUM_TYPE & Sbeg,
										   Interval & Address,
										   std::vector<Sparse::Row::entry> & Entries,
										   INMOST_DATA_REAL_TYPE coef,
										   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
										   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues,
										   INMOST_DATA_REAL_TYPE droptol);
	void OrderList(INMOST_DATA_ENUM_TYPE & Sbeg, 
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
				   std::vector<INMOST_DATA_ENUM_TYPE> & indices);
	void ScaleList(INMOST_DATA_REAL_TYPE coef,
				   INMOST_DATA_ENUM_TYPE Sbeg, 
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues);
	INMOST_DATA_REAL_TYPE Estimator1(INMOST_DATA_ENUM_TYPE k,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & Est,
									 INMOST_DATA_REAL_TYPE & mu_update);
	INMOST_DATA_REAL_TYPE Estimator2(INMOST_DATA_ENUM_TYPE k,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues,
									 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & Est,
									 INMOST_DATA_REAL_TYPE & mu_update);
	void EstimatorUpdate(INMOST_DATA_ENUM_TYPE k,
						 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
						 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues,
						 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & Est,
						 INMOST_DATA_REAL_TYPE & mu_update);
	void DiagonalUpdate(INMOST_DATA_ENUM_TYPE k,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & Diag,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndecesL,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValuesL,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeceU,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValuesU);
	void ClearList(INMOST_DATA_ENUM_TYPE beg,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & LineIndeces,
				   interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & LineValues);
	void PrepareGraph(INMOST_DATA_ENUM_TYPE wbeg,
					  INMOST_DATA_ENUM_TYPE wend,
					  const interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
					  const std::vector<Sparse::Row::entry> & Entries,
					  interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G);
	// tG should be preallocated by number of columns, that may be wider then wbeg:wend
	void PrepareGraphTranspose(INMOST_DATA_ENUM_TYPE wbeg,
							   INMOST_DATA_ENUM_TYPE wend,
							   const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G,
							   interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & tG);
	// pG should be preallocated by wbeg:wend, tind computed with PrepareGraphTranspose
	void PrepareGraphProduct(INMOST_DATA_ENUM_TYPE wbeg,
							 INMOST_DATA_ENUM_TYPE wend,
							 const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G,
							 const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & tG,
							 interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & pG);
	// moves wbeg:wend subset of rows from tG_in to tG_out and filters entries outside wbeg:wend
	// tG_in is not preserved to save memory
	void FilterGraphProduct(const Block & b,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invP,
				 		  	interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
							interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & pG_in,
							interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & pG_out);
	void FilterGraphTranspose(const Block & b,
							  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				 		  	  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invQ,
							  interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & tG_in,
							  interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & tG_out);
	void FilterGraph(const Block & b,
					 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & invP,
				 	 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
					 interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G_in,
					 interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G_out);
	// finds permutation that separates matrix into blocks by running GreedyDissection recursively
	void NestedDissection(INMOST_DATA_ENUM_TYPE wbeg, 
					 	  INMOST_DATA_ENUM_TYPE wend,
						  const interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						  const std::vector<Sparse::Row::entry> & Entries,
						  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				 		  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
						  std::vector<Block> & blocks,
						  INMOST_DATA_ENUM_TYPE max_size);
	void KwayDissection(INMOST_DATA_ENUM_TYPE wbeg, 
					 	INMOST_DATA_ENUM_TYPE wend,
						const interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						const std::vector<Sparse::Row::entry> & Entries,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				 		interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
						std::vector<Block> & blocks,
						int parts);
	// finds permutation that separates matrix into blocks
	void GreedyDissection(const Block & b,
						  const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G,
						  const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & tG,
						  const interval< INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & pG,
						  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
				 		  interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
						  std::vector<Block> & blocks, int kway_parts);
						//   int wgt_sep, int wgt_blk, int kway_parts);
	//compute interval of column indices
	void ColumnInterval(INMOST_DATA_ENUM_TYPE wbeg, 
						 INMOST_DATA_ENUM_TYPE wend,
						 const interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						 const std::vector<Sparse::Row::entry> & Entries,
						 INMOST_DATA_ENUM_TYPE & cbeg,
						 INMOST_DATA_ENUM_TYPE & cend);
	// column permutations
	// has to call functions to permute scaling and E,F blocks
	void ReorderMatrixQ(interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						std::vector<Sparse::Row::entry> & Entries,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ);

	// rows and columns permutations
	// has to call functions to permute scaling and E,F blocks
	void ReorderMatrixPQ(interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						 std::vector<Sparse::Row::entry> & Entries,
						 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
						 interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP);
	
	void PrepareTranspose(INMOST_DATA_ENUM_TYPE cbeg,
						  INMOST_DATA_ENUM_TYPE cend,
						  interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						  std::vector<Sparse::Row::entry> & Entries,
						  interval<INMOST_DATA_ENUM_TYPE, std::vector< std::pair<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> > > & Indices );
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
286
287
						  
						  
	void MaximalTransversal(INMOST_DATA_ENUM_TYPE wbeg,
							INMOST_DATA_ENUM_TYPE wend,
							interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
							std::vector<Sparse::Row::entry> & Entries,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & U,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & V,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DL,
							interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR);
	
	void SymmetricGraph(INMOST_DATA_ENUM_TYPE wbeg,
						INMOST_DATA_ENUM_TYPE wend,
						interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						std::vector<Sparse::Row::entry> & Entries,
						std::vector<INMOST_DATA_ENUM_TYPE> & xadj,
						std::vector< INMOST_DATA_ENUM_TYPE > & adjncy);
						
	void SymmetricGraphWeights(	INMOST_DATA_ENUM_TYPE wbeg,
								INMOST_DATA_ENUM_TYPE wend,
								interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
								std::vector<Sparse::Row::entry> & Entries,
								interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DL,
								interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR,
								std::vector<INMOST_DATA_ENUM_TYPE> & xadj,
								std::vector<INMOST_DATA_REAL_TYPE> & wadj,
								std::vector< INMOST_DATA_ENUM_TYPE > & adjncy);
								
	void ReorderColumns(INMOST_DATA_ENUM_TYPE wbeg,
						INMOST_DATA_ENUM_TYPE wend,
						interval<INMOST_DATA_ENUM_TYPE, Interval> & Address,
						std::vector<Sparse::Row::entry> & Entries,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & V,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_REAL_TYPE> & DR,
						Sparse::Vector & DR0);
						
						
	void WRCMOrdering(	INMOST_DATA_ENUM_TYPE wbeg,
						INMOST_DATA_ENUM_TYPE wend,
						std::vector<INMOST_DATA_ENUM_TYPE> & xadj, 
						std::vector<INMOST_DATA_ENUM_TYPE> & adjncy,
						std::vector<INMOST_DATA_REAL_TYPE> & wadj,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ);

	void RCMOrdering(	INMOST_DATA_ENUM_TYPE wbeg,
						INMOST_DATA_ENUM_TYPE wend,
						std::vector<INMOST_DATA_ENUM_TYPE> & xadj, 
						std::vector<INMOST_DATA_ENUM_TYPE> & adjncy,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ);				
	void MetisOrdering(	INMOST_DATA_ENUM_TYPE wbeg,
						INMOST_DATA_ENUM_TYPE wend,
						std::vector<INMOST_DATA_ENUM_TYPE> & xadj, 
						std::vector<INMOST_DATA_ENUM_TYPE> & adjncy,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localP,
						interval<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> & localQ);
							
288
289
290
291
	void DumpGraph(std::string name, interval<INMOST_DATA_ENUM_TYPE, std::vector<INMOST_DATA_ENUM_TYPE> > & G);

	int Thread();
	int Threads();
292
293

	// Sparse::Vector div;
Kirill Terekhov's avatar
Kirill Terekhov committed
294
295
296
297
298
299
300
301
302
303
304
public:
	INMOST_DATA_ENUM_TYPE & EnumParameter(std::string name);
	INMOST_DATA_REAL_TYPE & RealParameter(std::string name);
	void Copy(const Method * other);
	MLMTILUC_preconditioner(const MLMTILUC_preconditioner & other);
	MLMTILUC_preconditioner & operator =(MLMTILUC_preconditioner const & other);
	MLMTILUC_preconditioner(Solver::OrderInfo & info);
	bool isInitialized();
	bool isFinalized();
	bool Initialize();
	bool Finalize();
305
306
	int Descend(INMOST_DATA_ENUM_TYPE level, Sparse::Vector & inout);
	int Ascend(INMOST_DATA_ENUM_TYPE level, Sparse::Vector & inout);
Kirill Terekhov's avatar
Kirill Terekhov committed
307
308
309
310
311
312
313
314
315
	bool Solve(Sparse::Vector & input, Sparse::Vector & output);
	bool ReplaceMAT(Sparse::Matrix & A);
	bool ReplaceSOL(Sparse::Vector & x);
	bool ReplaceRHS(Sparse::Vector & b);
	Method * Duplicate();
	~MLMTILUC_preconditioner();
};

#endif //__SOLVER_MLMTILUC2__