glpluf.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847
  1. /* glpluf.c (LU-factorization) */
  2. /***********************************************************************
  3. * This code is part of GLPK (GNU Linear Programming Kit).
  4. *
  5. * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
  6. * 2009, 2010 Andrew Makhorin, Department for Applied Informatics,
  7. * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
  8. * E-mail: <mao@gnu.org>.
  9. *
  10. * GLPK is free software: you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * GLPK is distributed in the hope that it will be useful, but WITHOUT
  16. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  18. * License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
  22. ***********************************************************************/
  23. #include "glpenv.h"
  24. #include "glpluf.h"
  25. #define xfault xerror
  26. /* CAUTION: DO NOT CHANGE THE LIMIT BELOW */
  27. #define N_MAX 100000000 /* = 100*10^6 */
  28. /* maximal order of the original matrix */
  29. /***********************************************************************
  30. * NAME
  31. *
  32. * luf_create_it - create LU-factorization
  33. *
  34. * SYNOPSIS
  35. *
  36. * #include "glpluf.h"
  37. * LUF *luf_create_it(void);
  38. *
  39. * DESCRIPTION
  40. *
  41. * The routine luf_create_it creates a program object, which represents
  42. * LU-factorization of a square matrix.
  43. *
  44. * RETURNS
  45. *
  46. * The routine luf_create_it returns a pointer to the object created. */
  47. LUF *luf_create_it(void)
  48. { LUF *luf;
  49. luf = xmalloc(sizeof(LUF));
  50. luf->n_max = luf->n = 0;
  51. luf->valid = 0;
  52. luf->fr_ptr = luf->fr_len = NULL;
  53. luf->fc_ptr = luf->fc_len = NULL;
  54. luf->vr_ptr = luf->vr_len = luf->vr_cap = NULL;
  55. luf->vr_piv = NULL;
  56. luf->vc_ptr = luf->vc_len = luf->vc_cap = NULL;
  57. luf->pp_row = luf->pp_col = NULL;
  58. luf->qq_row = luf->qq_col = NULL;
  59. luf->sv_size = 0;
  60. luf->sv_beg = luf->sv_end = 0;
  61. luf->sv_ind = NULL;
  62. luf->sv_val = NULL;
  63. luf->sv_head = luf->sv_tail = 0;
  64. luf->sv_prev = luf->sv_next = NULL;
  65. luf->vr_max = NULL;
  66. luf->rs_head = luf->rs_prev = luf->rs_next = NULL;
  67. luf->cs_head = luf->cs_prev = luf->cs_next = NULL;
  68. luf->flag = NULL;
  69. luf->work = NULL;
  70. luf->new_sva = 0;
  71. luf->piv_tol = 0.10;
  72. luf->piv_lim = 4;
  73. luf->suhl = 1;
  74. luf->eps_tol = 1e-15;
  75. luf->max_gro = 1e+10;
  76. luf->nnz_a = luf->nnz_f = luf->nnz_v = 0;
  77. luf->max_a = luf->big_v = 0.0;
  78. luf->rank = 0;
  79. return luf;
  80. }
  81. /***********************************************************************
  82. * NAME
  83. *
  84. * luf_defrag_sva - defragment the sparse vector area
  85. *
  86. * SYNOPSIS
  87. *
  88. * #include "glpluf.h"
  89. * void luf_defrag_sva(LUF *luf);
  90. *
  91. * DESCRIPTION
  92. *
  93. * The routine luf_defrag_sva defragments the sparse vector area (SVA)
  94. * gathering all unused locations in one continuous extent. In order to
  95. * do that the routine moves all unused locations from the left part of
  96. * SVA (which contains rows and columns of the matrix V) to the middle
  97. * part (which contains free locations). This is attained by relocating
  98. * elements of rows and columns of the matrix V toward the beginning of
  99. * the left part.
  100. *
  101. * NOTE that this "garbage collection" involves changing row and column
  102. * pointers of the matrix V. */
  103. void luf_defrag_sva(LUF *luf)
  104. { int n = luf->n;
  105. int *vr_ptr = luf->vr_ptr;
  106. int *vr_len = luf->vr_len;
  107. int *vr_cap = luf->vr_cap;
  108. int *vc_ptr = luf->vc_ptr;
  109. int *vc_len = luf->vc_len;
  110. int *vc_cap = luf->vc_cap;
  111. int *sv_ind = luf->sv_ind;
  112. double *sv_val = luf->sv_val;
  113. int *sv_next = luf->sv_next;
  114. int sv_beg = 1;
  115. int i, j, k;
  116. /* skip rows and columns, which do not need to be relocated */
  117. for (k = luf->sv_head; k != 0; k = sv_next[k])
  118. { if (k <= n)
  119. { /* i-th row of the matrix V */
  120. i = k;
  121. if (vr_ptr[i] != sv_beg) break;
  122. vr_cap[i] = vr_len[i];
  123. sv_beg += vr_cap[i];
  124. }
  125. else
  126. { /* j-th column of the matrix V */
  127. j = k - n;
  128. if (vc_ptr[j] != sv_beg) break;
  129. vc_cap[j] = vc_len[j];
  130. sv_beg += vc_cap[j];
  131. }
  132. }
  133. /* relocate other rows and columns in order to gather all unused
  134. locations in one continuous extent */
  135. for (k = k; k != 0; k = sv_next[k])
  136. { if (k <= n)
  137. { /* i-th row of the matrix V */
  138. i = k;
  139. memmove(&sv_ind[sv_beg], &sv_ind[vr_ptr[i]],
  140. vr_len[i] * sizeof(int));
  141. memmove(&sv_val[sv_beg], &sv_val[vr_ptr[i]],
  142. vr_len[i] * sizeof(double));
  143. vr_ptr[i] = sv_beg;
  144. vr_cap[i] = vr_len[i];
  145. sv_beg += vr_cap[i];
  146. }
  147. else
  148. { /* j-th column of the matrix V */
  149. j = k - n;
  150. memmove(&sv_ind[sv_beg], &sv_ind[vc_ptr[j]],
  151. vc_len[j] * sizeof(int));
  152. memmove(&sv_val[sv_beg], &sv_val[vc_ptr[j]],
  153. vc_len[j] * sizeof(double));
  154. vc_ptr[j] = sv_beg;
  155. vc_cap[j] = vc_len[j];
  156. sv_beg += vc_cap[j];
  157. }
  158. }
  159. /* set new pointer to the beginning of the free part */
  160. luf->sv_beg = sv_beg;
  161. return;
  162. }
  163. /***********************************************************************
  164. * NAME
  165. *
  166. * luf_enlarge_row - enlarge row capacity
  167. *
  168. * SYNOPSIS
  169. *
  170. * #include "glpluf.h"
  171. * int luf_enlarge_row(LUF *luf, int i, int cap);
  172. *
  173. * DESCRIPTION
  174. *
  175. * The routine luf_enlarge_row enlarges capacity of the i-th row of the
  176. * matrix V to cap locations (assuming that its current capacity is less
  177. * than cap). In order to do that the routine relocates elements of the
  178. * i-th row to the end of the left part of SVA (which contains rows and
  179. * columns of the matrix V) and then expands the left part by allocating
  180. * cap free locations from the free part. If there are less than cap
  181. * free locations, the routine defragments the sparse vector area.
  182. *
  183. * Due to "garbage collection" this operation may change row and column
  184. * pointers of the matrix V.
  185. *
  186. * RETURNS
  187. *
  188. * If no error occured, the routine returns zero. Otherwise, in case of
  189. * overflow of the sparse vector area, the routine returns non-zero. */
  190. int luf_enlarge_row(LUF *luf, int i, int cap)
  191. { int n = luf->n;
  192. int *vr_ptr = luf->vr_ptr;
  193. int *vr_len = luf->vr_len;
  194. int *vr_cap = luf->vr_cap;
  195. int *vc_cap = luf->vc_cap;
  196. int *sv_ind = luf->sv_ind;
  197. double *sv_val = luf->sv_val;
  198. int *sv_prev = luf->sv_prev;
  199. int *sv_next = luf->sv_next;
  200. int ret = 0;
  201. int cur, k, kk;
  202. xassert(1 <= i && i <= n);
  203. xassert(vr_cap[i] < cap);
  204. /* if there are less than cap free locations, defragment SVA */
  205. if (luf->sv_end - luf->sv_beg < cap)
  206. { luf_defrag_sva(luf);
  207. if (luf->sv_end - luf->sv_beg < cap)
  208. { ret = 1;
  209. goto done;
  210. }
  211. }
  212. /* save current capacity of the i-th row */
  213. cur = vr_cap[i];
  214. /* copy existing elements to the beginning of the free part */
  215. memmove(&sv_ind[luf->sv_beg], &sv_ind[vr_ptr[i]],
  216. vr_len[i] * sizeof(int));
  217. memmove(&sv_val[luf->sv_beg], &sv_val[vr_ptr[i]],
  218. vr_len[i] * sizeof(double));
  219. /* set new pointer and new capacity of the i-th row */
  220. vr_ptr[i] = luf->sv_beg;
  221. vr_cap[i] = cap;
  222. /* set new pointer to the beginning of the free part */
  223. luf->sv_beg += cap;
  224. /* now the i-th row starts in the rightmost location among other
  225. rows and columns of the matrix V, so its node should be moved
  226. to the end of the row/column linked list */
  227. k = i;
  228. /* remove the i-th row node from the linked list */
  229. if (sv_prev[k] == 0)
  230. luf->sv_head = sv_next[k];
  231. else
  232. { /* capacity of the previous row/column can be increased at the
  233. expense of old locations of the i-th row */
  234. kk = sv_prev[k];
  235. if (kk <= n) vr_cap[kk] += cur; else vc_cap[kk-n] += cur;
  236. sv_next[sv_prev[k]] = sv_next[k];
  237. }
  238. if (sv_next[k] == 0)
  239. luf->sv_tail = sv_prev[k];
  240. else
  241. sv_prev[sv_next[k]] = sv_prev[k];
  242. /* insert the i-th row node to the end of the linked list */
  243. sv_prev[k] = luf->sv_tail;
  244. sv_next[k] = 0;
  245. if (sv_prev[k] == 0)
  246. luf->sv_head = k;
  247. else
  248. sv_next[sv_prev[k]] = k;
  249. luf->sv_tail = k;
  250. done: return ret;
  251. }
  252. /***********************************************************************
  253. * NAME
  254. *
  255. * luf_enlarge_col - enlarge column capacity
  256. *
  257. * SYNOPSIS
  258. *
  259. * #include "glpluf.h"
  260. * int luf_enlarge_col(LUF *luf, int j, int cap);
  261. *
  262. * DESCRIPTION
  263. *
  264. * The routine luf_enlarge_col enlarges capacity of the j-th column of
  265. * the matrix V to cap locations (assuming that its current capacity is
  266. * less than cap). In order to do that the routine relocates elements
  267. * of the j-th column to the end of the left part of SVA (which contains
  268. * rows and columns of the matrix V) and then expands the left part by
  269. * allocating cap free locations from the free part. If there are less
  270. * than cap free locations, the routine defragments the sparse vector
  271. * area.
  272. *
  273. * Due to "garbage collection" this operation may change row and column
  274. * pointers of the matrix V.
  275. *
  276. * RETURNS
  277. *
  278. * If no error occured, the routine returns zero. Otherwise, in case of
  279. * overflow of the sparse vector area, the routine returns non-zero. */
  280. int luf_enlarge_col(LUF *luf, int j, int cap)
  281. { int n = luf->n;
  282. int *vr_cap = luf->vr_cap;
  283. int *vc_ptr = luf->vc_ptr;
  284. int *vc_len = luf->vc_len;
  285. int *vc_cap = luf->vc_cap;
  286. int *sv_ind = luf->sv_ind;
  287. double *sv_val = luf->sv_val;
  288. int *sv_prev = luf->sv_prev;
  289. int *sv_next = luf->sv_next;
  290. int ret = 0;
  291. int cur, k, kk;
  292. xassert(1 <= j && j <= n);
  293. xassert(vc_cap[j] < cap);
  294. /* if there are less than cap free locations, defragment SVA */
  295. if (luf->sv_end - luf->sv_beg < cap)
  296. { luf_defrag_sva(luf);
  297. if (luf->sv_end - luf->sv_beg < cap)
  298. { ret = 1;
  299. goto done;
  300. }
  301. }
  302. /* save current capacity of the j-th column */
  303. cur = vc_cap[j];
  304. /* copy existing elements to the beginning of the free part */
  305. memmove(&sv_ind[luf->sv_beg], &sv_ind[vc_ptr[j]],
  306. vc_len[j] * sizeof(int));
  307. memmove(&sv_val[luf->sv_beg], &sv_val[vc_ptr[j]],
  308. vc_len[j] * sizeof(double));
  309. /* set new pointer and new capacity of the j-th column */
  310. vc_ptr[j] = luf->sv_beg;
  311. vc_cap[j] = cap;
  312. /* set new pointer to the beginning of the free part */
  313. luf->sv_beg += cap;
  314. /* now the j-th column starts in the rightmost location among
  315. other rows and columns of the matrix V, so its node should be
  316. moved to the end of the row/column linked list */
  317. k = n + j;
  318. /* remove the j-th column node from the linked list */
  319. if (sv_prev[k] == 0)
  320. luf->sv_head = sv_next[k];
  321. else
  322. { /* capacity of the previous row/column can be increased at the
  323. expense of old locations of the j-th column */
  324. kk = sv_prev[k];
  325. if (kk <= n) vr_cap[kk] += cur; else vc_cap[kk-n] += cur;
  326. sv_next[sv_prev[k]] = sv_next[k];
  327. }
  328. if (sv_next[k] == 0)
  329. luf->sv_tail = sv_prev[k];
  330. else
  331. sv_prev[sv_next[k]] = sv_prev[k];
  332. /* insert the j-th column node to the end of the linked list */
  333. sv_prev[k] = luf->sv_tail;
  334. sv_next[k] = 0;
  335. if (sv_prev[k] == 0)
  336. luf->sv_head = k;
  337. else
  338. sv_next[sv_prev[k]] = k;
  339. luf->sv_tail = k;
  340. done: return ret;
  341. }
  342. /***********************************************************************
  343. * reallocate - reallocate LU-factorization arrays
  344. *
  345. * This routine reallocates arrays, whose size depends of n, the order
  346. * of the matrix A to be factorized. */
  347. static void reallocate(LUF *luf, int n)
  348. { int n_max = luf->n_max;
  349. luf->n = n;
  350. if (n <= n_max) goto done;
  351. if (luf->fr_ptr != NULL) xfree(luf->fr_ptr);
  352. if (luf->fr_len != NULL) xfree(luf->fr_len);
  353. if (luf->fc_ptr != NULL) xfree(luf->fc_ptr);
  354. if (luf->fc_len != NULL) xfree(luf->fc_len);
  355. if (luf->vr_ptr != NULL) xfree(luf->vr_ptr);
  356. if (luf->vr_len != NULL) xfree(luf->vr_len);
  357. if (luf->vr_cap != NULL) xfree(luf->vr_cap);
  358. if (luf->vr_piv != NULL) xfree(luf->vr_piv);
  359. if (luf->vc_ptr != NULL) xfree(luf->vc_ptr);
  360. if (luf->vc_len != NULL) xfree(luf->vc_len);
  361. if (luf->vc_cap != NULL) xfree(luf->vc_cap);
  362. if (luf->pp_row != NULL) xfree(luf->pp_row);
  363. if (luf->pp_col != NULL) xfree(luf->pp_col);
  364. if (luf->qq_row != NULL) xfree(luf->qq_row);
  365. if (luf->qq_col != NULL) xfree(luf->qq_col);
  366. if (luf->sv_prev != NULL) xfree(luf->sv_prev);
  367. if (luf->sv_next != NULL) xfree(luf->sv_next);
  368. if (luf->vr_max != NULL) xfree(luf->vr_max);
  369. if (luf->rs_head != NULL) xfree(luf->rs_head);
  370. if (luf->rs_prev != NULL) xfree(luf->rs_prev);
  371. if (luf->rs_next != NULL) xfree(luf->rs_next);
  372. if (luf->cs_head != NULL) xfree(luf->cs_head);
  373. if (luf->cs_prev != NULL) xfree(luf->cs_prev);
  374. if (luf->cs_next != NULL) xfree(luf->cs_next);
  375. if (luf->flag != NULL) xfree(luf->flag);
  376. if (luf->work != NULL) xfree(luf->work);
  377. luf->n_max = n_max = n + 100;
  378. luf->fr_ptr = xcalloc(1+n_max, sizeof(int));
  379. luf->fr_len = xcalloc(1+n_max, sizeof(int));
  380. luf->fc_ptr = xcalloc(1+n_max, sizeof(int));
  381. luf->fc_len = xcalloc(1+n_max, sizeof(int));
  382. luf->vr_ptr = xcalloc(1+n_max, sizeof(int));
  383. luf->vr_len = xcalloc(1+n_max, sizeof(int));
  384. luf->vr_cap = xcalloc(1+n_max, sizeof(int));
  385. luf->vr_piv = xcalloc(1+n_max, sizeof(double));
  386. luf->vc_ptr = xcalloc(1+n_max, sizeof(int));
  387. luf->vc_len = xcalloc(1+n_max, sizeof(int));
  388. luf->vc_cap = xcalloc(1+n_max, sizeof(int));
  389. luf->pp_row = xcalloc(1+n_max, sizeof(int));
  390. luf->pp_col = xcalloc(1+n_max, sizeof(int));
  391. luf->qq_row = xcalloc(1+n_max, sizeof(int));
  392. luf->qq_col = xcalloc(1+n_max, sizeof(int));
  393. luf->sv_prev = xcalloc(1+n_max+n_max, sizeof(int));
  394. luf->sv_next = xcalloc(1+n_max+n_max, sizeof(int));
  395. luf->vr_max = xcalloc(1+n_max, sizeof(double));
  396. luf->rs_head = xcalloc(1+n_max, sizeof(int));
  397. luf->rs_prev = xcalloc(1+n_max, sizeof(int));
  398. luf->rs_next = xcalloc(1+n_max, sizeof(int));
  399. luf->cs_head = xcalloc(1+n_max, sizeof(int));
  400. luf->cs_prev = xcalloc(1+n_max, sizeof(int));
  401. luf->cs_next = xcalloc(1+n_max, sizeof(int));
  402. luf->flag = xcalloc(1+n_max, sizeof(int));
  403. luf->work = xcalloc(1+n_max, sizeof(double));
  404. done: return;
  405. }
  406. /***********************************************************************
  407. * initialize - initialize LU-factorization data structures
  408. *
  409. * This routine initializes data structures for subsequent computing
  410. * the LU-factorization of a given matrix A, which is specified by the
  411. * formal routine col. On exit V = A and F = P = Q = I, where I is the
  412. * unity matrix. (Row-wise representation of the matrix F is not used
  413. * at the factorization stage and therefore is not initialized.)
  414. *
  415. * If no error occured, the routine returns zero. Otherwise, in case of
  416. * overflow of the sparse vector area, the routine returns non-zero. */
  417. static int initialize(LUF *luf, int (*col)(void *info, int j, int rn[],
  418. double aj[]), void *info)
  419. { int n = luf->n;
  420. int *fc_ptr = luf->fc_ptr;
  421. int *fc_len = luf->fc_len;
  422. int *vr_ptr = luf->vr_ptr;
  423. int *vr_len = luf->vr_len;
  424. int *vr_cap = luf->vr_cap;
  425. int *vc_ptr = luf->vc_ptr;
  426. int *vc_len = luf->vc_len;
  427. int *vc_cap = luf->vc_cap;
  428. int *pp_row = luf->pp_row;
  429. int *pp_col = luf->pp_col;
  430. int *qq_row = luf->qq_row;
  431. int *qq_col = luf->qq_col;
  432. int *sv_ind = luf->sv_ind;
  433. double *sv_val = luf->sv_val;
  434. int *sv_prev = luf->sv_prev;
  435. int *sv_next = luf->sv_next;
  436. double *vr_max = luf->vr_max;
  437. int *rs_head = luf->rs_head;
  438. int *rs_prev = luf->rs_prev;
  439. int *rs_next = luf->rs_next;
  440. int *cs_head = luf->cs_head;
  441. int *cs_prev = luf->cs_prev;
  442. int *cs_next = luf->cs_next;
  443. int *flag = luf->flag;
  444. double *work = luf->work;
  445. int ret = 0;
  446. int i, i_ptr, j, j_beg, j_end, k, len, nnz, sv_beg, sv_end, ptr;
  447. double big, val;
  448. /* free all locations of the sparse vector area */
  449. sv_beg = 1;
  450. sv_end = luf->sv_size + 1;
  451. /* (row-wise representation of the matrix F is not initialized,
  452. because it is not used at the factorization stage) */
  453. /* build the matrix F in column-wise format (initially F = I) */
  454. for (j = 1; j <= n; j++)
  455. { fc_ptr[j] = sv_end;
  456. fc_len[j] = 0;
  457. }
  458. /* clear rows of the matrix V; clear the flag array */
  459. for (i = 1; i <= n; i++)
  460. vr_len[i] = vr_cap[i] = 0, flag[i] = 0;
  461. /* build the matrix V in column-wise format (initially V = A);
  462. count non-zeros in rows of this matrix; count total number of
  463. non-zeros; compute largest of absolute values of elements */
  464. nnz = 0;
  465. big = 0.0;
  466. for (j = 1; j <= n; j++)
  467. { int *rn = pp_row;
  468. double *aj = work;
  469. /* obtain j-th column of the matrix A */
  470. len = col(info, j, rn, aj);
  471. if (!(0 <= len && len <= n))
  472. xfault("luf_factorize: j = %d; len = %d; invalid column len"
  473. "gth\n", j, len);
  474. /* check for free locations */
  475. if (sv_end - sv_beg < len)
  476. { /* overflow of the sparse vector area */
  477. ret = 1;
  478. goto done;
  479. }
  480. /* set pointer to the j-th column */
  481. vc_ptr[j] = sv_beg;
  482. /* set length of the j-th column */
  483. vc_len[j] = vc_cap[j] = len;
  484. /* count total number of non-zeros */
  485. nnz += len;
  486. /* walk through elements of the j-th column */
  487. for (ptr = 1; ptr <= len; ptr++)
  488. { /* get row index and numerical value of a[i,j] */
  489. i = rn[ptr];
  490. val = aj[ptr];
  491. if (!(1 <= i && i <= n))
  492. xfault("luf_factorize: i = %d; j = %d; invalid row index"
  493. "\n", i, j);
  494. if (flag[i])
  495. xfault("luf_factorize: i = %d; j = %d; duplicate element"
  496. " not allowed\n", i, j);
  497. if (val == 0.0)
  498. xfault("luf_factorize: i = %d; j = %d; zero element not "
  499. "allowed\n", i, j);
  500. /* add new element v[i,j] = a[i,j] to j-th column */
  501. sv_ind[sv_beg] = i;
  502. sv_val[sv_beg] = val;
  503. sv_beg++;
  504. /* big := max(big, |a[i,j]|) */
  505. if (val < 0.0) val = - val;
  506. if (big < val) big = val;
  507. /* mark non-zero in the i-th position of the j-th column */
  508. flag[i] = 1;
  509. /* increase length of the i-th row */
  510. vr_cap[i]++;
  511. }
  512. /* reset all non-zero marks */
  513. for (ptr = 1; ptr <= len; ptr++) flag[rn[ptr]] = 0;
  514. }
  515. /* allocate rows of the matrix V */
  516. for (i = 1; i <= n; i++)
  517. { /* get length of the i-th row */
  518. len = vr_cap[i];
  519. /* check for free locations */
  520. if (sv_end - sv_beg < len)
  521. { /* overflow of the sparse vector area */
  522. ret = 1;
  523. goto done;
  524. }
  525. /* set pointer to the i-th row */
  526. vr_ptr[i] = sv_beg;
  527. /* reserve locations for the i-th row */
  528. sv_beg += len;
  529. }
  530. /* build the matrix V in row-wise format using representation of
  531. this matrix in column-wise format */
  532. for (j = 1; j <= n; j++)
  533. { /* walk through elements of the j-th column */
  534. j_beg = vc_ptr[j];
  535. j_end = j_beg + vc_len[j] - 1;
  536. for (k = j_beg; k <= j_end; k++)
  537. { /* get row index and numerical value of v[i,j] */
  538. i = sv_ind[k];
  539. val = sv_val[k];
  540. /* store element in the i-th row */
  541. i_ptr = vr_ptr[i] + vr_len[i];
  542. sv_ind[i_ptr] = j;
  543. sv_val[i_ptr] = val;
  544. /* increase count of the i-th row */
  545. vr_len[i]++;
  546. }
  547. }
  548. /* initialize the matrices P and Q (initially P = Q = I) */
  549. for (k = 1; k <= n; k++)
  550. pp_row[k] = pp_col[k] = qq_row[k] = qq_col[k] = k;
  551. /* set sva partitioning pointers */
  552. luf->sv_beg = sv_beg;
  553. luf->sv_end = sv_end;
  554. /* the initial physical order of rows and columns of the matrix V
  555. is n+1, ..., n+n, 1, ..., n (firstly columns, then rows) */
  556. luf->sv_head = n+1;
  557. luf->sv_tail = n;
  558. for (i = 1; i <= n; i++)
  559. { sv_prev[i] = i-1;
  560. sv_next[i] = i+1;
  561. }
  562. sv_prev[1] = n+n;
  563. sv_next[n] = 0;
  564. for (j = 1; j <= n; j++)
  565. { sv_prev[n+j] = n+j-1;
  566. sv_next[n+j] = n+j+1;
  567. }
  568. sv_prev[n+1] = 0;
  569. sv_next[n+n] = 1;
  570. /* clear working arrays */
  571. for (k = 1; k <= n; k++)
  572. { flag[k] = 0;
  573. work[k] = 0.0;
  574. }
  575. /* initialize some statistics */
  576. luf->nnz_a = nnz;
  577. luf->nnz_f = 0;
  578. luf->nnz_v = nnz;
  579. luf->max_a = big;
  580. luf->big_v = big;
  581. luf->rank = -1;
  582. /* initially the active submatrix is the entire matrix V */
  583. /* largest of absolute values of elements in each active row is
  584. unknown yet */
  585. for (i = 1; i <= n; i++) vr_max[i] = -1.0;
  586. /* build linked lists of active rows */
  587. for (len = 0; len <= n; len++) rs_head[len] = 0;
  588. for (i = 1; i <= n; i++)
  589. { len = vr_len[i];
  590. rs_prev[i] = 0;
  591. rs_next[i] = rs_head[len];
  592. if (rs_next[i] != 0) rs_prev[rs_next[i]] = i;
  593. rs_head[len] = i;
  594. }
  595. /* build linked lists of active columns */
  596. for (len = 0; len <= n; len++) cs_head[len] = 0;
  597. for (j = 1; j <= n; j++)
  598. { len = vc_len[j];
  599. cs_prev[j] = 0;
  600. cs_next[j] = cs_head[len];
  601. if (cs_next[j] != 0) cs_prev[cs_next[j]] = j;
  602. cs_head[len] = j;
  603. }
  604. done: /* return to the factorizing routine */
  605. return ret;
  606. }
  607. /***********************************************************************
  608. * find_pivot - choose a pivot element
  609. *
  610. * This routine chooses a pivot element in the active submatrix of the
  611. * matrix U = P*V*Q.
  612. *
  613. * It is assumed that on entry the matrix U has the following partially
  614. * triangularized form:
  615. *
  616. * 1 k n
  617. * 1 x x x x x x x x x x
  618. * . x x x x x x x x x
  619. * . . x x x x x x x x
  620. * . . . x x x x x x x
  621. * k . . . . * * * * * *
  622. * . . . . * * * * * *
  623. * . . . . * * * * * *
  624. * . . . . * * * * * *
  625. * . . . . * * * * * *
  626. * n . . . . * * * * * *
  627. *
  628. * where rows and columns k, k+1, ..., n belong to the active submatrix
  629. * (elements of the active submatrix are marked by '*').
  630. *
  631. * Since the matrix U = P*V*Q is not stored, the routine works with the
  632. * matrix V. It is assumed that the row-wise representation corresponds
  633. * to the matrix V, but the column-wise representation corresponds to
  634. * the active submatrix of the matrix V, i.e. elements of the matrix V,
  635. * which doesn't belong to the active submatrix, are missing from the
  636. * column linked lists. It is also assumed that each active row of the
  637. * matrix V is in the set R[len], where len is number of non-zeros in
  638. * the row, and each active column of the matrix V is in the set C[len],
  639. * where len is number of non-zeros in the column (in the latter case
  640. * only elements of the active submatrix are counted; such elements are
  641. * marked by '*' on the figure above).
  642. *
  643. * For the reason of numerical stability the routine applies so called
  644. * threshold pivoting proposed by J.Reid. It is assumed that an element
  645. * v[i,j] can be selected as a pivot candidate if it is not very small
  646. * (in absolute value) among other elements in the same row, i.e. if it
  647. * satisfies to the stability condition |v[i,j]| >= tol * max|v[i,*]|,
  648. * where 0 < tol < 1 is a given tolerance.
  649. *
  650. * In order to keep sparsity of the matrix V the routine uses Markowitz
  651. * strategy, trying to choose such element v[p,q], which satisfies to
  652. * the stability condition (see above) and has smallest Markowitz cost
  653. * (nr[p]-1) * (nc[q]-1), where nr[p] and nc[q] are numbers of non-zero
  654. * elements, respectively, in the p-th row and in the q-th column of the
  655. * active submatrix.
  656. *
  657. * In order to reduce the search, i.e. not to walk through all elements
  658. * of the active submatrix, the routine exploits a technique proposed by
  659. * I.Duff. This technique is based on using the sets R[len] and C[len]
  660. * of active rows and columns.
  661. *
  662. * If the pivot element v[p,q] has been chosen, the routine stores its
  663. * indices to the locations *p and *q and returns zero. Otherwise, if
  664. * the active submatrix is empty and therefore the pivot element can't
  665. * be chosen, the routine returns non-zero. */
  666. static int find_pivot(LUF *luf, int *_p, int *_q)
  667. { int n = luf->n;
  668. int *vr_ptr = luf->vr_ptr;
  669. int *vr_len = luf->vr_len;
  670. int *vc_ptr = luf->vc_ptr;
  671. int *vc_len = luf->vc_len;
  672. int *sv_ind = luf->sv_ind;
  673. double *sv_val = luf->sv_val;
  674. double *vr_max = luf->vr_max;
  675. int *rs_head = luf->rs_head;
  676. int *rs_next = luf->rs_next;
  677. int *cs_head = luf->cs_head;
  678. int *cs_prev = luf->cs_prev;
  679. int *cs_next = luf->cs_next;
  680. double piv_tol = luf->piv_tol;
  681. int piv_lim = luf->piv_lim;
  682. int suhl = luf->suhl;
  683. int p, q, len, i, i_beg, i_end, i_ptr, j, j_beg, j_end, j_ptr,
  684. ncand, next_j, min_p, min_q, min_len;
  685. double best, cost, big, temp;
  686. /* initially no pivot candidates have been found so far */
  687. p = q = 0, best = DBL_MAX, ncand = 0;
  688. /* if in the active submatrix there is a column that has the only
  689. non-zero (column singleton), choose it as pivot */
  690. j = cs_head[1];
  691. if (j != 0)
  692. { xassert(vc_len[j] == 1);
  693. p = sv_ind[vc_ptr[j]], q = j;
  694. goto done;
  695. }
  696. /* if in the active submatrix there is a row that has the only
  697. non-zero (row singleton), choose it as pivot */
  698. i = rs_head[1];
  699. if (i != 0)
  700. { xassert(vr_len[i] == 1);
  701. p = i, q = sv_ind[vr_ptr[i]];
  702. goto done;
  703. }
  704. /* there are no singletons in the active submatrix; walk through
  705. other non-empty rows and columns */
  706. for (len = 2; len <= n; len++)
  707. { /* consider active columns that have len non-zeros */
  708. for (j = cs_head[len]; j != 0; j = next_j)
  709. { /* the j-th column has len non-zeros */
  710. j_beg = vc_ptr[j];
  711. j_end = j_beg + vc_len[j] - 1;
  712. /* save pointer to the next column with the same length */
  713. next_j = cs_next[j];
  714. /* find an element in the j-th column, which is placed in a
  715. row with minimal number of non-zeros and satisfies to the
  716. stability condition (such element may not exist) */
  717. min_p = min_q = 0, min_len = INT_MAX;
  718. for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++)
  719. { /* get row index of v[i,j] */
  720. i = sv_ind[j_ptr];
  721. i_beg = vr_ptr[i];
  722. i_end = i_beg + vr_len[i] - 1;
  723. /* if the i-th row is not shorter than that one, where
  724. minimal element is currently placed, skip v[i,j] */
  725. if (vr_len[i] >= min_len) continue;
  726. /* determine the largest of absolute values of elements
  727. in the i-th row */
  728. big = vr_max[i];
  729. if (big < 0.0)
  730. { /* the largest value is unknown yet; compute it */
  731. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  732. { temp = sv_val[i_ptr];
  733. if (temp < 0.0) temp = - temp;
  734. if (big < temp) big = temp;
  735. }
  736. vr_max[i] = big;
  737. }
  738. /* find v[i,j] in the i-th row */
  739. for (i_ptr = vr_ptr[i]; sv_ind[i_ptr] != j; i_ptr++);
  740. xassert(i_ptr <= i_end);
  741. /* if v[i,j] doesn't satisfy to the stability condition,
  742. skip it */
  743. temp = sv_val[i_ptr];
  744. if (temp < 0.0) temp = - temp;
  745. if (temp < piv_tol * big) continue;
  746. /* v[i,j] is better than the current minimal element */
  747. min_p = i, min_q = j, min_len = vr_len[i];
  748. /* if Markowitz cost of the current minimal element is
  749. not greater than (len-1)**2, it can be chosen right
  750. now; this heuristic reduces the search and works well
  751. in many cases */
  752. if (min_len <= len)
  753. { p = min_p, q = min_q;
  754. goto done;
  755. }
  756. }
  757. /* the j-th column has been scanned */
  758. if (min_p != 0)
  759. { /* the minimal element is a next pivot candidate */
  760. ncand++;
  761. /* compute its Markowitz cost */
  762. cost = (double)(min_len - 1) * (double)(len - 1);
  763. /* choose between the minimal element and the current
  764. candidate */
  765. if (cost < best) p = min_p, q = min_q, best = cost;
  766. /* if piv_lim candidates have been considered, there are
  767. doubts that a much better candidate exists; therefore
  768. it's time to terminate the search */
  769. if (ncand == piv_lim) goto done;
  770. }
  771. else
  772. { /* the j-th column has no elements, which satisfy to the
  773. stability condition; Uwe Suhl suggests to exclude such
  774. column from the further consideration until it becomes
  775. a column singleton; in hard cases this significantly
  776. reduces a time needed for pivot searching */
  777. if (suhl)
  778. { /* remove the j-th column from the active set */
  779. if (cs_prev[j] == 0)
  780. cs_head[len] = cs_next[j];
  781. else
  782. cs_next[cs_prev[j]] = cs_next[j];
  783. if (cs_next[j] == 0)
  784. /* nop */;
  785. else
  786. cs_prev[cs_next[j]] = cs_prev[j];
  787. /* the following assignment is used to avoid an error
  788. when the routine eliminate (see below) will try to
  789. remove the j-th column from the active set */
  790. cs_prev[j] = cs_next[j] = j;
  791. }
  792. }
  793. }
  794. /* consider active rows that have len non-zeros */
  795. for (i = rs_head[len]; i != 0; i = rs_next[i])
  796. { /* the i-th row has len non-zeros */
  797. i_beg = vr_ptr[i];
  798. i_end = i_beg + vr_len[i] - 1;
  799. /* determine the largest of absolute values of elements in
  800. the i-th row */
  801. big = vr_max[i];
  802. if (big < 0.0)
  803. { /* the largest value is unknown yet; compute it */
  804. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  805. { temp = sv_val[i_ptr];
  806. if (temp < 0.0) temp = - temp;
  807. if (big < temp) big = temp;
  808. }
  809. vr_max[i] = big;
  810. }
  811. /* find an element in the i-th row, which is placed in a
  812. column with minimal number of non-zeros and satisfies to
  813. the stability condition (such element always exists) */
  814. min_p = min_q = 0, min_len = INT_MAX;
  815. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  816. { /* get column index of v[i,j] */
  817. j = sv_ind[i_ptr];
  818. /* if the j-th column is not shorter than that one, where
  819. minimal element is currently placed, skip v[i,j] */
  820. if (vc_len[j] >= min_len) continue;
  821. /* if v[i,j] doesn't satisfy to the stability condition,
  822. skip it */
  823. temp = sv_val[i_ptr];
  824. if (temp < 0.0) temp = - temp;
  825. if (temp < piv_tol * big) continue;
  826. /* v[i,j] is better than the current minimal element */
  827. min_p = i, min_q = j, min_len = vc_len[j];
  828. /* if Markowitz cost of the current minimal element is
  829. not greater than (len-1)**2, it can be chosen right
  830. now; this heuristic reduces the search and works well
  831. in many cases */
  832. if (min_len <= len)
  833. { p = min_p, q = min_q;
  834. goto done;
  835. }
  836. }
  837. /* the i-th row has been scanned */
  838. if (min_p != 0)
  839. { /* the minimal element is a next pivot candidate */
  840. ncand++;
  841. /* compute its Markowitz cost */
  842. cost = (double)(len - 1) * (double)(min_len - 1);
  843. /* choose between the minimal element and the current
  844. candidate */
  845. if (cost < best) p = min_p, q = min_q, best = cost;
  846. /* if piv_lim candidates have been considered, there are
  847. doubts that a much better candidate exists; therefore
  848. it's time to terminate the search */
  849. if (ncand == piv_lim) goto done;
  850. }
  851. else
  852. { /* this can't be because this can never be */
  853. xassert(min_p != min_p);
  854. }
  855. }
  856. }
  857. done: /* bring the pivot to the factorizing routine */
  858. *_p = p, *_q = q;
  859. return (p == 0);
  860. }
  861. /***********************************************************************
  862. * eliminate - perform gaussian elimination.
  863. *
  864. * This routine performs elementary gaussian transformations in order
  865. * to eliminate subdiagonal elements in the k-th column of the matrix
  866. * U = P*V*Q using the pivot element u[k,k], where k is the number of
  867. * the current elimination step.
  868. *
  869. * The parameters p and q are, respectively, row and column indices of
  870. * the element v[p,q], which corresponds to the element u[k,k].
  871. *
  872. * Each time when the routine applies the elementary transformation to
  873. * a non-pivot row of the matrix V, it stores the corresponding element
  874. * to the matrix F in order to keep the main equality A = F*V.
  875. *
  876. * The routine assumes that on entry the matrices L = P*F*inv(P) and
  877. * U = P*V*Q are the following:
  878. *
  879. * 1 k 1 k n
  880. * 1 1 . . . . . . . . . 1 x x x x x x x x x x
  881. * x 1 . . . . . . . . . x x x x x x x x x
  882. * x x 1 . . . . . . . . . x x x x x x x x
  883. * x x x 1 . . . . . . . . . x x x x x x x
  884. * k x x x x 1 . . . . . k . . . . * * * * * *
  885. * x x x x _ 1 . . . . . . . . # * * * * *
  886. * x x x x _ . 1 . . . . . . . # * * * * *
  887. * x x x x _ . . 1 . . . . . . # * * * * *
  888. * x x x x _ . . . 1 . . . . . # * * * * *
  889. * n x x x x _ . . . . 1 n . . . . # * * * * *
  890. *
  891. * matrix L matrix U
  892. *
  893. * where rows and columns of the matrix U with numbers k, k+1, ..., n
  894. * form the active submatrix (eliminated elements are marked by '#' and
  895. * other elements of the active submatrix are marked by '*'). Note that
  896. * each eliminated non-zero element u[i,k] of the matrix U gives the
  897. * corresponding element l[i,k] of the matrix L (marked by '_').
  898. *
  899. * Actually all operations are performed on the matrix V. Should note
  900. * that the row-wise representation corresponds to the matrix V, but the
  901. * column-wise representation corresponds to the active submatrix of the
  902. * matrix V, i.e. elements of the matrix V, which doesn't belong to the
  903. * active submatrix, are missing from the column linked lists.
  904. *
  905. * Let u[k,k] = v[p,q] be the pivot. In order to eliminate subdiagonal
  906. * elements u[i',k] = v[i,q], i' = k+1, k+2, ..., n, the routine applies
  907. * the following elementary gaussian transformations:
  908. *
  909. * (i-th row of V) := (i-th row of V) - f[i,p] * (p-th row of V),
  910. *
  911. * where f[i,p] = v[i,q] / v[p,q] is a gaussian multiplier.
  912. *
  913. * Additionally, in order to keep the main equality A = F*V, each time
  914. * when the routine applies the transformation to i-th row of the matrix
  915. * V, it also adds f[i,p] as a new element to the matrix F.
  916. *
  917. * IMPORTANT: On entry the working arrays flag and work should contain
  918. * zeros. This status is provided by the routine on exit.
  919. *
  920. * If no error occured, the routine returns zero. Otherwise, in case of
  921. * overflow of the sparse vector area, the routine returns non-zero. */
  922. static int eliminate(LUF *luf, int p, int q)
  923. { int n = luf->n;
  924. int *fc_ptr = luf->fc_ptr;
  925. int *fc_len = luf->fc_len;
  926. int *vr_ptr = luf->vr_ptr;
  927. int *vr_len = luf->vr_len;
  928. int *vr_cap = luf->vr_cap;
  929. double *vr_piv = luf->vr_piv;
  930. int *vc_ptr = luf->vc_ptr;
  931. int *vc_len = luf->vc_len;
  932. int *vc_cap = luf->vc_cap;
  933. int *sv_ind = luf->sv_ind;
  934. double *sv_val = luf->sv_val;
  935. int *sv_prev = luf->sv_prev;
  936. int *sv_next = luf->sv_next;
  937. double *vr_max = luf->vr_max;
  938. int *rs_head = luf->rs_head;
  939. int *rs_prev = luf->rs_prev;
  940. int *rs_next = luf->rs_next;
  941. int *cs_head = luf->cs_head;
  942. int *cs_prev = luf->cs_prev;
  943. int *cs_next = luf->cs_next;
  944. int *flag = luf->flag;
  945. double *work = luf->work;
  946. double eps_tol = luf->eps_tol;
  947. /* at this stage the row-wise representation of the matrix F is
  948. not used, so fr_len can be used as a working array */
  949. int *ndx = luf->fr_len;
  950. int ret = 0;
  951. int len, fill, i, i_beg, i_end, i_ptr, j, j_beg, j_end, j_ptr, k,
  952. p_beg, p_end, p_ptr, q_beg, q_end, q_ptr;
  953. double fip, val, vpq, temp;
  954. xassert(1 <= p && p <= n);
  955. xassert(1 <= q && q <= n);
  956. /* remove the p-th (pivot) row from the active set; this row will
  957. never return there */
  958. if (rs_prev[p] == 0)
  959. rs_head[vr_len[p]] = rs_next[p];
  960. else
  961. rs_next[rs_prev[p]] = rs_next[p];
  962. if (rs_next[p] == 0)
  963. ;
  964. else
  965. rs_prev[rs_next[p]] = rs_prev[p];
  966. /* remove the q-th (pivot) column from the active set; this column
  967. will never return there */
  968. if (cs_prev[q] == 0)
  969. cs_head[vc_len[q]] = cs_next[q];
  970. else
  971. cs_next[cs_prev[q]] = cs_next[q];
  972. if (cs_next[q] == 0)
  973. ;
  974. else
  975. cs_prev[cs_next[q]] = cs_prev[q];
  976. /* find the pivot v[p,q] = u[k,k] in the p-th row */
  977. p_beg = vr_ptr[p];
  978. p_end = p_beg + vr_len[p] - 1;
  979. for (p_ptr = p_beg; sv_ind[p_ptr] != q; p_ptr++) /* nop */;
  980. xassert(p_ptr <= p_end);
  981. /* store value of the pivot */
  982. vpq = (vr_piv[p] = sv_val[p_ptr]);
  983. /* remove the pivot from the p-th row */
  984. sv_ind[p_ptr] = sv_ind[p_end];
  985. sv_val[p_ptr] = sv_val[p_end];
  986. vr_len[p]--;
  987. p_end--;
  988. /* find the pivot v[p,q] = u[k,k] in the q-th column */
  989. q_beg = vc_ptr[q];
  990. q_end = q_beg + vc_len[q] - 1;
  991. for (q_ptr = q_beg; sv_ind[q_ptr] != p; q_ptr++) /* nop */;
  992. xassert(q_ptr <= q_end);
  993. /* remove the pivot from the q-th column */
  994. sv_ind[q_ptr] = sv_ind[q_end];
  995. vc_len[q]--;
  996. q_end--;
  997. /* walk through the p-th (pivot) row, which doesn't contain the
  998. pivot v[p,q] already, and do the following... */
  999. for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++)
  1000. { /* get column index of v[p,j] */
  1001. j = sv_ind[p_ptr];
  1002. /* store v[p,j] to the working array */
  1003. flag[j] = 1;
  1004. work[j] = sv_val[p_ptr];
  1005. /* remove the j-th column from the active set; this column will
  1006. return there later with new length */
  1007. if (cs_prev[j] == 0)
  1008. cs_head[vc_len[j]] = cs_next[j];
  1009. else
  1010. cs_next[cs_prev[j]] = cs_next[j];
  1011. if (cs_next[j] == 0)
  1012. ;
  1013. else
  1014. cs_prev[cs_next[j]] = cs_prev[j];
  1015. /* find v[p,j] in the j-th column */
  1016. j_beg = vc_ptr[j];
  1017. j_end = j_beg + vc_len[j] - 1;
  1018. for (j_ptr = j_beg; sv_ind[j_ptr] != p; j_ptr++) /* nop */;
  1019. xassert(j_ptr <= j_end);
  1020. /* since v[p,j] leaves the active submatrix, remove it from the
  1021. j-th column; however, v[p,j] is kept in the p-th row */
  1022. sv_ind[j_ptr] = sv_ind[j_end];
  1023. vc_len[j]--;
  1024. }
  1025. /* walk through the q-th (pivot) column, which doesn't contain the
  1026. pivot v[p,q] already, and perform gaussian elimination */
  1027. while (q_beg <= q_end)
  1028. { /* element v[i,q] should be eliminated */
  1029. /* get row index of v[i,q] */
  1030. i = sv_ind[q_beg];
  1031. /* remove the i-th row from the active set; later this row will
  1032. return there with new length */
  1033. if (rs_prev[i] == 0)
  1034. rs_head[vr_len[i]] = rs_next[i];
  1035. else
  1036. rs_next[rs_prev[i]] = rs_next[i];
  1037. if (rs_next[i] == 0)
  1038. ;
  1039. else
  1040. rs_prev[rs_next[i]] = rs_prev[i];
  1041. /* find v[i,q] in the i-th row */
  1042. i_beg = vr_ptr[i];
  1043. i_end = i_beg + vr_len[i] - 1;
  1044. for (i_ptr = i_beg; sv_ind[i_ptr] != q; i_ptr++) /* nop */;
  1045. xassert(i_ptr <= i_end);
  1046. /* compute gaussian multiplier f[i,p] = v[i,q] / v[p,q] */
  1047. fip = sv_val[i_ptr] / vpq;
  1048. /* since v[i,q] should be eliminated, remove it from the i-th
  1049. row */
  1050. sv_ind[i_ptr] = sv_ind[i_end];
  1051. sv_val[i_ptr] = sv_val[i_end];
  1052. vr_len[i]--;
  1053. i_end--;
  1054. /* and from the q-th column */
  1055. sv_ind[q_beg] = sv_ind[q_end];
  1056. vc_len[q]--;
  1057. q_end--;
  1058. /* perform gaussian transformation:
  1059. (i-th row) := (i-th row) - f[i,p] * (p-th row)
  1060. note that now the p-th row, which is in the working array,
  1061. doesn't contain the pivot v[p,q], and the i-th row doesn't
  1062. contain the eliminated element v[i,q] */
  1063. /* walk through the i-th row and transform existing non-zero
  1064. elements */
  1065. fill = vr_len[p];
  1066. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  1067. { /* get column index of v[i,j] */
  1068. j = sv_ind[i_ptr];
  1069. /* v[i,j] := v[i,j] - f[i,p] * v[p,j] */
  1070. if (flag[j])
  1071. { /* v[p,j] != 0 */
  1072. temp = (sv_val[i_ptr] -= fip * work[j]);
  1073. if (temp < 0.0) temp = - temp;
  1074. flag[j] = 0;
  1075. fill--; /* since both v[i,j] and v[p,j] exist */
  1076. if (temp == 0.0 || temp < eps_tol)
  1077. { /* new v[i,j] is closer to zero; replace it by exact
  1078. zero, i.e. remove it from the active submatrix */
  1079. /* remove v[i,j] from the i-th row */
  1080. sv_ind[i_ptr] = sv_ind[i_end];
  1081. sv_val[i_ptr] = sv_val[i_end];
  1082. vr_len[i]--;
  1083. i_ptr--;
  1084. i_end--;
  1085. /* find v[i,j] in the j-th column */
  1086. j_beg = vc_ptr[j];
  1087. j_end = j_beg + vc_len[j] - 1;
  1088. for (j_ptr = j_beg; sv_ind[j_ptr] != i; j_ptr++);
  1089. xassert(j_ptr <= j_end);
  1090. /* remove v[i,j] from the j-th column */
  1091. sv_ind[j_ptr] = sv_ind[j_end];
  1092. vc_len[j]--;
  1093. }
  1094. else
  1095. { /* v_big := max(v_big, |v[i,j]|) */
  1096. if (luf->big_v < temp) luf->big_v = temp;
  1097. }
  1098. }
  1099. }
  1100. /* now flag is the pattern of the set v[p,*] \ v[i,*], and fill
  1101. is number of non-zeros in this set; therefore up to fill new
  1102. non-zeros may appear in the i-th row */
  1103. if (vr_len[i] + fill > vr_cap[i])
  1104. { /* enlarge the i-th row */
  1105. if (luf_enlarge_row(luf, i, vr_len[i] + fill))
  1106. { /* overflow of the sparse vector area */
  1107. ret = 1;
  1108. goto done;
  1109. }
  1110. /* defragmentation may change row and column pointers of the
  1111. matrix V */
  1112. p_beg = vr_ptr[p];
  1113. p_end = p_beg + vr_len[p] - 1;
  1114. q_beg = vc_ptr[q];
  1115. q_end = q_beg + vc_len[q] - 1;
  1116. }
  1117. /* walk through the p-th (pivot) row and create new elements
  1118. of the i-th row that appear due to fill-in; column indices
  1119. of these new elements are accumulated in the array ndx */
  1120. len = 0;
  1121. for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++)
  1122. { /* get column index of v[p,j], which may cause fill-in */
  1123. j = sv_ind[p_ptr];
  1124. if (flag[j])
  1125. { /* compute new non-zero v[i,j] = 0 - f[i,p] * v[p,j] */
  1126. temp = (val = - fip * work[j]);
  1127. if (temp < 0.0) temp = - temp;
  1128. if (temp == 0.0 || temp < eps_tol)
  1129. /* if v[i,j] is closer to zero; just ignore it */;
  1130. else
  1131. { /* add v[i,j] to the i-th row */
  1132. i_ptr = vr_ptr[i] + vr_len[i];
  1133. sv_ind[i_ptr] = j;
  1134. sv_val[i_ptr] = val;
  1135. vr_len[i]++;
  1136. /* remember column index of v[i,j] */
  1137. ndx[++len] = j;
  1138. /* big_v := max(big_v, |v[i,j]|) */
  1139. if (luf->big_v < temp) luf->big_v = temp;
  1140. }
  1141. }
  1142. else
  1143. { /* there is no fill-in, because v[i,j] already exists in
  1144. the i-th row; restore the flag of the element v[p,j],
  1145. which was reset before */
  1146. flag[j] = 1;
  1147. }
  1148. }
  1149. /* add new non-zeros v[i,j] to the corresponding columns */
  1150. for (k = 1; k <= len; k++)
  1151. { /* get column index of new non-zero v[i,j] */
  1152. j = ndx[k];
  1153. /* one free location is needed in the j-th column */
  1154. if (vc_len[j] + 1 > vc_cap[j])
  1155. { /* enlarge the j-th column */
  1156. if (luf_enlarge_col(luf, j, vc_len[j] + 10))
  1157. { /* overflow of the sparse vector area */
  1158. ret = 1;
  1159. goto done;
  1160. }
  1161. /* defragmentation may change row and column pointers of
  1162. the matrix V */
  1163. p_beg = vr_ptr[p];
  1164. p_end = p_beg + vr_len[p] - 1;
  1165. q_beg = vc_ptr[q];
  1166. q_end = q_beg + vc_len[q] - 1;
  1167. }
  1168. /* add new non-zero v[i,j] to the j-th column */
  1169. j_ptr = vc_ptr[j] + vc_len[j];
  1170. sv_ind[j_ptr] = i;
  1171. vc_len[j]++;
  1172. }
  1173. /* now the i-th row has been completely transformed, therefore
  1174. it can return to the active set with new length */
  1175. rs_prev[i] = 0;
  1176. rs_next[i] = rs_head[vr_len[i]];
  1177. if (rs_next[i] != 0) rs_prev[rs_next[i]] = i;
  1178. rs_head[vr_len[i]] = i;
  1179. /* the largest of absolute values of elements in the i-th row
  1180. is currently unknown */
  1181. vr_max[i] = -1.0;
  1182. /* at least one free location is needed to store the gaussian
  1183. multiplier */
  1184. if (luf->sv_end - luf->sv_beg < 1)
  1185. { /* there are no free locations at all; defragment SVA */
  1186. luf_defrag_sva(luf);
  1187. if (luf->sv_end - luf->sv_beg < 1)
  1188. { /* overflow of the sparse vector area */
  1189. ret = 1;
  1190. goto done;
  1191. }
  1192. /* defragmentation may change row and column pointers of the
  1193. matrix V */
  1194. p_beg = vr_ptr[p];
  1195. p_end = p_beg + vr_len[p] - 1;
  1196. q_beg = vc_ptr[q];
  1197. q_end = q_beg + vc_len[q] - 1;
  1198. }
  1199. /* add the element f[i,p], which is the gaussian multiplier,
  1200. to the matrix F */
  1201. luf->sv_end--;
  1202. sv_ind[luf->sv_end] = i;
  1203. sv_val[luf->sv_end] = fip;
  1204. fc_len[p]++;
  1205. /* end of elimination loop */
  1206. }
  1207. /* at this point the q-th (pivot) column should be empty */
  1208. xassert(vc_len[q] == 0);
  1209. /* reset capacity of the q-th column */
  1210. vc_cap[q] = 0;
  1211. /* remove node of the q-th column from the addressing list */
  1212. k = n + q;
  1213. if (sv_prev[k] == 0)
  1214. luf->sv_head = sv_next[k];
  1215. else
  1216. sv_next[sv_prev[k]] = sv_next[k];
  1217. if (sv_next[k] == 0)
  1218. luf->sv_tail = sv_prev[k];
  1219. else
  1220. sv_prev[sv_next[k]] = sv_prev[k];
  1221. /* the p-th column of the matrix F has been completely built; set
  1222. its pointer */
  1223. fc_ptr[p] = luf->sv_end;
  1224. /* walk through the p-th (pivot) row and do the following... */
  1225. for (p_ptr = p_beg; p_ptr <= p_end; p_ptr++)
  1226. { /* get column index of v[p,j] */
  1227. j = sv_ind[p_ptr];
  1228. /* erase v[p,j] from the working array */
  1229. flag[j] = 0;
  1230. work[j] = 0.0;
  1231. /* the j-th column has been completely transformed, therefore
  1232. it can return to the active set with new length; however
  1233. the special case c_prev[j] = c_next[j] = j means that the
  1234. routine find_pivot excluded the j-th column from the active
  1235. set due to Uwe Suhl's rule, and therefore in this case the
  1236. column can return to the active set only if it is a column
  1237. singleton */
  1238. if (!(vc_len[j] != 1 && cs_prev[j] == j && cs_next[j] == j))
  1239. { cs_prev[j] = 0;
  1240. cs_next[j] = cs_head[vc_len[j]];
  1241. if (cs_next[j] != 0) cs_prev[cs_next[j]] = j;
  1242. cs_head[vc_len[j]] = j;
  1243. }
  1244. }
  1245. done: /* return to the factorizing routine */
  1246. return ret;
  1247. }
  1248. /***********************************************************************
  1249. * build_v_cols - build the matrix V in column-wise format
  1250. *
  1251. * This routine builds the column-wise representation of the matrix V
  1252. * using its row-wise representation.
  1253. *
  1254. * If no error occured, the routine returns zero. Otherwise, in case of
  1255. * overflow of the sparse vector area, the routine returns non-zero. */
  1256. static int build_v_cols(LUF *luf)
  1257. { int n = luf->n;
  1258. int *vr_ptr = luf->vr_ptr;
  1259. int *vr_len = luf->vr_len;
  1260. int *vc_ptr = luf->vc_ptr;
  1261. int *vc_len = luf->vc_len;
  1262. int *vc_cap = luf->vc_cap;
  1263. int *sv_ind = luf->sv_ind;
  1264. double *sv_val = luf->sv_val;
  1265. int *sv_prev = luf->sv_prev;
  1266. int *sv_next = luf->sv_next;
  1267. int ret = 0;
  1268. int i, i_beg, i_end, i_ptr, j, j_ptr, k, nnz;
  1269. /* it is assumed that on entry all columns of the matrix V are
  1270. empty, i.e. vc_len[j] = vc_cap[j] = 0 for all j = 1, ..., n,
  1271. and have been removed from the addressing list */
  1272. /* count non-zeros in columns of the matrix V; count total number
  1273. of non-zeros in this matrix */
  1274. nnz = 0;
  1275. for (i = 1; i <= n; i++)
  1276. { /* walk through elements of the i-th row and count non-zeros
  1277. in the corresponding columns */
  1278. i_beg = vr_ptr[i];
  1279. i_end = i_beg + vr_len[i] - 1;
  1280. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  1281. vc_cap[sv_ind[i_ptr]]++;
  1282. /* count total number of non-zeros */
  1283. nnz += vr_len[i];
  1284. }
  1285. /* store total number of non-zeros */
  1286. luf->nnz_v = nnz;
  1287. /* check for free locations */
  1288. if (luf->sv_end - luf->sv_beg < nnz)
  1289. { /* overflow of the sparse vector area */
  1290. ret = 1;
  1291. goto done;
  1292. }
  1293. /* allocate columns of the matrix V */
  1294. for (j = 1; j <= n; j++)
  1295. { /* set pointer to the j-th column */
  1296. vc_ptr[j] = luf->sv_beg;
  1297. /* reserve locations for the j-th column */
  1298. luf->sv_beg += vc_cap[j];
  1299. }
  1300. /* build the matrix V in column-wise format using this matrix in
  1301. row-wise format */
  1302. for (i = 1; i <= n; i++)
  1303. { /* walk through elements of the i-th row */
  1304. i_beg = vr_ptr[i];
  1305. i_end = i_beg + vr_len[i] - 1;
  1306. for (i_ptr = i_beg; i_ptr <= i_end; i_ptr++)
  1307. { /* get column index */
  1308. j = sv_ind[i_ptr];
  1309. /* store element in the j-th column */
  1310. j_ptr = vc_ptr[j] + vc_len[j];
  1311. sv_ind[j_ptr] = i;
  1312. sv_val[j_ptr] = sv_val[i_ptr];
  1313. /* increase length of the j-th column */
  1314. vc_len[j]++;
  1315. }
  1316. }
  1317. /* now columns are placed in the sparse vector area behind rows
  1318. in the order n+1, n+2, ..., n+n; so insert column nodes in the
  1319. addressing list using this order */
  1320. for (k = n+1; k <= n+n; k++)
  1321. { sv_prev[k] = k-1;
  1322. sv_next[k] = k+1;
  1323. }
  1324. sv_prev[n+1] = luf->sv_tail;
  1325. sv_next[luf->sv_tail] = n+1;
  1326. sv_next[n+n] = 0;
  1327. luf->sv_tail = n+n;
  1328. done: /* return to the factorizing routine */
  1329. return ret;
  1330. }
  1331. /***********************************************************************
  1332. * build_f_rows - build the matrix F in row-wise format
  1333. *
  1334. * This routine builds the row-wise representation of the matrix F using
  1335. * its column-wise representation.
  1336. *
  1337. * If no error occured, the routine returns zero. Otherwise, in case of
  1338. * overflow of the sparse vector area, the routine returns non-zero. */
  1339. static int build_f_rows(LUF *luf)
  1340. { int n = luf->n;
  1341. int *fr_ptr = luf->fr_ptr;
  1342. int *fr_len = luf->fr_len;
  1343. int *fc_ptr = luf->fc_ptr;
  1344. int *fc_len = luf->fc_len;
  1345. int *sv_ind = luf->sv_ind;
  1346. double *sv_val = luf->sv_val;
  1347. int ret = 0;
  1348. int i, j, j_beg, j_end, j_ptr, ptr, nnz;
  1349. /* clear rows of the matrix F */
  1350. for (i = 1; i <= n; i++) fr_len[i] = 0;
  1351. /* count non-zeros in rows of the matrix F; count total number of
  1352. non-zeros in this matrix */
  1353. nnz = 0;
  1354. for (j = 1; j <= n; j++)
  1355. { /* walk through elements of the j-th column and count non-zeros
  1356. in the corresponding rows */
  1357. j_beg = fc_ptr[j];
  1358. j_end = j_beg + fc_len[j] - 1;
  1359. for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++)
  1360. fr_len[sv_ind[j_ptr]]++;
  1361. /* increase total number of non-zeros */
  1362. nnz += fc_len[j];
  1363. }
  1364. /* store total number of non-zeros */
  1365. luf->nnz_f = nnz;
  1366. /* check for free locations */
  1367. if (luf->sv_end - luf->sv_beg < nnz)
  1368. { /* overflow of the sparse vector area */
  1369. ret = 1;
  1370. goto done;
  1371. }
  1372. /* allocate rows of the matrix F */
  1373. for (i = 1; i <= n; i++)
  1374. { /* set pointer to the end of the i-th row; later this pointer
  1375. will be set to the beginning of the i-th row */
  1376. fr_ptr[i] = luf->sv_end;
  1377. /* reserve locations for the i-th row */
  1378. luf->sv_end -= fr_len[i];
  1379. }
  1380. /* build the matrix F in row-wise format using this matrix in
  1381. column-wise format */
  1382. for (j = 1; j <= n; j++)
  1383. { /* walk through elements of the j-th column */
  1384. j_beg = fc_ptr[j];
  1385. j_end = j_beg + fc_len[j] - 1;
  1386. for (j_ptr = j_beg; j_ptr <= j_end; j_ptr++)
  1387. { /* get row index */
  1388. i = sv_ind[j_ptr];
  1389. /* store element in the i-th row */
  1390. ptr = --fr_ptr[i];
  1391. sv_ind[ptr] = j;
  1392. sv_val[ptr] = sv_val[j_ptr];
  1393. }
  1394. }
  1395. done: /* return to the factorizing routine */
  1396. return ret;
  1397. }
  1398. /***********************************************************************
  1399. * NAME
  1400. *
  1401. * luf_factorize - compute LU-factorization
  1402. *
  1403. * SYNOPSIS
  1404. *
  1405. * #include "glpluf.h"
  1406. * int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j,
  1407. * int ind[], double val[]), void *info);
  1408. *
  1409. * DESCRIPTION
  1410. *
  1411. * The routine luf_factorize computes LU-factorization of a specified
  1412. * square matrix A.
  1413. *
  1414. * The parameter luf specifies LU-factorization program object created
  1415. * by the routine luf_create_it.
  1416. *
  1417. * The parameter n specifies the order of A, n > 0.
  1418. *
  1419. * The formal routine col specifies the matrix A to be factorized. To
  1420. * obtain j-th column of A the routine luf_factorize calls the routine
  1421. * col with the parameter j (1 <= j <= n). In response the routine col
  1422. * should store row indices and numerical values of non-zero elements
  1423. * of j-th column of A to locations ind[1,...,len] and val[1,...,len],
  1424. * respectively, where len is the number of non-zeros in j-th column
  1425. * returned on exit. Neither zero nor duplicate elements are allowed.
  1426. *
  1427. * The parameter info is a transit pointer passed to the routine col.
  1428. *
  1429. * RETURNS
  1430. *
  1431. * 0 LU-factorization has been successfully computed.
  1432. *
  1433. * LUF_ESING
  1434. * The specified matrix is singular within the working precision.
  1435. * (On some elimination step the active submatrix is exactly zero,
  1436. * so no pivot can be chosen.)
  1437. *
  1438. * LUF_ECOND
  1439. * The specified matrix is ill-conditioned.
  1440. * (On some elimination step too intensive growth of elements of the
  1441. * active submatix has been detected.)
  1442. *
  1443. * If matrix A is well scaled, the return code LUF_ECOND may also mean
  1444. * that the threshold pivoting tolerance piv_tol should be increased.
  1445. *
  1446. * In case of non-zero return code the factorization becomes invalid.
  1447. * It should not be used in other operations until the cause of failure
  1448. * has been eliminated and the factorization has been recomputed again
  1449. * with the routine luf_factorize.
  1450. *
  1451. * REPAIRING SINGULAR MATRIX
  1452. *
  1453. * If the routine luf_factorize returns non-zero code, it provides all
  1454. * necessary information that can be used for "repairing" the matrix A,
  1455. * where "repairing" means replacing linearly dependent columns of the
  1456. * matrix A by appropriate columns of the unity matrix. This feature is
  1457. * needed when this routine is used for factorizing the basis matrix
  1458. * within the simplex method procedure.
  1459. *
  1460. * On exit linearly dependent columns of the (partially transformed)
  1461. * matrix U have numbers rank+1, rank+2, ..., n, where rank is estimated
  1462. * rank of the matrix A stored by the routine to the member luf->rank.
  1463. * The correspondence between columns of A and U is the same as between
  1464. * columns of V and U. Thus, linearly dependent columns of the matrix A
  1465. * have numbers qq_col[rank+1], qq_col[rank+2], ..., qq_col[n], where
  1466. * qq_col is the column-like representation of the permutation matrix Q.
  1467. * It is understood that each j-th linearly dependent column of the
  1468. * matrix U should be replaced by the unity vector, where all elements
  1469. * are zero except the unity diagonal element u[j,j]. On the other hand
  1470. * j-th row of the matrix U corresponds to the row of the matrix V (and
  1471. * therefore of the matrix A) with the number pp_row[j], where pp_row is
  1472. * the row-like representation of the permutation matrix P. Thus, each
  1473. * j-th linearly dependent column of the matrix U should be replaced by
  1474. * column of the unity matrix with the number pp_row[j].
  1475. *
  1476. * The code that repairs the matrix A may look like follows:
  1477. *
  1478. * for (j = rank+1; j <= n; j++)
  1479. * { replace the column qq_col[j] of the matrix A by the column
  1480. * pp_row[j] of the unity matrix;
  1481. * }
  1482. *
  1483. * where rank, pp_row, and qq_col are members of the structure LUF. */
  1484. int luf_factorize(LUF *luf, int n, int (*col)(void *info, int j,
  1485. int ind[], double val[]), void *info)
  1486. { int *pp_row, *pp_col, *qq_row, *qq_col;
  1487. double max_gro = luf->max_gro;
  1488. int i, j, k, p, q, t, ret;
  1489. if (n < 1)
  1490. xfault("luf_factorize: n = %d; invalid parameter\n", n);
  1491. if (n > N_MAX)
  1492. xfault("luf_factorize: n = %d; matrix too big\n", n);
  1493. /* invalidate the factorization */
  1494. luf->valid = 0;
  1495. /* reallocate arrays, if necessary */
  1496. reallocate(luf, n);
  1497. pp_row = luf->pp_row;
  1498. pp_col = luf->pp_col;
  1499. qq_row = luf->qq_row;
  1500. qq_col = luf->qq_col;
  1501. /* estimate initial size of the SVA, if not specified */
  1502. if (luf->sv_size == 0 && luf->new_sva == 0)
  1503. luf->new_sva = 5 * (n + 10);
  1504. more: /* reallocate the sparse vector area, if required */
  1505. if (luf->new_sva > 0)
  1506. { if (luf->sv_ind != NULL) xfree(luf->sv_ind);
  1507. if (luf->sv_val != NULL) xfree(luf->sv_val);
  1508. luf->sv_size = luf->new_sva;
  1509. luf->sv_ind = xcalloc(1+luf->sv_size, sizeof(int));
  1510. luf->sv_val = xcalloc(1+luf->sv_size, sizeof(double));
  1511. luf->new_sva = 0;
  1512. }
  1513. /* initialize LU-factorization data structures */
  1514. if (initialize(luf, col, info))
  1515. { /* overflow of the sparse vector area */
  1516. luf->new_sva = luf->sv_size + luf->sv_size;
  1517. xassert(luf->new_sva > luf->sv_size);
  1518. goto more;
  1519. }
  1520. /* main elimination loop */
  1521. for (k = 1; k <= n; k++)
  1522. { /* choose a pivot element v[p,q] */
  1523. if (find_pivot(luf, &p, &q))
  1524. { /* no pivot can be chosen, because the active submatrix is
  1525. exactly zero */
  1526. luf->rank = k - 1;
  1527. ret = LUF_ESING;
  1528. goto done;
  1529. }
  1530. /* let v[p,q] correspond to u[i',j']; permute k-th and i'-th
  1531. rows and k-th and j'-th columns of the matrix U = P*V*Q to
  1532. move the element u[i',j'] to the position u[k,k] */
  1533. i = pp_col[p], j = qq_row[q];
  1534. xassert(k <= i && i <= n && k <= j && j <= n);
  1535. /* permute k-th and i-th rows of the matrix U */
  1536. t = pp_row[k];
  1537. pp_row[i] = t, pp_col[t] = i;
  1538. pp_row[k] = p, pp_col[p] = k;
  1539. /* permute k-th and j-th columns of the matrix U */
  1540. t = qq_col[k];
  1541. qq_col[j] = t, qq_row[t] = j;
  1542. qq_col[k] = q, qq_row[q] = k;
  1543. /* eliminate subdiagonal elements of k-th column of the matrix
  1544. U = P*V*Q using the pivot element u[k,k] = v[p,q] */
  1545. if (eliminate(luf, p, q))
  1546. { /* overflow of the sparse vector area */
  1547. luf->new_sva = luf->sv_size + luf->sv_size;
  1548. xassert(luf->new_sva > luf->sv_size);
  1549. goto more;
  1550. }
  1551. /* check relative growth of elements of the matrix V */
  1552. if (luf->big_v > max_gro * luf->max_a)
  1553. { /* the growth is too intensive, therefore most probably the
  1554. matrix A is ill-conditioned */
  1555. luf->rank = k - 1;
  1556. ret = LUF_ECOND;
  1557. goto done;
  1558. }
  1559. }
  1560. /* now the matrix U = P*V*Q is upper triangular, the matrix V has
  1561. been built in row-wise format, and the matrix F has been built
  1562. in column-wise format */
  1563. /* defragment the sparse vector area in order to merge all free
  1564. locations in one continuous extent */
  1565. luf_defrag_sva(luf);
  1566. /* build the matrix V in column-wise format */
  1567. if (build_v_cols(luf))
  1568. { /* overflow of the sparse vector area */
  1569. luf->new_sva = luf->sv_size + luf->sv_size;
  1570. xassert(luf->new_sva > luf->sv_size);
  1571. goto more;
  1572. }
  1573. /* build the matrix F in row-wise format */
  1574. if (build_f_rows(luf))
  1575. { /* overflow of the sparse vector area */
  1576. luf->new_sva = luf->sv_size + luf->sv_size;
  1577. xassert(luf->new_sva > luf->sv_size);
  1578. goto more;
  1579. }
  1580. /* the LU-factorization has been successfully computed */
  1581. luf->valid = 1;
  1582. luf->rank = n;
  1583. ret = 0;
  1584. /* if there are few free locations in the sparse vector area, try
  1585. increasing its size in the future */
  1586. t = 3 * (n + luf->nnz_v) + 2 * luf->nnz_f;
  1587. if (luf->sv_size < t)
  1588. { luf->new_sva = luf->sv_size;
  1589. while (luf->new_sva < t)
  1590. { k = luf->new_sva;
  1591. luf->new_sva = k + k;
  1592. xassert(luf->new_sva > k);
  1593. }
  1594. }
  1595. done: /* return to the calling program */
  1596. return ret;
  1597. }
  1598. /***********************************************************************
  1599. * NAME
  1600. *
  1601. * luf_f_solve - solve system F*x = b or F'*x = b
  1602. *
  1603. * SYNOPSIS
  1604. *
  1605. * #include "glpluf.h"
  1606. * void luf_f_solve(LUF *luf, int tr, double x[]);
  1607. *
  1608. * DESCRIPTION
  1609. *
  1610. * The routine luf_f_solve solves either the system F*x = b (if the
  1611. * flag tr is zero) or the system F'*x = b (if the flag tr is non-zero),
  1612. * where the matrix F is a component of LU-factorization specified by
  1613. * the parameter luf, F' is a matrix transposed to F.
  1614. *
  1615. * On entry the array x should contain elements of the right-hand side
  1616. * vector b in locations x[1], ..., x[n], where n is the order of the
  1617. * matrix F. On exit this array will contain elements of the solution
  1618. * vector x in the same locations. */
  1619. void luf_f_solve(LUF *luf, int tr, double x[])
  1620. { int n = luf->n;
  1621. int *fr_ptr = luf->fr_ptr;
  1622. int *fr_len = luf->fr_len;
  1623. int *fc_ptr = luf->fc_ptr;
  1624. int *fc_len = luf->fc_len;
  1625. int *pp_row = luf->pp_row;
  1626. int *sv_ind = luf->sv_ind;
  1627. double *sv_val = luf->sv_val;
  1628. int i, j, k, beg, end, ptr;
  1629. double xk;
  1630. if (!luf->valid)
  1631. xfault("luf_f_solve: LU-factorization is not valid\n");
  1632. if (!tr)
  1633. { /* solve the system F*x = b */
  1634. for (j = 1; j <= n; j++)
  1635. { k = pp_row[j];
  1636. xk = x[k];
  1637. if (xk != 0.0)
  1638. { beg = fc_ptr[k];
  1639. end = beg + fc_len[k] - 1;
  1640. for (ptr = beg; ptr <= end; ptr++)
  1641. x[sv_ind[ptr]] -= sv_val[ptr] * xk;
  1642. }
  1643. }
  1644. }
  1645. else
  1646. { /* solve the system F'*x = b */
  1647. for (i = n; i >= 1; i--)
  1648. { k = pp_row[i];
  1649. xk = x[k];
  1650. if (xk != 0.0)
  1651. { beg = fr_ptr[k];
  1652. end = beg + fr_len[k] - 1;
  1653. for (ptr = beg; ptr <= end; ptr++)
  1654. x[sv_ind[ptr]] -= sv_val[ptr] * xk;
  1655. }
  1656. }
  1657. }
  1658. return;
  1659. }
  1660. /***********************************************************************
  1661. * NAME
  1662. *
  1663. * luf_v_solve - solve system V*x = b or V'*x = b
  1664. *
  1665. * SYNOPSIS
  1666. *
  1667. * #include "glpluf.h"
  1668. * void luf_v_solve(LUF *luf, int tr, double x[]);
  1669. *
  1670. * DESCRIPTION
  1671. *
  1672. * The routine luf_v_solve solves either the system V*x = b (if the
  1673. * flag tr is zero) or the system V'*x = b (if the flag tr is non-zero),
  1674. * where the matrix V is a component of LU-factorization specified by
  1675. * the parameter luf, V' is a matrix transposed to V.
  1676. *
  1677. * On entry the array x should contain elements of the right-hand side
  1678. * vector b in locations x[1], ..., x[n], where n is the order of the
  1679. * matrix V. On exit this array will contain elements of the solution
  1680. * vector x in the same locations. */
  1681. void luf_v_solve(LUF *luf, int tr, double x[])
  1682. { int n = luf->n;
  1683. int *vr_ptr = luf->vr_ptr;
  1684. int *vr_len = luf->vr_len;
  1685. double *vr_piv = luf->vr_piv;
  1686. int *vc_ptr = luf->vc_ptr;
  1687. int *vc_len = luf->vc_len;
  1688. int *pp_row = luf->pp_row;
  1689. int *qq_col = luf->qq_col;
  1690. int *sv_ind = luf->sv_ind;
  1691. double *sv_val = luf->sv_val;
  1692. double *b = luf->work;
  1693. int i, j, k, beg, end, ptr;
  1694. double temp;
  1695. if (!luf->valid)
  1696. xfault("luf_v_solve: LU-factorization is not valid\n");
  1697. for (k = 1; k <= n; k++) b[k] = x[k], x[k] = 0.0;
  1698. if (!tr)
  1699. { /* solve the system V*x = b */
  1700. for (k = n; k >= 1; k--)
  1701. { i = pp_row[k], j = qq_col[k];
  1702. temp = b[i];
  1703. if (temp != 0.0)
  1704. { x[j] = (temp /= vr_piv[i]);
  1705. beg = vc_ptr[j];
  1706. end = beg + vc_len[j] - 1;
  1707. for (ptr = beg; ptr <= end; ptr++)
  1708. b[sv_ind[ptr]] -= sv_val[ptr] * temp;
  1709. }
  1710. }
  1711. }
  1712. else
  1713. { /* solve the system V'*x = b */
  1714. for (k = 1; k <= n; k++)
  1715. { i = pp_row[k], j = qq_col[k];
  1716. temp = b[j];
  1717. if (temp != 0.0)
  1718. { x[i] = (temp /= vr_piv[i]);
  1719. beg = vr_ptr[i];
  1720. end = beg + vr_len[i] - 1;
  1721. for (ptr = beg; ptr <= end; ptr++)
  1722. b[sv_ind[ptr]] -= sv_val[ptr] * temp;
  1723. }
  1724. }
  1725. }
  1726. return;
  1727. }
  1728. /***********************************************************************
  1729. * NAME
  1730. *
  1731. * luf_a_solve - solve system A*x = b or A'*x = b
  1732. *
  1733. * SYNOPSIS
  1734. *
  1735. * #include "glpluf.h"
  1736. * void luf_a_solve(LUF *luf, int tr, double x[]);
  1737. *
  1738. * DESCRIPTION
  1739. *
  1740. * The routine luf_a_solve solves either the system A*x = b (if the
  1741. * flag tr is zero) or the system A'*x = b (if the flag tr is non-zero),
  1742. * where the parameter luf specifies LU-factorization of the matrix A,
  1743. * A' is a matrix transposed to A.
  1744. *
  1745. * On entry the array x should contain elements of the right-hand side
  1746. * vector b in locations x[1], ..., x[n], where n is the order of the
  1747. * matrix A. On exit this array will contain elements of the solution
  1748. * vector x in the same locations. */
  1749. void luf_a_solve(LUF *luf, int tr, double x[])
  1750. { if (!luf->valid)
  1751. xfault("luf_a_solve: LU-factorization is not valid\n");
  1752. if (!tr)
  1753. { /* A = F*V, therefore inv(A) = inv(V)*inv(F) */
  1754. luf_f_solve(luf, 0, x);
  1755. luf_v_solve(luf, 0, x);
  1756. }
  1757. else
  1758. { /* A' = V'*F', therefore inv(A') = inv(F')*inv(V') */
  1759. luf_v_solve(luf, 1, x);
  1760. luf_f_solve(luf, 1, x);
  1761. }
  1762. return;
  1763. }
  1764. /***********************************************************************
  1765. * NAME
  1766. *
  1767. * luf_delete_it - delete LU-factorization
  1768. *
  1769. * SYNOPSIS
  1770. *
  1771. * #include "glpluf.h"
  1772. * void luf_delete_it(LUF *luf);
  1773. *
  1774. * DESCRIPTION
  1775. *
  1776. * The routine luf_delete deletes LU-factorization specified by the
  1777. * parameter luf and frees all the memory allocated to this program
  1778. * object. */
  1779. void luf_delete_it(LUF *luf)
  1780. { if (luf->fr_ptr != NULL) xfree(luf->fr_ptr);
  1781. if (luf->fr_len != NULL) xfree(luf->fr_len);
  1782. if (luf->fc_ptr != NULL) xfree(luf->fc_ptr);
  1783. if (luf->fc_len != NULL) xfree(luf->fc_len);
  1784. if (luf->vr_ptr != NULL) xfree(luf->vr_ptr);
  1785. if (luf->vr_len != NULL) xfree(luf->vr_len);
  1786. if (luf->vr_cap != NULL) xfree(luf->vr_cap);
  1787. if (luf->vr_piv != NULL) xfree(luf->vr_piv);
  1788. if (luf->vc_ptr != NULL) xfree(luf->vc_ptr);
  1789. if (luf->vc_len != NULL) xfree(luf->vc_len);
  1790. if (luf->vc_cap != NULL) xfree(luf->vc_cap);
  1791. if (luf->pp_row != NULL) xfree(luf->pp_row);
  1792. if (luf->pp_col != NULL) xfree(luf->pp_col);
  1793. if (luf->qq_row != NULL) xfree(luf->qq_row);
  1794. if (luf->qq_col != NULL) xfree(luf->qq_col);
  1795. if (luf->sv_ind != NULL) xfree(luf->sv_ind);
  1796. if (luf->sv_val != NULL) xfree(luf->sv_val);
  1797. if (luf->sv_prev != NULL) xfree(luf->sv_prev);
  1798. if (luf->sv_next != NULL) xfree(luf->sv_next);
  1799. if (luf->vr_max != NULL) xfree(luf->vr_max);
  1800. if (luf->rs_head != NULL) xfree(luf->rs_head);
  1801. if (luf->rs_prev != NULL) xfree(luf->rs_prev);
  1802. if (luf->rs_next != NULL) xfree(luf->rs_next);
  1803. if (luf->cs_head != NULL) xfree(luf->cs_head);
  1804. if (luf->cs_prev != NULL) xfree(luf->cs_prev);
  1805. if (luf->cs_next != NULL) xfree(luf->cs_next);
  1806. if (luf->flag != NULL) xfree(luf->flag);
  1807. if (luf->work != NULL) xfree(luf->work);
  1808. xfree(luf);
  1809. return;
  1810. }
  1811. /* eof */