PageRenderTime 115ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/RecoHI/HiJetAlgos/plugins/bpmpd-2.11.f

https://github.com/dgonzal/cmssw
FORTRAN Legacy | 10561 lines | 7634 code | 37 blank | 2890 comment | 1177 complexity | 881adb4359ed0b0928a69c6c0060d33f MD5 | raw file
Possible License(s): GPL-3.0
  1. C Version for CMSSW, modified to suppress gfortran warnings
  2. C -------------------------------------------------------------------
  3. c Primal-dual method with supernodal cholesky factorization
  4. c Version 2.11 (1996 December)
  5. c Written by Cs. Meszaros, MTA SzTAKI, Budapest, Hungary
  6. c Questions, remarks to the e-mail address:
  7. c meszaros@lutra.sztaki.hu
  8. c
  9. c All rights reserved ! Free for academic and research use only !
  10. c Commercial users are required to purchase a software license.
  11. c
  12. c Related publications:
  13. c
  14. c Meszaros, Cs.: Fast Cholesky Factorization for Interior Point Methods
  15. c of Linear Programming. Computers & Mathematics with Applications,
  16. c Vol. 31. No.4/5 (1996) pp. 49-51.
  17. c
  18. c Meszaros, Cs.: The "inexact" minimum local fill-in ordering algorithm.
  19. c Working Paper WP 95-7, Computer and Automation Institute, Hungarian
  20. c Academy of Sciences
  21. c
  22. c Maros I., Meszaros Cs.: The Role of the Augmented System in Interior
  23. c Point Methods. European Journal of Operations Researches
  24. c (submitted)
  25. c
  26. c ===========================================================================
  27. c
  28. c Callable interface
  29. c
  30. c Standard form: ax-s=b u>=x,s>=l
  31. c
  32. c remarks:
  33. c EQ rows 0 >= s >= 0
  34. c GT rows +inf >= s >= 0
  35. c LT rows 0 >= s >= -inf
  36. c FR rows +inf >= s >= -inf
  37. c
  38. c input: obj objective function (to be minimize) (n)
  39. c rhs right-hand side (m)
  40. c lbound lower bounds (m+n)
  41. c ubound upper bounds (m+n)
  42. c colpnt pointer to the columns (n+1)
  43. c rowidx row indices (nz)
  44. c nonzeros nonzero values (nz)
  45. c big practical +inf
  46. c
  47. c output: code termination code
  48. c xs primal values
  49. c dv dual values
  50. c dspr dual resuduals
  51. c
  52. c Input arrays will be destroyed !
  53. c
  54. c ===========================================================================
  55. c
  56. subroutine solver(
  57. x obj,rhs,lbound,ubound,diag,odiag,xs,dxs,dxsn,up,dspr,ddspr,
  58. x ddsprn,dsup,ddsup,ddsupn,dv,ddv,ddvn,prinf,upinf,duinf,scale,
  59. x nonzeros,
  60. x vartyp,slktyp,colpnt,ecolpnt,count,vcstat,pivots,invprm,
  61. x snhead,nodtyp,inta1,prehis,rowidx,rindex,
  62. x code,opt,iter,corect,fixn,dropn,fnzmax,fnzmin,addobj,
  63. x bigbou,big,ft)
  64. c
  65. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  66. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  67. c
  68. common/initv/ prmin,upmax,dumin,stamet,safmet,premet,regul
  69. real*8 prmin,upmax,dumin
  70. integer*4 stamet,safmet,premet,regul
  71. c
  72. integer*4 fixn,dropn,code,iter,corect,fnzmin,fnzmax,ft
  73. real*8 addobj,opt,big,
  74. x obj(n),rhs(m),lbound(mn),ubound(mn),scale(mn),diag(mn),odiag(mn),
  75. x xs(mn),dxs(mn),dxsn(mn),up(mn),dspr(mn),ddspr(mn),ddsprn(mn),
  76. x dsup(mn),ddsup(mn),ddsupn(mn),dv(m),ddv(m),ddvn(m),
  77. x nonzeros(cfree),prinf(m),upinf(mn),duinf(mn),bigbou
  78. integer*4 vartyp(n),slktyp(m),colpnt(n1),ecolpnt(mn),
  79. x count(mn),vcstat(mn),pivots(mn),invprm(mn),snhead(mn),
  80. x nodtyp(mn),inta1(mn),prehis(mn),rowidx(cfree),rindex(rfree)
  81. c
  82. common/numer/ tplus,tzer
  83. real*8 tplus,tzer
  84. common/ascal/ objnor,rhsnor,scdiff,scpass,scalmet
  85. real*8 objnor,rhsnor,scdiff
  86. integer*4 scpass,scalmet
  87. c ---------------------------------------------------------------------------
  88. integer*4 i,j,k,active,pnt1,pnt2,prelen,freen
  89. real*8 scobj,scrhs,sol,lbig
  90. character*99 buff
  91. C CMSSW: Temporary integer array needed to avoid reusing REAL*8 for
  92. C integer storage
  93. integer*4 pmbig(m),ppbig(m),dmbig(n),dpbig(n)
  94. integer*4 iwork1(mn+mn),iwork2(mn+mn),iwork3(mn+mn),iwork4(mn+mn),
  95. & iwork5(mn+mn)
  96. c ---------------------------------------------------------------------------
  97. c
  98. c inicializalas
  99. c
  100. if(cfree.le.(nz+1)*2)then
  101. write(buff,'(1x,a)')'Not enough memory, realmem < nz !'
  102. call mprnt(buff)
  103. code=-2
  104. goto 50
  105. endif
  106. if(rfree.le.nz)then
  107. write(buff,'(1x,a)')'Not enough memory, intmem < nz !'
  108. call mprnt(buff)
  109. code=-2
  110. goto 50
  111. endif
  112. iter=0
  113. corect=0
  114. prelen=0
  115. fnzmin=cfree
  116. fnzmax=-1
  117. scobj=1.0d+0
  118. scrhs=1.0d+0
  119. code=0
  120. lbig=0.9d+0*big
  121. if(bigbou.gt.lbig)then
  122. lbig=bigbou
  123. big=lbig/0.9d+0
  124. endif
  125. do i=1,mn
  126. scale(i)=1.0d+0
  127. enddo
  128. c
  129. c Remove fix variables and free rows
  130. c
  131. do i=1,n
  132. vartyp(i)=0
  133. if(abs(ubound(i)-lbound(i)).le.tplus*(abs(lbound(i)+1.0d0)))then
  134. vartyp(i)= 1
  135. vcstat(i)=-2-1
  136. pnt1=colpnt(i)
  137. pnt2=colpnt(i+1)-1
  138. do j=pnt1,pnt2
  139. rhs(rowidx(j))=rhs(rowidx(j))-ubound(i)*nonzeros(j)
  140. enddo
  141. addobj=addobj+obj(i)*lbound(i)
  142. else
  143. vcstat(i)=0
  144. endif
  145. enddo
  146. do i=1,m
  147. slktyp(i)=0
  148. j=i+n
  149. if((ubound(j).gt.lbig).and.(lbound(j).lt.-lbig))then
  150. vcstat(j)=-2-1
  151. else
  152. vcstat(j)=0
  153. endif
  154. enddo
  155. c
  156. c p r e s o l v e r
  157. c
  158. call timer(k)
  159. if(premet.gt.0)then
  160. write(buff,'(1x)')
  161. call mprnt(buff)
  162. write(buff,'(1x,a)')'Process: presolv'
  163. call mprnt(buff)
  164. call presol(colpnt,rowidx,nonzeros,rindex,nonzeros(nz+1),
  165. x snhead,snhead(n1),nodtyp,nodtyp(n1),vcstat,vcstat(n1),
  166. x ecolpnt,count,ecolpnt(n1),count(n1),
  167. C CMSSW: Prevent REAL*8 reusage warning
  168. C Was: vartyp,dxsn(n1),dxs(n1),diag(n1),odiag(n1),
  169. x vartyp,dxsn(n1),dxs(n1),pmbig,ppbig,
  170. x ubound,lbound,ubound(n1),lbound(n1),rhs,obj,prehis,prelen,
  171. C CMSSW: Prevent REAL*8 reusage warning
  172. C Was: addobj,big,pivots,invprm,dv,ddv,dxsn,dxs,diag,odiag,premet,code)
  173. x addobj,big,pivots,invprm,dv,ddv,dxsn,dxs,dmbig,dpbig,premet,
  174. x code)
  175. write(buff,'(1x,a)')'Presolv done...'
  176. call mprnt(buff)
  177. if(code.ne.0)goto 45
  178. endif
  179. c
  180. c Remove lower bounds
  181. c
  182. call stndrd(ubound,lbound,rhs,obj,nonzeros,
  183. x vartyp,slktyp,vcstat,colpnt,rowidx,addobj,tplus,tzer,lbig,big)
  184. c
  185. c Scaling before aggregator
  186. c
  187. i=iand(scalmet,255)
  188. j=iand(scpass,255)
  189. if(i.gt.0)call mscale(colpnt,rowidx,nonzeros,obj,rhs,ubound,
  190. x vcstat,scale,upinf,i,j,scdiff,ddsup,dxsn,dxs,snhead)
  191. c
  192. c Aggregator
  193. c
  194. if(premet.gt.127)then
  195. write(buff,'(1x)')
  196. call mprnt(buff)
  197. write(buff,'(1x,a)')'Process: aggregator'
  198. call mprnt(buff)
  199. call aggreg(colpnt,rowidx,nonzeros,rindex,
  200. x vcstat,vcstat(n1),ecolpnt,count,ecolpnt(n1),count(n1),
  201. x rhs,obj,prehis,prelen,pivots,vartyp,slktyp,invprm,snhead,
  202. x nodtyp,inta1,inta1(n1),dv,addobj,premet,code)
  203. write(buff,'(1x,a)')'Aggregator done...'
  204. call mprnt(buff)
  205. if(code.ne.0)goto 55
  206. endif
  207. c
  208. c Scaling after aggregator
  209. c
  210. i=scalmet/256
  211. j=scpass/256
  212. if(i.gt.0)call mscale(colpnt,rowidx,nonzeros,obj,rhs,
  213. x ubound,vcstat,scale,upinf,i,j,scdiff,ddsup,dxsn,dxs,snhead)
  214. c
  215. call timer(j)
  216. write(buff,'(1x)')
  217. call mprnt(buff)
  218. write(buff,'(1x,a,f8.2,a)')
  219. x 'Time for presolv, scaling and aggregator: ',0.01*(j-k),' sec.'
  220. call mprnt(buff)
  221. c
  222. c cleaning
  223. c
  224. do i=1,mn
  225. xs(i)=0.0d+0
  226. dspr(i)=0.0d+0
  227. dsup(i)=0.0d+0
  228. up(i)=0.0d+0
  229. enddo
  230. do i=1,m
  231. dv(i)=0.0d+0
  232. enddo
  233. c
  234. c Is the problem solved ?
  235. c
  236. fixn=0
  237. dropn=0
  238. freen=0
  239. do i=1,n
  240. if(vcstat(i).le.-2)then
  241. fixn=fixn+1
  242. else if(vartyp(i).eq.0) then
  243. freen=freen+1
  244. endif
  245. enddo
  246. do i=1,m
  247. if(vcstat(i+n).le.-2)dropn=dropn+1
  248. enddo
  249. active=mn-fixn-dropn
  250. if(active.eq.0)code=2
  251. if(code.gt.0)then
  252. opt=addobj
  253. write(buff,'(1x,a)')'Problem is solved by the pre-solver'
  254. call mprnt(buff)
  255. if(code.gt.0)goto 55
  256. goto 50
  257. endif
  258. c
  259. c Presolve statistics
  260. c
  261. if(premet.gt.0)then
  262. i=0
  263. j=0
  264. do k=1,n
  265. if(vcstat(k).gt.-2)then
  266. i=i+count(k)-ecolpnt(k)+1
  267. if(j.lt.count(k)-ecolpnt(k)+1)j=count(k)-ecolpnt(k)+1
  268. endif
  269. enddo
  270. write(buff,'(1x,a22,i8)')'Number of rows :',(m-dropn)
  271. call mprnt(buff)
  272. write(buff,'(1x,a22,i8)')'Number of columns :',(n-fixn)
  273. call mprnt(buff)
  274. write(buff,'(1x,a22,i8)')'Free variables :',freen
  275. call mprnt(buff)
  276. write(buff,'(1x,a22,i8)')'No. of nonzeros :',i
  277. call mprnt(buff)
  278. write(buff,'(1x,a22,i8)')'Longest column count :',j
  279. call mprnt(buff)
  280. endif
  281. c
  282. c Incrase rowidx by n
  283. c
  284. j=colpnt(1)
  285. k=colpnt(n+1)-1
  286. do i=j,k
  287. rowidx(i)=rowidx(i)+n
  288. enddo
  289. active=mn-fixn-dropn
  290. c
  291. c Normalize obj and rhs
  292. c
  293. if(objnor.gt.tzer)then
  294. call scalobj(obj,scobj,vcstat,objnor)
  295. endif
  296. if(rhsnor.gt.tzer)then
  297. call scalrhs(rhs,scrhs,vcstat,rhsnor,ubound,xs,up)
  298. endif
  299. c
  300. c Calling phas12
  301. c
  302. sol=scobj*scrhs
  303. i=mn+mn
  304. call timer(k)
  305. call phas12(
  306. x obj,rhs,ubound,diag,odiag,xs,dxs,dxsn,up,dspr,ddspr,
  307. x ddsprn,dsup,ddsup,ddsupn,dv,ddv,ddvn,nonzeros,prinf,upinf,duinf,
  308. x vartyp,slktyp,colpnt,ecolpnt,count,vcstat,pivots,invprm,
  309. x snhead,nodtyp,inta1,rowidx,rindex,
  310. C CMSSW: Prevent REAL*8 reusage warning
  311. C Was: dxs,dxsn,ddspr,ddsprn,ddsup,ddsupn,
  312. x dxs,iwork1,iwork2,iwork3,iwork4,iwork5,
  313. x code,opt,iter,corect,fixn,dropn,active,fnzmax,fnzmin,addobj,
  314. x sol,ft,i)
  315. call timer(j)
  316. write(buff,'(1x,a,f11.2,a)')'Solver time ',0.01*(j-k),' sec.'
  317. call mprnt(buff)
  318. c
  319. c Decrease rowidx by n
  320. c
  321. j=colpnt(1)
  322. k=colpnt(n+1)-1
  323. do i=j,k
  324. rowidx(i)=rowidx(i)-n
  325. enddo
  326. c
  327. c Rescaling
  328. c
  329. 55 do i=1,m
  330. rhs(i)=rhs(i)*scrhs*scale(i+n)
  331. ubound(i+n)=ubound(i+n)*scrhs*scale(i+n)
  332. xs(i+n)=xs(i+n)*scrhs*scale(i+n)
  333. up(i+n)=up(i+n)*scrhs*scale(i+n)
  334. dv(i)=dv(i)*scobj/scale(i+n)
  335. dspr(i+n)=dspr(i+n)/scale(i+n)*scobj
  336. dsup(i+n)=dsup(i+n)/scale(i+n)*scobj
  337. enddo
  338. c
  339. do i=1,n
  340. obj(i)=obj(i)*scobj*scale(i)
  341. ubound(i)=ubound(i)*scrhs/scale(i)
  342. pnt1=colpnt(i)
  343. pnt2=colpnt(i+1)-1
  344. do j=pnt1,pnt2
  345. nonzeros(j)=nonzeros(j)*scale(i)*scale(rowidx(j)+n)
  346. enddo
  347. c
  348. xs(i)=xs(i)/scale(i)*scrhs
  349. up(i)=up(i)/scale(i)*scrhs
  350. dspr(i)=dspr(i)*scale(i)*scobj
  351. dsup(i)=dsup(i)*scale(i)*scobj
  352. enddo
  353. c
  354. c Postprocessing
  355. c
  356. 45 call pstsol(colpnt,rowidx,nonzeros,vcstat,vcstat(n1),
  357. x vartyp,slktyp,ubound,lbound,ubound(n1),lbound(n1),rhs,obj,xs,
  358. x inta1,ddvn,prehis,prelen,big)
  359. c
  360. 50 return
  361. end
  362. c
  363. c ===========================================================================
  364. c
  365. subroutine stndrd(ubound,lbound,rhs,obj,nonzeros,
  366. x vartyp,slktyp,vcstat,colpnt,rowidx,addobj,tplus,tzer,lbig,big)
  367. c
  368. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  369. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  370. c
  371. integer*4 vartyp(n),slktyp(m),vcstat(mn),colpnt(n1),rowidx(nz)
  372. real*8 ubound(mn),lbound(mn),rhs(m),obj(n),nonzeros(nz),
  373. x addobj,tplus,tzer,lbig,big
  374. c
  375. integer*4 i,j,k,pnt1,pnt2
  376. c
  377. c generate standard form, row modification
  378. c
  379. k=0
  380. do 150 i=1,m
  381. j=i+n
  382. if(vcstat(j).gt.-2)then
  383. if(abs(ubound(j)-lbound(j)).le.tplus*(abs(lbound(j))+1d0))then
  384. slktyp(i)=0
  385. ubound(j)=0.0d+00
  386. rhs(i)=rhs(i)+lbound(j)
  387. goto 150
  388. endif
  389. ccc if((ubound(j).gt.lbig).and.(lbound(j).lt.-lbig))then
  390. ccc vcstat(j)=-2
  391. ccc slktyp(i)=0
  392. ccc goto 150
  393. ccc endif
  394. if(lbound(j).lt.-lbig)then
  395. slktyp(i)=2
  396. lbound(j)=-ubound(j)
  397. ubound(j)=big
  398. rhs(i)=-rhs(i)
  399. k=k+1
  400. else
  401. slktyp(i)=1
  402. endif
  403. rhs(i)=rhs(i)+lbound(j)
  404. ubound(j)=ubound(j)-lbound(j)
  405. if(ubound(j).lt.lbig)slktyp(i)=-slktyp(i)
  406. else
  407. slktyp(i)=0
  408. endif
  409. 150 continue
  410. c
  411. c negate reverse rows
  412. c
  413. if(k.gt.0)then
  414. do i=1,n
  415. pnt1=colpnt(i)
  416. pnt2=colpnt(i+1)-1
  417. do j=pnt1,pnt2
  418. if(abs(slktyp(rowidx(j))).ge.2)nonzeros(j)=-nonzeros(j)
  419. enddo
  420. enddo
  421. endif
  422. c
  423. c column modification
  424. c
  425. do 155 i=1,n
  426. if(vcstat(i).gt.-2)then
  427. ccc if(abs(ubound(i)-lbound(i)).le.tplus*(abs(lbound(i))+1d0))then
  428. ccc vcstat(i)=-2
  429. ccc vartyp(i)= 1
  430. ccc do j=colpnt(i),colpnt(i+1)-1
  431. ccc rhs(rowidx(j))=rhs(rowidx(j))-nonzeros(j)*lbound(i)
  432. ccc enddo
  433. ccc addobj=addobj+obj(i)*lbound(i)
  434. ccc goto 155
  435. ccc endif
  436. if((ubound(i).gt.lbig).and.(lbound(i).lt.-lbig))then
  437. vartyp(i)=0
  438. goto 155
  439. endif
  440. if(lbound(i).lt.-lbig)then
  441. vartyp(i)=2
  442. lbound(i)=-ubound(i)
  443. ubound(i)=big
  444. obj(i)=-obj(i)
  445. do j=colpnt(i),colpnt(i+1)-1
  446. nonzeros(j)=-nonzeros(j)
  447. enddo
  448. else
  449. vartyp(i)=1
  450. endif
  451. if(abs(lbound(i)).gt.tzer)then
  452. if(ubound(i).lt.lbig)ubound(i)=ubound(i)-lbound(i)
  453. do j=colpnt(i),colpnt(i+1)-1
  454. rhs(rowidx(j))=rhs(rowidx(j))-nonzeros(j)*lbound(i)
  455. enddo
  456. addobj=addobj+obj(i)*lbound(i)
  457. endif
  458. if(ubound(i).lt.lbig)vartyp(i)=-vartyp(i)
  459. endif
  460. 155 continue
  461. return
  462. end
  463. c
  464. c ===========================================================================
  465. c Primal-dual method with supernodal cholesky factorization
  466. c Version 2.11 (1996 December)
  467. c Written by Cs. Meszaros, MTA SzTAKI, Budapest, Hungary
  468. c e-mail: meszaros@lutra.sztaki.hu
  469. c see "bpmain.f"
  470. c
  471. c code=-2 General memory limit (no solution)
  472. c code=-1 Memory limit during iterations
  473. c code= 0
  474. c code= 1 No optimum
  475. c code= 2 Otimal solution
  476. c code= 3 Primal Infeasible
  477. c code= 4 Dual Infeasible
  478. c
  479. c ===========================================================================
  480. c
  481. subroutine phas12(
  482. x obj,rhs,bounds,diag,odiag,xs,dxs,dxsn,up,dspr,ddspr,
  483. x ddsprn,dsup,ddsup,ddsupn,dv,ddv,ddvn,nonzeros,prinf,upinf,duinf,
  484. x vartyp,slktyp,colpnt,ecolpnt,count,vcstat,pivots,invprm,
  485. x snhead,nodtyp,inta1,rowidx,rindex,
  486. x rwork1,iwork1,iwork2,iwork3,iwork4,iwork5,
  487. x code,opt,iter,corect,fixn,dropn,active,fnzmax,fnzmin,addobj,
  488. x scobj,factim,mn2)
  489. c
  490. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  491. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  492. c
  493. common/mscal/ varadd,slkadd,scfree
  494. real*8 varadd,slkadd,scfree
  495. c
  496. common/numer/ tplus,tzer
  497. real*8 tplus,tzer
  498. c
  499. common/param/ palpha,dalpha
  500. real*8 palpha,dalpha
  501. c
  502. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  503. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  504. c
  505. common/toler/ tsdir,topt1,topt2,tfeas1,tfeas2,feas1,feas2,
  506. x pinfs,dinfs,inftol,maxiter
  507. real*8 tsdir,topt1,topt2,tfeas1,tfeas2,feas1,feas2,
  508. x pinfs,dinfs,inftol
  509. integer*4 maxiter
  510. c
  511. common/initv/ prmin,upmax,dumin,stamet,safmet,premet,regul
  512. real*8 prmin,upmax,dumin
  513. integer*4 stamet,safmet,premet,regul
  514. c
  515. integer*4 fixn,dropn,active,code,iter,corect,fnzmin,fnzmax,mn2
  516. real*8 addobj,scobj,opt
  517. c
  518. common/predp/ ccstop,barset,bargrw,barmin,mincor,maxcor,inibar
  519. real*8 ccstop,barset,bargrw,barmin
  520. integer*4 mincor,maxcor,inibar
  521. c
  522. common/predc/ target,tsmall,tlarge,center,corstp,mincc,maxcc
  523. real*8 target,tsmall,tlarge,center,corstp
  524. integer*4 mincc,maxcc
  525. common/itref/ tresx,tresy,maxref
  526. real*8 tresx,tresy
  527. integer*4 maxref
  528. c
  529. real*8 obj(n),rhs(m),bounds(mn),diag(mn),odiag(mn),xs(mn),
  530. x dxs(mn),dxsn(mn),up(mn),dspr(mn),ddspr(mn),ddsprn(mn),dsup(mn),
  531. x ddsup(mn),ddsupn(mn),dv(m),ddv(m),ddvn(m),nonzeros(cfree),
  532. x prinf(m),upinf(mn),duinf(mn),rwork1(mn)
  533. integer*4 vartyp(n),slktyp(m),colpnt(n1),ecolpnt(mn),count(mn),
  534. x vcstat(mn),pivots(mn),invprm(mn),snhead(mn),nodtyp(mn),
  535. x inta1(mn),rowidx(cfree),rindex(rfree),factim,
  536. x iwork1(mn2),iwork2(mn2),iwork3(mn2),iwork4(mn2),iwork5(mn2)
  537. c
  538. c ---------------------------------------------------------------------------
  539. c
  540. integer*4 i,j,err,factyp,pphase,dphase,t1,t2,opphas,odphas
  541. real*8 pinf,dinf,uinf,prelinf,drelinf,popt,dopt,cgap,
  542. x prstpl,dustpl,barpar,oper,maxstp,pinfrd,dinfrd,objerr,nonopt,
  543. x oprelinf,odrelinf,opinf,odinf,ocgap
  544. integer*4 corr,corrc,barn,fxp,fxd,fxu,nropt
  545. character*99 buff,sbuff
  546. character*1 wmark
  547. c
  548. c to save parameters
  549. c
  550. integer*4 maxcco,mxrefo
  551. real*8 lamo,spdeno,bargro,topto
  552. C CMSSW: Temporary integer array needed to avoid reusing REAL*8 for
  553. C integer storage
  554. integer*4 inta12(mn)
  555. c
  556. c --------------------------------------------------------------------------
  557. c
  558. 101 format(1x,' ')
  559. 102 format(1x,'It-PC P.Inf D.Inf U.Inf Actions ',
  560. x 'P.Obj D.Obj Barpar')
  561. 103 format(1x,'------------------------------------------------',
  562. x '------------------------------')
  563. 104 format(1x,I2,a1,I1,I1,' ',1PD7.1,' ',1PD7.1,' ',1PD6.0,
  564. x ' ',I2,' ',I3,' ',I3,' ',1PD15.8,' ',1PD15.8,' ',1PD6.0)
  565. c
  566. c Saving parameters
  567. c
  568. maxcco=maxcc
  569. mxrefo=maxref
  570. lamo=lam
  571. spdeno=supdens
  572. bargro=bargrw
  573. topto=topt1
  574. c
  575. c Include dummy ranges if requested
  576. c
  577. if(regul.gt.0)then
  578. do i=1,m
  579. if(slktyp(i).eq.0)then
  580. slktyp(i)=-1
  581. bounds(i+n)=0.0d+0
  582. endif
  583. enddo
  584. endif
  585. c
  586. c Other initialization
  587. c
  588. nropt=0
  589. factim=0
  590. wmark='-'
  591. fxp=0
  592. fxd=0
  593. fxu=0
  594. c
  595. call stlamb(colpnt,vcstat,rowidx,inta1,fixn,dropn,factyp)
  596. call timer(t1)
  597. j=0
  598. do i=1,n
  599. if((vcstat(i).gt.-2).and.(vartyp(i).eq.0))j=j+1
  600. enddo
  601. if((j.gt.0).and.(scfree.lt.tzer))factyp=1
  602. c
  603. c Initial scaling matrix (diagonal)
  604. c
  605. call fscale (vcstat,diag,odiag,vartyp,slktyp)
  606. do i=1,m
  607. dv(i)=0.0d+0
  608. enddo
  609. ccc i=2*rfree
  610. ccc j=400
  611. ccc call paintmat(m,n,nz,i,rowidx,colpnt,rindex,j,'matrix01.pic')
  612. c
  613. c Initial factorization
  614. c
  615. fnzmax=0
  616. if(factyp.eq.1)then
  617. call ffactor(ecolpnt,vcstat,colpnt,rowidx,
  618. x iwork4,pivots,count,nonzeros,diag,
  619. x iwork1,iwork1(mn+1),iwork2,iwork2(mn+1),inta1,iwork5,
  620. x iwork5(mn+1),iwork3,iwork3(mn+1),iwork4(mn+1),rindex,
  621. x rwork1,fixn,dropn,fnzmax,fnzmin,active,oper,xs,slktyp,code)
  622. if(code.ne.0)goto 999
  623. call supnode(ecolpnt,count,rowidx,vcstat,pivots,snhead,
  624. x invprm,nodtyp)
  625. else
  626. c
  627. c minimum local fill-in ordering
  628. c
  629. i=int(tfind)
  630. if(order.lt.1.5)i=0
  631. if(order.lt.0.5)i=-1
  632. call symmfo(inta1,pivots,ecolpnt,vcstat,
  633. x colpnt,rowidx,nodtyp,rindex,iwork3,invprm,
  634. x count,snhead,iwork1,iwork1(mn+1),iwork2,iwork2(mn+1),
  635. x iwork4,iwork4(mn+1),iwork3(mn+1),iwork5,iwork5(mn+1),
  636. C CMSSW: Prevent REAL*8 reusage warning
  637. C Was: nonzeros,fnzmax,oper,i,rwork1,code
  638. x nonzeros,fnzmax,oper,i,inta12,code)
  639. if(code.ne.0)goto 999
  640. call supnode(ecolpnt,count,rowidx,vcstat,pivots,snhead,
  641. x invprm,nodtyp)
  642. popt=trabs
  643. trabs=tabs
  644. call nfactor(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  645. x diag,err,rwork1,iwork2,iwork2(mn+1),dropn,slktyp,
  646. x snhead,iwork3,invprm,nodtyp,dv,odiag)
  647. trabs=popt
  648. endif
  649. fnzmin=fnzmax
  650. c
  651. c Compute centrality and iterative refinement power
  652. c
  653. if(fnzmin.eq.0)fnzmin=1
  654. cgap=oper/fnzmin/10.0d+0
  655. j=0
  656. 78 if(cgap.ge.1.0d+0)then
  657. cgap=cgap/2
  658. j=j+1
  659. goto 78
  660. endif
  661. if(j.eq.0)j=1
  662. if(maxcc.le.0d+0)then
  663. maxcc=-maxcc
  664. else
  665. if(j.le.maxcc)maxcc=j
  666. endif
  667. if(mincc.gt.maxcc)maxcc=mincc
  668. cgap=log(1.0d+0+oper/fnzmin/5.0d+0)/log(2.0d+00)
  669. if(maxref.le.0)then
  670. maxref=-maxref
  671. else
  672. maxref=int(cgap*maxref)
  673. endif
  674. if(maxref.le.0)maxref=0
  675. write(buff,'(1x,a,i2)')'Centrality correction Power:',maxcc
  676. call mprnt(buff)
  677. write(buff,'(1x,a,i2)')'Iterative refinement Power:',maxref
  678. call mprnt(buff)
  679. c
  680. c Starting point
  681. c
  682. call initsol(xs,up,dv,dspr,dsup,rhs,obj,bounds,vartyp,slktyp,
  683. x vcstat,colpnt,ecolpnt,pivots,rowidx,nonzeros,diag,rwork1,
  684. x count)
  685. call timer(t2)
  686. c
  687. write(buff,'(1x,a,f12.2,a)')'FIRSTFACTOR TIME :',
  688. x (dble(t2-t1)*0.01d+0),' sec'
  689. call mprnt(buff)
  690. c
  691. maxstp=1.0d+0
  692. iter=0
  693. corect=0
  694. corr=0
  695. corrc=0
  696. barn=0
  697. cgap=0.0d+0
  698. do i=1,mn
  699. if(vcstat(i).gt.-2)then
  700. if(i.le.n)then
  701. j=vartyp(i)
  702. else
  703. j=slktyp(i-n)
  704. endif
  705. if(j.ne.0)then
  706. cgap=cgap+xs(i)*dspr(i)
  707. barn=barn+1
  708. endif
  709. if(j.lt.0)then
  710. cgap=cgap+up(i)*dsup(i)
  711. barn=barn+1
  712. endif
  713. endif
  714. enddo
  715. if(barn.lt.1)barn=1
  716. ccc i=2*rfree
  717. ccc j=350
  718. ccc call paintaat(mn,nz,pivotn,i,rowidx,ecolpnt,count,rindex,
  719. ccc x j,pivots,iwork1,iwork1(mn+1),iwork2,iwork2(mn+1),iwork3,
  720. ccc x iwork3(mn+1),'normal01.pic')
  721. ccc i=2*rfree
  722. ccc j=400
  723. ccc call paintata(mn,nz,pivotn,i,rowidx,ecolpnt,count,rindex,
  724. ccc x j,pivots,iwork1,iwork1(mn+1),iwork2,iwork2(mn+1),iwork3,
  725. ccc x 'atapat01.pic')
  726. ccc i=2*rfree
  727. ccc j=350
  728. ccc err=nz
  729. ccc call paintfct(mn,cfree,pivotn,i,rowidx,ecolpnt,count,rindex,
  730. ccc x j,pivots,iwork2,err,'factor01.pic')
  731. c
  732. c Initialize for the iteration loop
  733. c
  734. do i=1,n
  735. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  736. if(xs(i).gt.dspr(i))then
  737. vcstat(i)=1
  738. else
  739. vcstat(i)=0
  740. endif
  741. endif
  742. enddo
  743. do i=1,m
  744. if((vcstat(i+n).gt.-2).and.(slktyp(i).ne.0))then
  745. if(xs(i+n).gt.dspr(i+n))then
  746. vcstat(i+n)=1
  747. else
  748. vcstat(i+n)=0
  749. endif
  750. endif
  751. enddo
  752. opphas=0
  753. odphas=0
  754. pinfrd=1.0d+0
  755. dinfrd=1.0d+0
  756. barpar=0.0d+0
  757. c
  758. c main iteration loop
  759. c
  760. 10 if(mod(iter,20).eq.0)then
  761. write(buff,101)
  762. call mprnt(buff)
  763. write(buff,102)
  764. call mprnt(buff)
  765. write(buff,103)
  766. call mprnt(buff)
  767. endif
  768. c
  769. c Infeasibilities
  770. c
  771. call cprinf(xs,prinf,slktyp,colpnt,rowidx,nonzeros,
  772. x rhs,vcstat,pinf)
  773. call cduinf(dv,dspr,dsup,duinf,vartyp,slktyp,colpnt,rowidx,
  774. x nonzeros,obj,vcstat,dinf)
  775. call cupinf(xs,up,upinf,bounds,vartyp,slktyp,vcstat,
  776. x uinf)
  777. c
  778. c Objectives
  779. c
  780. call cpdobj(popt,dopt,obj,rhs,bounds,xs,dv,dsup,
  781. x vcstat,vartyp,slktyp)
  782. popt=scobj*popt+addobj
  783. dopt=scobj*dopt+addobj
  784. c
  785. c Stopping criteria
  786. c
  787. call stpcrt(prelinf,drelinf,popt,dopt,cgap,iter,
  788. x code,pphase,dphase,maxstp,pinf,uinf,dinf,
  789. x prinf,upinf,duinf,nonopt,pinfrd,dinfrd,
  790. x prstpl,dustpl,obj,rhs,bounds,xs,dxs,dspr,ddspr,dsup,ddsup,dv,ddv,
  791. x up,addobj,scobj,vcstat,vartyp,slktyp,
  792. x oprelinf,odrelinf,opinf,odinf,ocgap,opphas,odphas,sbuff)
  793. c
  794. write(buff,104)iter,wmark,corr,corrc,pinf,dinf,uinf,fxp,fxd,fxu,
  795. x popt,dopt,barpar
  796. call mprnt(buff)
  797. if(code.ne.0)then
  798. write(buff,'(1x)')
  799. call mprnt(buff)
  800. call mprnt(sbuff)
  801. goto 90
  802. endif
  803. c
  804. c P-D solution modification
  805. c
  806. call pdmodi(xs,dspr,vcstat,vartyp,slktyp,cgap,popt,
  807. x dopt,prinf,duinf,upinf,colpnt,rowidx,nonzeros,pinf,uinf,dinf)
  808. c
  809. c Fixing variables / dropping rows / handling dual slacks
  810. c
  811. i=fixn
  812. call varfix(vartyp,slktyp,rhs,colpnt,rowidx,nonzeros,
  813. x xs,up,dspr,dsup,vcstat,fixn,dropn,addobj,scobj,obj,bounds,
  814. x duinf,dinf,fxp,fxd,fxu)
  815. if(fixn.ne.i)then
  816. call supupd(pivots,invprm,snhead,nodtyp,vcstat,ecolpnt)
  817. call cprinf(xs,prinf,slktyp,colpnt,rowidx,nonzeros,
  818. x rhs,vcstat,pinf)
  819. call cupinf(xs,up,upinf,bounds,vartyp,slktyp,vcstat,
  820. x uinf)
  821. endif
  822. c
  823. c Compute gap
  824. c
  825. cgap=0.0d+0
  826. do i=1,mn
  827. if(vcstat(i).gt.-2)then
  828. if(i.le.n)then
  829. j=vartyp(i)
  830. else
  831. j=slktyp(i-n)
  832. endif
  833. if(j.ne.0)then
  834. cgap=cgap+xs(i)*dspr(i)
  835. if(j.lt.0)then
  836. cgap=cgap+up(i)*dsup(i)
  837. endif
  838. endif
  839. endif
  840. enddo
  841. c
  842. c Computation of the scaling matrix
  843. c
  844. objerr=abs(dopt-popt)/(abs(popt)+1.0d+0)
  845. call cdiag(xs,up,dspr,dsup,vartyp,slktyp,vcstat,diag,odiag)
  846. pinfrd=pinf
  847. dinfrd=dinf
  848. c
  849. c The actual factorization
  850. c
  851. 50 err=0
  852. call timer(t1)
  853. if (factyp.eq.1) then
  854. call mfactor(ecolpnt,vcstat,colpnt,rowidx,pivots,
  855. x count,iwork4,nonzeros,diag,err,rwork1,iwork2,iwork2(mn+1),
  856. x dropn,slktyp,snhead,iwork3,invprm,nodtyp,dv,odiag)
  857. else
  858. call nfactor(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  859. x diag,err,rwork1,iwork2,iwork2(mn+1),dropn,slktyp,
  860. x snhead,iwork3,invprm,nodtyp,dv,odiag)
  861. endif
  862. call timer(t2)
  863. if(err.gt.0)then
  864. do i=1,mn
  865. diag(i)=odiag(i)
  866. enddo
  867. call newsmf(colpnt,pivots,rowidx,nonzeros,ecolpnt,count,
  868. x vcstat,invprm,snhead,nodtyp,iwork1,rwork1,iwork2,iwork3,
  869. x iwork4,code)
  870. if(code.lt.0)then
  871. write(buff,'(1x)')
  872. call mprnt(buff)
  873. goto 90
  874. endif
  875. goto 50
  876. endif
  877. factim=factim+t2-t1
  878. c
  879. c We are in the finish ?
  880. c
  881. wmark(1:1)='-'
  882. if(objerr.gt.1.0d+0)objerr=1.0d+0
  883. if(objerr.lt.topt1)objerr=topt1
  884. if((objerr.le.topt1*10.0d+0).and.(pphase+dphase.eq.4))then
  885. if(bargrw.gt.0.1d+0)bargrw=0.1d+0
  886. nropt=nropt+1
  887. if(nropt.eq.5)then
  888. nropt=0
  889. topt1=topt1*sqrt(10.d+0)
  890. write(buff,'(1x,a)')'Near otptimal but slow convergence.'
  891. call mprnt(buff)
  892. endif
  893. wmark(1:1)='+'
  894. endif
  895. c
  896. c primal-dual predictor-corrector direction
  897. c
  898. call cpdpcd(xs,up,dspr,dsup,prinf,duinf,upinf,
  899. x dxsn,ddvn,ddsprn,ddsupn,dxs,ddv,ddspr,ddsup,bounds,
  900. x ecolpnt,count,pivots,vcstat,diag,odiag,rowidx,nonzeros,
  901. x colpnt,vartyp,slktyp,barpar,corr,prstpl,dustpl,barn,cgap)
  902. corect=corect+corr
  903. c
  904. c primal-dual centality-correction
  905. c
  906. call cpdccd(xs,up,dspr,dsup,upinf,
  907. x dxsn,ddvn,ddsprn,ddsupn,dxs,ddv,ddspr,ddsup,bounds,
  908. x ecolpnt,count,pivots,vcstat,diag,odiag,rowidx,nonzeros,
  909. x colpnt,vartyp,slktyp,barpar,corrc,prstpl,dustpl)
  910. corect=corect+corrc
  911. c
  912. c compute steplengths
  913. c
  914. iter=iter+1
  915. prstpl=prstpl*palpha
  916. dustpl=dustpl*dalpha
  917. c
  918. c compute the new primal-dual solution
  919. c
  920. call cnewpd(prstpl,xs,dxs,up,upinf,dustpl,dv,ddv,dspr,
  921. x ddspr,dsup,ddsup,vartyp,slktyp,vcstat,maxstp)
  922. c
  923. c End main loop
  924. c
  925. goto 10
  926. c
  927. 90 opt=(dopt-popt)/(abs(popt)+1.0d+0)
  928. write(buff,'(1x,a,1PD11.4,a,1PD18.10)')
  929. x 'ABSOLUTE infeas. Primal :',pinf, ' Dual :',dinf
  930. call mprnt(buff)
  931. write(buff,'(1x,a,1PD11.4,a,1PD18.10)')
  932. x 'PRIMAL : Relative infeas. :',prelinf,' Objective :',popt
  933. call mprnt(buff)
  934. write(buff,'(1x,a,1PD11.4,a,1PD18.10)')
  935. x 'DUAL : Relative infeas. :',drelinf,' Objective :',dopt
  936. call mprnt(buff)
  937. write(buff,'(1x,a,1PD11.4,a,1PD18.10)')
  938. x 'Complementarity gap :',cgap,' Duality gap :',opt
  939. call mprnt(buff)
  940. opt=popt
  941. c
  942. c Restoring parameters
  943. c
  944. 999 maxcc=maxcco
  945. maxref=mxrefo
  946. lam=lamo
  947. supdens=spdeno
  948. bargrw=bargro
  949. topt1=topto
  950. return
  951. end
  952. c
  953. c ===========================================================================
  954. c ===========================================================================
  955. c
  956. subroutine mscale(colpnt,rowidx,nonzeros,
  957. x obj,rhs,ubound,vcstat,scale,scalen,scalmet,scpass,scdiff,
  958. x ddsup,ddsupn,dxs,snhead)
  959. c
  960. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  961. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  962. c
  963. integer*4 colpnt(n1),rowidx(nz),vcstat(mn),
  964. x scalmet,scpass,snhead(mn)
  965. real*8 nonzeros(cfree),obj(n),rhs(m),ubound(mn),scale(mn),
  966. x scalen(mn),scdiff,ddsup(mn),ddsupn(mn),dxs(mn)
  967. c
  968. integer*4 i
  969. character*99 buff
  970. c
  971. write(buff,'(1x)')
  972. call mprnt(buff)
  973. write(buff,'(1x,a)')'Process: scaling'
  974. call mprnt(buff)
  975. c
  976. do i=1,mn
  977. scalen(i)=1.0d+0
  978. enddo
  979. c
  980. if((scalmet.eq.2).or.(scalmet.eq.4))then
  981. call scale1(ubound,nonzeros,colpnt,obj,scalen,vcstat,
  982. x rowidx,rhs,ddsup,scpass,scdiff,snhead,nonzeros(nz+1))
  983. endif
  984. if((scalmet.eq.3).or.(scalmet.eq.5))then
  985. call scale2(ubound,nonzeros,colpnt,obj,scalen,vcstat,
  986. x rowidx,rhs,scpass,scdiff,ddsup,ddsupn,dxs,snhead)
  987. endif
  988. if((scalmet.gt.0).and.(scalmet.le.3))then
  989. call sccol2(ubound,nonzeros,colpnt,obj,scalen,
  990. x vcstat,rowidx)
  991. call scrow2(rhs,ubound,nonzeros,rowidx,colpnt,ddsup,
  992. x scalen,vcstat)
  993. endif
  994. c
  995. do i=1,mn
  996. scale(i)=scale(i)*scalen(i)
  997. enddo
  998. c
  999. write(buff,'(1x,a)')'Scaling done...'
  1000. call mprnt(buff)
  1001. return
  1002. end
  1003. c
  1004. c ============================================================================
  1005. c
  1006. subroutine scale1(bounds,rownzs,colpnt,obj,scale,
  1007. x vcstat,rowidx,rhs,work1,scpass,scdif,veclen,
  1008. x lognz)
  1009. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1010. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1011. common/numer/ tplus,tzer
  1012. real*8 tplus,tzer
  1013. real*8 bounds(mn),rownzs(cfree),obj(n),scale(mn),
  1014. x rhs(m),work1(mn),scdif,lognz(nz)
  1015. integer*4 rowidx(cfree),colpnt(n1),vcstat(mn),scpass,veclen(mn)
  1016. c
  1017. real*8 defic,odefic
  1018. integer*4 pass,i,j,pnt1,pnt2,nonz
  1019. character*99 buff
  1020. c
  1021. pass=0
  1022. nonz=0
  1023. defic= 1.0d+0
  1024. odefic=0.0d+0
  1025. do i=1,mn
  1026. veclen(i)=0
  1027. enddo
  1028. do i=1,n
  1029. if(vcstat(i).gt.-2)then
  1030. pnt1=colpnt(i)
  1031. pnt2=colpnt(i+1)-1
  1032. do j=pnt1,pnt2
  1033. if((abs(rownzs(j)).gt.tzer).and.
  1034. x (vcstat(rowidx(j)+n).gt.-2))then
  1035. lognz(j)=log(abs(rownzs(j)))
  1036. veclen(i)=veclen(i)+1
  1037. veclen(rowidx(j)+n)=veclen(rowidx(j)+n)+1
  1038. nonz=nonz+1
  1039. odefic=odefic+abs(lognz(j))
  1040. else
  1041. lognz(j)=0.0d+0
  1042. endif
  1043. enddo
  1044. endif
  1045. enddo
  1046. do i=1,mn
  1047. if(veclen(i).eq.0)veclen(i)=1
  1048. scale(i)=0.0d+0
  1049. enddo
  1050. if(nonz.eq.0)goto 999
  1051. odefic=exp(odefic/dble(nonz))
  1052. if(odefic.le.scdif)goto 999
  1053. 10 write(buff,'(1x,a,i2,a,d12.6)')'Pass',pass,'. Average def.',odefic
  1054. call mprnt(buff)
  1055. call sccol1(colpnt,scale,
  1056. x vcstat,rowidx,veclen,lognz)
  1057. pass=pass+1
  1058. call scrow1(rowidx,colpnt,work1,scale,vcstat,defic,veclen,lognz)
  1059. defic=exp(defic/dble(nonz))
  1060. if(defic.le.scdif)goto 999
  1061. if(pass.ge.scpass)goto 999
  1062. if(odefic.le.defic)goto 999
  1063. odefic=defic
  1064. goto 10
  1065. 999 write(buff,'(1x,a,i2,a,d12.6)')'Pass',pass,'. Average def.',defic
  1066. call mprnt(buff)
  1067. c
  1068. c Scaling
  1069. c
  1070. do i=1,mn
  1071. scale(i)=exp(scale(i))
  1072. enddo
  1073. do i=1,n
  1074. pnt1=colpnt(i)
  1075. pnt2=colpnt(i+1)-1
  1076. do j=pnt1,pnt2
  1077. rownzs(j)=rownzs(j)/scale(i)/scale(rowidx(j)+n)
  1078. enddo
  1079. obj(i)=obj(i)/scale(i)
  1080. bounds(i)=bounds(i)*scale(i)
  1081. enddo
  1082. do i=1,m
  1083. rhs(i)=rhs(i)/scale(i+n)
  1084. bounds(i+n)=bounds(i+n)/scale(i+n)
  1085. enddo
  1086. return
  1087. end
  1088. c
  1089. c ============================================================================
  1090. c
  1091. subroutine scrow1(rowidx,colpnt,
  1092. x maxi,scale,excld,ss,veclen,lognz)
  1093. c
  1094. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1095. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1096. c
  1097. real*8 lognz(nz),maxi(mn),scale(mn),ss
  1098. integer*4 rowidx(cfree),colpnt(n1),excld(mn),veclen(mn)
  1099. common/numer/ tplus,tzer
  1100. real*8 tplus,tzer
  1101. c ---------------------------------------------------------------------------
  1102. integer*4 i,j,pnt1,pnt2
  1103. real*8 sol
  1104. c ---------------------------------------------------------------------------
  1105. ss=0
  1106. do i=1,m
  1107. maxi(i)=0.0d+0
  1108. enddo
  1109. do i=1,n
  1110. if(excld(i).gt.-2)then
  1111. sol=scale(i)
  1112. pnt1=colpnt(i)
  1113. pnt2=colpnt(i+1)-1
  1114. do j=pnt1,pnt2
  1115. if(excld(rowidx(j)+n).gt.-2)then
  1116. maxi(rowidx(j))=maxi(rowidx(j))+lognz(j)-sol
  1117. ss=ss+abs(lognz(j)-sol-scale(rowidx(j)+n))
  1118. endif
  1119. enddo
  1120. endif
  1121. enddo
  1122. do i=1,m
  1123. scale(n+i)=maxi(i)/veclen(i+n)
  1124. enddo
  1125. return
  1126. end
  1127. c
  1128. c ===========================================================================
  1129. c
  1130. subroutine sccol1(colpnt,scale,
  1131. x excld,rowidx,veclen,lognz)
  1132. c
  1133. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1134. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1135. c
  1136. real*8 scale(mn),lognz(nz)
  1137. integer*4 colpnt(n1),excld(mn),rowidx(cfree),veclen(mn)
  1138. common/numer/ tplus,tzer
  1139. real*8 tplus,tzer
  1140. c ---------------------------------------------------------------------------
  1141. integer*4 i,j,pnt1,pnt2
  1142. real*8 ma
  1143. c ---------------------------------------------------------------------------
  1144. do i=1,n
  1145. ma=0.0d+0
  1146. if(excld(i).gt.-2)then
  1147. pnt1=colpnt(i)
  1148. pnt2=colpnt(i+1)-1
  1149. do j=pnt1,pnt2
  1150. ma=ma+lognz(j)-scale(rowidx(j)+n)
  1151. enddo
  1152. scale(i)=ma/veclen(i)
  1153. endif
  1154. enddo
  1155. return
  1156. end
  1157. c
  1158. c ===========================================================================
  1159. c
  1160. subroutine scrow2(rhs,bounds,rownzs,rowidx,
  1161. x colpnt,maxi,scale,excld)
  1162. c
  1163. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1164. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1165. c
  1166. common/numer/ tplus,tzer
  1167. real*8 tplus,tzer
  1168. c
  1169. real*8 rownzs(cfree),bounds(mn),rhs(m),maxi(m),scale(mn)
  1170. integer*4 rowidx(cfree),colpnt(n1),excld(mn)
  1171. c ---------------------------------------------------------------------------
  1172. integer*4 i,j,pnt1,pnt2,k
  1173. real*8 sol
  1174. c ---------------------------------------------------------------------------
  1175. do i=1,m
  1176. maxi(i)=0
  1177. enddo
  1178. do i=1,n
  1179. if(excld(i).gt.-2)then
  1180. pnt1=colpnt(i)
  1181. pnt2=colpnt(i+1)-1
  1182. do j=pnt1,pnt2
  1183. k=rowidx(j)
  1184. sol=abs(rownzs(j))
  1185. if (maxi(k).lt.sol)maxi(k)=sol
  1186. enddo
  1187. endif
  1188. enddo
  1189. do i=1,m
  1190. if(maxi(i).le.tzer)maxi(i)=1.0d+0
  1191. scale(n+i)=maxi(i)*scale(n+i)
  1192. rhs(i)=rhs(i)/maxi(i)
  1193. bounds(i+n)=bounds(i+n)/maxi(i)
  1194. enddo
  1195. do i=1,n
  1196. pnt1=colpnt(i)
  1197. pnt2=colpnt(i+1)-1
  1198. do j=pnt1,pnt2
  1199. k=rowidx(j)
  1200. rownzs(j)=rownzs(j)/maxi(k)
  1201. enddo
  1202. enddo
  1203. return
  1204. end
  1205. c
  1206. c ===========================================================================
  1207. c
  1208. subroutine sccol2(bounds,rownzs,colpnt,obj,scale,
  1209. x excld,rowidx)
  1210. c
  1211. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1212. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1213. c
  1214. real*8 rownzs(cfree),bounds(mn),obj(n),scale(mn)
  1215. integer*4 colpnt(n1),excld(mn),rowidx(cfree)
  1216. common/numer/ tplus,tzer
  1217. real*8 tplus,tzer
  1218. c ---------------------------------------------------------------------------
  1219. integer*4 i,j,pnt1,pnt2
  1220. real*8 sol,ma
  1221. c ---------------------------------------------------------------------------
  1222. do i=1,n
  1223. if(excld(i).gt.-2)then
  1224. ma=0
  1225. pnt1=colpnt(i)
  1226. pnt2=colpnt(i+1)-1
  1227. do j=pnt1,pnt2
  1228. if(excld(rowidx(j)+n).gt.-2)then
  1229. sol=abs(rownzs(j))
  1230. if (ma.lt.sol)ma=sol
  1231. endif
  1232. enddo
  1233. if (ma.le.tzer)ma=1.0d+0
  1234. scale(i)=ma*scale(i)
  1235. do j=pnt1,pnt2
  1236. rownzs(j)=rownzs(j)/ma
  1237. enddo
  1238. obj(i)=obj(i)/ma
  1239. bounds(i)=bounds(i)*ma
  1240. endif
  1241. enddo
  1242. return
  1243. end
  1244. c
  1245. c ===========================================================================
  1246. c
  1247. subroutine scalobj(obj,scobj,excld,objnor)
  1248. c
  1249. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1250. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1251. c
  1252. real*8 obj(n),scobj,objnor
  1253. integer*4 excld(n),i
  1254. character*99 buff
  1255. c ---------------------------------------------------------------------------
  1256. scobj=0.0d+0
  1257. do i=1,n
  1258. if(excld(i).gt.-2)then
  1259. if (abs(obj(i)).gt.scobj)scobj=abs(obj(i))
  1260. endif
  1261. enddo
  1262. scobj=scobj/objnor
  1263. if(scobj.lt.1.0d-08)scobj=1.0d-08
  1264. write(buff,'(1x,a,d8.2)')'Obj. scaled ',scobj
  1265. call mprnt(buff)
  1266. do i=1,n
  1267. obj(i)=obj(i)/scobj
  1268. enddo
  1269. return
  1270. end
  1271. c
  1272. c ===========================================================================
  1273. c
  1274. subroutine scalrhs(rhs,scrhs,excld,rhsnor,bounds,xs,up )
  1275. c
  1276. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1277. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1278. c
  1279. real*8 rhs(m),scrhs,rhsnor,bounds(mn),xs(mn),up(mn)
  1280. integer*4 excld(mn),i
  1281. character*99 buff
  1282. c ---------------------------------------------------------------------------
  1283. scrhs=0.0d+0
  1284. do i=1,m
  1285. if(excld(i+n).gt.-2)then
  1286. if(abs(rhs(i)).gt.scrhs)scrhs=abs(rhs(i))
  1287. endif
  1288. enddo
  1289. scrhs=scrhs/rhsnor
  1290. if(scrhs.lt.1.0d-08)scrhs=1.0d-08
  1291. write(buff,'(1x,a,d8.2)')'Rhs. scaled ',scrhs
  1292. call mprnt(buff)
  1293. do i=1,m
  1294. rhs(i)=rhs(i)/scrhs
  1295. enddo
  1296. do i=1,mn
  1297. bounds(i)=bounds(i)/scrhs
  1298. xs(i)=xs(i)/scrhs
  1299. up(i)=up(i)/scrhs
  1300. enddo
  1301. return
  1302. end
  1303. c
  1304. c ============================================================================
  1305. c Curtis-Reid Scaling algorithm
  1306. c ============================================================================
  1307. c
  1308. subroutine scale2(bounds,rownzs,colpnt,obj,sc,
  1309. x vcstat,rowidx,rhs,scpass,scdif,scm1,rk,logsum,count)
  1310. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1311. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1312. common/numer/ tplus,tzer
  1313. real*8 tplus,tzer
  1314. c
  1315. real*8 bounds(mn),rownzs(cfree),obj(n),sc(mn),
  1316. x rhs(m),scdif,scm1(mn),rk(mn),logsum(mn)
  1317. integer*4 rowidx(cfree),colpnt(n1),vcstat(mn),scpass,count(mn)
  1318. c
  1319. integer*4 i,j,in,pnt1,pnt2,pass
  1320. real*8 logdef,s,qk,qkm1,ek,ekm1,ekm2,sk,skm1
  1321. character*99 buff
  1322. c
  1323. pass=0
  1324. do i=1,mn
  1325. count(i)=0
  1326. logsum(i)=0.0d+0
  1327. enddo
  1328. logdef=0.0d+0
  1329. in=0
  1330. do i=1,n
  1331. if(vcstat(i).gt.-2)then
  1332. pnt1=colpnt(i)
  1333. pnt2=colpnt(i+1)-1
  1334. do j=pnt1,pnt2
  1335. if(vcstat(rowidx(j)+n).gt.-2)then
  1336. if(abs(rownzs(j)).gt.tzer)then
  1337. s=log(abs(rownzs(j)))
  1338. count(rowidx(j)+n)=count(rowidx(j)+n)+1
  1339. count(i)=count(i)+1
  1340. logsum(i)=logsum(i)+s
  1341. logsum(rowidx(j)+n)=logsum(rowidx(j)+n)+s
  1342. logdef=logdef+s*s
  1343. in=in+1
  1344. endif
  1345. endif
  1346. enddo
  1347. endif
  1348. enddo
  1349. do i=1,mn
  1350. if((vcstat(i).le.-2).or.(count(i).eq.0))count(i)=1
  1351. enddo
  1352. logdef=sqrt(logdef)/dble(in)
  1353. logdef=exp(logdef)
  1354. write(buff,'(1x,a,i2,a,d12.6)')'Pass',pass,'. Average def.',logdef
  1355. call mprnt(buff)
  1356. if(logdef.le.scdif)then
  1357. do i=1,mn
  1358. sc(i)=1.0d+0
  1359. enddo
  1360. goto 999
  1361. endif
  1362. c
  1363. c Initialize
  1364. c
  1365. do i=1,m
  1366. sc(i+n)=logsum(i+n)/count(i+n)
  1367. rk(i+n)=0
  1368. enddo
  1369. sk=0
  1370. do i=1,n
  1371. if(vcstat(i).gt.-2)then
  1372. s=logsum(i)
  1373. pnt1=colpnt(i)
  1374. pnt2=colpnt(i+1)-1
  1375. do j=pnt1,pnt2
  1376. s=s-logsum(rowidx(j)+n)/count(rowidx(j)+n)
  1377. enddo
  1378. else
  1379. s=0
  1380. endif
  1381. rk(i)=s
  1382. sk=sk+s*s/count(i)
  1383. sc(i)=0.0d+0
  1384. enddo
  1385. do i=1,mn
  1386. scm1(i)=sc(i)
  1387. enddo
  1388. ekm1=0
  1389. ek=0
  1390. qk=1.0d+0
  1391. c
  1392. c Curtis-Reid scaling
  1393. c
  1394. 10 pass=pass+1
  1395. do i=1,m
  1396. rk(i+n)=ek*rk(i+n)
  1397. enddo
  1398. do i=1,n
  1399. if(vcstat(i).gt.-2)then
  1400. pnt1=colpnt(i)
  1401. pnt2=colpnt(i+1)-1
  1402. s=rk(i)/count(i)
  1403. do j=pnt1,pnt2
  1404. if(vcstat(rowidx(j)+n).gt.-2)
  1405. x rk(rowidx(j)+n)=rk(rowidx(j)+n)+s
  1406. enddo
  1407. endif
  1408. enddo
  1409. skm1=sk
  1410. sk=0.0d+0
  1411. do i=1,m
  1412. rk(i+n)=-rk(i+n)/qk
  1413. sk=sk+rk(i+n)*rk(i+n)/count(i+n)
  1414. enddo
  1415. ekm2=ekm1
  1416. ekm1=ek
  1417. ek=qk*sk/skm1
  1418. qkm1=qk
  1419. qk=1-ek
  1420. if(pass.gt.scpass)goto 20
  1421. c
  1422. c Update Column-scale factors
  1423. c
  1424. do i=1,n
  1425. if(vcstat(i).gt.-2)then
  1426. s=sc(i)
  1427. sc(i)=s+(rk(i)/count(i)+ekm1*ekm2*(s-scm1(i)))/qk/qkm1
  1428. scm1(i)=s
  1429. endif
  1430. enddo
  1431. c
  1432. c even pass
  1433. c
  1434. do i=1,n
  1435. if(vcstat(i).gt.-2)then
  1436. s=ek*rk(i)
  1437. pnt1=colpnt(i)
  1438. pnt2=colpnt(i+1)-1
  1439. do j=pnt1,pnt2
  1440. if(vcstat(rowidx(j)+n).gt.-2)
  1441. x s=s+rk(rowidx(j)+n)/count(rowidx(j)+n)
  1442. enddo
  1443. s=-s/qk
  1444. else
  1445. s=0
  1446. endif
  1447. rk(i)=s
  1448. enddo
  1449. skm1=sk
  1450. sk=0.0d+0
  1451. do i=1,n
  1452. sk=sk+rk(i)*rk(i)/count(i)
  1453. enddo
  1454. ekm2=ekm1
  1455. ekm1=ek
  1456. ek=qk*sk/skm1
  1457. qkm1=qk
  1458. qk=1-ek
  1459. c
  1460. c Update Row-scale factors
  1461. c
  1462. do i=1,m
  1463. j=i+n
  1464. if(vcstat(j).gt.-2)then
  1465. s=sc(j)
  1466. sc(j)=s+(rk(j)/count(j)+ekm1*ekm2*(s-scm1(j)))/qk/qkm1
  1467. scm1(j)=s
  1468. endif
  1469. enddo
  1470. goto 10
  1471. c
  1472. c Syncronize Column factors
  1473. c
  1474. 20 do i=1,n
  1475. if(vcstat(i).gt.-2)then
  1476. sc(i)=sc(i)+(rk(i)/count(i)+ekm1*ekm2*(sc(i)-scm1(i)))/qkm1
  1477. endif
  1478. enddo
  1479. c
  1480. c Scaling
  1481. c
  1482. logdef=0
  1483. do i=1,mn
  1484. if(vcstat(i).gt.-2)then
  1485. sc(i)=exp(sc(i))
  1486. else
  1487. sc(i)=1.0d+0
  1488. endif
  1489. enddo
  1490. do i=1,n
  1491. pnt1=colpnt(i)
  1492. pnt2=colpnt(i+1)-1
  1493. do j=pnt1,pnt2
  1494. rownzs(j)=rownzs(j)/sc(i)/sc(rowidx(j)+n)
  1495. if((vcstat(rowidx(j)+n).gt.-2).and.
  1496. x (abs(rownzs(j)).gt.tzer))then
  1497. s=log(abs(rownzs(j)))
  1498. logdef=logdef+s*s
  1499. endif
  1500. enddo
  1501. obj(i)=obj(i)/sc(i)
  1502. bounds(i)=bounds(i)*sc(i)
  1503. enddo
  1504. do i=1,m
  1505. rhs(i)=rhs(i)/sc(i+n)
  1506. bounds(i+n)=bounds(i+n)/sc(i+n)
  1507. enddo
  1508. logdef=sqrt(logdef)/dble(in)
  1509. logdef=exp(logdef)
  1510. pass=pass-1
  1511. write(buff,'(1x,a,i2,a,d12.6)')'Pass',pass,'. Average def.',logdef
  1512. call mprnt(buff)
  1513. 999 return
  1514. end
  1515. c
  1516. c ============================================================================
  1517. c ===========================================================================
  1518. c
  1519. subroutine stlamb(colpnt,vcstat,rowidx,cnt,fixn,dropn,p)
  1520. c
  1521. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1522. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1523. c
  1524. integer*4 colpnt(n1),vcstat(mn),rowidx(nz),cnt(mn),
  1525. x fixn,dropn,p
  1526. c
  1527. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  1528. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  1529. c
  1530. common/setden/ maxdense,densgap,setlam,denslen
  1531. real*8 maxdense,densgap
  1532. integer*4 setlam,denslen
  1533. c
  1534. integer*4 i,j,pnt1,pnt2,cn,lcn,lcd,ndn,z,maxcn
  1535. real*8 la
  1536. character*99 buff
  1537. c
  1538. c ---------------------------------------------------------------------------
  1539. c
  1540. C CMSSW: Explicit initialization needed
  1541. ndn=0
  1542. write(buff,'(1X)')
  1543. call mprnt(buff)
  1544. do i=1,m
  1545. cnt(i)=0
  1546. enddo
  1547. if((m-dropn).ge.(n-fixn))then
  1548. cnt(1)=m-dropn-n+fixn
  1549. endif
  1550. maxcn=0
  1551. do i=1,n
  1552. if(vcstat(i).gt.-2)then
  1553. pnt1=colpnt(i)
  1554. pnt2=colpnt(i+1)-1
  1555. cn=0
  1556. do j=pnt1,pnt2
  1557. if(vcstat(rowidx(j)).gt.-2)cn=cn+1
  1558. enddo
  1559. if(cn.gt.0)cnt(cn)=cnt(cn)+1
  1560. vcstat(i)=cn
  1561. if(maxcn.lt.cn)maxcn=cn
  1562. endif
  1563. enddo
  1564. if(setlam.lt.0)goto 70
  1565. c
  1566. cn =maxcn
  1567. lcd=maxcn
  1568. lcn=maxcn
  1569. z=0
  1570. C CMSSW: Explicit integer conversion needed
  1571. pnt1=int((n-fixn+m-dropn)*maxdense)
  1572. pnt2=0
  1573. if((m-dropn).ge.1.5*(n-fixn))then
  1574. maxdense=1.0
  1575. endif
  1576. if((m-dropn).ge.2.5*(n-fixn))then
  1577. lcn=1
  1578. lcd=2
  1579. goto 60
  1580. endif
  1581. c
  1582. do while ((pnt2.le.pnt1).and.(cn.gt.0))
  1583. if(cnt(cn).eq.0)then
  1584. z=z+1
  1585. else
  1586. if(z.gt.0)then
  1587. if((densgap*cn*cn).le.(cn+z+1)*(cn+z+1))then
  1588. lcd=cn+z+1
  1589. lcn=cn
  1590. ndn=pnt2
  1591. endif
  1592. z=0
  1593. endif
  1594. pnt2=pnt2+cnt(cn)
  1595. endif
  1596. cn=cn-1
  1597. enddo
  1598. c
  1599. 60 write(buff,'(1X,A,I6)')'Largest sparse column length :',lcn
  1600. call mprnt(buff)
  1601. if((maxcn.le.denslen).or.(lcn.eq.maxcn))then
  1602. write(buff,'(1X,A)')'Problem has no dense columns'
  1603. call mprnt(buff)
  1604. lcn=maxcn
  1605. else
  1606. write(buff,'(1X,A,I6)')'Smallest dense column length :',lcd
  1607. call mprnt(buff)
  1608. write(buff,'(1X,A,I6)')'Number of dense columns :',ndn
  1609. call mprnt(buff)
  1610. endif
  1611. la=lcn+0.5
  1612. la=la/m
  1613. write(buff,'(1X,A,F7.4)')'Computed density parameter : ',la
  1614. call mprnt(buff)
  1615. if(la.gt.lam)then
  1616. lam=la
  1617. else
  1618. write(buff,'(1X,A,F7.4)') 'Parameter reset to value : ',lam
  1619. call mprnt(buff)
  1620. endif
  1621. 70 lam=lam*m
  1622. p=1
  1623. if((lam.ge.maxcn).and.(setlam.le.0))p=2
  1624. if(supdens.le.lam)supdens=lam
  1625. c
  1626. write(buff,'(1X)')
  1627. call mprnt(buff)
  1628. return
  1629. end
  1630. c
  1631. c ===========================================================================
  1632. c ===========================================================================
  1633. c
  1634. subroutine symmfo(inta1,pivots,ecolpnt,vcstat,
  1635. x colpnt,rowidx,rowpnt,colindex,perm,invperm,
  1636. x count,inta2,inta3,inta4,inta5,inta6,inta7,inta8,inta9,
  1637. x inta10,inta11,nonzeros,l,oper,tfind,inta12,code)
  1638. c
  1639. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1640. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  1641. c
  1642. integer*4 inta1(mn),ecolpnt(mn),pivots(mn),vcstat(mn),
  1643. x colpnt(n1),rowidx(cfree),rowpnt(mn),colindex(rfree),
  1644. x perm(mn),invperm(mn),count(mn),inta2(mn),inta3(mn),inta4(mn),
  1645. x inta5(mn),inta6(mn),inta7(mn),inta8(mn),inta9(mn),inta10(mn),
  1646. x inta11(mn),tfind,inta12(mn),l,code
  1647. c
  1648. real*8 nonzeros(cfree),oper
  1649. c
  1650. integer*4 i,j,k,t1,tt1,t2,p1,p2,pnt,pnt1,pnt2,aatnz
  1651. character*99 buff
  1652. c
  1653. c ---------------------------------------------------------------------------
  1654. c
  1655. 1 format(1x,'Building aat time:',f9.2,' sec')
  1656. 2 format(1x,'Building ordering list time:',f9.2,' sec')
  1657. 4 format(1x,'Symbolic factorisation time:',f9.2,' sec')
  1658. 5 format(1x,'Total symbolic phase time:',f9.2,' sec')
  1659. 6 format(1x,'Sub-diagonal nonzeros in aat :',i9)
  1660. 7 format(1x,'Sub-diagonal nonzeros in L :',i9)
  1661. 8 format(1x,'NONZEROS :',i12)
  1662. 9 format(1x,'OPERATIONS :',f13.0)
  1663. 10 format(1x,'Minimum Local Fill-in Ordering with Power:',i3)
  1664. 11 format(1x,'Minimum Degree Ordering (Power=0)')
  1665. 12 format(1x,'Without Ordering')
  1666. c
  1667. call timer (tt1)
  1668. if(tfind.lt.0)then
  1669. write(buff,12)
  1670. else if(tfind.eq.0)then
  1671. write(buff,11)
  1672. else
  1673. write(buff,10)tfind
  1674. endif
  1675. oper=0.0d+0
  1676. call mprnt(buff)
  1677. do i=1,nz
  1678. rowidx(i)=rowidx(i)-n
  1679. enddo
  1680. if(rfree.lt.nz)then
  1681. write(buff,'(1x,a)')'Not enough integer memory'
  1682. call mprnt(buff)
  1683. code=-2
  1684. goto 999
  1685. endif
  1686. if(cfree.lt.2*nz)then
  1687. write(buff,'(1x,a)')'Not enough real memory'
  1688. call mprnt(buff)
  1689. code=-2
  1690. goto 999
  1691. endif
  1692. c
  1693. c If no ordering...
  1694. c
  1695. if(tfind.lt.0)then
  1696. t2=tt1
  1697. do i=1,m
  1698. perm(i)=i
  1699. enddo
  1700. goto 50
  1701. endif
  1702. c
  1703. c Otherwise...
  1704. c
  1705. do i=1,n
  1706. inta2(i)=i
  1707. enddo
  1708. call transps(n,m,nz,colpnt,rowidx,nonzeros,
  1709. x rowpnt,colindex,nonzeros(nz+1),inta2)
  1710. k=1
  1711. l=m
  1712. do i=1,m
  1713. pivots(i)=0
  1714. if(vcstat(i+n).le.-2)then
  1715. invperm(l)=i
  1716. l=l-1
  1717. else
  1718. invperm(k)=i
  1719. k=k+1
  1720. endif
  1721. enddo
  1722. call transps(m,n,nz,rowpnt,colindex,nonzeros(nz+1),
  1723. x colpnt,rowidx,nonzeros,invperm)
  1724. do i=1,n
  1725. p1=colpnt(i)
  1726. if(vcstat(i).le.-2)then
  1727. p2=colpnt(i)-1
  1728. else
  1729. p2=colpnt(i+1)-1
  1730. 19 if((p1.le.p2).and.(vcstat(rowidx(p2)+n).le.-2))then
  1731. p2=p2-1
  1732. goto 19
  1733. endif
  1734. endif
  1735. perm(i)=p1
  1736. invperm(i)=p2
  1737. enddo
  1738. c
  1739. pnt=nz+1
  1740. do i=1,m
  1741. if(pnt+mn.gt.cfree)then
  1742. write(buff,'(1x,a)')'Not enough real memory'
  1743. call mprnt(buff)
  1744. code=-2
  1745. goto 999
  1746. endif
  1747. pivots(i)=1
  1748. if(vcstat(i+n).gt.-2)then
  1749. ecolpnt(i)=pnt
  1750. pnt1=rowpnt(i)
  1751. pnt2=rowpnt(i+1)-1
  1752. do j=pnt1,pnt2
  1753. k=colindex(j)
  1754. if(vcstat(k).gt.-2)then
  1755. p1=perm(k)
  1756. p2=invperm(k)
  1757. perm(k)=perm(k)+1
  1758. do l=p1,p2
  1759. if(pivots(rowidx(l)).eq.0)then
  1760. pivots(rowidx(l))=1
  1761. rowidx(pnt)=rowidx(l)
  1762. pnt=pnt+1
  1763. endif
  1764. enddo
  1765. endif
  1766. enddo
  1767. count(i)=pnt-ecolpnt(i)
  1768. do j=ecolpnt(i),pnt-1
  1769. pivots(rowidx(j))=0
  1770. enddo
  1771. endif
  1772. enddo
  1773. aatnz=pnt-nz-1
  1774. c
  1775. c
  1776. call timer (t2)
  1777. write(buff,1)dble(t2-tt1)/100.0d+0
  1778. call mprnt(buff)
  1779. c
  1780. c call minimum fill-in ordering
  1781. c
  1782. call genmfo(m,mn,nz,cfree,rfree,pivotn,
  1783. x ecolpnt,count,perm,rowpnt,vcstat(n+1),rowidx,
  1784. x invperm,inta1,inta2,inta3,inta4,inta5,inta6,inta7,
  1785. x inta8,inta9,inta10,inta11,colindex,tfind,inta12,pivots,code)
  1786. if(code.lt.0)goto 999
  1787. c
  1788. c
  1789. 50 call timer(t1)
  1790. write(buff,2)dble(t1-t2)/100.0d+0
  1791. call mprnt(buff)
  1792. c
  1793. pivotn=0
  1794. do 30 i=1,n
  1795. ecolpnt(i)=colpnt(i)
  1796. count(i)=colpnt(i+1)-1
  1797. inta2(i)=i
  1798. if(vcstat(i).le.-2)goto 30
  1799. pivotn=pivotn+1
  1800. pivots(pivotn)=i
  1801. 30 continue
  1802. c
  1803. call transps(n,m,nz,colpnt,rowidx,nonzeros,
  1804. x rowpnt,colindex,nonzeros(nz+1),inta2)
  1805. c
  1806. k=1
  1807. l=m
  1808. do 40 i=1,m
  1809. j=perm(i)
  1810. if(vcstat(j+n).le.-2)then
  1811. invperm(l)=j
  1812. l=l-1
  1813. else
  1814. pivotn=pivotn+1
  1815. pivots(pivotn)=j+n
  1816. invperm(k)=j
  1817. k=k+1
  1818. endif
  1819. 40 continue
  1820. c
  1821. call transps(m,n,nz,rowpnt,colindex,nonzeros(nz+1),
  1822. x colpnt,rowidx,nonzeros,invperm)
  1823. c
  1824. do 20 i=1,nz
  1825. rowidx(i)=rowidx(i)+n
  1826. 20 continue
  1827. c
  1828. do i=1,n
  1829. if(vcstat(i).gt.-2)then
  1830. k=ecolpnt(i)
  1831. l=count(i)
  1832. 35 if((l.ge.k).and.(vcstat(rowidx(l)).le.-2))then
  1833. l=l-1
  1834. goto 35
  1835. endif
  1836. count(i)=l
  1837. endif
  1838. enddo
  1839. c
  1840. call symfact(pivots,rowidx,ecolpnt,count,vcstat,
  1841. x perm,invperm,inta2,inta1,l,code)
  1842. if(code.lt.0)goto 999
  1843. call timer(t2)
  1844. write(buff,4)dble(t2-t1)/100.0d+0
  1845. call mprnt(buff)
  1846. if(tfind.ge.0)then
  1847. write(buff,6)aatnz
  1848. call mprnt(buff)
  1849. endif
  1850. write(buff,7)l
  1851. call mprnt(buff)
  1852. c
  1853. do 55 i=1,mn
  1854. inta1(i)=0
  1855. 55 continue
  1856. l=0
  1857. do 60 i=1,pivotn
  1858. j=pivots(pivotn-i+1)
  1859. k=count(j)-ecolpnt(j)+1
  1860. if(k.eq.0)goto 60
  1861. l=l+k
  1862. inta1(j)=inta1(rowidx(ecolpnt(j)))+k
  1863. oper=oper+(dble(k)*dble(k)+dble(k))/2.0d+0
  1864. 60 continue
  1865. call timer(t1)
  1866. write(buff,5)dble(t2-tt1)/100.0d+0
  1867. call mprnt(buff)
  1868. write(buff,8)l
  1869. call mprnt(buff)
  1870. write(buff,9)oper
  1871. call mprnt(buff)
  1872. c
  1873. 999 return
  1874. end
  1875. c
  1876. c ===========================================================================
  1877. c Minimum local fill-in ordering
  1878. c
  1879. c ===========================================================================
  1880. c
  1881. subroutine genmfo(m,mn,nz,cfree,rfree,pivotn,
  1882. x pntc,ccol,permut,pntr,crow,rowidx,
  1883. x mark,cpermf,cpermb,rpermf,rpermb,cfill,rfill,cpnt,
  1884. x cnext,cprew,suplst,fillin,colidx,tfind,noddeg,supdeg,code)
  1885. c
  1886. integer*4 m,mn,nz,cfree,rfree,pivotn,rowidx(cfree),colidx(rfree),
  1887. x permut(m),cpermf(m),cpermb(m),rpermf(m),rpermb(m),
  1888. x ccol(m),crow(m),pntc(m),pntr(m),mark(m),cfill(m),cpnt(m),
  1889. x cnext(m),cprew(m),rfill(m),suplst(m),fillin(m),tfind,
  1890. x noddeg(m),supdeg(m),code
  1891. character*99 buff
  1892. c
  1893. c ---------------------------------------------------------------------------
  1894. c INPUT PARAMETERS
  1895. c
  1896. c m number of rows
  1897. c mn an number greather than m
  1898. c nz last used position of the column file
  1899. c cfree length of the column file (column file is used from nz+1 to cfree)
  1900. c rfree length of the row file (row file is used from 1 to rfree)
  1901. c rowidx column file (containing the lower tiriangular part of AAT)
  1902. c colidx row file
  1903. c pntc pointer to the columns of the lower diagonal of AAT
  1904. c ccol column lengths of AAT
  1905. c crow if crow(i)<-1 row i is removed from the ordering
  1906. c tfind search loop, tfind=0 gives the minimum degree ordering
  1907. c suggested value tfind=25
  1908. c
  1909. c
  1910. c OUTPUT PARAMETERS
  1911. c permut the ordering
  1912. c pivotn Number of ordered nodes
  1913. c
  1914. c
  1915. c Others: Integer working arrays of size m
  1916. c
  1917. c
  1918. c --------------------------------------------------------------------------
  1919. integer*4 pnt,pnt1,pnt2,i,j,k,l,o,p,endmem,ccfree,rcfree,pmode,
  1920. x rfirst,rlast,cfirst,clast,pcol,pcnt,ppnt1,ppnt2,fill,prewcol,
  1921. x ii,mm,mfill,supnd,hsupnd,oo,nnz,fnd,oldpcol,q,fl
  1922. c---------------------------------------------------------------------------
  1923. c
  1924. 1 format(' NOT ENOUGH MEMORY IN THE ROW FILE ')
  1925. 2 format(' NOT ENOUGH MEMORY IN THE COLUMN FILE ')
  1926. 3 format(' Analyse for supernodes in aat :',i9,' col')
  1927. 4 format(' Final supernodal columns disabled:',i9,' col')
  1928. 5 format(' Hidden supernodal columns :',i9,' col')
  1929. C CMSSW: Explicit initialization needed
  1930. clast=0
  1931. c
  1932. c initialization
  1933. c
  1934. code=0
  1935. endmem=cfree
  1936. pivotn=0
  1937. pmode =0
  1938. do i=1,m
  1939. permut(i)=0
  1940. suplst(i)=0
  1941. fillin(i)=-1
  1942. supdeg(i)=1
  1943. if(crow(i).gt.-2)then
  1944. crow(i)=0
  1945. endif
  1946. enddo
  1947. c
  1948. c Compute crow
  1949. c
  1950. do 10 i=1,m
  1951. if(crow(i).le.-2)goto 10
  1952. pnt1=pntc(i)
  1953. pnt2=pnt1+ccol(i)-1
  1954. do j=pnt1,pnt2
  1955. crow(rowidx(j))=crow(rowidx(j))+1
  1956. enddo
  1957. clast=i
  1958. 10 continue
  1959. cpermf(clast)=0
  1960. ccfree=cfree-pntc(clast)-ccol(clast)
  1961. if(ccfree.lt.mn)then
  1962. write(buff,2)
  1963. call mprnt(buff)
  1964. code=-2
  1965. goto 999
  1966. endif
  1967. c
  1968. c create pointers to colidx
  1969. c
  1970. do i=1,m
  1971. cprew(i)=0
  1972. enddo
  1973. pnt=1
  1974. do i=1,m
  1975. if(crow(i).ge.0)then
  1976. pntr(i)=pnt
  1977. rfill(i)=pnt
  1978. pnt=pnt+crow(i)
  1979. endif
  1980. enddo
  1981. rcfree=rfree-pnt
  1982. if(rcfree.lt.mn)then
  1983. write(buff,1)
  1984. call mprnt(buff)
  1985. code=-2
  1986. goto 999
  1987. endif
  1988. c
  1989. c create the row file : symbolical transps the matrix, set up noddeg
  1990. c
  1991. do i=1,m
  1992. noddeg(i)=ccol(i)+crow(i)
  1993. if(crow(i).ge.0)then
  1994. pnt1=pntc(i)
  1995. pnt2=pnt1+ccol(i)-1
  1996. do j=pnt1,pnt2
  1997. k=rowidx(j)
  1998. colidx(rfill(k))=i
  1999. rfill(k)=rfill(k)+1
  2000. enddo
  2001. endif
  2002. enddo
  2003. c
  2004. c Search supernodes
  2005. c
  2006. hsupnd=0
  2007. supnd=0
  2008. do i=1,m
  2009. if(crow(i).ge.0)then
  2010. pnt1=pntr(i)
  2011. pnt2=pnt1+crow(i)-1
  2012. do j=pnt1,pnt2
  2013. mark(colidx(j))=i
  2014. enddo
  2015. mark(i)=i
  2016. pnt1=pntc(i)
  2017. pnt2=pnt1+ccol(i)-1
  2018. do j=pnt1,pnt2
  2019. mark(rowidx(j))=i
  2020. enddo
  2021. p=ccol(i)+crow(i)
  2022. 118 if (pnt1.le.pnt2)then
  2023. o=rowidx(pnt1)
  2024. call chknod(m,cfree,rfree,i,o,p,ccol,crow,mark,pntc,
  2025. x pntr,rowidx,colidx,supdeg,suplst,ii)
  2026. supnd=supnd+ii
  2027. pnt1=pnt1-ii
  2028. pnt2=pnt2-ii
  2029. pnt1=pnt1+1
  2030. goto 118
  2031. endif
  2032. endif
  2033. enddo
  2034. write(buff,3)supnd
  2035. call mprnt(buff)
  2036. c
  2037. c Set up lists
  2038. c
  2039. do i=1,m
  2040. mark(i)=0
  2041. cpnt(i)=0
  2042. cnext(i)=0
  2043. enddo
  2044. cfirst=0
  2045. clast=0
  2046. rfirst=0
  2047. rlast=0
  2048. mm=0
  2049. do i=1,m
  2050. if(crow(i).ge.0)then
  2051. mm=mm+1
  2052. if(cfirst.eq.0)then
  2053. cfirst=i
  2054. else
  2055. cpermf(clast)=i
  2056. endif
  2057. cpermb(i)=clast
  2058. clast=i
  2059. c
  2060. if(rfirst.eq.0)then
  2061. rfirst=i
  2062. else
  2063. rpermf(rlast)=i
  2064. endif
  2065. rpermb(i)=rlast
  2066. rlast=i
  2067. c
  2068. j=noddeg(i)-supdeg(i)+2
  2069. if(j.gt.0)then
  2070. o=cpnt(j)
  2071. cnext(i)=o
  2072. cpnt(j)=i
  2073. if(o.ne.0)cprew(o)=i
  2074. endif
  2075. cprew(i)=0
  2076. endif
  2077. enddo
  2078. cpermf(clast)=0
  2079. rpermf(rlast)=0
  2080. pcol=0
  2081. c
  2082. c loop for pivots
  2083. c
  2084. 50 oldpcol=pcol
  2085. pcol=0
  2086. nnz=1
  2087. if(oldpcol.eq.0)goto 9114
  2088. c
  2089. c Find supernodal pivot
  2090. c
  2091. mfill=0
  2092. k=pntc(oldpcol)
  2093. l=k+ccol(oldpcol)-1
  2094. oo=ccol(oldpcol)-1
  2095. 9125 if(k.gt.l)goto 9114
  2096. j=rowidx(k)
  2097. if(crow(j)+ccol(j).eq.oo)then
  2098. hsupnd=hsupnd+1
  2099. pcol=j
  2100. goto 9200
  2101. endif
  2102. k=k+1
  2103. goto 9125
  2104. c
  2105. c Find another pivot
  2106. c
  2107. 9114 pmode=0
  2108. fnd=0
  2109. mfill=-1
  2110. 9110 j=cpnt(nnz)
  2111. if((j.gt.0).and.(pmode.eq.0))then
  2112. pmode=nnz
  2113. if(tfind.eq.0)then
  2114. pcol=j
  2115. mfill=1
  2116. goto 9200
  2117. endif
  2118. endif
  2119. 9120 if(j.le.0)goto 9150
  2120. if(fillin(j).ge.0)then
  2121. fill=fillin(j)
  2122. goto 9175
  2123. endif
  2124. c
  2125. c set up mark and cfill
  2126. c
  2127. q=0
  2128. fill=0
  2129. k=pntc(j)
  2130. l=k+ccol(j)-1
  2131. p=0
  2132. do o=k,l
  2133. q=q+1
  2134. cfill(q)=rowidx(o)
  2135. mark(rowidx(o))=supdeg(rowidx(o))
  2136. fill=fill-(supdeg(rowidx(o))*(supdeg(rowidx(o))-1))/2
  2137. enddo
  2138. k=pntr(j)
  2139. l=k+crow(j)-1
  2140. do o=k,l
  2141. q=q+1
  2142. cfill(q)=colidx(o)
  2143. mark(colidx(o))=supdeg(colidx(o))
  2144. fill=fill-(supdeg(colidx(o))*(supdeg(colidx(o))-1))/2
  2145. enddo
  2146. c
  2147. c compute fill-in
  2148. c
  2149. fill=fill+((noddeg(j)-supdeg(j))*(noddeg(j)-supdeg(j)+1))/2
  2150. do p=1,q
  2151. fl=0
  2152. o=cfill(p)
  2153. k=pntc(o)
  2154. l=k+ccol(o)-1
  2155. do oo=k,l
  2156. fl=fl+mark(rowidx(oo))
  2157. enddo
  2158. fill=fill-supdeg(o)*fl
  2159. enddo
  2160. c
  2161. c administration
  2162. c
  2163. do o=1,q
  2164. mark(cfill(o))=0
  2165. enddo
  2166. c
  2167. c Test
  2168. c
  2169. fillin(j)=fill
  2170. 9175 if(mfill.lt.0)mfill=fill+1
  2171. if(fill.lt.mfill)then
  2172. mfill=fill
  2173. pcol=j
  2174. endif
  2175. fnd=fnd+1
  2176. if((fnd.gt.tfind).or.(mfill.eq.0))goto 9200
  2177. j=cnext(j)
  2178. goto 9120
  2179. c
  2180. c next bunch
  2181. c
  2182. 9150 nnz=nnz+1
  2183. if(nnz.le.m)goto 9110
  2184. 9200 if (pcol.eq.0)goto 900
  2185. endmem=cfree
  2186. ccfree=cfree-pntc(clast)-ccol(clast)
  2187. rcfree=rfree-pntr(rlast)-crow(rlast)
  2188. c
  2189. c compress column file
  2190. c
  2191. if(ccfree.lt.mn)then
  2192. call mccmpr(mn,cfree,ccfree,endmem,nz,
  2193. x pntc,ccol,cfirst,cpermf,rowidx,code)
  2194. if(code.lt.0)goto 999
  2195. endif
  2196. c
  2197. c remove pcol from the cpermf lists
  2198. c
  2199. prewcol=cpermb(pcol)
  2200. o=cpermf(pcol)
  2201. if(prewcol.ne.0)then
  2202. cpermf(prewcol)=o
  2203. else
  2204. cfirst=o
  2205. endif
  2206. if(o.eq.0)then
  2207. clast=prewcol
  2208. else
  2209. cpermb(o)=prewcol
  2210. endif
  2211. c
  2212. c remove pcol from the rpermf lists
  2213. c
  2214. prewcol=rpermb(pcol)
  2215. o=rpermf(pcol)
  2216. if(prewcol.ne.0)then
  2217. rpermf(prewcol)=o
  2218. else
  2219. rfirst=o
  2220. endif
  2221. if(o.eq.0)then
  2222. rlast=prewcol
  2223. else
  2224. rpermb(o)=prewcol
  2225. endif
  2226. c
  2227. c administration
  2228. c
  2229. pivotn=pivotn+1
  2230. permut(pivotn)=pcol
  2231. pcnt=ccol(pcol)+crow(pcol)
  2232. c
  2233. c remove pcol from the counter lists
  2234. c
  2235. o=cnext(pcol)
  2236. ii=cprew(pcol)
  2237. if(ii.eq.0)then
  2238. cpnt(noddeg(pcol)-supdeg(pcol)+2)=o
  2239. else
  2240. cnext(ii)=o
  2241. endif
  2242. if(o.ne.0)cprew(o)=ii
  2243. c
  2244. ppnt1=endmem-pcnt
  2245. ppnt2=ppnt1+pcnt-1
  2246. endmem=endmem-pcnt
  2247. ccfree=ccfree-pcnt
  2248. pnt=ppnt1
  2249. c
  2250. c create pivot column from the row file
  2251. c
  2252. pnt1=pntr(pcol)
  2253. pnt2=pnt1+crow(pcol)-1
  2254. do 70 i=pnt1,pnt2
  2255. o=colidx(i)
  2256. l=pntc(o)
  2257. p=l+ccol(o)-1
  2258. c
  2259. c find element and move in the column o
  2260. c
  2261. cfill(o)=ccol(o)-1
  2262. rfill(o)= 0
  2263. do 75 k=l,p
  2264. if(rowidx(k).eq.pcol)then
  2265. mark(o)=1
  2266. rowidx(pnt)=o
  2267. pnt=pnt+1
  2268. rowidx(k)=rowidx(p)
  2269. goto 70
  2270. endif
  2271. 75 continue
  2272. 70 continue
  2273. mm=pnt
  2274. c
  2275. c extend pivot column from the column file
  2276. c
  2277. pnt1=pntc(pcol)
  2278. pnt2=pnt1+ccol(pcol)-1
  2279. do 60 j=pnt1,pnt2
  2280. o=rowidx(j)
  2281. mark(o)=1
  2282. rowidx(pnt)=o
  2283. pnt=pnt+1
  2284. c
  2285. c remove pcol from the row file
  2286. c
  2287. rfill(o)=-1
  2288. cfill(o)=ccol(o)
  2289. l=pntr(o)
  2290. p=l+crow(o)-2
  2291. do 55 k=l,p
  2292. if(colidx(k).eq.pcol)then
  2293. colidx(k)=colidx(p+1)
  2294. goto 60
  2295. endif
  2296. 55 continue
  2297. 60 continue
  2298. pntc(pcol)=ppnt1
  2299. ccol(pcol)=pcnt
  2300. c
  2301. c remove columns from the counter lists
  2302. c
  2303. do 77 j=ppnt1,ppnt2
  2304. i=rowidx(j)
  2305. o=cnext(i)
  2306. ii=cprew(i)
  2307. if(ii.eq.0)then
  2308. cpnt(noddeg(i)-supdeg(i)+2)=o
  2309. else
  2310. cnext(ii)=o
  2311. endif
  2312. if(o.ne.0)cprew(o)=ii
  2313. 77 continue
  2314. c
  2315. c elimination loop
  2316. c
  2317. if(mfill.gt.0)then
  2318. c
  2319. if(ppnt1.lt.mm)call hpsort((mm-ppnt1),rowidx(ppnt1))
  2320. if(mm.lt.ppnt2)call hpsort((ppnt2-mm+1),rowidx(mm))
  2321. c
  2322. do 80 p=ppnt1,ppnt2
  2323. i=rowidx(p)
  2324. c
  2325. c delete element from mark
  2326. c
  2327. mark(i)=0
  2328. pcnt=pcnt-1
  2329. c
  2330. c transformation on the column i
  2331. c
  2332. fill=pcnt
  2333. pnt1=pntc(i)
  2334. pnt2=pnt1+cfill(i)-1
  2335. do 90 k=pnt1,pnt2
  2336. o=rowidx(k)
  2337. if(mark(o).ne.0)then
  2338. fill=fill-1
  2339. mark(o)=0
  2340. endif
  2341. 90 continue
  2342. c
  2343. c compute the free space
  2344. c
  2345. ii=cpermf(i)
  2346. if(ii.eq.0)then
  2347. k=endmem-pnt2-1
  2348. else
  2349. k=pntc(ii)-pnt2-1
  2350. endif
  2351. c
  2352. c move column to the end of the column file
  2353. c
  2354. if(fill.gt.k)then
  2355. if (ccfree.lt.mn)then
  2356. call mccmpr(mn,cfree,ccfree,endmem,nz,
  2357. x pntc,ccol,cfirst,cpermf,rowidx,code)
  2358. if(code.lt.0)goto 999
  2359. pnt1=pntc(i)
  2360. pnt2=pnt1+cfill(i)-1
  2361. endif
  2362. if(i.ne.clast)then
  2363. l=pntc(clast)+ccol(clast)
  2364. pntc(i)=l
  2365. do 95 k=pnt1,pnt2
  2366. rowidx(l)=rowidx(k)
  2367. l=l+1
  2368. 95 continue
  2369. pnt1=pntc(i)
  2370. pnt2=l-1
  2371. prewcol=cpermb(i)
  2372. if(prewcol.eq.0)then
  2373. cfirst=ii
  2374. else
  2375. cpermf(prewcol)=ii
  2376. endif
  2377. cpermb(ii)=prewcol
  2378. cpermf(clast)=i
  2379. cpermb(i)=clast
  2380. clast=i
  2381. cpermf(clast)=0
  2382. endif
  2383. endif
  2384. c
  2385. c create fill in
  2386. c
  2387. do 97 k=p+1,ppnt2
  2388. o=rowidx(k)
  2389. if(mark(o).eq.0)then
  2390. mark(o)=1
  2391. else
  2392. pnt2=pnt2+1
  2393. rowidx(pnt2)=o
  2394. rfill(o)=rfill(o)+1
  2395. endif
  2396. 97 continue
  2397. pnt2=pnt2+1
  2398. ccol(i)=pnt2-pnt1
  2399. if(i.eq.clast)then
  2400. ccfree=endmem-pnt2-1
  2401. endif
  2402. 80 continue
  2403. else
  2404. do p=ppnt1,ppnt2
  2405. i=rowidx(p)
  2406. ccol(i)=ccol(i)-1-rfill(i)
  2407. mark(i)=0
  2408. enddo
  2409. endif
  2410. c
  2411. c make space for fills in the row file
  2412. c
  2413. do 100 j=ppnt1,ppnt2
  2414. i=rowidx(j)
  2415. if(mfill.eq.0)goto 135
  2416. pnt2=pntr(i)+crow(i)-1
  2417. c
  2418. c compute the free space
  2419. c
  2420. ii=rpermf(i)
  2421. if(ii.eq.0)then
  2422. k=rfree-pnt2-1
  2423. else
  2424. k=pntr(ii)-pnt2-1
  2425. endif
  2426. c
  2427. c move row to the end of the row file
  2428. c
  2429. if(k.lt.rfill(i))then
  2430. if(rcfree.lt.mn)then
  2431. call rcomprs(mn,rfree,
  2432. x rcfree,pntr,crow,rfirst,rpermf,colidx,code)
  2433. if(code.lt.0)goto 999
  2434. endif
  2435. if(ii.ne.0)then
  2436. pnt1=pntr(i)
  2437. pnt2=pnt1+crow(i)-1
  2438. pnt=pntr(rlast)+crow(rlast)
  2439. pntr(i)=pnt
  2440. do 110 l=pnt1,pnt2
  2441. colidx(pnt)=colidx(l)
  2442. pnt=pnt+1
  2443. 110 continue
  2444. c
  2445. c update the rperm lists
  2446. c
  2447. prewcol=rpermb(i)
  2448. if(prewcol.eq.0)then
  2449. rfirst=ii
  2450. else
  2451. rpermf(prewcol)=ii
  2452. endif
  2453. rpermb(ii)=prewcol
  2454. rpermf(rlast)=i
  2455. rpermb(i)=rlast
  2456. rlast=i
  2457. rpermf(rlast)=0
  2458. endif
  2459. endif
  2460. 135 crow(i)=crow(i)+rfill(i)
  2461. if(i.eq.rlast)rcfree=rfree-crow(i)-pntr(i)
  2462. noddeg(i)=noddeg(i)-supdeg(pcol)
  2463. 100 continue
  2464. if(mfill.eq.0)goto 150
  2465. c
  2466. c make pointers to the end of the filled rows
  2467. c
  2468. do 120 j=ppnt1,ppnt2
  2469. rfill(rowidx(j))=pntr(rowidx(j))+crow(rowidx(j))-1
  2470. 120 continue
  2471. c
  2472. c generate fill-in in the row file, update noddeg
  2473. c
  2474. do j=ppnt1,ppnt2
  2475. o=rowidx(j)
  2476. pnt1=pntc(o)+cfill(o)
  2477. pnt2=pntc(o)+ccol(o)-1
  2478. do k=pnt1,pnt2
  2479. colidx(rfill(rowidx(k)))=o
  2480. rfill(rowidx(k))=rfill(rowidx(k))-1
  2481. noddeg(o)=noddeg(o)+supdeg(rowidx(k))
  2482. noddeg(rowidx(k))=noddeg(rowidx(k))+supdeg(o)
  2483. enddo
  2484. enddo
  2485. c
  2486. c Indicate new fill-in computation
  2487. c
  2488. if(tfind.gt.0)then
  2489. do j=ppnt1,ppnt2
  2490. i=rowidx(j)
  2491. fillin(i)=-1
  2492. pnt1=pntc(i)+cfill(i)
  2493. pnt2=pntc(i)+ccol(i)-1
  2494. do pnt=pnt1,pnt2
  2495. ii=rowidx(pnt)
  2496. if(rfill(ii).ge.0)then
  2497. k=pntc(ii)
  2498. l=k+ccol(ii)-1
  2499. do o=k,l
  2500. fillin(rowidx(o))=-1
  2501. enddo
  2502. k=pntr(ii)
  2503. l=k+crow(ii)-1
  2504. do o=k,l
  2505. fillin(colidx(o))=-1
  2506. enddo
  2507. rfill(ii)=-1
  2508. endif
  2509. enddo
  2510. enddo
  2511. endif
  2512. c
  2513. c Searching for new supernodes
  2514. c
  2515. 150 l=0
  2516. j=ppnt1
  2517. 151 if(j.le.ppnt2)then
  2518. i=rowidx(j)
  2519. p=ccol(i)+crow(i)
  2520. c
  2521. pnt1=pntc(i)
  2522. pnt2=pnt1+ccol(i)-1
  2523. do k=pnt1,pnt2
  2524. if(mark(rowidx(k)).eq.0)then
  2525. l=l+1
  2526. cfill(l)=rowidx(k)
  2527. endif
  2528. mark(rowidx(k))=i
  2529. enddo
  2530. c
  2531. if(mark(i).eq.0)then
  2532. l=l+1
  2533. cfill(l)=i
  2534. endif
  2535. mark(i)=i
  2536. c
  2537. pnt1=pntr(i)
  2538. pnt2=pnt1+crow(i)-1
  2539. do k=pnt1,pnt2
  2540. if(mark(colidx(k)).eq.0)then
  2541. l=l+1
  2542. cfill(l)=colidx(k)
  2543. endif
  2544. mark(colidx(k))=i
  2545. enddo
  2546. c
  2547. k=j+1
  2548. 152 if(k.le.ppnt2)then
  2549. o=rowidx(k)
  2550. call chknod(m,cfree,rfree,i,o,p,ccol,crow,mark,pntc,
  2551. x pntr,rowidx,colidx,supdeg,suplst,ii)
  2552. if(ii.gt.0)then
  2553. supnd=supnd+1
  2554. c
  2555. prewcol=cpermb(o)
  2556. oo=cpermf(o)
  2557. if(prewcol.ne.0)then
  2558. cpermf(prewcol)=oo
  2559. else
  2560. cfirst=oo
  2561. endif
  2562. if(oo.eq.0)then
  2563. clast=prewcol
  2564. else
  2565. cpermb(oo)=prewcol
  2566. endif
  2567. c
  2568. prewcol=rpermb(o)
  2569. oo=rpermf(o)
  2570. if(prewcol.ne.0)then
  2571. rpermf(prewcol)=oo
  2572. else
  2573. rfirst=oo
  2574. endif
  2575. if(oo.eq.0)then
  2576. rlast=prewcol
  2577. else
  2578. rpermb(oo)=prewcol
  2579. endif
  2580. c
  2581. rowidx(k)=rowidx(ppnt2)
  2582. k=k-1
  2583. ppnt2=ppnt2-1
  2584. ccol(pcol)=ccol(pcol)-1
  2585. endif
  2586. k=k+1
  2587. goto 152
  2588. endif
  2589. j=j+1
  2590. goto 151
  2591. endif
  2592. do i=1,l
  2593. mark(cfill(i))=0
  2594. enddo
  2595. c
  2596. c update the counter lists
  2597. c
  2598. do j=ppnt1,ppnt2
  2599. i=rowidx(j)
  2600. fill=noddeg(i)-supdeg(i)+2
  2601. o=cpnt(fill)
  2602. cnext(i)=o
  2603. cpnt(fill)=i
  2604. if(o.ne.0)cprew(o)=i
  2605. cprew(i)=0
  2606. enddo
  2607. c
  2608. c Augment the permutation with the supernodes
  2609. c
  2610. i=suplst(pcol)
  2611. 155 if(i.gt.0)then
  2612. pivotn=pivotn+1
  2613. permut(pivotn)=i
  2614. i=suplst(i)
  2615. goto 155
  2616. endif
  2617. goto 50
  2618. c
  2619. c Augment the permutation with the disabled rows
  2620. c
  2621. 900 do i=1,m
  2622. if(crow(i).le.-2)then
  2623. pivotn=pivotn+1
  2624. permut(pivotn)=i
  2625. endif
  2626. enddo
  2627. write(buff,4)supnd
  2628. call mprnt(buff)
  2629. write(buff,5)hsupnd
  2630. call mprnt(buff)
  2631. c
  2632. c Ready
  2633. c
  2634. 999 return
  2635. end
  2636. c
  2637. c ===========================================================================
  2638. c
  2639. subroutine mccmpr(mn,cfree,ccfree,endmem,nz,
  2640. x pnt,count,cfirst,cpermf,rowidx,code)
  2641. integer*4 mn,cfree,ccfree,endmem,nz,pnt(mn),rowidx(cfree),
  2642. x count(mn),cpermf(mn),cfirst,code
  2643. c
  2644. integer*4 i,j,pnt1,pnt2,pnt0
  2645. character*99 buff
  2646. c ---------------------------------------------------------------------------
  2647. 2 format(' NOT ENOUGH MEMORY DETECTED IN SUBROUTINE CCOMPRESS')
  2648. pnt0=nz+1
  2649. i=cfirst
  2650. 40 if(i.le.0)goto 30
  2651. pnt1=pnt(i)
  2652. if(pnt1.lt.pnt0)goto 10
  2653. if(pnt1.eq.pnt0)then
  2654. pnt0=pnt0+count(i)
  2655. goto 10
  2656. endif
  2657. pnt(i)=pnt0
  2658. pnt2=pnt1+count(i)-1
  2659. do 20 j=pnt1,pnt2
  2660. rowidx(pnt0)=rowidx(j)
  2661. pnt0=pnt0+1
  2662. 20 continue
  2663. 10 i=cpermf(i)
  2664. goto 40
  2665. 30 ccfree=endmem-pnt0-1
  2666. if(ccfree.lt.mn)then
  2667. write(buff,2)
  2668. call mprnt(buff)
  2669. code=-2
  2670. endif
  2671. return
  2672. end
  2673. c
  2674. c ===========================================================================
  2675. c
  2676. subroutine chknod(m,cfree,rfree,i,o,p,ccol,crow,mark,pntc,
  2677. x pntr,rowidx,colidx,supdeg,suplst,fnd)
  2678. c
  2679. integer*4 m,cfree,rfree,i,o,p,ccol(m),crow(m),mark(m),pntc(m),
  2680. x pntr(m),rowidx(cfree),colidx(rfree),supdeg(m),suplst(m),fnd
  2681. c
  2682. integer*4 ppnt1,ppnt2,k,l,pnt,ii,pnod
  2683. c
  2684. fnd=0
  2685. if(ccol(o)+crow(o).ne.p)goto 120
  2686. ppnt1=pntr(o)
  2687. ppnt2=ppnt1+crow(o)-1
  2688. 111 if(ppnt1.le.ppnt2)then
  2689. if(mark(colidx(ppnt1)).ne.i)goto 119
  2690. ppnt1=ppnt1+1
  2691. goto 111
  2692. endif
  2693. ppnt1=pntc(o)
  2694. ppnt2=ppnt1+ccol(o)-1
  2695. 112 if(ppnt1.le.ppnt2)then
  2696. if(mark(rowidx(ppnt1)).ne.i)goto 119
  2697. ppnt1=ppnt1+1
  2698. goto 112
  2699. endif
  2700. c
  2701. c include column o (and its list) in to the list of column i
  2702. c
  2703. pnod=o
  2704. 211 if(suplst(pnod).ne.0)then
  2705. pnod=suplst(pnod)
  2706. goto 211
  2707. endif
  2708. suplst(pnod)=suplst(i)
  2709. suplst(i)=o
  2710. supdeg(i)=supdeg(i)+supdeg(o)
  2711. c
  2712. c remove column/row o from the row and column files
  2713. c
  2714. ppnt1=pntr(o)
  2715. ppnt2=ppnt1+crow(o)-1
  2716. do 124 k=ppnt1,ppnt2
  2717. l=colidx(k)
  2718. pnt=pntc(l)
  2719. ii=pnt+ccol(l)-1
  2720. ccol(l)=ccol(l)-1
  2721. 123 if(pnt.le.ii)then
  2722. if(rowidx(pnt).eq.o)then
  2723. rowidx(pnt)=rowidx(ii)
  2724. goto 124
  2725. endif
  2726. pnt=pnt+1
  2727. goto 123
  2728. endif
  2729. 124 continue
  2730. ppnt1=pntc(o)
  2731. ppnt2=ppnt1+ccol(o)-1
  2732. do 127 k=ppnt1,ppnt2
  2733. l=rowidx(k)
  2734. pnt=pntr(l)
  2735. ii=pnt+crow(l)-1
  2736. crow(l)=crow(l)-1
  2737. 126 if(pnt.le.ii)then
  2738. if(colidx(pnt).eq.o)then
  2739. colidx(pnt)=colidx(ii)
  2740. goto 127
  2741. endif
  2742. pnt=pnt+1
  2743. goto 126
  2744. endif
  2745. 127 continue
  2746. crow(o)=-1
  2747. p=p-1
  2748. fnd=1
  2749. goto 120
  2750. 119 fnd=0
  2751. 120 return
  2752. end
  2753. c
  2754. c ===========================================================================
  2755. c
  2756. subroutine hpsort(n,iarr)
  2757. c
  2758. integer*4 n,iarr(n)
  2759. c
  2760. integer*4 i,j,l,ir,rra
  2761. c
  2762. c ---------------------------------------------------------------------------
  2763. c
  2764. l=n/2+1
  2765. ir=n
  2766. 10 if(l.gt.1)then
  2767. l=l-1
  2768. rra=iarr(l)
  2769. else
  2770. rra=iarr(ir)
  2771. iarr(ir)=iarr(1)
  2772. ir=ir-1
  2773. if(ir.le.1)then
  2774. iarr(1)=rra
  2775. goto 999
  2776. endif
  2777. endif
  2778. i=l
  2779. j=l+l
  2780. 20 if(j-ir)40,50,60
  2781. 40 if(iarr(j).lt.iarr(j+1))j=j+1
  2782. 50 if(rra.lt.iarr(j))then
  2783. iarr(i)=iarr(j)
  2784. i=j
  2785. j=j+j
  2786. else
  2787. j=ir+1
  2788. endif
  2789. goto 20
  2790. 60 iarr(i)=rra
  2791. goto 10
  2792. 999 return
  2793. end
  2794. c
  2795. c ===========================================================================
  2796. c ==========================================================================
  2797. c
  2798. subroutine symfact (pivots,rowidx,ecolpnt,count,
  2799. x vcstat,list,next,work,mark,fill,code)
  2800. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  2801. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  2802. c
  2803. integer*4 pivots(mn),ecolpnt(mn),count(mn),vcstat(mn),
  2804. x list(mn),next(mn),work(mn),mark(mn),rowidx(cfree),code
  2805. c
  2806. integer*4 i,ii,j,k,l,pnt1,pnt2,fnz,kprew,fill
  2807. character*99 buff
  2808. c
  2809. c --------------------------------------------------------------------------
  2810. c
  2811. fnz=nz+1
  2812. c
  2813. do 10 i=1,mn
  2814. list(i)=0
  2815. next(i)=0
  2816. mark(i)=0
  2817. work(i)=mn+1
  2818. 10 continue
  2819. do 15 i=1,pivotn
  2820. work(pivots(i))=i
  2821. 15 continue
  2822. do 20 i=1,n
  2823. if(vcstat(i).le.-2)goto 20
  2824. j=rowidx(ecolpnt(i))
  2825. next(i)=list(j)
  2826. list(j)=i
  2827. 20 continue
  2828. c
  2829. do 50 ii=1,pivotn
  2830. i=pivots(ii)
  2831. mark(i)=1
  2832. if(i.le.n)goto 50
  2833. l=fnz
  2834. ecolpnt(i)=fnz
  2835. kprew=list(i)
  2836. 60 if(kprew.eq.0)goto 70
  2837. pnt1=ecolpnt(kprew)
  2838. pnt2=count(kprew)
  2839. if(fnz.ge.cfree-m)then
  2840. write(buff,'(1x,a)')'Not enough memory'
  2841. call mprnt(buff)
  2842. code=-2
  2843. goto 999
  2844. endif
  2845. do j=pnt1,pnt2
  2846. k=rowidx(j)
  2847. if(mark(k).eq.0)then
  2848. mark(k)=1
  2849. rowidx(fnz)=k
  2850. fnz=fnz+1
  2851. endif
  2852. enddo
  2853. kprew=next(kprew)
  2854. goto 60
  2855. 70 do j=l,fnz-1
  2856. mark(rowidx(j))=0
  2857. enddo
  2858. count(i)=fnz-1
  2859. k=fnz-l
  2860. if(k.gt.0)then
  2861. call hpsrt(k,mn,rowidx(l),work)
  2862. j=rowidx(l)
  2863. next(i)=list(j)
  2864. list(j)=i
  2865. endif
  2866. 50 continue
  2867. fill=fnz-nz-1
  2868. 999 return
  2869. end
  2870. c
  2871. c ===========================================================================
  2872. c
  2873. subroutine transps(n,m,nz,colpnt,rowidx,colnz,
  2874. x rowpnt,colindex,rownz,perm)
  2875. c
  2876. integer*4 n,m,nz,colpnt(n+1),rowidx(nz),rowpnt(m+1),
  2877. x colindex(nz),perm(n)
  2878. real*8 colnz(nz),rownz(nz)
  2879. c
  2880. integer*4 i,j,k,pnt1,pnt2,ii
  2881. c
  2882. c ---------------------------------------------------------------------------
  2883. c
  2884. do 10 i=1,m+1
  2885. rowpnt(i)=0
  2886. 10 continue
  2887. do 20 i=1,n
  2888. pnt1=colpnt(i)
  2889. pnt2=colpnt(i+1)-1
  2890. do 30 j=pnt1,pnt2
  2891. k=rowidx(j)
  2892. rowpnt(k)=rowpnt(k)+1
  2893. 30 continue
  2894. 20 continue
  2895. c
  2896. j=rowpnt(1)
  2897. k=1
  2898. do 40 i=1,m
  2899. rowpnt(i)=k
  2900. k=k+j
  2901. j=rowpnt(i+1)
  2902. 40 continue
  2903. c
  2904. do 50 ii=1,n
  2905. i=perm(ii)
  2906. pnt1=colpnt(i)
  2907. pnt2=colpnt(i+1)-1
  2908. do 60 j=pnt1,pnt2
  2909. k=rowidx(j)
  2910. colindex(rowpnt(k))=i
  2911. rownz(rowpnt(k))=colnz(j)
  2912. rowpnt(k)=rowpnt(k)+1
  2913. 60 continue
  2914. 50 continue
  2915. c
  2916. do 70 i=1,m
  2917. rowpnt(m-i+2)=rowpnt(m-i+1)
  2918. 70 continue
  2919. rowpnt(1)=1
  2920. return
  2921. end
  2922. c
  2923. c =========================================================================
  2924. c
  2925. subroutine hpsrt(n,mn,iarr,index)
  2926. c
  2927. integer*4 n,mn,iarr(n),index(mn)
  2928. c
  2929. integer*4 i,j,l,ir,rra
  2930. c
  2931. c ---------------------------------------------------------------------------
  2932. c
  2933. l=n/2+1
  2934. ir=n
  2935. 10 if(l.gt.1)then
  2936. l=l-1
  2937. rra=iarr(l)
  2938. else
  2939. rra=iarr(ir)
  2940. iarr(ir)=iarr(1)
  2941. ir=ir-1
  2942. if(ir.le.1)then
  2943. iarr(1)=rra
  2944. goto 999
  2945. endif
  2946. endif
  2947. i=l
  2948. j=l+l
  2949. 20 if(j-ir)40,50,60
  2950. 40 if(index(iarr(j)).lt.index(iarr(j+1)))j=j+1
  2951. 50 if(index(rra).lt.index(iarr(j)))then
  2952. iarr(i)=iarr(j)
  2953. i=j
  2954. j=j+j
  2955. else
  2956. j=ir+1
  2957. endif
  2958. goto 20
  2959. 60 iarr(i)=rra
  2960. goto 10
  2961. 999 if(n.gt.0)then
  2962. if(index(iarr(n)).gt.mn)then
  2963. n=n-1
  2964. goto 999
  2965. endif
  2966. endif
  2967. return
  2968. end
  2969. c
  2970. c ===========================================================================
  2971. c ==========================================================================
  2972. c
  2973. subroutine newsmf(colpnt,pivots,rowidx,cnonz,ecolpnt,count,
  2974. x vcstat,invprm,snhead,nodtyp,mark,workr,list,prew,next,code)
  2975. c
  2976. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  2977. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  2978. common/logprt/ loglog,lfile
  2979. integer*4 loglog,lfile
  2980. c
  2981. integer*4 pivots(mn),ecolpnt(mn),count(mn),vcstat(mn),
  2982. x invprm(mn),snhead(mn),nodtyp(mn),mark(mn),rowidx(cfree),
  2983. x colpnt(n1),list(mn),prew(mn),next(mn),code
  2984. real*8 cnonz(nz),workr(mn)
  2985. c
  2986. integer*4 i,ii,j,k,l,o,pnt1,pnt2,fnz,kprew
  2987. character*99 buff
  2988. c
  2989. c --------------------------------------------------------------------------
  2990. c
  2991. fnz=nz+1
  2992. c
  2993. c Restructuring the ordering
  2994. c
  2995. k=0
  2996. l=mn+1
  2997. do i=1,pivotn
  2998. j=pivots(i)
  2999. if(vcstat(j).gt.-1)then
  3000. k=k+1
  3001. invprm(k)=j
  3002. else if(vcstat(j).eq.-1)then
  3003. l=l-1
  3004. invprm(l)=j
  3005. endif
  3006. enddo
  3007. c
  3008. write(buff,'(1x,a,i5,a)')
  3009. x 'Instable pivot(s), correcting',(mn-l+1),' pivot position(s)'
  3010. call mprnt(buff)
  3011. c
  3012. do i=1,k
  3013. pivots(i)=invprm(i)
  3014. enddo
  3015. pivotn=k
  3016. do i=l,mn
  3017. pivotn=pivotn+1
  3018. pivots(pivotn)=invprm(i)
  3019. enddo
  3020. c
  3021. c Reorder the matrix
  3022. c
  3023. do 10 i=1,mn
  3024. invprm(i)=0
  3025. snhead(i)=0
  3026. mark(i)=0
  3027. nodtyp(i)=mn+1
  3028. next(i)=0
  3029. prew(i)=0
  3030. list(i)=0
  3031. 10 continue
  3032. do i=1,pivotn
  3033. nodtyp(pivots(i))=i
  3034. enddo
  3035. do ii=1,pivotn
  3036. i=pivots(ii)
  3037. if(i.le.n)then
  3038. pnt1=colpnt(i)
  3039. pnt2=colpnt(i+1)-1
  3040. k=pnt2-pnt1+1
  3041. if(k.gt.0)then
  3042. do j=pnt1,pnt2
  3043. workr(rowidx(j))=cnonz(j)
  3044. enddo
  3045. call hpsrt(k,mn,rowidx(pnt1),nodtyp)
  3046. do j=pnt1,pnt2
  3047. cnonz(j)=workr(rowidx(j))
  3048. enddo
  3049. endif
  3050. ecolpnt(i)=pnt1
  3051. 15 if((pnt1.le.pnt2).and.(vcstat(rowidx(pnt2)).le.-2))then
  3052. pnt2=pnt2-1
  3053. goto 15
  3054. endif
  3055. count(i)=pnt2
  3056. if(pnt1.le.pnt2)then
  3057. j=rowidx(pnt1)
  3058. o=list(j)
  3059. next(i)=o
  3060. list(j)=i
  3061. if(o.ne.0)prew(o)=i
  3062. prew(i)=0
  3063. endif
  3064. endif
  3065. enddo
  3066. c
  3067. do 50 ii=1,pivotn
  3068. i=pivots(ii)
  3069. mark(i)=1
  3070. if(i.le.n)then
  3071. c
  3072. c Remove i from the secondary list
  3073. c
  3074. if(ecolpnt(i).le.count(i))then
  3075. k=next(i)
  3076. l=prew(i)
  3077. if(k.gt.0)then
  3078. prew(k)=l
  3079. endif
  3080. if(l.gt.0)then
  3081. next(l)=k
  3082. else
  3083. list(rowidx(ecolpnt(i)))=k
  3084. endif
  3085. endif
  3086. c
  3087. c Simple column of A
  3088. c
  3089. if(invprm(i).eq.0)then
  3090. l=ecolpnt(i)
  3091. k=count(i)-l+1
  3092. goto 72
  3093. endif
  3094. c
  3095. c Transformed column of A
  3096. c
  3097. pnt1=ecolpnt(i)
  3098. pnt2=count(i)
  3099. l=fnz
  3100. ecolpnt(i)=fnz
  3101. if(fnz.ge.cfree-mn)then
  3102. write(buff,'(1x,a)')'Not enough memory'
  3103. call mprnt(buff)
  3104. code=-1
  3105. goto 999
  3106. endif
  3107. do j=pnt1,pnt2
  3108. mark(rowidx(j))=1
  3109. rowidx(fnz)=rowidx(j)
  3110. fnz=fnz+1
  3111. enddo
  3112. goto 59
  3113. endif
  3114. c
  3115. c Create nonzero pattern
  3116. c
  3117. l=fnz
  3118. ecolpnt(i)=fnz
  3119. if(fnz.ge.cfree-mn)then
  3120. write(buff,'(1x,a)')'Not enough memory'
  3121. call mprnt(buff)
  3122. code=-2
  3123. goto 999
  3124. endif
  3125. kprew=list(i)
  3126. 25 if(kprew.eq.0)goto 59
  3127. k=next(kprew)
  3128. mark(kprew)=1
  3129. rowidx(fnz)=kprew
  3130. fnz=fnz+1
  3131. pnt1=ecolpnt(kprew)+1
  3132. pnt2=count(kprew)
  3133. ecolpnt(kprew)=pnt1
  3134. if(pnt1.le.pnt2)then
  3135. j=rowidx(pnt1)
  3136. o=list(j)
  3137. next(kprew)=o
  3138. list(j)=kprew
  3139. if(o.ne.0)prew(o)=kprew
  3140. prew(kprew)=0
  3141. endif
  3142. kprew=k
  3143. goto 25
  3144. c
  3145. c Build new column structure
  3146. c
  3147. 59 kprew=invprm(i)
  3148. 60 if(kprew.eq.0)goto 70
  3149. pnt1=ecolpnt(kprew)
  3150. pnt2=count(kprew)
  3151. do j=pnt1,pnt2
  3152. k=rowidx(j)
  3153. if(mark(k).eq.0)then
  3154. mark(k)=1
  3155. rowidx(fnz)=k
  3156. fnz=fnz+1
  3157. endif
  3158. enddo
  3159. kprew=snhead(kprew)
  3160. goto 60
  3161. c
  3162. c Linking invperms, free working arrays
  3163. c
  3164. 70 do j=l,fnz-1
  3165. mark(rowidx(j))=0
  3166. enddo
  3167. count(i)=fnz-1
  3168. k=fnz-l
  3169. if(k.gt.1)call hpsrt(k,mn,rowidx(l),nodtyp)
  3170. 72 if(k.gt.0)then
  3171. j=rowidx(l)
  3172. snhead(i)=invprm(j)
  3173. invprm(j)=i
  3174. endif
  3175. 50 continue
  3176. c
  3177. c End of creation of nonzero pattern, set up new supernode partitions
  3178. c
  3179. k=loglog
  3180. loglog=0
  3181. call supnode(ecolpnt,count,rowidx,vcstat,pivots,snhead,
  3182. x invprm,nodtyp)
  3183. loglog=k
  3184. 999 return
  3185. end
  3186. c
  3187. c =========================================================================
  3188. c super dense oszlopok 'multiply' kezelessel
  3189. c
  3190. c ===========================================================================
  3191. c
  3192. subroutine ffactor(pntc,crow,colpnt,rowidx,
  3193. x mark,pivcols,ccol,nonz,diag,
  3194. x cpermf,cpermb,rpermf,rpermb,pntr,cfill,rfill,
  3195. x cpnt,cnext,cprew,rindex,workr,
  3196. x fixn,dropn,fnzmax,fnzmin,active,oper,actual,slktyp,code)
  3197. c
  3198. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  3199. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  3200. c
  3201. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  3202. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  3203. c
  3204. common/numer/ tplus,tzer
  3205. real*8 tplus,tzer
  3206. c
  3207. integer*4 rowidx(cfree),rindex(rfree),colpnt(n1),
  3208. x pivcols(mn),cpermf(mn),cpermb(mn),rpermf(mn),rpermb(mn),
  3209. x ccol(mn),crow(mn),pntc(mn),pntr(mn),mark(mn),cfill(mn),
  3210. x cpnt(mn),cnext(mn),cprew(mn),slktyp(m),rfill(mn),fixn,
  3211. x dropn,fnzmax,fnzmin,active,col,dcols,code
  3212. real*8 nonz(cfree),diag(mn),workr(mn),actual(mn),oper
  3213. character*99 buff
  3214. c
  3215. c ---------------------------------------------------------------------------
  3216. c
  3217. c cpermf oszloplista elore lancolasa, fejmutato cfirst
  3218. c cpermb oszloplista hatra lancolasa, fejmutato clast
  3219. c rpermf sorlista elore lancolase, fejmutato rfirst
  3220. c rpermb sorlista hatra lancolasa, fejmutato rlast
  3221. c ccol oszlopszamlalok
  3222. c crow sorszamlalok (vcstat)
  3223. c pntc oszlopmutatok
  3224. c pntr sormutatok
  3225. c mark eliminacios integer segedtomb
  3226. c workr eliminacios real segedtomb
  3227. c cfill a sorfolytonos tarolas update-elesehez segedtomb
  3228. c rfill a sorfolytonos tarolas update-elesehez segedtomb
  3229. c cpnt szamlalok szerinti listak fejmutatoja
  3230. c cnext szamlalok szerinti elore-lancolt lista
  3231. c cprew szamlalok szerinti hatra-lancolt lista
  3232. c
  3233. c --------------------------------------------------------------------------
  3234. integer*4 pnt,pnt1,pnt2,i,j,k,l,o,p,endmem,ccfree,rcfree,pmode,
  3235. x rfirst,rlast,cfirst,clast,pcol,pcnt,ppnt1,ppnt2,fill,
  3236. x prewcol,ii,pass,minm,w1,wignore,method
  3237. real*8 pivot,ss,tltmp1,tltmp2
  3238. C CMSSW: Temporary integer array needed to avoid reusing REAL*8 for
  3239. C integer storage
  3240. integer*4 inds(mn)
  3241. c---------------------------------------------------------------------------
  3242. c
  3243. 1 format(' NOT ENOUGH MEMORY IN THE ROW FILE ')
  3244. 2 format(' NOT ENOUGH MEMORY IN THE COLUMN FILE ')
  3245. 3 format(' ROW REALAXED :',i6,' DIAG :',d12.6,' TYPE :',i3)
  3246. 4 format(' COLUMN DROPPED :',i6,' DIAG :',d12.6)
  3247. 6 format(' NONZEROS :',i12)
  3248. 7 format(' OPERATIONS :',f13.0)
  3249. 8 format(' Superdense cols. :',i12)
  3250. C CMSSW: Explicit initialization needed
  3251. tltmp1=0
  3252. tltmp2=0
  3253. c
  3254. c move elements in the dropped rows to the end of the columns
  3255. c
  3256. code=0
  3257. if((order.gt.2.5).and.(order.lt.3.5))then
  3258. method=1
  3259. write(buff,'(a)')' Minimum Local Fill-In Heuristic'
  3260. else
  3261. method=0
  3262. write(buff,'(a)')' Minimum Degree Heuristic'
  3263. endif
  3264. call mprnt(buff)
  3265. wignore=10
  3266. w1=0
  3267. pass=2
  3268. minm=-m-1
  3269. if(dropn.gt.0)then
  3270. do 15 i=1,n
  3271. if(crow(i).le.-2)goto 15
  3272. pnt1=colpnt(i)
  3273. pnt2=colpnt(i+1)-1
  3274. p=pnt2
  3275. do 16 j=pnt2,pnt1,-1
  3276. if(crow(rowidx(j)).gt.-2)goto 16
  3277. o=rowidx(j)
  3278. pivot=nonz(j)
  3279. rowidx(j)=rowidx(p)
  3280. rowidx(p)=o
  3281. nonz(j)=nonz(p)
  3282. nonz(p)=pivot
  3283. p=p-1
  3284. 16 continue
  3285. 15 continue
  3286. endif
  3287. c
  3288. c initialization
  3289. c
  3290. endmem=cfree
  3291. pivotn=0
  3292. pnt=nz+1
  3293. cfirst=0
  3294. clast =0
  3295. pmode =0
  3296. do 11 i=1,mn
  3297. pivcols(i)=0
  3298. ccol(i)=0
  3299. if(crow(i).gt.-2)then
  3300. crow(i)=0
  3301. else
  3302. if(minm.ge.crow(i))minm=crow(i)-1
  3303. endif
  3304. mark(i)=0
  3305. 11 continue
  3306. c
  3307. c set up the permut lists and compute crow
  3308. c
  3309. dcols=0
  3310. do 10 i=1,mn
  3311. if(crow(i).le.-2)goto 10
  3312. if(i.le.n)then
  3313. pnt1=colpnt(i)
  3314. pnt2=colpnt(i+1)-1
  3315. o=0
  3316. do while((pnt1+o.le.pnt2).and.(crow(rowidx(pnt1+o)).gt.-2))
  3317. o=o+1
  3318. enddo
  3319. if(o.ge.supdens)then
  3320. pass=1
  3321. crow(i)=minm
  3322. dcols=dcols+1
  3323. goto 10
  3324. endif
  3325. pnt2=pnt1+o-1
  3326. do j=pnt1,pnt2
  3327. crow(rowidx(j))=crow(rowidx(j))+1
  3328. enddo
  3329. pntc(i)=pnt1
  3330. ccol(i)=o
  3331. else
  3332. pntc(i)=pnt
  3333. ccol(i)=0
  3334. pnt=pnt+1
  3335. endif
  3336. if(cfirst.eq.0)then
  3337. cfirst=i
  3338. else
  3339. cpermf(clast)=i
  3340. endif
  3341. cpermb(i)=clast
  3342. clast=i
  3343. 10 continue
  3344. cpermf(clast)=0
  3345. ccfree=cfree-pnt
  3346. if(ccfree.lt.mn)then
  3347. write(buff,2)
  3348. call mprnt(buff)
  3349. code=-2
  3350. goto 999
  3351. endif
  3352. write(buff,8)dcols
  3353. call mprnt(buff)
  3354. if(pass.eq.1)then
  3355. tltmp1=tpiv2
  3356. tltmp2=tabs
  3357. tabs=tpiv2
  3358. endif
  3359. c
  3360. c create pointers to rindex
  3361. c
  3362. 500 do i=1,mn
  3363. cpnt(i) =0
  3364. cnext(i)=0
  3365. cprew(i)=0
  3366. workr(i)=0.0d+0
  3367. enddo
  3368. pnt=1
  3369. i=cfirst
  3370. rfirst=0
  3371. rlast=0
  3372. 25 if(i.gt.0)then
  3373. if(rfirst.eq.0)then
  3374. rfirst=i
  3375. else
  3376. rpermf(rlast)=i
  3377. endif
  3378. rpermb(i)=rlast
  3379. rlast=i
  3380. pntr(i)=pnt
  3381. rfill(i)=pnt
  3382. pnt=pnt+crow(i)
  3383. c
  3384. c initialize the counter lists
  3385. c
  3386. j=crow(i)+ccol(i)+1
  3387. if(j.gt.0)then
  3388. o=cpnt(j)
  3389. cnext(i)=o
  3390. cpnt(j)=i
  3391. if(o.ne.0)cprew(o)=i
  3392. endif
  3393. cprew(i)=0
  3394. i=cpermf(i)
  3395. goto 25
  3396. endif
  3397. rcfree=rfree-pnt
  3398. if(rcfree.lt.mn)then
  3399. write(buff,1)
  3400. call mprnt(buff)
  3401. code=-2
  3402. goto 999
  3403. endif
  3404. c
  3405. c create the row file : symbolical transps the matrix
  3406. c
  3407. i=cfirst
  3408. 26 if(i.gt.0)then
  3409. pnt1=pntc(i)
  3410. pnt2=pnt1+ccol(i)-1
  3411. do 27 j=pnt1,pnt2
  3412. k=rowidx(j)
  3413. if(crow(k).le.-2)goto 27
  3414. rindex(rfill(k))=i
  3415. rfill(k)=rfill(k)+1
  3416. 27 continue
  3417. i=cpermf(i)
  3418. goto 26
  3419. endif
  3420. rpermf(rlast)=0
  3421. pcol=0
  3422. c
  3423. c loop for pivots
  3424. c
  3425. 50 call fndpiv(cpnt,cnext,pntc,ccol,crow,rowidx,nonz,
  3426. C CMSSW: Prevent REAL*8 reusage warning
  3427. C Was: diag,pcol,pivot,pmode,method,workr,mark,rindex,pntr
  3428. x diag,pcol,pivot,pmode,method,inds,mark,rindex,pntr)
  3429. if (pcol.eq.0)goto 900
  3430. pivot=1.0d+0/pivot
  3431. diag(pcol)=pivot
  3432. ccfree=endmem-pntc(clast)-ccol(clast)
  3433. c
  3434. c compress column file
  3435. c
  3436. if(ccfree.lt.mn)then
  3437. call ccomprs(mn,cfree,ccfree,endmem,nz,
  3438. x pntc,ccol,cfirst,cpermf,rowidx,nonz,code)
  3439. if(code.lt.0)goto 999
  3440. endif
  3441. c
  3442. c remove pcol from the cpermf lists
  3443. c
  3444. prewcol=cpermb(pcol)
  3445. o=cpermf(pcol)
  3446. if(prewcol.ne.0)then
  3447. cpermf(prewcol)=o
  3448. else
  3449. cfirst=o
  3450. endif
  3451. if(o.eq.0)then
  3452. clast=prewcol
  3453. else
  3454. cpermb(o)=prewcol
  3455. endif
  3456. c
  3457. c remove pcol from the rpermf lists
  3458. c
  3459. prewcol=rpermb(pcol)
  3460. o=rpermf(pcol)
  3461. if(prewcol.ne.0)then
  3462. rpermf(prewcol)=o
  3463. else
  3464. rfirst=o
  3465. endif
  3466. if(o.eq.0)then
  3467. rlast=prewcol
  3468. else
  3469. rpermb(o)=prewcol
  3470. endif
  3471. c
  3472. c administration
  3473. c
  3474. pivotn=pivotn+1
  3475. pivcols(pivotn)=pcol
  3476. pcnt=ccol(pcol)+crow(pcol)
  3477. c
  3478. c remove pcol from the counter lists
  3479. c
  3480. o=cnext(pcol)
  3481. ii=cprew(pcol)
  3482. if(ii.eq.0)then
  3483. cpnt(pcnt+1)=o
  3484. else
  3485. cnext(ii)=o
  3486. endif
  3487. if(o.ne.0)cprew(o)=ii
  3488. pnt1=pntc(pcol)
  3489. pnt2=pnt1+ccol(pcol)-1
  3490. if(pnt1.gt.nz)then
  3491. ppnt1=endmem-pcnt
  3492. ppnt2=ppnt1+pcnt-1
  3493. endmem=endmem-pcnt
  3494. ccfree=ccfree-pcnt
  3495. pnt=ppnt1
  3496. do 60 j=pnt1,pnt2
  3497. o=rowidx(j)
  3498. mark(o)=1
  3499. workr(o)=nonz(j)
  3500. rowidx(pnt)=o
  3501. pnt=pnt+1
  3502. c
  3503. c remove pcol from the row file
  3504. c
  3505. rfill(o)=-1
  3506. cfill(o)=ccol(o)
  3507. l=pntr(o)
  3508. p=l+crow(o)-2
  3509. do 55 k=l,p
  3510. if(rindex(k).eq.pcol)then
  3511. rindex(k)=rindex(p+1)
  3512. goto 60
  3513. endif
  3514. 55 continue
  3515. 60 continue
  3516. pntc(pcol)=ppnt1
  3517. c
  3518. c create pivot column from the row file
  3519. c
  3520. pnt1=pntr(pcol)
  3521. pnt2=pnt1+crow(pcol)-1
  3522. do 70 i=pnt1,pnt2
  3523. o=rindex(i)
  3524. l=pntc(o)
  3525. p=l+ccol(o)-1
  3526. c
  3527. c move the original column
  3528. c
  3529. if(l.le.nz)then
  3530. if(ccfree.lt.mn)then
  3531. call ccomprs(mn,cfree,ccfree,endmem,nz,
  3532. x pntc,ccol,cfirst,cpermf,rowidx,nonz,code)
  3533. if(code.lt.0)goto 999
  3534. l=pntc(o)
  3535. p=l+ccol(o)-1
  3536. endif
  3537. ccfree=ccfree-ccol(o)
  3538. j=pntc(clast)+ccol(clast)
  3539. if(j.le.nz)j=nz+1
  3540. pntc(o)=j
  3541. do 72 k=l,p
  3542. nonz(j)=nonz(k)
  3543. rowidx(j)=rowidx(k)
  3544. j=j+1
  3545. 72 continue
  3546. l=pntc(o)
  3547. p=j-1
  3548. c
  3549. c update the cpermf lists
  3550. c
  3551. prewcol=cpermb(o)
  3552. k=cpermf(o)
  3553. if(prewcol.ne.0)then
  3554. cpermf(prewcol)=k
  3555. else
  3556. if(k.ne.0)then
  3557. cfirst=k
  3558. else
  3559. goto 93
  3560. endif
  3561. endif
  3562. if(k.eq.0)then
  3563. clast=prewcol
  3564. else
  3565. cpermb(k)=prewcol
  3566. endif
  3567. cpermf(clast)=o
  3568. cpermb(o)=clast
  3569. cpermf(o)=0
  3570. clast=o
  3571. 93 endif
  3572. c
  3573. c find element and move in the column o
  3574. c
  3575. cfill(o)=ccol(o)-1
  3576. rfill(o)= 0
  3577. do 75 k=l,p
  3578. if(rowidx(k).eq.pcol)then
  3579. mark(o)=1
  3580. rowidx(pnt)=o
  3581. pnt=pnt+1
  3582. workr(o)=nonz(k)
  3583. rowidx(k)=rowidx(p)
  3584. nonz(k)=nonz(p)
  3585. goto 70
  3586. endif
  3587. 75 continue
  3588. 70 continue
  3589. else
  3590. ppnt1=pnt1
  3591. ppnt2=pnt2
  3592. do 65 j=pnt1,pnt2
  3593. o=rowidx(j)
  3594. mark(o)=1
  3595. workr(o)=nonz(j)
  3596. c
  3597. c remove pcol from the row file
  3598. c
  3599. rfill(o)=-1
  3600. cfill(o)=ccol(o)
  3601. l=pntr(o)
  3602. p=l+crow(o)-2
  3603. do 67 k=l,p
  3604. if(rindex(k).eq.pcol)then
  3605. rindex(k)=rindex(p+1)
  3606. goto 65
  3607. endif
  3608. 67 continue
  3609. 65 continue
  3610. endif
  3611. ccol(pcol)=pcnt
  3612. c
  3613. c remove columns from the counter lists
  3614. c
  3615. do 77 j=ppnt1,ppnt2
  3616. i=rowidx(j)
  3617. o=cnext(i)
  3618. ii=cprew(i)
  3619. if(ii.eq.0)then
  3620. cpnt(crow(i)+ccol(i)+1)=o
  3621. else
  3622. cnext(ii)=o
  3623. endif
  3624. if(o.ne.0)cprew(o)=ii
  3625. 77 continue
  3626. c
  3627. c Sort pivot column, set-up workr
  3628. c
  3629. if(ppnt1.lt.ppnt2)call hpsort((ppnt2-ppnt1+1),rowidx(ppnt1))
  3630. do p=ppnt1,ppnt2
  3631. nonz(p)=workr(rowidx(p))
  3632. workr(rowidx(p))=workr(rowidx(p))*pivot
  3633. enddo
  3634. c
  3635. c elimination loop
  3636. c
  3637. do 80 p=ppnt1,ppnt2
  3638. i=rowidx(p)
  3639. ss=nonz(p)
  3640. c
  3641. c transforme diag and delete element from mark
  3642. c
  3643. diag(i)=diag(i)-ss*workr(i)
  3644. mark(i)=0
  3645. pcnt=pcnt-1
  3646. c
  3647. c transformation on the column i
  3648. c
  3649. fill=pcnt
  3650. pnt1=pntc(i)
  3651. pnt2=pnt1+cfill(i)-1
  3652. do 90 k=pnt1,pnt2
  3653. o=rowidx(k)
  3654. if(mark(o).ne.0)then
  3655. nonz(k)=nonz(k)-ss*workr(o)
  3656. fill=fill-1
  3657. mark(o)=0
  3658. endif
  3659. 90 continue
  3660. c
  3661. c compute the free space
  3662. c
  3663. ii=cpermf(i)
  3664. if(ii.eq.0)then
  3665. k=endmem-pnt2-1
  3666. else
  3667. k=pntc(ii)-pnt2-1
  3668. endif
  3669. c
  3670. c move column to the end of the column file
  3671. c
  3672. if(fill.gt.k)then
  3673. if (ccfree.lt.mn)then
  3674. call ccomprs(mn,cfree,ccfree,endmem,nz,
  3675. x pntc,ccol,cfirst,cpermf,rowidx,nonz,code)
  3676. if(code.lt.0)goto 999
  3677. pnt1=pntc(i)
  3678. pnt2=pnt1+cfill(i)-1
  3679. endif
  3680. if(i.ne.clast)then
  3681. l=pntc(clast)+ccol(clast)
  3682. pntc(i)=l
  3683. do 95 k=pnt1,pnt2
  3684. rowidx(l)=rowidx(k)
  3685. nonz(l)=nonz(k)
  3686. l=l+1
  3687. 95 continue
  3688. pnt1=pntc(i)
  3689. pnt2=l-1
  3690. prewcol=cpermb(i)
  3691. if(prewcol.eq.0)then
  3692. cfirst=ii
  3693. else
  3694. cpermf(prewcol)=ii
  3695. endif
  3696. cpermb(ii)=prewcol
  3697. cpermf(clast)=i
  3698. cpermb(i)=clast
  3699. clast=i
  3700. cpermf(clast)=0
  3701. endif
  3702. endif
  3703. c
  3704. c create fill in
  3705. c
  3706. do 97 k=p+1,ppnt2
  3707. o=rowidx(k)
  3708. if(mark(o).eq.0)then
  3709. mark(o)=1
  3710. else
  3711. pnt2=pnt2+1
  3712. nonz(pnt2)=-ss*workr(o)
  3713. rowidx(pnt2)=o
  3714. rfill(o)=rfill(o)+1
  3715. endif
  3716. 97 continue
  3717. pnt2=pnt2+1
  3718. ccol(i)=pnt2-pnt1
  3719. if(i.eq.clast)then
  3720. ccfree=endmem-pnt2-1
  3721. endif
  3722. 80 continue
  3723. c
  3724. c make space for fills in the row file
  3725. c
  3726. do 100 j=ppnt1,ppnt2
  3727. i=rowidx(j)
  3728. c
  3729. c update the counter lists
  3730. c
  3731. fill=ccol(i)+crow(i)+rfill(i)+1
  3732. o=cpnt(fill)
  3733. cnext(i)=o
  3734. cpnt(fill)=i
  3735. if(o.ne.0)cprew(o)=i
  3736. cprew(i)=0
  3737. pnt2=pntr(i)+crow(i)-1
  3738. c
  3739. c compute the free space
  3740. c
  3741. ii=rpermf(i)
  3742. if(ii.eq.0)then
  3743. k=rfree-pnt2-1
  3744. else
  3745. k=pntr(ii)-pnt2-1
  3746. endif
  3747. c
  3748. c move row to the end of the row file
  3749. c
  3750. if(k.lt.rfill(i))then
  3751. if(rcfree.lt.mn)then
  3752. call rcomprs(mn,rfree,
  3753. x rcfree,pntr,crow,rfirst,rpermf,rindex,code)
  3754. if(code.lt.0)goto 999
  3755. endif
  3756. if(ii.ne.0)then
  3757. pnt1=pntr(i)
  3758. pnt2=pnt1+crow(i)-1
  3759. pnt=pntr(rlast)+crow(rlast)
  3760. pntr(i)=pnt
  3761. do 110 l=pnt1,pnt2
  3762. rindex(pnt)=rindex(l)
  3763. pnt=pnt+1
  3764. 110 continue
  3765. c
  3766. c update the rperm lists
  3767. c
  3768. prewcol=rpermb(i)
  3769. if(prewcol.eq.0)then
  3770. rfirst=ii
  3771. else
  3772. rpermf(prewcol)=ii
  3773. endif
  3774. rpermb(ii)=prewcol
  3775. rpermf(rlast)=i
  3776. rpermb(i)=rlast
  3777. rlast=i
  3778. rpermf(rlast)=0
  3779. endif
  3780. endif
  3781. crow(i)=crow(i)+rfill(i)
  3782. if(i.eq.rlast)rcfree=rfree-crow(i)-pntr(i)
  3783. 100 continue
  3784. c
  3785. c make pointers to the end of the filled rows
  3786. c
  3787. do 120 j=ppnt1,ppnt2
  3788. rfill(rowidx(j))=pntr(rowidx(j))+crow(rowidx(j))-1
  3789. 120 continue
  3790. c
  3791. c generate fill in the row file
  3792. c
  3793. do 130 j=ppnt1,ppnt2
  3794. o=rowidx(j)
  3795. pnt1=pntc(o)+cfill(o)
  3796. pnt2=pntc(o)+ccol(o)-1
  3797. do 140 k=pnt1,pnt2
  3798. rindex(rfill(rowidx(k)))=o
  3799. rfill(rowidx(k))=rfill(rowidx(k))-1
  3800. 140 continue
  3801. 130 continue
  3802. c
  3803. c end of the pivot loop
  3804. c
  3805. goto 50
  3806. c
  3807. c compute the 'superdense' columns, enter in pass=2
  3808. c
  3809. 900 if(pass.eq.1)then
  3810. pass=pass+1
  3811. tpiv2=tltmp1
  3812. tabs=tltmp2
  3813. pmode=1
  3814. call ccomprs(mn,cfree,ccfree,endmem,nz,
  3815. x pntc,ccol,cfirst,cpermf,rowidx,nonz,code)
  3816. if(code.lt.0)goto 999
  3817. call excols(rowidx,nonz,rpermf,rpermb,crow,
  3818. x pntc,ccol,pivcols,cpermf,cpermb,workr,colpnt,diag,
  3819. x cfirst,clast,endmem,ccfree,minm,code)
  3820. if(code.lt.0)goto 999
  3821. goto 500
  3822. endif
  3823. c
  3824. c rank check
  3825. c
  3826. if(pivotn.lt.mn-fixn-dropn)then
  3827. i=cfirst
  3828. 910 if (i.gt.0)then
  3829. crow(i)=-2
  3830. if(i.le.n)then
  3831. w1=w1+1
  3832. if(w1.le.wignore)then
  3833. write(buff,4)i,diag(i)
  3834. call mprnt(buff)
  3835. endif
  3836. fixn=fixn+1
  3837. else
  3838. w1=w1+1
  3839. if(w1.le.wignore)then
  3840. write(buff,3)(i-n),diag(i),slktyp(i-n)
  3841. call mprnt(buff)
  3842. endif
  3843. actual(i)=-1
  3844. dropn=dropn+1
  3845. endif
  3846. i=cpermf(i)
  3847. goto 910
  3848. endif
  3849. active=mn-pivotn
  3850. w1=w1-wignore
  3851. if(w1.gt.0)then
  3852. write(buff,'(1x,a,i5)')'Warnings ignored:',w1
  3853. call mprnt(buff)
  3854. endif
  3855. endif
  3856. c
  3857. c repermut
  3858. c
  3859. do 955 i=1,mn
  3860. mark(i)=mn+1
  3861. pntr(i)=0
  3862. 955 continue
  3863. do 915 i=1,pivotn
  3864. mark(pivcols(i))=i
  3865. 915 continue
  3866. fill=0
  3867. oper=0.0d+0
  3868. do 920 i=1,mn
  3869. if(crow(i).le.-2)goto 920
  3870. pnt1=pntc(i)
  3871. if(pnt1.le.nz)goto 920
  3872. if(ccol(i).gt.0)then
  3873. pnt2=pnt1+ccol(i)-1
  3874. do j=pnt1,pnt2
  3875. workr(rowidx(j))=nonz(j)
  3876. enddo
  3877. call hpsrt(ccol(i),mn,rowidx(pnt1),mark)
  3878. do j=pnt1,pnt2
  3879. nonz(j)=workr(rowidx(j))
  3880. enddo
  3881. endif
  3882. fill=fill+ccol(i)
  3883. oper=oper+dble(ccol(i)*ccol(i)+ccol(i))/2.0d+0
  3884. 920 continue
  3885. do 950 i=1,n
  3886. if(crow(i).le.-2)goto 950
  3887. pnt1=colpnt(i)
  3888. pnt2=colpnt(i+1)-1
  3889. k=pnt2-pnt1+1
  3890. if(k.gt.0)then
  3891. do j=pnt1,pnt2
  3892. workr(rowidx(j))=nonz(j)
  3893. enddo
  3894. call hpsrt(k,mn,rowidx(pnt1),mark)
  3895. do j=pnt1,pnt2
  3896. nonz(j)=workr(rowidx(j))
  3897. enddo
  3898. endif
  3899. if(pntc(i).lt.nz)then
  3900. ccol(i)=k
  3901. fill=fill+ccol(i)
  3902. oper=oper+dble(ccol(i)*ccol(i)+ccol(i))/2.0d+0
  3903. endif
  3904. 950 continue
  3905. c
  3906. c create the counter inta1 for the minor iterations
  3907. c
  3908. do 960 i=1,pivotn
  3909. col=pivcols(pivotn-i+1)
  3910. if(ccol(col).eq.0)goto 960
  3911. pntr(col)=pntr(rowidx(pntc(col)))+ccol(col)
  3912. 960 continue
  3913. c
  3914. c modify ccol ( counter ->> pointer )
  3915. c
  3916. do 970 i=1,pivotn
  3917. col=pivcols(i)
  3918. ccol(col)=pntc(col)+ccol(col)-1
  3919. 970 continue
  3920. c
  3921. c end of ffactor
  3922. c
  3923. if(fnzmin.gt.fill)fnzmin=fill
  3924. if(fnzmax.lt.fill)fnzmax=fill
  3925. write(buff,6)fill
  3926. call mprnt(buff)
  3927. write(buff,7)oper
  3928. call mprnt(buff)
  3929. if(method.eq.1)tfind=-tfind
  3930. 999 return
  3931. end
  3932. c
  3933. c ===========================================================================
  3934. c
  3935. subroutine ccomprs(mn,cfree,ccfree,endmem,nz,
  3936. x pnt,count,cfirst,cpermf,rowidx,nonz,code)
  3937. integer*4 mn,cfree,ccfree,endmem,nz,pnt(mn),rowidx(cfree),
  3938. x count(mn),cpermf(mn),cfirst,code
  3939. real*8 nonz(cfree)
  3940. c
  3941. integer*4 i,j,pnt1,pnt2,pnt0
  3942. character*99 buff
  3943. c ---------------------------------------------------------------------------
  3944. 2 format(' NOT ENOUGH MEMORY DETECTED IN SUBROUTINE CCOMPRESS')
  3945. pnt0=nz+1
  3946. i=cfirst
  3947. 40 if(i.le.0)goto 30
  3948. pnt1=pnt(i)
  3949. if(pnt1.lt.pnt0)goto 10
  3950. if(pnt1.eq.pnt0)then
  3951. pnt0=pnt0+count(i)
  3952. goto 10
  3953. endif
  3954. pnt(i)=pnt0
  3955. pnt2=pnt1+count(i)-1
  3956. do 20 j=pnt1,pnt2
  3957. rowidx(pnt0)=rowidx(j)
  3958. nonz(pnt0)=nonz(j)
  3959. pnt0=pnt0+1
  3960. 20 continue
  3961. 10 i=cpermf(i)
  3962. goto 40
  3963. 30 ccfree=endmem-pnt0-1
  3964. if(ccfree.lt.mn)then
  3965. write(buff,2)
  3966. call mprnt(buff)
  3967. code=-2
  3968. endif
  3969. return
  3970. end
  3971. c
  3972. c ===========================================================================
  3973. c
  3974. subroutine rcomprs(mn,rfree,rcfree,pnt,count,rfirst,
  3975. x rpermf,rindex,code)
  3976. integer*4 mn,rfree,rcfree,pnt(mn),count(mn),rfirst,rpermf(mn),
  3977. x rindex(rfree),code
  3978. c
  3979. integer*4 i,j,ppnt,pnt1,pnt2
  3980. character*99 buff
  3981. c
  3982. c ---------------------------------------------------------------------------
  3983. c
  3984. 2 format(' NOT ENOUGH MEMORY DETECTED IN SUBROUTINE RCOMPRESS')
  3985. ppnt=1
  3986. i=rfirst
  3987. 5 if(i.eq.0)goto 20
  3988. pnt1=pnt(i)
  3989. if(ppnt.eq.pnt1)then
  3990. ppnt=ppnt+count(i)
  3991. goto 15
  3992. endif
  3993. pnt2=pnt1+count(i)-1
  3994. pnt(i)=ppnt
  3995. do 10 j=pnt1,pnt2
  3996. rindex(ppnt)=rindex(j)
  3997. ppnt=ppnt+1
  3998. 10 continue
  3999. 15 i=rpermf(i)
  4000. goto 5
  4001. 20 rcfree=rfree-ppnt
  4002. if(rcfree.lt.mn)then
  4003. write(buff,2)
  4004. call mprnt(buff)
  4005. code=-2
  4006. endif
  4007. return
  4008. end
  4009. c
  4010. c ==========================================================================
  4011. c
  4012. subroutine excols(rowidx,nonz,rpermf,rpermb,crow,
  4013. x pntc,ccol,pivcols,cpermf,cpermb,workr,colpnt,diag,
  4014. x cfirst,clast,endmem,ccfree,minm,code)
  4015. c
  4016. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4017. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4018. c
  4019. integer*4 rowidx(cfree),rpermf(mn),rpermb(mn),crow(mn),
  4020. x pntc(mn),ccol(mn),pivcols(mn),cpermf(mn),cpermb(mn),colpnt(n1),
  4021. x cfirst,clast,endmem,ccfree,minm,code
  4022. real*8 nonz(cfree),workr(mn),diag(mn)
  4023. c
  4024. integer*4 i,j,k,l,o,prewcol,pnt1,pnt2,ppnt1,ppnt2
  4025. real*8 ss
  4026. character*99 buff
  4027. c
  4028. c ----------------------------------------------------------------------------
  4029. c
  4030. 2 format(' NOT ENOUGH MEMORY IN THE COLUMN FILE ')
  4031. c
  4032. do i=1,mn
  4033. rpermf(i)=0
  4034. rpermb(i)=0
  4035. if(crow(i).gt.-2)crow(i)=0
  4036. enddo
  4037. do i=1,pivotn
  4038. crow(pivcols(i))=-1
  4039. enddo
  4040. prewcol=0
  4041. do 200 i=1,n
  4042. if(crow(i).ne.minm)goto 200
  4043. if(prewcol.eq.0)prewcol=i
  4044. ppnt1=colpnt(i)
  4045. ppnt2=colpnt(i+1)-1
  4046. c
  4047. c update column's permut list
  4048. c
  4049. if(clast.ne.0)then
  4050. pnt1=pntc(clast)+ccol(clast)
  4051. cpermf(clast)=i
  4052. else
  4053. cfirst=i
  4054. pnt1=0
  4055. endif
  4056. cpermb(i)=clast
  4057. cpermf(i)=0
  4058. clast=i
  4059. if(pnt1.lt.nz)pnt1=nz+1
  4060. pntc(i)=pnt1
  4061. pnt2=pnt1
  4062. c
  4063. c repack the original column
  4064. c
  4065. do 202 j=ppnt1,ppnt2
  4066. k=rowidx(j)
  4067. if(crow(k).gt.-2)then
  4068. workr(k)=nonz(j)
  4069. rpermf(k)=1
  4070. if(crow(k).eq.-1)then
  4071. rpermb(k)=rpermb(k)+1
  4072. endif
  4073. rowidx(pnt2)=k
  4074. pnt2=pnt2+1
  4075. endif
  4076. 202 continue
  4077. c
  4078. c Ftran on the column
  4079. c
  4080. do j=1,pivotn
  4081. o=pivcols(j)
  4082. if(rpermf(o).gt.0)then
  4083. ppnt1=pntc(o)
  4084. ppnt2=ppnt1+ccol(o)-1
  4085. ss=-workr(o)*diag(o)
  4086. diag(i)=diag(i)+ss*workr(o)
  4087. do k=ppnt1,ppnt2
  4088. l=rowidx(k)
  4089. if(rpermf(l).eq.0)then
  4090. workr(l)=nonz(k)*ss
  4091. rowidx(pnt2)=l
  4092. pnt2=pnt2+1
  4093. rpermf(l)=1
  4094. if((crow(l).eq.-1).or.(l.lt.i))then
  4095. rpermb(l)=rpermb(l)+1
  4096. endif
  4097. else
  4098. workr(l)=workr(l)+nonz(k)*ss
  4099. endif
  4100. enddo
  4101. endif
  4102. enddo
  4103. c
  4104. c augftr with the prewious columns
  4105. c
  4106. j=prewcol
  4107. 215 if(j.ne.i)then
  4108. ppnt1=pntc(j)
  4109. ppnt2=ppnt1+ccol(j)-1
  4110. do k=ppnt1,ppnt2
  4111. l=rowidx(k)
  4112. if((crow(l).eq.-1).and.(rpermf(l).gt.0))then
  4113. if(rpermf(j).eq.0)then
  4114. workr(j)=-workr(l)*nonz(k)*diag(l)
  4115. rowidx(pnt2)=j
  4116. pnt2=pnt2+1
  4117. rpermf(j)=1
  4118. rpermb(j)=rpermb(j)+1
  4119. else
  4120. workr(j)=workr(j)-workr(l)*nonz(k)*diag(l)
  4121. endif
  4122. endif
  4123. enddo
  4124. j=cpermf(j)
  4125. goto 215
  4126. endif
  4127. ccol(i)=pnt2-pnt1
  4128. c
  4129. c pack the column
  4130. c
  4131. pnt2=pnt2-1
  4132. do j=pnt1,pnt2
  4133. o=rowidx(j)
  4134. nonz(j)=workr(o)
  4135. rpermf(o)=0
  4136. enddo
  4137. ccfree=endmem-pntc(clast)-ccol(clast)
  4138. if(ccfree.lt.mn)then
  4139. write(buff,2)
  4140. call mprnt(buff)
  4141. code=-2
  4142. goto 999
  4143. endif
  4144. crow(i)=0
  4145. 200 continue
  4146. c
  4147. c Make space in the old factors
  4148. c
  4149. o=0
  4150. do i=1,pivotn
  4151. j=pivcols(i)
  4152. o=o+rpermb(j)
  4153. enddo
  4154. ppnt1=endmem-o
  4155. if(ccfree.le.o)then
  4156. write(buff,2)
  4157. call mprnt(buff)
  4158. code=-2
  4159. goto 999
  4160. endif
  4161. endmem=ppnt1
  4162. ccfree=ccfree-o
  4163. do i=pivotn,1,-1
  4164. k=pivcols(i)
  4165. pnt1=pntc(k)
  4166. if(pnt1.gt.nz)then
  4167. pnt2=pnt1+ccol(k)-1
  4168. pntc(k)=ppnt1
  4169. do j=pnt1,pnt2
  4170. rowidx(ppnt1)=rowidx(j)
  4171. nonz(ppnt1)=nonz(j)
  4172. ppnt1=ppnt1+1
  4173. enddo
  4174. ppnt1=ppnt1+rpermb(k)
  4175. endif
  4176. enddo
  4177. c
  4178. c make space in the active submatrix
  4179. c
  4180. o=0
  4181. i=cfirst
  4182. 220 if(i.ne.0)then
  4183. o=o+rpermb(i)
  4184. i=cpermf(i)
  4185. goto 220
  4186. endif
  4187. if(ccfree.le.o)then
  4188. write(buff,2)
  4189. call mprnt(buff)
  4190. code=-2
  4191. goto 999
  4192. endif
  4193. ccfree=ccfree-o
  4194. ppnt1=pntc(clast)+ccol(clast)+o
  4195. i=clast
  4196. 230 if(i.ne.0)then
  4197. pnt1=pntc(i)
  4198. if(pnt1.gt.nz)then
  4199. pnt2=pnt1+ccol(i)-1
  4200. ppnt1=ppnt1-rpermb(i)
  4201. do j=pnt2,pnt1,-1
  4202. rowidx(ppnt1)=rowidx(j)
  4203. nonz(ppnt1)=nonz(j)
  4204. ppnt1=ppnt1-1
  4205. enddo
  4206. pntc(i)=ppnt1+1
  4207. endif
  4208. i=cpermb(i)
  4209. goto 230
  4210. endif
  4211. c
  4212. c Store the dense columns in the final positions
  4213. c
  4214. i=prewcol
  4215. 250 if(i.gt.0)then
  4216. pnt1=pntc(i)
  4217. pnt2=pnt1+ccol(i)-1
  4218. ppnt1=pnt1
  4219. do j=pnt1,pnt2
  4220. o=rowidx(j)
  4221. if((crow(o).eq.-1).or.(o.lt.i))then
  4222. k=pntc(o)+ccol(o)
  4223. nonz(k)=nonz(j)
  4224. rowidx(k)=i
  4225. ccol(o)=ccol(o)+1
  4226. else
  4227. nonz(ppnt1)=nonz(j)
  4228. rowidx(ppnt1)=rowidx(j)
  4229. ppnt1=ppnt1+1
  4230. endif
  4231. enddo
  4232. ccol(i)=ppnt1-pnt1
  4233. i=cpermf(i)
  4234. goto 250
  4235. endif
  4236. c
  4237. c compute crow
  4238. c
  4239. do i=1,mn
  4240. if(crow(i).gt.-2)crow(i)=0
  4241. enddo
  4242. i=cfirst
  4243. 280 if(i.gt.0)then
  4244. pnt1=pntc(i)
  4245. pnt2=pnt1+ccol(i)-1
  4246. do j=pnt1,pnt2
  4247. crow(rowidx(j))=crow(rowidx(j))+1
  4248. enddo
  4249. i=cpermf(i)
  4250. goto 280
  4251. endif
  4252. 999 return
  4253. end
  4254. c
  4255. c =============================================================================
  4256. c Find pivot in the augmented system
  4257. c Prefer the pivot for expanding the supernodes
  4258. c Method=0 minimum count
  4259. c Method=1 minimum local fill in
  4260. c ===========================================================================
  4261. c
  4262. subroutine fndpiv(cpnt,cnext,pntc,ccol,crow,rowidx,nonzeros,
  4263. x diag,pivcol,pivot,md,method,inds,mark,rindex,pntr)
  4264. c
  4265. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4266. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4267. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4268. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4269. c
  4270. integer*4 cpnt(mn),cnext(mn),pntc(mn),ccol(mn),crow(mn),pivcol,
  4271. x rowidx(cfree),md,method,inds(mn),mark(mn),rindex(rfree),
  4272. x pntr(mn)
  4273. real*8 nonzeros(cfree),diag(mn),pivot
  4274. c --------------------------------------------------------------------------
  4275. integer*4 j,k,l,o,nnz,ffind,oldpcol,oldlen,p1,p2,srcmod
  4276. integer*4 fill,mfill,q,oo,kk
  4277. real*8 sol,stab,stab1,d,toler,ss
  4278. c --------------------------------------------------------------------------
  4279. C CMSSW: Explicit initialization needed
  4280. p1=0
  4281. p2=0
  4282. oldlen=0
  4283. fill=0
  4284. stab=0
  4285. stab1=0
  4286. c
  4287. c find pivot in sparse columns
  4288. c
  4289. mfill=-1
  4290. toler=tpiv1
  4291. if(md.gt.0)then
  4292. srcmod=1
  4293. goto 101
  4294. endif
  4295. 10 pivcol=pivcol+1
  4296. if (pivcol.ge.n)goto 100
  4297. if(crow(pivcol).ne.0)goto 10
  4298. if(ccol(pivcol).gt.lam)goto 10
  4299. pivot=diag(pivcol)
  4300. if(abs(pivot).lt.tpiv2)goto 10
  4301. goto 200
  4302. c
  4303. c find pivot in the another columns
  4304. c
  4305. 100 md=1
  4306. srcmod=0
  4307. 101 oldpcol=pivcol
  4308. pivcol=0
  4309. stab1=0
  4310. pivot=0
  4311. nnz=md-1
  4312. ffind=0
  4313. if(nnz.lt.1)nnz=1
  4314. md=md-1
  4315. if(md.le.1)md=1
  4316. c
  4317. c Find supernodal pivot (srcmode=1)
  4318. c
  4319. 115 if(oldpcol.eq.0)goto 112
  4320. p1=pntc(oldpcol)
  4321. p2=p1+ccol(oldpcol)-1
  4322. oldlen=ccol(oldpcol)
  4323. 125 if(p1.gt.p2)goto 114
  4324. j=rowidx(p1)
  4325. if((crow(j)+ccol(j)).lt.oldlen)goto 121
  4326. 145 p1=p1+1
  4327. goto 125
  4328. 114 if(pivcol.gt.0)goto 200
  4329. c
  4330. c Find another pivot
  4331. c
  4332. 112 srcmod=0
  4333. md=0
  4334. 110 j=cpnt(nnz)
  4335. if((j.gt.0).and.(md.eq.0))md=nnz
  4336. 120 if(j.le.0)goto 150
  4337. c
  4338. c Compute fill in
  4339. c
  4340. if(method.ne.0)then
  4341. q=0
  4342. k=pntc(j)
  4343. l=k+ccol(j)-1
  4344. do o=k,l
  4345. q=q+1
  4346. inds(q)=rowidx(o)
  4347. mark(rowidx(o))=1
  4348. enddo
  4349. k=pntr(j)
  4350. l=k+crow(j)-1
  4351. do o=k,l
  4352. q=q+1
  4353. inds(q)=rindex(o)
  4354. mark(rindex(o))=1
  4355. enddo
  4356. fill=(q*(q-1))/2
  4357. do kk=1,q
  4358. o=inds(kk)
  4359. k=pntc(o)
  4360. l=k+ccol(o)-1
  4361. do oo=k,l
  4362. fill=fill-mark(rowidx(oo))
  4363. enddo
  4364. enddo
  4365. do o=1,q
  4366. mark(inds(o))=0
  4367. enddo
  4368. else
  4369. fill=crow(j)
  4370. endif
  4371. ffind=ffind+1
  4372. if((mfill.ge.0).and.(fill.ge.mfill))goto 130
  4373. 121 d=diag(j)
  4374. sol=abs(d)
  4375. if(sol.lt.tabs)goto 130
  4376. k=pntc(j)
  4377. c
  4378. c stability test
  4379. c
  4380. stab=sol
  4381. l=k+ccol(j)-1
  4382. do 32 o=k,l
  4383. ss=abs(nonzeros(o))
  4384. if(stab.lt.ss)stab=ss
  4385. 32 continue
  4386. stab=sol/stab
  4387. if(stab.lt.toler)goto 130
  4388. if(mfill.lt.0)mfill=fill+1
  4389. if((fill.lt.mfill).or.((fill.eq.mfill).and.(stab.gt.stab1)))then
  4390. pivot=d
  4391. pivcol=j
  4392. stab1=stab
  4393. mfill=fill
  4394. goto 130
  4395. endif
  4396. 130 if((srcmod.gt.0).and.(pivcol.ne.0))then
  4397. cccc md=md-1
  4398. cccc if(md.lt.1)md=1
  4399. goto 200
  4400. endif
  4401. if((ffind.gt.tfind).and.(pivcol.ne.0))goto 200
  4402. if(srcmod.gt.0)goto 145
  4403. j=cnext(j)
  4404. goto 120
  4405. 150 if((pivcol.eq.0).or.(method.ne.0))then
  4406. nnz=nnz+1
  4407. if(nnz.le.mn)goto 110
  4408. if(pivcol.gt.0)goto 200
  4409. toler=toler/10
  4410. nnz=md
  4411. if((toler.ge.tpiv2).and.(nnz.gt.0))goto 115
  4412. md=1
  4413. endif
  4414. 200 return
  4415. end
  4416. c
  4417. c ==========================================================================
  4418. c Supernodal left looking, primer supernode loop (cache),
  4419. c Supernode update with indirect addressing
  4420. c Relative pivot tolerance
  4421. c =============================================================================
  4422. c
  4423. subroutine nfactor(ecolpnt,
  4424. x vcstat,rowidx,pivots,count,
  4425. x nonzeros,diag,err,updat,mut,index,dropn,slktyp,
  4426. x snhead,fpnt,invperm,nodtyp,dv,odiag)
  4427. c
  4428. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4429. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4430. c
  4431. integer*4 err,mut(mn),dropn,ecolpnt(mn),vcstat(mn),
  4432. x rowidx(cfree),pivots(mn),count(mn),index(mn),slktyp(m)
  4433. integer*4 snhead(mn),fpnt(mn),invperm(mn),nodtyp(mn)
  4434. real*8 nonzeros(cfree),diag(mn),updat(mn),dv(m),odiag(mn)
  4435. c
  4436. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4437. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4438. common/numer/ tplus,tzer
  4439. real*8 tplus,tzer
  4440. c -----------------------------------------------------------------------------
  4441. integer*4 i,j,k,o,p,pnt1,pnt2,ppnt1,ppnt2,col,kprew,
  4442. x prewnode,ppnode,rb,w1
  4443. real*8 s,diap,diam
  4444. character*99 buff
  4445. c------------------------------------------------------------------------------
  4446. C CMSSW: Explicit initialization needed
  4447. ppnt1=0
  4448. ppnt2=0
  4449. err=0
  4450. w1=0
  4451. c
  4452. c initialization
  4453. c
  4454. do 10 i=1,mn
  4455. mut(i)=0
  4456. index(i)=0
  4457. updat(i)=0.0
  4458. fpnt(i)=ecolpnt(i)
  4459. 10 continue
  4460. ppnode=0
  4461. prewnode=0
  4462. i=0
  4463. c
  4464. c loop for pivot columns
  4465. c
  4466. 100 i=i+1
  4467. if(i.gt.pivotn)goto 60
  4468. col=pivots(i)
  4469. c
  4470. c step vcstat if relaxed
  4471. c
  4472. if(vcstat(col).le.-2)then
  4473. call colremv(i,col,mut,index,fpnt,count,pivots,invperm,
  4474. x snhead,nodtyp,rowidx,nonzeros,ppnode,prewnode)
  4475. diag(col)=0.0
  4476. i=i-1
  4477. if((ppnode.gt.0).and.(prewnode.eq.i))goto 110
  4478. goto 100
  4479. endif
  4480. c
  4481. ppnt1=ecolpnt(col)
  4482. ppnt2=count(col)
  4483. if(ppnt1.le.nz)then
  4484. diag(col)=1.0d00/diag(col)
  4485. goto 180
  4486. endif
  4487. kprew=index(col)
  4488. c
  4489. c compute
  4490. c
  4491. diap=diag(col)
  4492. diam=0.0d+0
  4493. 130 if(kprew)129,150,131
  4494. c
  4495. c Standard transformation
  4496. c
  4497. 131 k=mut(kprew)
  4498. pnt1=fpnt(kprew)
  4499. pnt2=count(kprew)
  4500. if(pnt1.lt.pnt2)then
  4501. o=rowidx(pnt1+1)
  4502. mut(kprew)=index(o)
  4503. index(o)=kprew
  4504. endif
  4505. pnt1=pnt1+1
  4506. fpnt(kprew)=pnt1
  4507. s=-nonzeros(pnt1-1)*diag(kprew)
  4508. if(kprew.le.n)then
  4509. diap=diap+s*nonzeros(pnt1-1)
  4510. else
  4511. diam=diam+s*nonzeros(pnt1-1)
  4512. endif
  4513. do 170 o=pnt1,pnt2
  4514. updat(rowidx(o))=updat(rowidx(o))+s*nonzeros(o)
  4515. 170 continue
  4516. kprew=k
  4517. goto 130
  4518. c
  4519. c supernodal transformation
  4520. c
  4521. 129 kprew=-kprew
  4522. k=mut(kprew)
  4523. p=invperm(kprew)
  4524. pnt1=fpnt(kprew)+1
  4525. if(pnt1.le.count(kprew))then
  4526. o=rowidx(pnt1)
  4527. mut(kprew)=index(o)
  4528. index(o)=-kprew
  4529. endif
  4530. if(kprew.le.n)then
  4531. call cspnd(p,snhead(p),diag,nonzeros,
  4532. x fpnt,count,pivots,updat,diap,rowidx(pnt1))
  4533. else
  4534. call cspnd(p,snhead(p),diag,nonzeros,
  4535. x fpnt,count,pivots,updat,diam,rowidx(pnt1))
  4536. endif
  4537. kprew=k
  4538. goto 130
  4539. c
  4540. c pack a column, and free the working array
  4541. c
  4542. 150 do k=ppnt1,ppnt2
  4543. nonzeros(k)=updat(rowidx(k))
  4544. updat(rowidx(k))=0
  4545. enddo
  4546. c
  4547. c set up diag
  4548. c
  4549. if((ppnode.le.0).or.(prewnode.ne.snhead(i)))then
  4550. diap=diap+diam
  4551. diam=max(trabs,abs(diam*trabs))
  4552. if(abs(diap).lt.diam)then
  4553. call rngchk(rowidx,nonzeros,ecolpnt(col),count(col),
  4554. x vcstat,rb,diag,slktyp,dropn,col,dv,diap,w1,odiag(col))
  4555. if(rb.ne.0)err=1
  4556. diag(col)=diap
  4557. if(vcstat(col).le.-2)goto 100
  4558. else
  4559. diag(col)=1.0d00/diap
  4560. endif
  4561. else
  4562. diag(col)=diam
  4563. updat(col)=diap
  4564. endif
  4565. c
  4566. c Transformation in (primer) supernode
  4567. c
  4568. 110 if(prewnode.eq.i)then
  4569. if(ppnode.gt.0)then
  4570. do j=ppnode+1,i
  4571. o=j-1
  4572. p=pivots(j)
  4573. call cspnode(ppnode,o,diag,nonzeros,fpnt,count,pivots,
  4574. x nonzeros(ecolpnt(p)),diag(p))
  4575. diam=max(trabs,abs(diag(p)*trabs))
  4576. diag(p)=diag(p)+updat(p)
  4577. if(abs(diag(p)).lt.diam)then
  4578. call rngchk(rowidx,nonzeros,ecolpnt(p),count(p),
  4579. x vcstat,rb,diag,slktyp,dropn,p,dv,diag(p),w1,odiag(p))
  4580. if(rb.ne.0)err=1
  4581. else
  4582. diag(p)=1.0d00/diag(p)
  4583. endif
  4584. enddo
  4585. endif
  4586. ppnode=0
  4587. endif
  4588. c
  4589. c Update the linked list
  4590. c
  4591. 180 if(snhead(i).eq.0)then
  4592. ppnode=0
  4593. if(ppnt1.le.ppnt2)then
  4594. j=rowidx(ppnt1)
  4595. mut(col)=index(j)
  4596. index(j)=col
  4597. endif
  4598. prewnode=0
  4599. else
  4600. if(prewnode.ne.snhead(i))then
  4601. prewnode=snhead(i)
  4602. if(nodtyp(i).gt.0)then
  4603. ppnode=i
  4604. else
  4605. ppnode=-i
  4606. endif
  4607. if(ecolpnt(pivots(prewnode)).le.count(pivots(prewnode)))then
  4608. j=rowidx(ecolpnt(pivots(prewnode)))
  4609. mut(col)=index(j)
  4610. index(j)=-col
  4611. endif
  4612. endif
  4613. endif
  4614. c
  4615. c end of the main loop
  4616. c
  4617. goto 100
  4618. c
  4619. c end of mfactor
  4620. c
  4621. 60 if(w1.gt.0)then
  4622. write(buff,'(1x,a,i6)')'Total warnings of row dependencies:',w1
  4623. call mprnt(buff)
  4624. endif
  4625. return
  4626. end
  4627. c
  4628. c =============================================================================
  4629. c
  4630. subroutine colremv(i,col,mut,index,fpnt,count,pivots,invperm,
  4631. x snhead,nodtyp,rowidx,nonzeros,ppnode,prewnode)
  4632. c
  4633. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4634. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4635. c
  4636. integer*4 i,col,mut(mn),index(mn),fpnt(mn),count(mn),pivots(mn),
  4637. x invperm(mn),snhead(mn),nodtyp(mn),rowidx(cfree),ppnode,
  4638. x prewnode
  4639. real*8 nonzeros(cfree)
  4640. c
  4641. integer*4 j,jj,k,l,o,p,pnt1
  4642. c
  4643. jj=index(col)
  4644. 195 if(jj.eq.0)goto 103
  4645. if(jj.lt.0)then
  4646. j=-jj
  4647. else
  4648. j=jj
  4649. endif
  4650. k=mut(j)
  4651. pnt1=fpnt(j)
  4652. call move(pnt1,count(j),rowidx,nonzeros)
  4653. if(pnt1.le.count(j))then
  4654. o=rowidx(pnt1)
  4655. mut(j)=index(o)
  4656. index(o)=jj
  4657. endif
  4658. if(jj.lt.0)then
  4659. p=invperm(j)
  4660. l=snhead(p)
  4661. do o=p+1,l
  4662. call move(fpnt(pivots(o)),count(pivots(o)),rowidx,nonzeros)
  4663. enddo
  4664. endif
  4665. jj=k
  4666. goto 195
  4667. c
  4668. c Step in the primer supernode
  4669. c
  4670. 103 if((ppnode.gt.0).and.(prewnode.eq.snhead(i)))then
  4671. l=i-1
  4672. do o=ppnode,l
  4673. pnt1=fpnt(pivots(o))
  4674. 104 if(pnt1.le.count(pivots(o)))then
  4675. if(rowidx(pnt1).eq.col)then
  4676. call move(pnt1,count(pivots(o)),rowidx,nonzeros)
  4677. pnt1=count(pivots(o))
  4678. endif
  4679. pnt1=pnt1+1
  4680. goto 104
  4681. endif
  4682. enddo
  4683. endif
  4684. c
  4685. c Make changes
  4686. c
  4687. pivotn=pivotn-1
  4688. do j=i,pivotn
  4689. pivots(j)=pivots(j+1)
  4690. snhead(j)=snhead(j+1)
  4691. nodtyp(j)=nodtyp(j+1)
  4692. enddo
  4693. do j=1,pivotn
  4694. if(snhead(j).ge.i)snhead(j)=snhead(j)-1
  4695. invperm(pivots(j))=j
  4696. enddo
  4697. if(prewnode.ge.i)prewnode=prewnode-1
  4698. return
  4699. end
  4700. c
  4701. c =============================================================================
  4702. c
  4703. subroutine move(pnt1,pnt2,rowidx,nonzeros)
  4704. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4705. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4706. integer*4 pnt1,pnt2,rowidx(cfree),i,j
  4707. real*8 nonzeros(cfree),s
  4708. if(pnt1.le.pnt2)then
  4709. j=rowidx(pnt1)
  4710. s=nonzeros(pnt1)
  4711. pnt2=pnt2-1
  4712. do i=pnt1,pnt2
  4713. nonzeros(i)=nonzeros(i+1)
  4714. rowidx(i)=rowidx(i+1)
  4715. enddo
  4716. rowidx(pnt2+1)=j
  4717. nonzeros(pnt2+1)=s
  4718. endif
  4719. return
  4720. end
  4721. c
  4722. c =============================================================================
  4723. c Supernodal left looking, primer supernode loop (cache),
  4724. c Supernode update with indirect addressing
  4725. c Relative pivot tolerance
  4726. c ==========================================================================
  4727. c
  4728. subroutine mfactor(ecolpnt,
  4729. x vcstat,colpnt,rowidx,pivots,count,mut,nonzeros,
  4730. x diag,err,updat,list,index,dropn,slktyp,
  4731. x snhead,fpnt,invperm,nodtyp,dv,odiag)
  4732. c
  4733. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4734. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  4735. c
  4736. integer*4 err,list(mn),mut(mn),dropn
  4737. integer*4 ecolpnt(mn),vcstat(mn),colpnt(n1),rowidx(cfree)
  4738. integer*4 pivots(mn),count(mn),index(mn),slktyp(m)
  4739. integer*4 snhead(mn),fpnt(mn),invperm(mn),nodtyp(mn)
  4740. real*8 nonzeros(cfree),diag(mn),updat(mn),dv(m),odiag(mn)
  4741. c
  4742. common/factor/ tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4743. real*8 tpiv1,tpiv2,tabs,trabs,lam,tfind,order,supdens
  4744. common/numer/ tplus,tzer
  4745. real*8 tplus,tzer
  4746. c --------------------------------------------------------------------------
  4747. integer*4 i,j,k,l,o,p,pnt1,pnt2,ppnt1,ppnt2,mk,col,kprew,rb,
  4748. x ppnode,prewnode,w1
  4749. real*8 s,diap,diam
  4750. character*99 buff
  4751. c---------------------------------------------------------------------------
  4752. C CMSSW: Explicit initialization needed
  4753. o=0
  4754. err=0
  4755. w1=0
  4756. c
  4757. c initialization
  4758. c
  4759. do 10 i=1,mn
  4760. list(i)=0
  4761. index(i)=0
  4762. updat(i)=0.0d+0
  4763. fpnt(i)=0
  4764. 10 continue
  4765. c
  4766. c initialize dll
  4767. c
  4768. do 15 i=1,n
  4769. if(vcstat(i).le.-2)goto 15
  4770. k=ecolpnt(i)
  4771. if(k.le.nz)goto 15
  4772. pnt1=colpnt(i)
  4773. pnt2=colpnt(i+1)-1
  4774. if(pnt1.le.pnt2)then
  4775. o=rowidx(pnt1)
  4776. fpnt(i)=index(o)
  4777. index(o)=i
  4778. list(i)=pnt1
  4779. endif
  4780. 15 continue
  4781. c
  4782. c set the extra part of the matrix using a dll
  4783. c
  4784. do 20 col=1,pivotn
  4785. i=pivots(col)
  4786. pnt1=ecolpnt(i)
  4787. if(pnt1.le.nz)goto 20
  4788. pnt2=count(i)
  4789. o=0
  4790. if(i.le.n)then
  4791. if(vcstat(i).le.-2)goto 20
  4792. ppnt1=list(i)
  4793. ppnt2=colpnt(i+1)-1
  4794. do 18 j=ppnt1,ppnt2
  4795. k=rowidx(j)
  4796. updat(k)=nonzeros(j)
  4797. o=o+1
  4798. mut(o)=k
  4799. 18 continue
  4800. list(i)=ppnt2+1
  4801. else
  4802. kprew=index(i)
  4803. if(kprew.eq.0)goto 25
  4804. if(vcstat(i).le.-2)then
  4805. 21 mk=fpnt(kprew)
  4806. ppnt1=list(kprew)+1
  4807. if(ppnt1.lt.colpnt(kprew+1))then
  4808. list(kprew)=ppnt1
  4809. k=rowidx(ppnt1)
  4810. fpnt(kprew)=index(k)
  4811. index(k)=kprew
  4812. endif
  4813. kprew=mk
  4814. if(kprew.ne.0)goto 21
  4815. else
  4816. 22 mk=fpnt(kprew)
  4817. ppnt1=list(kprew)+1
  4818. if(ppnt1-colpnt(kprew+1))11,12,13
  4819. 11 updat(kprew)=nonzeros(ppnt1-1)
  4820. list(kprew)=ppnt1
  4821. k=rowidx(ppnt1)
  4822. fpnt(kprew)=index(k)
  4823. index(k)=kprew
  4824. o=o+1
  4825. mut(o)=kprew
  4826. goto 13
  4827. 12 updat(kprew)=nonzeros(ppnt1-1)
  4828. list(kprew)=ppnt1
  4829. o=o+1
  4830. mut(o)=kprew
  4831. 13 kprew=mk
  4832. if(kprew.ne.0)goto 22
  4833. endif
  4834. endif
  4835. c
  4836. c set column i and delete updat
  4837. c
  4838. 25 do 23 j=pnt1,pnt2
  4839. nonzeros(j)=updat(rowidx(j))
  4840. 23 continue
  4841. do 26 j=1,o
  4842. updat(mut(j))=0
  4843. 26 continue
  4844. 20 continue
  4845. c
  4846. c initialize for the computation
  4847. c
  4848. do 30 i=1,mn
  4849. mut(i)=0
  4850. fpnt(i)=ecolpnt(i)
  4851. list(i)=0
  4852. index(i)=0
  4853. updat(i)=0.0
  4854. 30 continue
  4855. ppnode=0
  4856. prewnode=0
  4857. i=0
  4858. c
  4859. c loop for pivot columns
  4860. c
  4861. 100 i=i+1
  4862. if(i.gt.pivotn)goto 60
  4863. col=pivots(i)
  4864. ppnt1=ecolpnt(col)
  4865. ppnt2=count(col)
  4866. c
  4867. c step vcstat if relaxed
  4868. c
  4869. if(vcstat(col).le.-2)then
  4870. call colremv(i,col,mut,index,fpnt,count,pivots,invperm,
  4871. x snhead,nodtyp,rowidx,nonzeros,ppnode,prewnode)
  4872. do 75 j=ppnt1,ppnt2
  4873. k=rowidx(j)
  4874. if((k.gt.n).or.(ecolpnt(k).le.nz))goto 75
  4875. l=colpnt(k)
  4876. o=colpnt(k+1)-1
  4877. do p=l,o
  4878. if(rowidx(p).eq.col)then
  4879. call move(p,o,rowidx,nonzeros)
  4880. goto 75
  4881. endif
  4882. enddo
  4883. 75 continue
  4884. i=i-1
  4885. if((ppnode.gt.0).and.(prewnode.eq.i))goto 110
  4886. goto 100
  4887. endif
  4888. c
  4889. if(ppnt1.le.nz)then
  4890. diag(col)=1.0d00/diag(col)
  4891. goto 180
  4892. endif
  4893. kprew=index(col)
  4894. c
  4895. c repack a column
  4896. c
  4897. do k=ppnt1,ppnt2
  4898. updat(rowidx(k))=nonzeros(k)
  4899. enddo
  4900. if(col.le.n)then
  4901. diam=diag(col)
  4902. diap=0.0d+0
  4903. else
  4904. diap=diag(col)
  4905. diam=0.0d+0
  4906. endif
  4907. 130 if(kprew)129,150,131
  4908. c
  4909. c Standard transformation
  4910. c
  4911. 131 k=mut(kprew)
  4912. pnt1=fpnt(kprew)
  4913. pnt2=count(kprew)
  4914. if(pnt1.lt.pnt2)then
  4915. o=rowidx(pnt1+1)
  4916. mut(kprew)=index(o)
  4917. index(o)=kprew
  4918. endif
  4919. pnt1=pnt1+1
  4920. fpnt(kprew)=pnt1
  4921. s=-nonzeros(pnt1-1)*diag(kprew)
  4922. if(kprew.le.n)then
  4923. diap=diap+s*nonzeros(pnt1-1)
  4924. else
  4925. diam=diam+s*nonzeros(pnt1-1)
  4926. endif
  4927. do 170 o=pnt1,pnt2
  4928. updat(rowidx(o))=updat(rowidx(o))+s*nonzeros(o)
  4929. 170 continue
  4930. kprew=k
  4931. goto 130
  4932. c
  4933. c supernodal transformation
  4934. c
  4935. 129 kprew=-kprew
  4936. k=mut(kprew)
  4937. p=invperm(kprew)
  4938. pnt1=fpnt(kprew)+1
  4939. if(pnt1.le.count(kprew))then
  4940. o=rowidx(pnt1)
  4941. mut(kprew)=index(o)
  4942. index(o)=-kprew
  4943. endif
  4944. if(kprew.le.n)then
  4945. call cspnd(p,snhead(p),diag,nonzeros,
  4946. x fpnt,count,pivots,updat,diap,rowidx(pnt1))
  4947. else
  4948. call cspnd(p,snhead(p),diag,nonzeros,
  4949. x fpnt,count,pivots,updat,diam,rowidx(pnt1))
  4950. endif
  4951. kprew=k
  4952. goto 130
  4953. c
  4954. c pack a column
  4955. c
  4956. 150 do k=ppnt1,ppnt2
  4957. nonzeros(k)=updat(rowidx(k))
  4958. enddo
  4959. c
  4960. c set up diag
  4961. c
  4962. if((ppnode.le.0).or.(prewnode.ne.snhead(i)))then
  4963. diap=diap+diam
  4964. diam=max(trabs,abs(diam*trabs))
  4965. if(abs(diap).lt.diam)then
  4966. call rngchk(rowidx,nonzeros,ecolpnt(col),count(col),
  4967. x vcstat,rb,diag,slktyp,dropn,col,dv,diap,w1,odiag(col))
  4968. if(rb.ne.0)err=1
  4969. diag(col)=diap
  4970. if(vcstat(col).le.-2)goto 100
  4971. else
  4972. diag(col)=1.0d00/diap
  4973. endif
  4974. else
  4975. diag(col)=diam
  4976. updat(col)=diap
  4977. endif
  4978. c
  4979. c Transformation in (primer) supernode
  4980. c
  4981. 110 if(prewnode.eq.i)then
  4982. if(ppnode.gt.0)then
  4983. do j=ppnode+1,i
  4984. o=j-1
  4985. p=pivots(j)
  4986. call cspnode(ppnode,o,diag,nonzeros,fpnt,count,pivots,
  4987. x nonzeros(ecolpnt(p)),diag(p))
  4988. diam=max(trabs,abs(diag(p)*trabs))
  4989. diag(p)=diag(p)+updat(p)
  4990. if(abs(diag(p)).lt.diam)then
  4991. call rngchk(rowidx,nonzeros,ecolpnt(p),count(p),
  4992. x vcstat,rb,diag,slktyp,dropn,p,dv,diag(p),w1,odiag(p))
  4993. if(rb.ne.0)err=1
  4994. else
  4995. diag(p)=1.0d+0/diag(p)
  4996. endif
  4997. enddo
  4998. endif
  4999. ppnode=0
  5000. endif
  5001. c
  5002. c Update the linked list
  5003. c
  5004. 180 if(snhead(i).eq.0)then
  5005. ppnode=0
  5006. if(ppnt1.le.ppnt2)then
  5007. j=rowidx(ppnt1)
  5008. mut(col)=index(j)
  5009. index(j)=col
  5010. endif
  5011. prewnode=0
  5012. else
  5013. if(prewnode.ne.snhead(i))then
  5014. prewnode=snhead(i)
  5015. if(nodtyp(i).gt.0)then
  5016. ppnode=i
  5017. else
  5018. ppnode=-i
  5019. endif
  5020. if(ecolpnt(pivots(prewnode)).le.count(pivots(prewnode)))then
  5021. j=rowidx(ecolpnt(pivots(prewnode)))
  5022. mut(col)=index(j)
  5023. index(j)=-col
  5024. endif
  5025. endif
  5026. endif
  5027. c
  5028. c end of the main loop
  5029. c
  5030. goto 100
  5031. c
  5032. c end of mfactor
  5033. c
  5034. 60 if(w1.gt.0)then
  5035. write(buff,'(1x,a,i6)')'Total warnings of row dependencies:',w1
  5036. call mprnt(buff)
  5037. endif
  5038. return
  5039. end
  5040. c
  5041. c =============================================================================
  5042. c =============================================================================
  5043. c
  5044. subroutine rngchk(rowidx,nonzeros,pnt1,pnt2,
  5045. x vcstat,rb,diag,slktyp,dropn,col,dv,dia,w1,odia)
  5046. c
  5047. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5048. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5049. c
  5050. common/numer/ tplus,tzer
  5051. real*8 tplus,tzer
  5052. c
  5053. integer*4 pnt1,pnt2,rowidx(cfree),vcstat(mn),rb,
  5054. x slktyp(m),dropn,col
  5055. real*8 nonzeros(cfree),diag(mn),dv(m),dia,odia
  5056. c
  5057. integer*4 i,j,w1,wignore
  5058. character*99 buff
  5059. c
  5060. c --------------------------------------------------------------------------
  5061. c
  5062. wignore=5
  5063. rb=0
  5064. if(col.le.n)then
  5065. if(diag(col).lt.0)then
  5066. dia=-1.0d+12
  5067. odia=odia+1.0d+00/dia
  5068. else
  5069. dia=+1.0d+12
  5070. odia=odia+1.0d+00/dia
  5071. endif
  5072. else
  5073. dia=0.0d+0
  5074. c
  5075. c Check for modification columns
  5076. c
  5077. do 10 i=pnt1,pnt2
  5078. j=rowidx(i)
  5079. if((vcstat(j).le.-2).or.(j.gt.n))goto 10
  5080. if(abs(nonzeros(i)).lt.tzer)goto 10
  5081. ccc dia=+1.0+10
  5082. ccc odia=odia+1.0d+00/dia
  5083. rb=1
  5084. vcstat(col)=-1
  5085. goto 20
  5086. 10 continue
  5087. c
  5088. c Dependent row, relax only if the dual variable is zero !
  5089. c
  5090. if(abs(dv(col-n)).lt.tzer)then
  5091. vcstat(col)=-2
  5092. dropn=dropn+1
  5093. w1=w1+1
  5094. if(w1.le.wignore)then
  5095. write(buff,'(1x,a,i5,a,i6)')
  5096. x 'WARNING : Row DROPPED ',col-n,' Type:',slktyp(col-n)
  5097. call mprnt(buff)
  5098. endif
  5099. endif
  5100. endif
  5101. 20 return
  5102. end
  5103. c
  5104. c ==========================================================================
  5105. c nem relativ nullazassal
  5106. c ==========================================================================
  5107. c
  5108. subroutine augftr(ecolpnt,
  5109. x vcstat,rowidx,pivots,count,nonzeros,diag,vector)
  5110. c
  5111. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5112. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5113. c
  5114. integer*4 ecolpnt(mn),vcstat(mn),rowidx(cfree)
  5115. integer*4 pivots(mn),count(mn)
  5116. real*8 nonzeros(cfree),diag(mn),vector(mn)
  5117. c
  5118. common/numer/ tplus,tzer
  5119. real*8 tplus,tzer
  5120. c --------------------------------------------------------------------------
  5121. integer*4 i,j,pnt1,pnt2,col,o
  5122. real*8 val
  5123. c---------------------------------------------------------------------------
  5124. do i=1,pivotn
  5125. col=pivots(i)
  5126. if (vcstat(col).gt.-2)then
  5127. val=vector(col)*diag(col)
  5128. if(abs(val).gt.tzer)then
  5129. pnt1=ecolpnt(col)
  5130. pnt2=count(col)
  5131. do j=pnt1,pnt2
  5132. o=rowidx(j)
  5133. vector(o)=vector(o)-val*nonzeros(j)
  5134. enddo
  5135. endif
  5136. endif
  5137. enddo
  5138. do i=1,mn
  5139. if(vcstat(i).le.-2)vector(i)=0
  5140. enddo
  5141. return
  5142. end
  5143. c
  5144. c ==========================================================================
  5145. c
  5146. subroutine augbtr(ecolpnt,
  5147. x vcstat,rowidx,pivots,count,nonzeros,diag,vector)
  5148. c
  5149. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5150. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5151. c
  5152. integer*4 ecolpnt(mn),vcstat(mn),rowidx(cfree)
  5153. integer*4 pivots(mn),count(mn)
  5154. real*8 nonzeros(cfree),diag(mn),vector(mn)
  5155. common/numer/ tplus,tzer
  5156. real*8 tplus,tzer
  5157. c --------------------------------------------------------------------------
  5158. integer*4 i,j,col,pnt1,pnt2
  5159. real*8 sol
  5160. c---------------------------------------------------------------------------
  5161. c
  5162. do i=1,pivotn
  5163. col=pivots(pivotn+1-i)
  5164. if(vcstat(col).gt.-2)then
  5165. sol=vector(col)
  5166. pnt1=ecolpnt(col)
  5167. pnt2=count(col)
  5168. do j=pnt1,pnt2
  5169. sol=sol-nonzeros(j)*vector(rowidx(j))
  5170. enddo
  5171. vector(col)=sol*diag(col)
  5172. endif
  5173. enddo
  5174. return
  5175. end
  5176. c ==========================================================================
  5177. c Multi predictor-corrector direction
  5178. c L2 norm
  5179. c ===========================================================================
  5180. c
  5181. subroutine citref(diag,odiag,pivots,rowidx,nonzeros,colpnt,
  5182. x ecolpnt,count,vcstat,xrhs,rwork1,rwork2,rwork3,
  5183. x bounds,xs,up,vartyp,slktyp)
  5184. c
  5185. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5186. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5187. common/numer/ tplus,tzer
  5188. real*8 tplus,tzer
  5189. common/itref/ tresx,tresy,maxref
  5190. real*8 tresx,tresy
  5191. integer*4 maxref
  5192. c
  5193. integer*4 ecolpnt(mn),count(mn),rowidx(cfree),
  5194. x pivots(mn),colpnt(n1),vcstat(mn),vartyp(n),slktyp(m)
  5195. real*8 diag(mn),odiag(mn),nonzeros(cfree),xrhs(mn),
  5196. x rwork1(mn),rwork2(mn),rwork3(mn),bounds(mn),xs(mn),up(mn)
  5197. c
  5198. c ---------------------------------------------------------------------------
  5199. c
  5200. integer*4 i,j,pnt1,pnt2,refn
  5201. real*8 maxrx,maxry,sx,sol,l2,ol2
  5202. c
  5203. c ---------------------------------------------------------------------------
  5204. c
  5205. c Simple case : No refinement
  5206. c
  5207. if(maxref.le.0)then
  5208. call augftr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  5209. x diag,xrhs)
  5210. call augbtr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  5211. x diag,xrhs)
  5212. goto 999
  5213. endif
  5214. do i=1,mn
  5215. rwork1(i)=xrhs(i)
  5216. enddo
  5217. ol2=1.0d+0/tzer
  5218. do i=1,mn
  5219. rwork3(i)=0.0d+0
  5220. enddo
  5221. refn=-1
  5222. c
  5223. c Main loop
  5224. c
  5225. 10 refn=refn+1
  5226. call augftr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  5227. x diag,xrhs)
  5228. call augbtr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  5229. x diag,xrhs)
  5230. do i=1,mn
  5231. xrhs(i)=xrhs(i)+rwork3(i)
  5232. enddo
  5233. c
  5234. c Compute the residuals
  5235. c
  5236. l2=0.0d+0
  5237. maxrx=0.0d+0
  5238. maxry=0.0d+0
  5239. do i=1,mn
  5240. rwork2(i)=rwork1(i)-odiag(i)*xrhs(i)
  5241. enddo
  5242. do i=1,n
  5243. if(vcstat(i).gt.-2)then
  5244. pnt1=colpnt(i)
  5245. pnt2=colpnt(i+1)-1
  5246. sx=xrhs(i)
  5247. sol=rwork2(i)
  5248. do j=pnt1,pnt2
  5249. rwork2(rowidx(j))=rwork2(rowidx(j))-nonzeros(j)*sx
  5250. sol=sol-nonzeros(j)*xrhs(rowidx(j))
  5251. enddo
  5252. rwork2(i)=sol
  5253. if(maxry.lt.abs(sol))maxry=abs(sol)
  5254. l2=l2+sol*sol
  5255. endif
  5256. enddo
  5257. do i=1,m
  5258. if(vcstat(i+n).gt.-2)then
  5259. if(maxrx.lt.abs(rwork2(i+n)))maxrx=abs(rwork2(i+n))
  5260. l2=l2+rwork2(i+n)*rwork2(i+n)
  5261. endif
  5262. enddo
  5263. l2=sqrt(l2)
  5264. if(l2.ge.ol2)then
  5265. do i=1,mn
  5266. xrhs(i)=rwork3(i)
  5267. enddo
  5268. else
  5269. if((maxrx.gt.tresx).or.(maxry.gt.tresy))then
  5270. if(refn.lt.maxref)then
  5271. ol2=l2
  5272. do i=1,mn
  5273. rwork3(i)=xrhs(i)
  5274. xrhs(i)=rwork2(i)
  5275. enddo
  5276. goto 10
  5277. endif
  5278. endif
  5279. endif
  5280. c
  5281. c End of the main loop, reset work3 (upinf)=bounds-xs-up
  5282. c
  5283. do i=1,mn
  5284. if(vcstat(i).gt.-2)then
  5285. if(i.le.n)then
  5286. j=vartyp(i)
  5287. else
  5288. j=slktyp(i-n)
  5289. endif
  5290. if(j.lt.0)then
  5291. sol=bounds(i)-xs(i)-up(i)
  5292. else
  5293. sol=0.0d+0
  5294. endif
  5295. else
  5296. sol=0.0d+0
  5297. endif
  5298. rwork3(i)=sol
  5299. enddo
  5300. c
  5301. c return
  5302. c
  5303. 999 return
  5304. end
  5305. c
  5306. c ============================================================================
  5307. c 6 way loop unrolling
  5308. c
  5309. c ============================================================================
  5310. c
  5311. subroutine cspnode(firstc,lastc,diag,nonzeros,
  5312. x fpnt,count,pivots,knz,dia)
  5313. c
  5314. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5315. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5316. c
  5317. integer*4 firstc,lastc,fpnt(mn),count(mn),pivots(mn)
  5318. real*8 diag(mn),nonzeros(cfree),knz(mn),dia
  5319. c
  5320. integer*4 pnt11,pnt12,pnt13,pnt14,pnt15,pnt16,
  5321. x col1,col2,col3,col4,col5,col6,frs,j,pnt2
  5322. real*8 s1,s2,s3,s4,s5,s6
  5323. c
  5324. c compute
  5325. c
  5326. frs=firstc
  5327. c
  5328. 99 if(lastc-2-frs) 98,30,97
  5329. 98 if(lastc-frs) 999,10,20
  5330. 97 if(lastc-4-frs) 40,50,60
  5331. c
  5332. c
  5333. c
  5334. 60 col1=pivots(frs)
  5335. col2=pivots(frs+1)
  5336. col3=pivots(frs+2)
  5337. col4=pivots(frs+3)
  5338. col5=pivots(frs+4)
  5339. col6=pivots(frs+5)
  5340. pnt11=fpnt(col1)
  5341. pnt12=fpnt(col2)
  5342. pnt13=fpnt(col3)
  5343. pnt14=fpnt(col4)
  5344. pnt15=fpnt(col5)
  5345. pnt16=fpnt(col6)
  5346. pnt2=count(col1)-pnt11
  5347. fpnt(col1)=pnt11+1
  5348. fpnt(col2)=pnt12+1
  5349. fpnt(col3)=pnt13+1
  5350. fpnt(col4)=pnt14+1
  5351. fpnt(col5)=pnt15+1
  5352. fpnt(col6)=pnt16+1
  5353. s1=-nonzeros(pnt11)*diag(col1)
  5354. s2=-nonzeros(pnt12)*diag(col2)
  5355. s3=-nonzeros(pnt13)*diag(col3)
  5356. s4=-nonzeros(pnt14)*diag(col4)
  5357. s5=-nonzeros(pnt15)*diag(col5)
  5358. s6=-nonzeros(pnt16)*diag(col6)
  5359. dia=dia+
  5360. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5361. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4+
  5362. x nonzeros(pnt15)*s5+nonzeros(pnt16)*s6
  5363. do j=1,pnt2
  5364. knz(j)=knz(j)+
  5365. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5366. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4+
  5367. x nonzeros(pnt15+j)*s5+nonzeros(pnt16+j)*s6
  5368. enddo
  5369. frs=frs+6
  5370. goto 99
  5371. c
  5372. c
  5373. c
  5374. 50 col1=pivots(frs)
  5375. col2=pivots(frs+1)
  5376. col3=pivots(frs+2)
  5377. col4=pivots(frs+3)
  5378. col5=pivots(frs+4)
  5379. pnt11=fpnt(col1)
  5380. pnt12=fpnt(col2)
  5381. pnt13=fpnt(col3)
  5382. pnt14=fpnt(col4)
  5383. pnt15=fpnt(col5)
  5384. pnt2=count(col1)-pnt11
  5385. fpnt(col1)=pnt11+1
  5386. fpnt(col2)=pnt12+1
  5387. fpnt(col3)=pnt13+1
  5388. fpnt(col4)=pnt14+1
  5389. fpnt(col5)=pnt15+1
  5390. s1=-nonzeros(pnt11)*diag(col1)
  5391. s2=-nonzeros(pnt12)*diag(col2)
  5392. s3=-nonzeros(pnt13)*diag(col3)
  5393. s4=-nonzeros(pnt14)*diag(col4)
  5394. s5=-nonzeros(pnt15)*diag(col5)
  5395. dia=dia+
  5396. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5397. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4+
  5398. x nonzeros(pnt15)*s5
  5399. do j=1,pnt2
  5400. knz(j)=knz(j)+
  5401. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5402. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4+
  5403. x nonzeros(pnt15+j)*s5
  5404. enddo
  5405. goto 999
  5406. c
  5407. c
  5408. c
  5409. 40 col1=pivots(frs)
  5410. col2=pivots(frs+1)
  5411. col3=pivots(frs+2)
  5412. col4=pivots(frs+3)
  5413. pnt11=fpnt(col1)
  5414. pnt12=fpnt(col2)
  5415. pnt13=fpnt(col3)
  5416. pnt14=fpnt(col4)
  5417. pnt2=count(col1)-pnt11
  5418. fpnt(col1)=pnt11+1
  5419. fpnt(col2)=pnt12+1
  5420. fpnt(col3)=pnt13+1
  5421. fpnt(col4)=pnt14+1
  5422. s1=-nonzeros(pnt11)*diag(col1)
  5423. s2=-nonzeros(pnt12)*diag(col2)
  5424. s3=-nonzeros(pnt13)*diag(col3)
  5425. s4=-nonzeros(pnt14)*diag(col4)
  5426. dia=dia+
  5427. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5428. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4
  5429. do j=1,pnt2
  5430. knz(j)=knz(j)+
  5431. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5432. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4
  5433. enddo
  5434. goto 999
  5435. c
  5436. c
  5437. c
  5438. 30 col1=pivots(frs)
  5439. col2=pivots(frs+1)
  5440. col3=pivots(frs+2)
  5441. pnt11=fpnt(col1)
  5442. pnt12=fpnt(col2)
  5443. pnt13=fpnt(col3)
  5444. pnt2=count(col1)-pnt11
  5445. fpnt(col1)=pnt11+1
  5446. fpnt(col2)=pnt12+1
  5447. fpnt(col3)=pnt13+1
  5448. s1=-nonzeros(pnt11)*diag(col1)
  5449. s2=-nonzeros(pnt12)*diag(col2)
  5450. s3=-nonzeros(pnt13)*diag(col3)
  5451. dia=dia+
  5452. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5453. x nonzeros(pnt13)*s3
  5454. do j=1,pnt2
  5455. knz(j)=knz(j)+
  5456. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5457. x nonzeros(pnt13+j)*s3
  5458. enddo
  5459. goto 999
  5460. c
  5461. c
  5462. c
  5463. 20 col1=pivots(frs)
  5464. col2=pivots(frs+1)
  5465. pnt11=fpnt(col1)
  5466. pnt12=fpnt(col2)
  5467. pnt2=count(col1)-pnt11
  5468. fpnt(col1)=pnt11+1
  5469. fpnt(col2)=pnt12+1
  5470. s1=-nonzeros(pnt11)*diag(col1)
  5471. s2=-nonzeros(pnt12)*diag(col2)
  5472. dia=dia+
  5473. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2
  5474. do j=1,pnt2
  5475. knz(j)=knz(j)+
  5476. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2
  5477. enddo
  5478. goto 999
  5479. c
  5480. c
  5481. c
  5482. 10 col1=pivots(frs)
  5483. pnt11=fpnt(col1)
  5484. pnt2=count(col1)-pnt11
  5485. fpnt(col1)=pnt11+1
  5486. s1=-nonzeros(pnt11)*diag(col1)
  5487. dia=dia+
  5488. x nonzeros(pnt11)*s1
  5489. do j=1,pnt2
  5490. knz(j)=knz(j)+
  5491. x nonzeros(pnt11+j)*s1
  5492. enddo
  5493. c
  5494. 999 return
  5495. end
  5496. c
  5497. c ==========================================================================
  5498. c 6 way loop unrolling
  5499. c
  5500. c ============================================================================
  5501. c
  5502. subroutine cspnd(firstc,lastc,diag,nonzeros,
  5503. x fpnt,count,pivots,knz,dia,index)
  5504. c
  5505. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5506. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5507. c
  5508. integer*4 firstc,lastc,fpnt(mn),count(mn),pivots(mn),index(mn)
  5509. real*8 diag(mn),nonzeros(cfree),knz(mn),dia
  5510. c
  5511. integer*4 pnt11,pnt12,pnt13,pnt14,pnt15,pnt16,
  5512. x col1,col2,col3,col4,col5,col6,frs,j,pnt2
  5513. real*8 s1,s2,s3,s4,s5,s6
  5514. c
  5515. c compute
  5516. c
  5517. frs=firstc
  5518. c
  5519. 99 if(lastc-2-frs) 98,30,97
  5520. 98 if(lastc-frs) 999,10,20
  5521. 97 if(lastc-4-frs) 40,50,60
  5522. c
  5523. c
  5524. c
  5525. 60 col1=pivots(frs)
  5526. col2=pivots(frs+1)
  5527. col3=pivots(frs+2)
  5528. col4=pivots(frs+3)
  5529. col5=pivots(frs+4)
  5530. col6=pivots(frs+5)
  5531. pnt11=fpnt(col1)
  5532. pnt12=fpnt(col2)
  5533. pnt13=fpnt(col3)
  5534. pnt14=fpnt(col4)
  5535. pnt15=fpnt(col5)
  5536. pnt16=fpnt(col6)
  5537. pnt2=count(col1)-pnt11
  5538. fpnt(col1)=pnt11+1
  5539. fpnt(col2)=pnt12+1
  5540. fpnt(col3)=pnt13+1
  5541. fpnt(col4)=pnt14+1
  5542. fpnt(col5)=pnt15+1
  5543. fpnt(col6)=pnt16+1
  5544. s1=-nonzeros(pnt11)*diag(col1)
  5545. s2=-nonzeros(pnt12)*diag(col2)
  5546. s3=-nonzeros(pnt13)*diag(col3)
  5547. s4=-nonzeros(pnt14)*diag(col4)
  5548. s5=-nonzeros(pnt15)*diag(col5)
  5549. s6=-nonzeros(pnt16)*diag(col6)
  5550. dia=dia+
  5551. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5552. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4+
  5553. x nonzeros(pnt15)*s5+nonzeros(pnt16)*s6
  5554. do j=1,pnt2
  5555. knz(index(j))=knz(index(j))+
  5556. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5557. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4+
  5558. x nonzeros(pnt15+j)*s5+nonzeros(pnt16+j)*s6
  5559. enddo
  5560. frs=frs+6
  5561. goto 99
  5562. c
  5563. c
  5564. c
  5565. 50 col1=pivots(frs)
  5566. col2=pivots(frs+1)
  5567. col3=pivots(frs+2)
  5568. col4=pivots(frs+3)
  5569. col5=pivots(frs+4)
  5570. pnt11=fpnt(col1)
  5571. pnt12=fpnt(col2)
  5572. pnt13=fpnt(col3)
  5573. pnt14=fpnt(col4)
  5574. pnt15=fpnt(col5)
  5575. pnt2=count(col1)-pnt11
  5576. fpnt(col1)=pnt11+1
  5577. fpnt(col2)=pnt12+1
  5578. fpnt(col3)=pnt13+1
  5579. fpnt(col4)=pnt14+1
  5580. fpnt(col5)=pnt15+1
  5581. s1=-nonzeros(pnt11)*diag(col1)
  5582. s2=-nonzeros(pnt12)*diag(col2)
  5583. s3=-nonzeros(pnt13)*diag(col3)
  5584. s4=-nonzeros(pnt14)*diag(col4)
  5585. s5=-nonzeros(pnt15)*diag(col5)
  5586. dia=dia+
  5587. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5588. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4+
  5589. x nonzeros(pnt15)*s5
  5590. do j=1,pnt2
  5591. knz(index(j))=knz(index(j))+
  5592. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5593. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4+
  5594. x nonzeros(pnt15+j)*s5
  5595. enddo
  5596. goto 999
  5597. c
  5598. c
  5599. c
  5600. 40 col1=pivots(frs)
  5601. col2=pivots(frs+1)
  5602. col3=pivots(frs+2)
  5603. col4=pivots(frs+3)
  5604. pnt11=fpnt(col1)
  5605. pnt12=fpnt(col2)
  5606. pnt13=fpnt(col3)
  5607. pnt14=fpnt(col4)
  5608. pnt2=count(col1)-pnt11
  5609. fpnt(col1)=pnt11+1
  5610. fpnt(col2)=pnt12+1
  5611. fpnt(col3)=pnt13+1
  5612. fpnt(col4)=pnt14+1
  5613. s1=-nonzeros(pnt11)*diag(col1)
  5614. s2=-nonzeros(pnt12)*diag(col2)
  5615. s3=-nonzeros(pnt13)*diag(col3)
  5616. s4=-nonzeros(pnt14)*diag(col4)
  5617. dia=dia+
  5618. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5619. x nonzeros(pnt13)*s3+nonzeros(pnt14)*s4
  5620. do j=1,pnt2
  5621. knz(index(j))=knz(index(j))+
  5622. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5623. x nonzeros(pnt13+j)*s3+nonzeros(pnt14+j)*s4
  5624. enddo
  5625. goto 999
  5626. c
  5627. c
  5628. c
  5629. 30 col1=pivots(frs)
  5630. col2=pivots(frs+1)
  5631. col3=pivots(frs+2)
  5632. pnt11=fpnt(col1)
  5633. pnt12=fpnt(col2)
  5634. pnt13=fpnt(col3)
  5635. pnt2=count(col1)-pnt11
  5636. fpnt(col1)=pnt11+1
  5637. fpnt(col2)=pnt12+1
  5638. fpnt(col3)=pnt13+1
  5639. s1=-nonzeros(pnt11)*diag(col1)
  5640. s2=-nonzeros(pnt12)*diag(col2)
  5641. s3=-nonzeros(pnt13)*diag(col3)
  5642. dia=dia+
  5643. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2+
  5644. x nonzeros(pnt13)*s3
  5645. do j=1,pnt2
  5646. knz(index(j))=knz(index(j))+
  5647. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2+
  5648. x nonzeros(pnt13+j)*s3
  5649. enddo
  5650. goto 999
  5651. c
  5652. c
  5653. c
  5654. 20 col1=pivots(frs)
  5655. col2=pivots(frs+1)
  5656. pnt11=fpnt(col1)
  5657. pnt12=fpnt(col2)
  5658. pnt2=count(col1)-pnt11
  5659. fpnt(col1)=pnt11+1
  5660. fpnt(col2)=pnt12+1
  5661. s1=-nonzeros(pnt11)*diag(col1)
  5662. s2=-nonzeros(pnt12)*diag(col2)
  5663. dia=dia+
  5664. x nonzeros(pnt11)*s1+nonzeros(pnt12)*s2
  5665. do j=1,pnt2
  5666. knz(index(j))=knz(index(j))+
  5667. x nonzeros(pnt11+j)*s1+nonzeros(pnt12+j)*s2
  5668. enddo
  5669. goto 999
  5670. c
  5671. c
  5672. c
  5673. 10 col1=pivots(frs)
  5674. pnt11=fpnt(col1)
  5675. pnt2=count(col1)-pnt11
  5676. fpnt(col1)=pnt11+1
  5677. s1=-nonzeros(pnt11)*diag(col1)
  5678. dia=dia+
  5679. x nonzeros(pnt11)*s1
  5680. do j=1,pnt2
  5681. knz(index(j))=knz(index(j))+
  5682. x nonzeros(pnt11+j)*s1
  5683. enddo
  5684. c
  5685. 999 return
  5686. end
  5687. c
  5688. c ==========================================================================
  5689. c ===========================================================================
  5690. c
  5691. subroutine supnode(ecolpnt,count,rowidx,vcstat,pivots,
  5692. x snhead,invperm,nodtyp)
  5693. c
  5694. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5695. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5696. common/sprnod/ psupn,ssupn,maxsnz
  5697. integer*4 psupn,ssupn,maxsnz
  5698. c
  5699. integer*4 ecolpnt(mn),count(mn),rowidx(cfree),vcstat(mn),
  5700. x pivots(mn),snhead(mn),invperm(mn),nodtyp(mn)
  5701. c
  5702. integer*4 i,j,k,l,i1,i2,ppnt1,ppnt2,pnt1,pnt2,pcol,col,snmode
  5703. integer*4 sn1,sn2,ss1,ss2,supnz
  5704. character*99 buff
  5705. c
  5706. 1 format(1x,'Supernodes :',i12,' ',i12)
  5707. 2 format(1x,'Supernodal cols. :',i12,' ',i12)
  5708. 3 format(1x,'Dense window :',i12)
  5709. c
  5710. C CMSSW: Explicit initialization needed
  5711. j=0
  5712. do i=1,mn
  5713. snhead(i)=0
  5714. invperm(i)=0
  5715. nodtyp(mn)=0
  5716. enddo
  5717. do i=1,pivotn
  5718. invperm(pivots(i))=i
  5719. enddo
  5720. sn1=0
  5721. sn2=0
  5722. ss1=0
  5723. ss2=0
  5724. pnt1=1
  5725. pnt2=0
  5726. i=0
  5727. 10 i=i+1
  5728. if(i.le.pivotn)then
  5729. pcol=pivots(i)
  5730. if(vcstat(pcol).gt.-2)then
  5731. j=0
  5732. ppnt1=ecolpnt(pcol)
  5733. ppnt2=count(pcol)
  5734. k=i+1
  5735. snmode=1
  5736. supnz=pnt2-pnt1+1
  5737. 20 if((k.le.pivotn).and.(ppnt1.le.ppnt2))then
  5738. col=pivots(k)
  5739. pnt1=ecolpnt(col)
  5740. pnt2=count(col)
  5741. supnz=supnz+pnt2-pnt1+1
  5742. if(((ppnt2-ppnt1-pnt2+pnt1).eq.1).and.(supnz.lt.maxsnz))then
  5743. if(col.ne.rowidx(ppnt1))goto 30
  5744. i2=ppnt1+1
  5745. i1=pnt1
  5746. 40 if(i1.le.pnt2)then
  5747. if(rowidx(i1).ne.rowidx(i2))goto 30
  5748. i1=i1+1
  5749. i2=i2+1
  5750. goto 40
  5751. endif
  5752. k=k+1
  5753. ppnt1=ppnt1+1
  5754. goto 20
  5755. endif
  5756. endif
  5757. 30 if(k.eq.i+1)then
  5758. snmode=-1
  5759. supnz=pnt2-pnt1+1
  5760. 25 if((k.le.pivotn).and.(ppnt1.le.ppnt2))then
  5761. col=pivots(k)
  5762. pnt1=ecolpnt(col)
  5763. pnt2=count(col)
  5764. supnz=supnz+pnt2-pnt1+1
  5765. if((ppnt2-ppnt1.eq.pnt2-pnt1).and.(supnz.le.maxsnz))then
  5766. i2=ppnt1
  5767. i1=pnt1
  5768. 45 if(i1.le.pnt2)then
  5769. if(rowidx(i1).ne.rowidx(i2))goto 35
  5770. i1=i1+1
  5771. i2=i2+1
  5772. goto 45
  5773. endif
  5774. k=k+1
  5775. goto 25
  5776. endif
  5777. endif
  5778. endif
  5779. 35 if(snmode.eq.1)then
  5780. denwin=k-i
  5781. if((k-i).lt.psupn)goto 10
  5782. sn1=sn1+1
  5783. ss1=ss1+(k-i)
  5784. j=sn1
  5785. else
  5786. if((k-i).lt.ssupn)goto 10
  5787. sn2=sn2+1
  5788. ss2=ss2+(k-i)
  5789. j=-sn2
  5790. endif
  5791. do l=i,k-1
  5792. snhead(l)=j
  5793. nodtyp(l)=j
  5794. enddo
  5795. i=k-1
  5796. endif
  5797. goto 10
  5798. endif
  5799. write(buff,1)sn1,sn2
  5800. call mprnt(buff)
  5801. write(buff,2)ss1,ss2
  5802. call mprnt(buff)
  5803. write(buff,3)denwin
  5804. call mprnt(buff)
  5805. k=0
  5806. do i=pivotn,1,-1
  5807. if(snhead(i).ne.0)then
  5808. if(k.ne.snhead(i))then
  5809. j=i
  5810. k=snhead(i)
  5811. endif
  5812. snhead(i)=j
  5813. else
  5814. k=0
  5815. endif
  5816. enddo
  5817. return
  5818. end
  5819. c
  5820. c ============================================================================
  5821. c Update supernode partitions after column fixing
  5822. c (only in the sparse part of the constraint matrix)
  5823. c =============================================================================
  5824. c
  5825. subroutine supupd(pivots,invperm,snhead,nodtyp,vcstat,
  5826. x ecolpnt)
  5827. c
  5828. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5829. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5830. c
  5831. integer*4 pivots(mn),invperm(mn),snhead(mn),nodtyp(mn),
  5832. x ecolpnt(mn),vcstat(mn)
  5833. c
  5834. integer*4 i,j,k
  5835. c
  5836. c Make changes : Compress pivots,nodetyp,snhead
  5837. c
  5838. i=1
  5839. j=0
  5840. 10 if(i.le.pivotn)then
  5841. k=pivots(i)
  5842. if((ecolpnt(k).gt.nz).or.(vcstat(k).gt.-2))then
  5843. j=j+1
  5844. pivots(j)=pivots(i)
  5845. snhead(j)=snhead(i)
  5846. nodtyp(j)=nodtyp(i)
  5847. endif
  5848. invperm(i)=j
  5849. i=i+1
  5850. goto 10
  5851. endif
  5852. pivotn=j
  5853. c
  5854. c Change snhead
  5855. c
  5856. do j=1,pivotn
  5857. if(snhead(j).gt.0)snhead(j)=invperm(snhead(j))
  5858. enddo
  5859. c
  5860. c Create new invperm
  5861. c
  5862. do j=1,pivotn
  5863. invperm(pivots(j))=j
  5864. enddo
  5865. return
  5866. end
  5867. c
  5868. c =============================================================================
  5869. c Computing the starting point xs,up in the primal space,
  5870. c dv, dspr,dsup in the dual space.
  5871. c
  5872. c ===========================================================================
  5873. c
  5874. subroutine initsol(xs,up,dv,dspr,dsup,rhs,obj,bounds,vartyp,
  5875. x slktyp,vcstat,colpnt,ecolpnt,pivots,rowidx,nonzeros,diag,
  5876. x updat1,count)
  5877. c
  5878. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5879. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  5880. c
  5881. common/initv/ prmin,upmax,dumin,stamet,safmet,premet,regul
  5882. real*8 prmin,upmax,dumin
  5883. integer*4 stamet,safmet,premet,regul
  5884. c
  5885. common/mscal/ varadd,slkadd,scfree
  5886. real*8 varadd,slkadd,scfree
  5887. c
  5888. common/numer/ tplus,tzer
  5889. real*8 tplus,tzer
  5890. c
  5891. integer*4 ecolpnt(mn),vcstat(mn),colpnt(n1),rowidx(cfree),
  5892. x pivots(mn),vartyp(n),slktyp(m),count(mn)
  5893. real*8 xs(mn),up(mn),dv(m),dspr(mn),dsup(mn),rhs(m),obj(n),
  5894. x bounds(mn),diag(mn),updat1(mn),nonzeros(cfree)
  5895. c
  5896. integer*4 i,j,pnt1,pnt2
  5897. real*8 sol,sb,spr,sdu,prlo,dulo,ngap
  5898. logical addall
  5899. c
  5900. c ---------------------------------------------------------------------------
  5901. c
  5902. c Reset all values
  5903. c
  5904. do i=1,mn
  5905. xs(i)=0.0d+0
  5906. up(i)=0.0d+0
  5907. dspr(i)=0.0d+0
  5908. dsup(i)=0.0d+0
  5909. if(i.le.m)dv(i)=0.0d+0
  5910. enddo
  5911. c
  5912. c RHS for XS ans UP
  5913. c
  5914. do i=1,m
  5915. if(slktyp(i).lt.0)then
  5916. if(bounds(i+n).gt.upmax)then
  5917. sol=upmax/2
  5918. else
  5919. sol=bounds(i+n)/2
  5920. endif
  5921. else
  5922. sol=0.0d+0
  5923. endif
  5924. updat1(i+n)=rhs(i)+sol
  5925. enddo
  5926. do i=1,n
  5927. if(vartyp(i).lt.0)then
  5928. if(bounds(i).gt.upmax)then
  5929. sol=-upmax
  5930. else
  5931. sol=-bounds(i)
  5932. endif
  5933. else
  5934. sol=0.0d+0
  5935. endif
  5936. updat1(i)=sol
  5937. enddo
  5938. c
  5939. call augftr(ecolpnt,
  5940. x vcstat,rowidx,pivots,count,nonzeros,diag,updat1)
  5941. call augbtr(ecolpnt,
  5942. x vcstat,rowidx,pivots,count,nonzeros,diag,updat1)
  5943. c
  5944. c Initial values for xs, up
  5945. c
  5946. do i=1,n
  5947. if(vcstat(i).gt.-2)then
  5948. xs(i)=updat1(i)
  5949. if(vartyp(i).lt.0)then
  5950. up(i)=bounds(i)-xs(i)
  5951. endif
  5952. endif
  5953. enddo
  5954. do i=1,m
  5955. j=i+n
  5956. if((vcstat(j).gt.-2).and.(slktyp(i).ne.0))then
  5957. xs(j)=-updat1(j)
  5958. if(slktyp(i).lt.0)then
  5959. xs(j)=(bounds(j)-updat1(j))/2
  5960. up(j)=bounds(j)-xs(j)
  5961. endif
  5962. endif
  5963. enddo
  5964. c
  5965. c Initial dual variables, stamet=2
  5966. c
  5967. if(stamet.eq.1)then
  5968. do i=1,m
  5969. dv(i)=0
  5970. dspr(i+n)=0
  5971. dsup(i+n)=0
  5972. enddo
  5973. do i=1,n
  5974. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  5975. if(vartyp(i).lt.0)then
  5976. dspr(i)=obj(i)/2
  5977. dsup(i)=-obj(i)/2
  5978. else
  5979. dspr(i)=obj(i)
  5980. endif
  5981. endif
  5982. enddo
  5983. else if(stamet.eq.2)then
  5984. do i=1,m
  5985. updat1(i+n)=0.0d+0
  5986. enddo
  5987. do i=1,n
  5988. updat1(i)=obj(i)
  5989. enddo
  5990. call augftr(ecolpnt,
  5991. x vcstat,rowidx,pivots,count,nonzeros,diag,updat1)
  5992. call augbtr(ecolpnt,
  5993. x vcstat,rowidx,pivots,count,nonzeros,diag,updat1)
  5994. do i=1,m
  5995. if(vcstat(i+n).gt.-2)then
  5996. dv(i)=updat1(i+n)
  5997. else
  5998. dv(i)=0.0d+0
  5999. endif
  6000. if(slktyp(i).ne.0)then
  6001. dspr(i+n)=-dv(i)
  6002. if(slktyp(i).lt.0)then
  6003. dspr(i+n)=-dv(i)/2
  6004. dsup(i+n)=dv(i)/2
  6005. endif
  6006. endif
  6007. enddo
  6008. do i=1,n
  6009. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  6010. if(vartyp(i).lt.0)then
  6011. dspr(i)=-updat1(i)
  6012. dsup(i)=updat1(i)
  6013. else
  6014. dspr(i)=-updat1(i)
  6015. endif
  6016. endif
  6017. enddo
  6018. endif
  6019. c
  6020. c Compute prmin,dumin
  6021. c
  6022. if(safmet.lt.0)then
  6023. safmet=-safmet
  6024. addall=.true.
  6025. else
  6026. addall=.false.
  6027. endif
  6028. c
  6029. c Marsten et al.
  6030. c
  6031. if(safmet.eq.2)then
  6032. do i=1,m
  6033. updat1(i)=0
  6034. enddo
  6035. do i=1,n
  6036. if(vcstat(i).gt.-2)then
  6037. pnt1=colpnt(i)
  6038. pnt2=colpnt(i+1)-1
  6039. sol=0.0d+0
  6040. sb=obj(i)
  6041. do j=pnt1,pnt2
  6042. if(vcstat(rowidx(j)).gt.-2)then
  6043. sol=sol+rhs(rowidx(j)-n)*nonzeros(j)
  6044. updat1(rowidx(j)-n)=updat1(rowidx(j)-n)+nonzeros(j)*sb
  6045. endif
  6046. enddo
  6047. if(prmin.lt.sol)prmin=sol
  6048. endif
  6049. enddo
  6050. do i=1,m
  6051. if(dumin.lt.abs(updat1(i)))dumin=abs(updat1(i))
  6052. enddo
  6053. endif
  6054. c
  6055. c Mehrotra
  6056. c
  6057. if(safmet.eq.3)then
  6058. spr=1.0d+0/tzer
  6059. sdu=1.0d+0/tzer
  6060. do i=1,mn
  6061. if(i.le.n)then
  6062. j=vartyp(i)
  6063. else
  6064. j=slktyp(i-n)
  6065. endif
  6066. if((vcstat(i).gt.-2).and.(j.ne.0))then
  6067. if(spr.gt.xs(i))spr=xs(i)
  6068. if(sdu.gt.dspr(i))sdu=dspr(i)
  6069. if(j.lt.0)then
  6070. if(spr.gt.up(i))spr=up(i)
  6071. if(sdu.gt.dsup(i))sdu=dsup(i)
  6072. endif
  6073. endif
  6074. enddo
  6075. spr=-1.5d+0*spr
  6076. sdu=-1.5d+0*sdu
  6077. if(spr.lt.0.001d+0)spr=0.001d+0
  6078. if(sdu.lt.0.001d+0)sdu=0.001d+0
  6079. prlo=0.0d+0
  6080. dulo=0.0d+0
  6081. ngap=0.0d+0
  6082. do i=1,mn
  6083. if(i.le.n)then
  6084. j=vartyp(i)
  6085. else
  6086. j=slktyp(i-n)
  6087. endif
  6088. if((vcstat(i).gt.-2).and.(j.ne.0))then
  6089. sol=xs(i)+spr
  6090. sb=dspr(i)+sdu
  6091. ngap=ngap+sol*sb
  6092. prlo=prlo+sol
  6093. dulo=dulo+sb
  6094. if(j.lt.0)then
  6095. sol=up(i)+spr
  6096. sb=dsup(i)+sdu
  6097. ngap=ngap+sol*sb
  6098. prlo=prlo+sol
  6099. dulo=dulo+sb
  6100. endif
  6101. endif
  6102. enddo
  6103. prmin=spr+0.5d+0*ngap/dulo
  6104. dumin=sdu+0.5d+0*ngap/prlo
  6105. endif
  6106. if(addall.and.(safmet.lt.3))then
  6107. sol=1.0d+0/tzer
  6108. sb=1.0d+0/tzer
  6109. do i=1,mn
  6110. if(vcstat(i).gt.-2)then
  6111. if(i.le.n)then
  6112. j=vartyp(i)
  6113. else
  6114. j=slktyp(i-n)
  6115. endif
  6116. if(j.ne.0)then
  6117. if(sol.gt.xs(i))sol=xs(i)
  6118. if(sb.gt.dspr(i))sb=dspr(i)
  6119. endif
  6120. if(j.lt.0)then
  6121. if(sol.gt.up(i))sol=up(i)
  6122. if(sb.gt.dsup(i))sb=dsup(i)
  6123. endif
  6124. endif
  6125. enddo
  6126. if(sol.lt.0)prmin=prmin-sol
  6127. if(sb.lt.0)dumin=dumin-sb
  6128. endif
  6129. c
  6130. c Correcting
  6131. c
  6132. if(addall)then
  6133. spr=1.0d+0/tzer
  6134. sdu=1.0d+0/tzer
  6135. sol=1.0d+0
  6136. else
  6137. spr=prmin
  6138. sdu=dumin
  6139. sol=0.0d+0
  6140. endif
  6141. do i=1,mn
  6142. if(vcstat(i).gt.-2)then
  6143. if(i.le.n)then
  6144. j=vartyp(i)
  6145. else
  6146. j=slktyp(i-n)
  6147. endif
  6148. if(j.ne.0)then
  6149. if(xs(i).lt.spr)then
  6150. xs(i)=sol*xs(i)+prmin
  6151. endif
  6152. if(dspr(i).lt.sdu)then
  6153. dspr(i)=sol*dspr(i)+dumin
  6154. endif
  6155. if(j.lt.0)then
  6156. if(up(i).lt.spr)then
  6157. up(i)=sol*up(i)+prmin
  6158. endif
  6159. if(dsup(i).lt.sdu)then
  6160. dsup(i)=sol*dsup(i)+dumin
  6161. endif
  6162. endif
  6163. endif
  6164. endif
  6165. enddo
  6166. c
  6167. return
  6168. end
  6169. c
  6170. c ===========================================================================
  6171. c
  6172. c Set up the initial scaling matrix
  6173. c (for the computation of the initial solution)
  6174. c
  6175. subroutine fscale(vcstat,diag,odiag,vartyp,slktyp)
  6176. c
  6177. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6178. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6179. common/mscal/ varadd,slkadd,scfree
  6180. real*8 varadd,slkadd,scfree
  6181. c
  6182. integer*4 vcstat(mn),vartyp(n),slktyp(m)
  6183. real*8 diag(mn),odiag(mn)
  6184. c
  6185. integer*4 i,j
  6186. real*8 sol
  6187. c
  6188. do i=1,mn
  6189. sol=0.0d+0
  6190. if(vcstat(i).gt.-2)then
  6191. if(i.le.n)then
  6192. j=vartyp(i)
  6193. if(j.gt.0)then
  6194. sol=-1.0d0
  6195. else if(j.lt.0)then
  6196. sol=-2.0d0
  6197. else
  6198. sol=-scfree
  6199. endif
  6200. else
  6201. j=slktyp(i-n)
  6202. if(j.gt.0)then
  6203. sol=1.0d0
  6204. else if(j.lt.0)then
  6205. sol=0.5d+0
  6206. else
  6207. sol=0.0d+0
  6208. endif
  6209. endif
  6210. endif
  6211. diag(i)=sol
  6212. odiag(i)=sol
  6213. enddo
  6214. return
  6215. end
  6216. c
  6217. c ============================================================================
  6218. c Compute primal, upper, dual infeasibilities
  6219. c ===========================================================================
  6220. c
  6221. subroutine cprinf(xs,prinf,slktyp,colpnt,rowidx,nonzeros,
  6222. x rhs,vcstat,pinf)
  6223. c
  6224. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6225. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6226. c
  6227. integer*4 slktyp(m),colpnt(n1),rowidx(nz),vcstat(mn)
  6228. real*8 xs(mn),prinf(m),rhs(m),nonzeros(nz),pinf
  6229. c
  6230. integer*4 i,j,pnt1,pnt2
  6231. real*8 sol
  6232. c
  6233. c ---------------------------------------------------------------------------
  6234. c
  6235. do i=1,m
  6236. prinf(i)=rhs(i)
  6237. enddo
  6238. pinf=0.0D+0
  6239. c
  6240. do i=1,n
  6241. if(vcstat(i).gt.-2)then
  6242. sol=xs(i)
  6243. pnt1=colpnt(i)
  6244. pnt2=colpnt(i+1)-1
  6245. do j=pnt1,pnt2
  6246. prinf(rowidx(j)-n)=prinf(rowidx(j)-n)-sol*nonzeros(j)
  6247. enddo
  6248. endif
  6249. enddo
  6250. do i=1,m
  6251. if(vcstat(i+n).gt.-2)then
  6252. if(slktyp(i).ne.0)then
  6253. sol=prinf(i)+xs(i+n)
  6254. else
  6255. sol=prinf(i)
  6256. endif
  6257. else
  6258. sol=0.0d+0
  6259. endif
  6260. prinf(i)=sol
  6261. if(pinf.lt.abs(sol))pinf=abs(sol)
  6262. enddo
  6263. return
  6264. end
  6265. c
  6266. c ===========================================================================
  6267. c
  6268. subroutine cupinf(xs,up,upinf,bounds,vartyp,slktyp,vcstat,
  6269. x uinf)
  6270. c
  6271. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6272. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6273. c
  6274. integer*4 vartyp(n),slktyp(m),vcstat(mn)
  6275. real*8 xs(mn),up(mn),upinf(mn),bounds(mn),uinf
  6276. c
  6277. integer*4 i
  6278. c
  6279. do i=1,mn
  6280. upinf(i)=0.0d+0
  6281. enddo
  6282. uinf=0.0d+0
  6283. do i=1,n
  6284. if((vcstat(i).gt.-2).and.(vartyp(i).lt.0))then
  6285. upinf(i)=bounds(i)-xs(i)-up(i)
  6286. if(uinf.lt.abs(upinf(i)))uinf=abs(upinf(i))
  6287. endif
  6288. enddo
  6289. do i=1,m
  6290. if((vcstat(i+n).gt.-2).and.(slktyp(i).lt.0))then
  6291. upinf(i+n)=bounds(i+n)-xs(i+n)-up(i+n)
  6292. if(uinf.lt.abs(upinf(i+n)))uinf=abs(upinf(i+n))
  6293. endif
  6294. enddo
  6295. return
  6296. end
  6297. c
  6298. c ============================================================================
  6299. c
  6300. subroutine cduinf(dv,dspr,dsup,duinf,vartyp,slktyp,colpnt,
  6301. x rowidx,nonzeros,obj,vcstat,dinf)
  6302. c
  6303. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6304. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6305. c
  6306. integer*4 vartyp(n),slktyp(m),colpnt(n1),rowidx(nz),
  6307. x vcstat(mn)
  6308. real*8 dv(m),dspr(mn),dsup(mn),duinf(mn),nonzeros(nz),obj(n),
  6309. x dinf
  6310. c
  6311. integer*4 i,j,pnt1,pnt2
  6312. real*8 sol
  6313. c
  6314. c ------------------------------------------------------------------------------
  6315. c
  6316. dinf=0.0d+0
  6317. c
  6318. do i=1,m
  6319. sol=0.0d+0
  6320. if(vcstat(i+n).gt.-2)then
  6321. if(slktyp(i).gt.0)then
  6322. sol=dv(i)-dspr(i+n)
  6323. else if(slktyp(i).lt.0)then
  6324. sol=dv(i)-dspr(i+n)+dsup(i+n)
  6325. endif
  6326. endif
  6327. duinf(i+n)=sol
  6328. enddo
  6329. c
  6330. do i=1,n
  6331. sol=0.0d+0
  6332. if(vcstat(i).gt.-2)then
  6333. pnt1=colpnt(i)
  6334. pnt2=colpnt(i+1)-1
  6335. do j=pnt1,pnt2
  6336. if(vcstat(rowidx(j)).gt.-2)then
  6337. sol=sol+dv(rowidx(j)-n)*nonzeros(j)
  6338. endif
  6339. enddo
  6340. if(vartyp(i))10,11,12
  6341. c
  6342. c Upper bounded variable
  6343. c
  6344. 10 sol=obj(i)-sol-dspr(i)+dsup(i)
  6345. goto 15
  6346. c
  6347. c Free variable
  6348. c
  6349. 11 sol=obj(i)-sol
  6350. goto 15
  6351. c
  6352. c Standard variable
  6353. c
  6354. 12 sol=obj(i)-sol-dspr(i)
  6355. endif
  6356. 15 duinf(i)=sol
  6357. enddo
  6358. c
  6359. c Compute absolute and relative infeasibility
  6360. c
  6361. do i=1,mn
  6362. sol=abs(duinf(i))
  6363. if(dinf.lt.sol)dinf=sol
  6364. enddo
  6365. c
  6366. return
  6367. end
  6368. c
  6369. c ==============================================================================
  6370. c
  6371. subroutine cpdobj(popt,dopt,obj,rhs,bounds,xs,dv,
  6372. x dsup,vcstat,vartyp,slktyp)
  6373. c
  6374. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6375. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6376. c
  6377. integer*4 vcstat(mn),vartyp(n),slktyp(m)
  6378. real*8 popt,dopt,obj(n),rhs(m),bounds(mn),xs(mn),dv(m),dsup(mn)
  6379. c
  6380. integer*4 i
  6381. c
  6382. popt=0.0d+0
  6383. dopt=0.0d+0
  6384. do i=1,n
  6385. if(vcstat(i).gt.-2)then
  6386. popt=popt+obj(i)*xs(i)
  6387. if(vartyp(i).lt.0)then
  6388. dopt=dopt-bounds(i)*dsup(i)
  6389. endif
  6390. endif
  6391. enddo
  6392. do i=1,m
  6393. if(vcstat(i+n).gt.-2)then
  6394. dopt=dopt+rhs(i)*dv(i)
  6395. if(slktyp(i).lt.0)then
  6396. dopt=dopt-bounds(i+n)*dsup(i+n)
  6397. endif
  6398. endif
  6399. enddo
  6400. return
  6401. end
  6402. c
  6403. c ===========================================================================
  6404. c ===========================================================================
  6405. c
  6406. subroutine stpcrt(prelinf,drelinf,popt,dopt,cgap,
  6407. x iter,code,pphase,dphase,maxstp,pinf,uinf,dinf,
  6408. x prinf,upinf,duinf,oldmp,pb,db,
  6409. x prstpl,dustpl,obj,rhs,bounds,xs,dxs,dspr,ddspr,dsup,
  6410. x ddsup,dv,ddv,up,addobj,scobj,vcstat,vartyp,slktyp,
  6411. x oprelinf,odrelinf,opinf,odinf,ocgap,opphas,odphas,buff)
  6412. c
  6413. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6414. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6415. c
  6416. real*8 prelinf,drelinf,popt,dopt,cgap,maxstp,
  6417. x pinf,uinf,oldmp,dinf,pb,db,oprelinf,odrelinf,opinf,odinf,ocgap
  6418. integer*4 iter,code,pphase,dphase,opphas,odphas
  6419. c
  6420. real*8 prstpl,dustpl,obj(n),rhs(m),bounds(mn),xs(mn),dxs(mn),
  6421. x dspr(mn),ddspr(mn),dsup(mn),ddsup(mn),dv(m),ddv(m),upinf(mn),
  6422. x up(mn),prinf(m),duinf(mn),addobj,scobj
  6423. integer*4 vcstat(mn),vartyp(n),slktyp(m)
  6424. character*99 buff
  6425. c
  6426. common/toler/ tsdir,topt1,topt2,tfeas1,tfeas2,feas1,feas2,
  6427. x pinfs,dinfs,inftol,maxiter
  6428. real*8 tsdir,topt1,topt2,tfeas1,tfeas2,feas1,feas2,
  6429. x pinfs,dinfs,inftol
  6430. integer*4 maxiter
  6431. c
  6432. real*8 oldpopt,olddopt,objnrm,rhsnrm,bndnrm,urelinf,mp
  6433. integer*4 i
  6434. c
  6435. prelinf=0.0d+0
  6436. urelinf=0.0d+0
  6437. drelinf=0.0d+0
  6438. objnrm =0.0d+0
  6439. rhsnrm =0.0d+0
  6440. bndnrm =0.0d+0
  6441. do i=1,n
  6442. if(vcstat(i).gt.-2)then
  6443. objnrm=objnrm+obj(i)*obj(i)
  6444. drelinf=drelinf+duinf(i)*duinf(i)
  6445. if(vartyp(i).lt.0)then
  6446. bndnrm=bndnrm+bounds(i)*bounds(i)
  6447. urelinf=urelinf+upinf(i)*upinf(i)
  6448. endif
  6449. endif
  6450. enddo
  6451. do i=1,m
  6452. if(vcstat(i+n).gt.-2)then
  6453. rhsnrm=rhsnrm+rhs(i)*rhs(i)
  6454. prelinf=prelinf+prinf(i)*prinf(i)
  6455. drelinf=drelinf+duinf(i+n)*duinf(i+n)
  6456. if(slktyp(i).lt.0)then
  6457. bndnrm=bndnrm+bounds(i+n)*bounds(i+n)
  6458. urelinf=urelinf+upinf(i+n)*upinf(i+n)
  6459. endif
  6460. endif
  6461. enddo
  6462. c
  6463. prelinf=sqrt(prelinf+urelinf)/(1.0d+0+sqrt(bndnrm+rhsnrm))
  6464. drelinf=sqrt(drelinf)/(1.0d+0+sqrt(objnrm))
  6465. if(drelinf.gt.dinf)drelinf=dinf
  6466. if(prelinf.gt.max(pinf,uinf))prelinf=max(pinf,uinf)
  6467. c
  6468. mp=prelinf+drelinf+
  6469. x abs(popt-dopt)/scobj/(1.0d+0+sqrt(rhsnrm+bndnrm)+sqrt(objnrm))
  6470. if(iter.le.1)oldmp=mp
  6471. c
  6472. code=0
  6473. if((prelinf.lt.tfeas1).and.
  6474. x (pinf.lt.feas1).and.(uinf.lt.feas1))then
  6475. pphase=2
  6476. else
  6477. pphase=1
  6478. pb=abs(pb-pinf)/(abs(pinf))
  6479. endif
  6480. if((drelinf.lt.tfeas2).and.(dinf.lt.feas2))then
  6481. dphase=2
  6482. else
  6483. dphase=1
  6484. db=abs(db-dinf)/(abs(dinf))
  6485. endif
  6486. c
  6487. if((abs(popt-dopt)/(abs(popt)+1.0d+0).le.topt1)
  6488. x. and.(pphase.eq.2).and.(dphase.eq.2))then
  6489. code=2
  6490. write(buff,'(1x,a)')
  6491. x 'Stopping criterion : Small infeasibility and duality gap'
  6492. else if((popt.lt.dopt).and.(pphase.eq.2).and.(dphase.eq.2))then
  6493. code=0
  6494. if(iter.gt.0)then
  6495. call cpdobj(oldpopt,olddopt,obj,rhs,bounds,dxs,ddv,ddsup,
  6496. x vcstat,vartyp,slktyp)
  6497. oldpopt=popt-oldpopt*scobj*prstpl
  6498. olddopt=dopt-olddopt*scobj*dustpl
  6499. if(oldpopt.ge.olddopt)then
  6500. code=2
  6501. maxstp=1.0d+0-(oldpopt-olddopt)/(dopt-olddopt-popt+oldpopt)
  6502. dustpl=-maxstp*dustpl
  6503. prstpl=-maxstp*prstpl
  6504. call cnewpd(prstpl,xs,dxs,up,upinf,dustpl,dv,ddv,dspr,
  6505. x ddspr,dsup,ddsup,vartyp,slktyp,vcstat,maxstp)
  6506. call cpdobj(popt,dopt,obj,rhs,bounds,xs,dv,dsup,
  6507. x vcstat,vartyp,slktyp)
  6508. popt=popt*scobj+addobj
  6509. dopt=dopt*scobj+addobj
  6510. endif
  6511. endif
  6512. if(code.gt.0)then
  6513. write(buff,'(1x,a)')
  6514. x 'Stopping criterion : Small infeasibility and duality gap'
  6515. else
  6516. write(buff,'(1x,a)')
  6517. x 'Stopping criterion : Negative gap (Wrong tolerances ?)'
  6518. code=1
  6519. endif
  6520. else if((mp.gt.topt1).and.(mp.gt.inftol*oldmp))then
  6521. if(pphase+dphase.eq.4)then
  6522. code=1
  6523. write(buff,'(1x,a)')
  6524. x 'Stopping Criterion: Possible numerical problems'
  6525. else if (opphas+odphas.eq.4)then
  6526. code=1
  6527. write(buff,'(1x,a)')
  6528. x 'Stopping Criterion: Instability, Suboptimal solution'
  6529. dustpl=-dustpl
  6530. prstpl=-prstpl
  6531. call cnewpd(prstpl,xs,dxs,up,upinf,dustpl,dv,ddv,dspr,
  6532. x ddspr,dsup,ddsup,vartyp,slktyp,vcstat,maxstp)
  6533. call cpdobj(popt,dopt,obj,rhs,bounds,xs,dv,dsup,
  6534. x vcstat,vartyp,slktyp)
  6535. call cpdobj(popt,dopt,obj,rhs,bounds,xs,dv,dsup,
  6536. x vcstat,vartyp,slktyp)
  6537. popt=popt*scobj+addobj
  6538. dopt=dopt*scobj+addobj
  6539. prelinf=oprelinf
  6540. drelinf=odrelinf
  6541. pinf=opinf
  6542. dinf=odinf
  6543. pphase=opphas
  6544. dphase=odphas
  6545. cgap=ocgap
  6546. else
  6547. write(buff,'(1x,a)')
  6548. x 'Stopping Criterion: Problem infeasibile'
  6549. code=4
  6550. if(pphase.eq.2)code=3
  6551. endif
  6552. else if(abs(cgap).lt.topt2)then
  6553. code=1
  6554. if((pphase.eq.2).and.(dphase.eq.2))code=2
  6555. write(buff,'(1x,a)')
  6556. x 'Stopping Criterion : Small complementarity gap'
  6557. else if(iter.ge.maxiter)then
  6558. code=1
  6559. write(buff,'(1x,a)')
  6560. x 'Stopping Criterion : Iteration limit is exeeded'
  6561. else if(maxstp.lt.tsdir)then
  6562. code=1
  6563. write(buff,'(1x,a)')
  6564. x 'Stopping Criterion : Very small step'
  6565. else if((iter.gt.0).and.(pphase.eq.1).and.(pb.lt.pinfs))then
  6566. code=4
  6567. write(buff,'(1x,a)')
  6568. x 'Stopping Criterion: Pinfs limit. Problem primal infeasibile'
  6569. else if((iter.gt.0).and.(dphase.eq.1).and.(db.lt.dinfs))then
  6570. code=3
  6571. write(buff,'(1x,a)')
  6572. x 'Stopping Criterion: Dinfs limit. Problem dual infeasibile'
  6573. endif
  6574. if(oldmp.gt.mp)oldmp=mp
  6575. oprelinf=prelinf
  6576. odrelinf=drelinf
  6577. opinf=pinf
  6578. odinf=dinf
  6579. opphas=pphase
  6580. odphas=dphase
  6581. ocgap=cgap
  6582. return
  6583. end
  6584. c
  6585. c ===========================================================================
  6586. c Compute the primal and dual steplengts
  6587. c
  6588. c ===========================================================================
  6589. c
  6590. subroutine cstpln(prstpl,xs,dxs,up,upinf,
  6591. x dustpl,dspr,ddspr,dsup,ddsup,vartyp,slktyp,vcstat)
  6592. c
  6593. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6594. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6595. common/param/ palpha,dalpha
  6596. real*8 palpha,dalpha
  6597. c
  6598. integer*4 vartyp(n),slktyp(m),vcstat(mn)
  6599. real*8 prstpl,xs(mn),dxs(mn),up(mn),upinf(mn),
  6600. x dustpl,dspr(mn),ddspr(mn),dsup(mn),ddsup(mn)
  6601. c
  6602. integer*4 i,j
  6603. real*8 sol,dup
  6604. c
  6605. prstpl=1.0d0/palpha
  6606. dustpl=1.0d0/dalpha
  6607. do i=1,mn
  6608. if(vcstat(i).gt.-2)then
  6609. if(i.le.n)then
  6610. j=vartyp(i)
  6611. else
  6612. j=slktyp(i-n)
  6613. endif
  6614. if(j.ne.0)then
  6615. if(dxs(i).lt.0.0d+0)then
  6616. sol=-xs(i)/dxs(i)
  6617. if(sol.lt.prstpl)prstpl=sol
  6618. endif
  6619. if(ddspr(i).lt.0.0d+0)then
  6620. sol=-dspr(i)/ddspr(i)
  6621. if(sol.lt.dustpl)dustpl=sol
  6622. endif
  6623. if (j.lt.0)then
  6624. dup=upinf(i)-dxs(i)
  6625. if(dup.lt.0.0d+0)then
  6626. sol=-up(i)/dup
  6627. if(sol.lt.prstpl)prstpl=sol
  6628. endif
  6629. if(ddsup(i).lt.0.0d+0)then
  6630. sol=-dsup(i)/ddsup(i)
  6631. if(sol.lt.dustpl)dustpl=sol
  6632. endif
  6633. endif
  6634. endif
  6635. endif
  6636. enddo
  6637. return
  6638. end
  6639. c
  6640. c ===========================================================================
  6641. c Compute the new primal and dual solution
  6642. c
  6643. c ===========================================================================
  6644. c
  6645. subroutine cnewpd(prstpl,xs,dxs,up,upinf,dustpl,dv,ddv,
  6646. x dspr,ddspr,dsup,ddsup,vartyp,slktyp,vcstat,maxd)
  6647. c
  6648. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6649. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6650. c
  6651. integer*4 vartyp(n),slktyp(m),vcstat(mn)
  6652. real*8 prstpl,xs(mn),dxs(mn),up(mn),upinf(mn),dustpl,dv(m),
  6653. x ddv(m),dspr(mn),ddspr(mn),dsup(mn),ddsup(mn),maxd
  6654. c
  6655. integer*4 i,j
  6656. real*8 maxdd,maxdp
  6657. c
  6658. maxdp=0.0d+0
  6659. maxdd=0.0d+0
  6660. do i=1,mn
  6661. if(vcstat(i).gt.-2)then
  6662. if(i.le.n)then
  6663. j=vartyp(i)
  6664. else
  6665. j=slktyp(i-n)
  6666. dv(i-n)=dv(i-n)+dustpl*ddv(i-n)
  6667. if(maxdd.lt.abs(ddv(i-n)))maxdd=abs(ddv(i-n))
  6668. endif
  6669. if((i.le.n).or.(j.ne.0))then
  6670. xs(i)=xs(i)+prstpl*dxs(i)
  6671. if(maxdp.lt.abs(dxs(i)))maxdp=abs(dxs(i))
  6672. dspr(i)=dspr(i)+dustpl*ddspr(i)
  6673. if(maxdd.lt.abs(ddspr(i)))maxdd=abs(ddspr(i))
  6674. endif
  6675. if (j.lt.0)then
  6676. up(i)=up(i)+prstpl*(upinf(i)-dxs(i))
  6677. if(maxdp.lt.abs(upinf(i)-dxs(i)))maxdp=abs(upinf(i)-dxs(i))
  6678. dsup(i)=dsup(i)+dustpl*ddsup(i)
  6679. if(maxdd.lt.abs(ddsup(i)))maxdd=abs(ddsup(i))
  6680. endif
  6681. endif
  6682. enddo
  6683. maxd=max(maxdp*prstpl,maxdd*dustpl)
  6684. return
  6685. end
  6686. c
  6687. c ===========================================================================
  6688. c Fixing variables and dropping rows
  6689. c ===========================================================================
  6690. c
  6691. subroutine varfix(vartyp,slktyp,rhs,colpnt,rowidx,nonzeros,
  6692. x xs,up,dspr,dsup,vcstat,fixn,dropn,addobj,scobj,obj,bounds,
  6693. x duinf,dinf,fxp,fxd,fxu)
  6694. c
  6695. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6696. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6697. c
  6698. common/drop/ tfixvar,tfixslack,slklim
  6699. real*8 tfixvar,tfixslack,slklim
  6700. c
  6701. common/numer/ tplus,tzer
  6702. real*8 tplus,tzer
  6703. c
  6704. common/mscal/ varadd,slkadd,scfree
  6705. real*8 varadd,slkadd,scfree
  6706. c
  6707. integer*4 colpnt(n1),vartyp(n),slktyp(m),rowidx(nz),
  6708. x vcstat(mn),fixn,dropn,fxp,fxd,fxu
  6709. real*8 rhs(m),nonzeros(nz),xs(mn),up(mn),addobj,scobj,obj(n),
  6710. x dspr(mn),dsup(mn),bounds(mn),duinf(mn),dinf
  6711. c
  6712. integer*4 i,j,pnt1,pnt2
  6713. real*8 sol
  6714. c
  6715. c ---------------------------------------------------------------------------
  6716. c
  6717. fxp=0
  6718. fxd=0
  6719. fxu=0
  6720. do i=1,n
  6721. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  6722. if((xs(i).lt.tfixvar).or.
  6723. x ((vartyp(i).lt.0).and.(up(i).lt.tfixvar)))then
  6724. fixn=fixn+1
  6725. fxp=fxp+1
  6726. vcstat(i)=-2
  6727. if(xs(i).lt.tfixvar)then
  6728. xs(i)=0.0d+0
  6729. up(i)=bounds(i)
  6730. else
  6731. xs(i)=bounds(i)
  6732. up(i)=0.0d+0
  6733. endif
  6734. sol=xs(i)
  6735. pnt1=colpnt(i)
  6736. pnt2=colpnt(i+1)-1
  6737. do j=pnt1,pnt2
  6738. rhs(rowidx(j)-n)=rhs(rowidx(j)-n)-sol*nonzeros(j)
  6739. enddo
  6740. addobj=addobj+scobj*obj(i)*sol
  6741. endif
  6742. if (dspr(i).lt.tfixslack)then
  6743. fxd=fxd+1
  6744. duinf(i)=duinf(i)-slklim+dspr(i)
  6745. dspr(i)=slklim
  6746. endif
  6747. endif
  6748. enddo
  6749. c
  6750. c Release upper bounds
  6751. c
  6752. do i=1,mn
  6753. if(i.le.n)then
  6754. j=vartyp(i)
  6755. else
  6756. j=slktyp(i-n)
  6757. endif
  6758. if((vcstat(i).gt.-2).and.(j.lt.0))then
  6759. if(dsup(i).lt.slklim)then
  6760. fxu=fxu+1
  6761. duinf(i)=duinf(i)-dsup(i)
  6762. dsup(i)=0
  6763. if(i.le.n)then
  6764. vartyp(i)=-j
  6765. else
  6766. slktyp(i-n)=-j
  6767. endif
  6768. endif
  6769. endif
  6770. enddo
  6771. c
  6772. c Relax rows
  6773. c
  6774. do i=1,m
  6775. j=i+n
  6776. if((vcstat(j).gt.-2).and.(slktyp(i).gt.0))then
  6777. if(dspr(j).lt.tfixslack)then
  6778. fxd=fxd+1
  6779. dropn=dropn+1
  6780. vcstat(j)=-2
  6781. endif
  6782. endif
  6783. enddo
  6784. c
  6785. c Compute new dual infeasibility
  6786. c
  6787. if((fxd.gt.0).or.(fxu.gt.0))then
  6788. dinf=0.0d+0
  6789. do i=1,mn
  6790. if(vcstat(i).gt.-2)then
  6791. if(abs(duinf(i)).gt.dinf)dinf=abs(duinf(i))
  6792. endif
  6793. enddo
  6794. endif
  6795. c
  6796. return
  6797. end
  6798. c
  6799. c ===========================================================================
  6800. c Modifying the primal and dual variables
  6801. c ===========================================================================
  6802. c
  6803. subroutine pdmodi(xs,dspr,vcstat,
  6804. x vartyp,slktyp,gap,pobj,dobj,prinf,duinf,upinf,
  6805. x colpnt,rowidx,rownz,pinf,uinf,dinf)
  6806. c
  6807. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6808. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6809. c
  6810. common/compl/ climit,ccorr
  6811. real*8 climit,ccorr
  6812. c
  6813. integer*4 vcstat(mn),vartyp(n),slktyp(m),colpnt(n1),rowidx(nz)
  6814. real*8 xs(mn),dspr(mn),gap,pobj,dobj,
  6815. x prinf(m),upinf(mn),duinf(mn),rownz(nz),pinf,uinf,dinf
  6816. c
  6817. integer*4 i,j,k,prm,dum,upm,pnt1,pnt2
  6818. real*8 sp,sd,sol,s
  6819. c
  6820. c --------------------------------------------------------------------------
  6821. c
  6822. prm=0
  6823. dum=0
  6824. upm=0
  6825. sd=gap
  6826. sp=abs(pobj-dobj)/(abs(pobj)+1.0d0)
  6827. sd=sd*ccorr
  6828. if(sd.gt.climit)sd=climit
  6829. do i=1,mn
  6830. if(vcstat(i).gt.-2)then
  6831. if(i.le.n)then
  6832. j=vartyp(i)
  6833. else
  6834. j=slktyp(i-n)
  6835. endif
  6836. if(j.ne.0)then
  6837. sp=xs(i)*dspr(i)
  6838. if(sp.lt.sd)then
  6839. if(xs(i).gt.dspr(i))then
  6840. sol=sd/xs(i)
  6841. duinf(i)=duinf(i)+dspr(i)-sol
  6842. dspr(i)=sol
  6843. dum=dum+1
  6844. else
  6845. sol=sd/dspr(i)
  6846. s=xs(i)-sol
  6847. xs(i)=sol
  6848. if(j.lt.0)then
  6849. upinf(i)=upinf(i)+s
  6850. upm=upm+1
  6851. endif
  6852. if(i.le.n)then
  6853. pnt1=colpnt(i)
  6854. pnt2=colpnt(i+1)-1
  6855. do k=pnt1,pnt2
  6856. prinf(rowidx(k)-n)=prinf(rowidx(k)-n)+s*rownz(k)
  6857. enddo
  6858. else
  6859. prinf(i-n)=prinf(i-n)-s
  6860. endif
  6861. prm=prm+1
  6862. endif
  6863. endif
  6864. ccc
  6865. ccc It's totally wrong! Do not modify upper bounds !
  6866. ccc
  6867. ccc if(j.lt.0)then
  6868. ccc sp=up(i)*dsup(i)
  6869. ccc if(sp.lt.sd)then
  6870. ccc if(up(i).gt.dsup(i))then
  6871. ccc sol=sd/up(i)
  6872. ccc duinf(i)=duinf(i)-dsup(i)+sol
  6873. ccc dsup(i)=sol
  6874. ccc dum=dum+1
  6875. ccc else
  6876. ccc sol=sd/dsup(i)
  6877. ccc upinf(i)=upinf(i)+up(i)-sol
  6878. ccc up(i)=sol
  6879. ccc upm=upm+1
  6880. ccc endif
  6881. ccc endif
  6882. ccc endif
  6883. endif
  6884. endif
  6885. enddo
  6886. c
  6887. c Correct infeas. norm
  6888. c
  6889. if(prm.gt.0)then
  6890. pinf=0.0d+0
  6891. do i=1,m
  6892. if(vcstat(i+n).gt.-2)then
  6893. if(abs(prinf(i)).gt.pinf)pinf=abs(prinf(i))
  6894. else
  6895. prinf(i)=0.0d+0
  6896. endif
  6897. enddo
  6898. endif
  6899. if(upm.gt.0)then
  6900. uinf=0.0d+0
  6901. do i=1,mn
  6902. if(vcstat(i).gt.-2)then
  6903. if(abs(upinf(i)).gt.uinf)uinf=abs(upinf(i))
  6904. else
  6905. upinf(i)=0.0d+0
  6906. endif
  6907. enddo
  6908. endif
  6909. if(dum.gt.0)then
  6910. dinf=0.0d+0
  6911. do i=1,mn
  6912. if(vcstat(i).gt.-2)then
  6913. if(abs(duinf(i)).gt.dinf)dinf=abs(duinf(i))
  6914. else
  6915. duinf(i)=0.0d+0
  6916. endif
  6917. enddo
  6918. endif
  6919. return
  6920. end
  6921. c
  6922. c ===========================================================================
  6923. c Scaling of free variables : "Average" of basics * scfree
  6924. c Correcting : "Average" of basics * varadd
  6925. c
  6926. c ===========================================================================
  6927. c
  6928. subroutine cdiag(xs,up,dspr,dsup,vartyp,slktyp,vcstat,diag,
  6929. x odiag)
  6930. c
  6931. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6932. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  6933. c
  6934. common/mscal/ varadd,slkadd,scfree
  6935. real*8 varadd,slkadd,scfree
  6936. c
  6937. common/numer/ tplus,tzer
  6938. real*8 tplus,tzer
  6939. c
  6940. integer*4 vartyp(n),slktyp(m),vcstat(mn)
  6941. real*8 xs(mn),up(mn),dspr(mn),dsup(mn),diag(mn),odiag(mn)
  6942. c
  6943. integer*4 i,j
  6944. real*8 sol,sn,sm,mins
  6945. c
  6946. c ---------------------------------------------------------------------------
  6947. c
  6948. sn=0.0d+0
  6949. mins=1.0d+0
  6950. j=0
  6951. do i=1,n
  6952. sol=0.0d+0
  6953. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  6954. if(vartyp(i).lt.0)then
  6955. sol=dspr(i)/xs(i)+dsup(i)/up(i)
  6956. else
  6957. sol=dspr(i)/xs(i)
  6958. endif
  6959. c
  6960. c Compute average on "basic" variables
  6961. c
  6962. if(mins.gt.sol)mins=sol
  6963. if(vcstat(i).gt.0)then
  6964. j=j+1
  6965. sn=sn+log(sol)
  6966. endif
  6967. endif
  6968. diag(i)=sol
  6969. odiag(i)=sol
  6970. enddo
  6971. c
  6972. c Compute geometric mean of the "basics"
  6973. c
  6974. if(j.eq.0)j=1
  6975. sol=exp(sn/dble(j))
  6976. c
  6977. c Set scale parameter for free variables
  6978. c
  6979. if(abs(scfree).lt.tzer)then
  6980. sn=0.0d+0
  6981. else if(scfree.lt.0.0d+0)then
  6982. sn=-scfree
  6983. else
  6984. sn=max(sol*scfree,mins)
  6985. endif
  6986. c
  6987. c Set regularization parameter
  6988. c
  6989. if(abs(varadd).lt.tzer)then
  6990. sm=0.0d+0
  6991. else if(varadd.lt.0.0d+0)then
  6992. sm=-varadd
  6993. else
  6994. sm=sol*varadd
  6995. endif
  6996. c
  6997. c Second pass: Set free variables and regularize
  6998. c
  6999. do i=1,n
  7000. if(vcstat(i).gt.-2)then
  7001. if(vartyp(i).eq.0)then
  7002. sol=sn
  7003. else
  7004. sol=diag(i)
  7005. endif
  7006. ccc if(sol.lt.sm*sm)sol=sm*sqrt(sol)
  7007. if(sol.lt.sm)sol=sm*sqrt(sol/sm)
  7008. diag(i)=-sol
  7009. odiag(i)=-sol
  7010. endif
  7011. enddo
  7012. c
  7013. c
  7014. c
  7015. j=0
  7016. sn=0.0d+0
  7017. do i=1,m
  7018. sol=0.0d+0
  7019. if(vcstat(i+n).gt.-2)then
  7020. if(slktyp(i).eq.0)then
  7021. sol=0.0d+0
  7022. else
  7023. if(slktyp(i).lt.0)then
  7024. sol=1.0d+0/(dspr(i+n)/xs(i+n)+dsup(i+n)/up(i+n))+0.0d+0
  7025. else
  7026. sol=xs(i+n)/dspr(i+n)
  7027. endif
  7028. if(vcstat(i+n).gt.0)then
  7029. j=j+1
  7030. sn=sn+log(sol)
  7031. endif
  7032. endif
  7033. endif
  7034. diag(i+n)=sol
  7035. odiag(i+n)=sol
  7036. enddo
  7037. if(j.eq.0)j=1
  7038. if(abs(slkadd).lt.tzer)then
  7039. sm=0.0d+0
  7040. else if(slkadd.lt.0.0d+0)then
  7041. sm=-slkadd
  7042. else
  7043. sm=exp(sn/dble(j))*slkadd
  7044. endif
  7045. if(sm.gt.tzer)then
  7046. do i=1,m
  7047. if(vcstat(i+n).gt.-2)then
  7048. sol=diag(i+n)
  7049. ccc if(sol.gt.sm*sm)sol=sm*sqrt(sol)
  7050. if(sol.gt.sm)sol=sm*sqrt(sol/sm)
  7051. diag(i+n)=sol
  7052. odiag(i+n)=sol
  7053. endif
  7054. enddo
  7055. endif
  7056. return
  7057. end
  7058. c
  7059. c ===========================================================================
  7060. c Multi predictor-corrector direction (Merothra)
  7061. c
  7062. c ===========================================================================
  7063. c
  7064. subroutine cpdpcd(xs,up,dspr,dsup,prinf,duinf,upinf,
  7065. x dxsn,ddvn,ddsprn,ddsupn,dxs,ddv,ddspr,ddsup,bounds,
  7066. x ecolpnt,count,pivots,vcstat,diag,odiag,rowidx,nonzeros,
  7067. x colpnt,vartyp,slktyp,barpar,corr,prstpl,dustpl,barn,cgap)
  7068. c
  7069. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7070. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7071. common/numer/ tplus,tzer
  7072. real*8 tplus,tzer
  7073. common/predp/ ccstop,barset,bargrw,barmin,mincor,maxcor,inibar
  7074. real*8 ccstop,barset,bargrw,barmin
  7075. integer*4 mincor,maxcor,inibar
  7076. c
  7077. integer*4 ecolpnt(mn),count(mn),vcstat(mn),rowidx(cfree),
  7078. x pivots(mn),colpnt(n1),vartyp(n),slktyp(m),corr,barn
  7079. real*8 xs(mn),up(mn),dspr(mn),dsup(mn),prinf(m),duinf(mn),
  7080. x upinf(mn),dxsn(mn),ddvn(m),ddsprn(mn),ddsupn(mn),
  7081. x dxs(mn),ddv(m),ddspr(mn),ddsup(mn),bounds(mn),
  7082. x diag(mn),odiag(mn),nonzeros(cfree),barpar,prstpl,dustpl,cgap
  7083. c
  7084. integer*4 i,j,cr,mxcor
  7085. real*8 sol,sb,ogap,ngap,obpar,ostp,ostd
  7086. c
  7087. c ---------------------------------------------------------------------------
  7088. c
  7089. c Compute ogap
  7090. c
  7091. ogap=cgap
  7092. if(barpar.lt.tzer)barpar=ogap/dble(barn)*barset
  7093. obpar=barpar
  7094. if(inibar.le.0)then
  7095. barpar=0.0d+0
  7096. else
  7097. barpar=ogap/dble(barn)*barset
  7098. if(barpar.gt.obpar*bargrw)barpar=obpar*bargrw
  7099. endif
  7100. c
  7101. cr=0
  7102. mxcor=maxcor
  7103. c
  7104. c Initialize : Reset
  7105. c
  7106. do i=1,m
  7107. ddv(i)=0.0d+0
  7108. enddo
  7109. do i=1,mn
  7110. dxs(i)=0.0d+0
  7111. ddspr(i)=0.0d+0
  7112. ddsup(i)=0.0d+0
  7113. enddo
  7114. c
  7115. c Affine scaling / primal-dual direction
  7116. c
  7117. do i=1,n
  7118. sol=0.0d+0
  7119. if(vcstat(i).gt.-2)then
  7120. if(vartyp(i))10,11,12
  7121. 10 sol=duinf(i)+dspr(i)-barpar/xs(i)
  7122. x -dsup(i)+(barpar-dsup(i)*upinf(i))/up(i)
  7123. goto 15
  7124. 11 sol=duinf(i)
  7125. goto 15
  7126. 12 sol=duinf(i)+dspr(i)-barpar/xs(i)
  7127. endif
  7128. 15 dxsn(i)=sol
  7129. enddo
  7130. c
  7131. do i=1,m
  7132. j=i+n
  7133. sol=0.0d+0
  7134. if(vcstat(j).gt.-2)then
  7135. if(slktyp(i))20,21,22
  7136. 20 sol=-(duinf(j)+dspr(j)-barpar/xs(j)
  7137. x -dsup(j)+(barpar-dsup(j)*upinf(j))/up(j))*odiag(j)
  7138. goto 25
  7139. 21 sol=0.0d+0
  7140. goto 25
  7141. 22 sol=-(duinf(j)+dspr(j)-barpar/xs(j))*odiag(j)
  7142. endif
  7143. 25 dxsn(j)=prinf(i)+sol
  7144. enddo
  7145. c
  7146. c Solve the augmented system
  7147. c
  7148. if(cr.lt.mincor)then
  7149. call augftr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  7150. x diag,dxsn)
  7151. call augbtr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  7152. x diag,dxsn)
  7153. else
  7154. call citref(diag,odiag,pivots,rowidx,nonzeros,colpnt,
  7155. x ecolpnt,count,vcstat,dxsn,ddsprn,ddsupn,upinf,
  7156. x bounds,xs,up,vartyp,slktyp)
  7157. endif
  7158. c
  7159. c Primal and dual variables
  7160. c Primal slacks : ds=D_s^{-1}*(b_s+dy)
  7161. c
  7162. do i=1,m
  7163. j=i+n
  7164. if(vcstat(j).gt.-2)then
  7165. ddvn(i)=dxsn(j)
  7166. if(slktyp(i).ne.0)then
  7167. if(slktyp(i).gt.0)then
  7168. sb=duinf(j)+dspr(j)-barpar/xs(j)
  7169. else
  7170. sb=duinf(j)+dspr(j)-barpar/xs(j)
  7171. x -dsup(j)+(barpar-dsup(j)*upinf(j))/up(j)
  7172. endif
  7173. dxsn(j)=-odiag(j)*(ddvn(i)+sb)
  7174. endif
  7175. endif
  7176. enddo
  7177. c
  7178. c Primal upper bounds, dual slacks
  7179. c dz=-Z+X^{-1}(mu -dx*dz -Z*dx)
  7180. c
  7181. do i=1,mn
  7182. if(vcstat(i).gt.-2)then
  7183. if(i.le.n)then
  7184. j=vartyp(i)
  7185. else
  7186. j=slktyp(i-n)
  7187. endif
  7188. if(j.lt.0)then
  7189. ddsupn(i)=-dsup(i)+(barpar-dsup(i)*(upinf(i)-dxsn(i)))/up(i)
  7190. endif
  7191. if(j.ne.0)then
  7192. ddsprn(i)=-dspr(i)+(barpar-dspr(i)*dxsn(i))/xs(i)
  7193. else if(i.le.n)then
  7194. ddsprn(i)=-dspr(i)
  7195. endif
  7196. endif
  7197. enddo
  7198. c
  7199. c Compute primal and dual steplengths
  7200. c
  7201. call cstpln(prstpl,xs,dxsn,up,upinf,
  7202. x dustpl,dspr,ddsprn,dsup,ddsupn,vartyp,slktyp,vcstat)
  7203. c
  7204. c Estimate basic variables vcstat(i)=1 for basic, 0 for nonbasic
  7205. c
  7206. do i=1,n
  7207. if((vcstat(i).gt.-2).and.(vartyp(i).ne.0))then
  7208. if(abs(ddsprn(i))*xs(i).gt.abs(dxsn(i))*dspr(i))then
  7209. vcstat(i)=1
  7210. else
  7211. vcstat(i)=0
  7212. endif
  7213. endif
  7214. enddo
  7215. do i=1,m
  7216. if((vcstat(i+n).gt.-2).and.(slktyp(i).ne.0))then
  7217. if(abs(ddsprn(i+n))*xs(i+n).gt.abs(dxsn(i+n))*dspr(i+n))then
  7218. vcstat(i+n)=1
  7219. else
  7220. vcstat(i+n)=0
  7221. endif
  7222. endif
  7223. enddo
  7224. c
  7225. c Compute ngap
  7226. c
  7227. ngap=0.0d+0
  7228. do i=1,mn
  7229. if(vcstat(i).gt.-2)then
  7230. if(i.le.n)then
  7231. j=vartyp(i)
  7232. else
  7233. j=slktyp(i-n)
  7234. endif
  7235. if(j.ne.0)then
  7236. ngap=ngap+(xs(i)+prstpl*dxsn(i))*(dspr(i)+dustpl*ddsprn(i))
  7237. if(j.lt.0)then
  7238. ngap=ngap+(up(i)+prstpl*(upinf(i)-dxsn(i)))*
  7239. x (dsup(i)+dustpl*ddsupn(i))
  7240. endif
  7241. endif
  7242. endif
  7243. enddo
  7244. cgap=ngap/dble(barn)
  7245. ostp=prstpl
  7246. ostd=dustpl
  7247. do i=1,mn
  7248. dxs(i)=dxsn(i)
  7249. ddspr(i)=ddsprn(i)
  7250. ddsup(i)=ddsupn(i)
  7251. enddo
  7252. do i=1,m
  7253. ddv(i)=ddvn(i)
  7254. enddo
  7255. c
  7256. c Compute barrier
  7257. c
  7258. barpar=ngap*ngap*ngap/(ogap*ogap*dble(barn))
  7259. if(barpar.gt.ogap/dble(barn)*barset)barpar=ogap/dble(barn)*barset
  7260. if(barpar.gt.obpar*bargrw)barpar=obpar*bargrw
  7261. if(barpar.lt.barmin)barpar=0.0d+0
  7262. if(mxcor.le.0)goto 999
  7263. c
  7264. c Higher order predictor-corrector direction
  7265. c
  7266. 50 cr=cr+1
  7267. do i=1,n
  7268. sol=0.0d+0
  7269. if(vcstat(i).gt.-2)then
  7270. if(vartyp(i))30,31,32
  7271. 30 sol=duinf(i)+dspr(i)+(ddspr(i)*dxs(i)-barpar)/xs(i)
  7272. x -dsup(i)-(ddsup(i)*(upinf(i)-dxs(i))-barpar+dsup(i)*
  7273. x upinf(i))/up(i)
  7274. goto 35
  7275. 31 sol=duinf(i)
  7276. goto 35
  7277. 32 sol=duinf(i)+dspr(i)+(ddspr(i)*dxs(i)-barpar)/xs(i)
  7278. endif
  7279. 35 dxsn(i)=sol
  7280. enddo
  7281. c
  7282. do i=1,m
  7283. j=i+n
  7284. sol=0.0d+0
  7285. if(vcstat(j).gt.-2)then
  7286. if(slktyp(i))40,41,42
  7287. 40 sol=-(duinf(j)+dspr(j)+(ddspr(j)*dxs(j)-barpar)/xs(j)
  7288. x -dsup(j)-(ddsup(j)*(upinf(j)-dxs(j))-barpar+dsup(j)*
  7289. x upinf(j))/up(j))*odiag(j)
  7290. goto 45
  7291. 41 sol=0.0d+0
  7292. goto 45
  7293. 42 sol=-(duinf(j)+dspr(j)+(ddspr(j)*dxs(j)-barpar)/xs(j))*odiag(j)
  7294. endif
  7295. 45 dxsn(j)=prinf(i)+sol
  7296. enddo
  7297. c
  7298. c Solve the augmented system
  7299. c
  7300. if(cr.lt.mincor)then
  7301. call augftr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  7302. x diag,dxsn)
  7303. call augbtr(ecolpnt,vcstat,rowidx,pivots,count,nonzeros,
  7304. x diag,dxsn)
  7305. else
  7306. call citref(diag,odiag,pivots,rowidx,nonzeros,colpnt,
  7307. x ecolpnt,count,vcstat,dxsn,ddsprn,ddsupn,upinf,
  7308. x bounds,xs,up,vartyp,slktyp)
  7309. endif
  7310. c
  7311. c Primal and dual variables
  7312. c Primal slacks : ds=D_s^{-1}*(b_s+dy)
  7313. c
  7314. do i=1,m
  7315. j=i+n
  7316. if(vcstat(j).gt.-2)then
  7317. ddvn(i)=dxsn(j)
  7318. if(slktyp(i).ne.0)then
  7319. if(slktyp(i).gt.0)then
  7320. sb=duinf(j)+dspr(j)+(ddspr(j)*dxs(j)-barpar)/xs(j)
  7321. else
  7322. sb=duinf(j)+dspr(j)+(ddspr(j)*dxs(j)-barpar)/xs(j)
  7323. x -dsup(j)-(ddsup(j)*(upinf(j)-dxs(j))-barpar+dsup(j)*
  7324. x upinf(j))/up(j)
  7325. endif
  7326. dxsn(j)=-odiag(j)*(ddvn(i)+sb)
  7327. endif
  7328. endif
  7329. enddo
  7330. c
  7331. c Primal upper bounds, dual slacks
  7332. c dz=-Z+X^{-1}(mu -dx*dz -Z*dx)
  7333. c
  7334. do i=1,mn
  7335. if(vcstat(i).gt.-2)then
  7336. if(i.le.n)then
  7337. j=vartyp(i)
  7338. else
  7339. j=slktyp(i-n)
  7340. endif
  7341. if(j.lt.0)then
  7342. ddsupn(i)=
  7343. x -dsup(i)+(barpar-ddsup(i)*(upinf(i)-dxs(i))
  7344. x -dsup(i)*(upinf(i)-dxsn(i)))/up(i)
  7345. endif
  7346. if(j.ne.0)then
  7347. ddsprn(i)=
  7348. x -dspr(i)+(barpar-ddspr(i)*dxs(i)-dspr(i)*dxsn(i))/xs(i)
  7349. else if(i.le.n)then
  7350. ddsprn(i)=-dspr(i)
  7351. endif
  7352. endif
  7353. enddo
  7354. c
  7355. c Compute primal and dual steplengths
  7356. c
  7357. call cstpln(prstpl,xs,dxsn,up,upinf,dustpl,dspr,
  7358. x ddsprn,dsup,ddsupn,vartyp,slktyp,vcstat)
  7359. c
  7360. c Compute ngap
  7361. c
  7362. ngap=0.0d+0
  7363. do i=1,mn
  7364. if(vcstat(i).gt.-2)then
  7365. if(i.le.n)then
  7366. j=vartyp(i)
  7367. else
  7368. j=slktyp(i-n)
  7369. endif
  7370. if(j.ne.0)then
  7371. ngap=ngap+(xs(i)+prstpl*dxsn(i))*(dspr(i)+dustpl*ddsprn(i))
  7372. if(j.lt.0)then
  7373. ngap=ngap+(up(i)+prstpl*(upinf(i)-dxsn(i)))*
  7374. x (dsup(i)+dustpl*ddsupn(i))
  7375. endif
  7376. endif
  7377. endif
  7378. enddo
  7379. c
  7380. c Check corrections criteria
  7381. c
  7382. if(cr.gt.mincor)then
  7383. if(min(prstpl,dustpl).lt.ccstop*min(ostp,ostd))then
  7384. if(min(prstpl,dustpl).lt.min(ostp,ostd))then
  7385. prstpl=ostp
  7386. dustpl=ostd
  7387. cr=cr-1
  7388. goto 999
  7389. else
  7390. mxcor=cr
  7391. endif
  7392. endif
  7393. endif
  7394. c
  7395. c Continue correcting, change the actual search direction
  7396. c
  7397. cgap=ngap/dble(barn)
  7398. ostp=prstpl
  7399. ostd=dustpl
  7400. do i=1,mn
  7401. dxs(i)=dxsn(i)
  7402. ddspr(i)=ddsprn(i)
  7403. ddsup(i)=ddsupn(i)
  7404. enddo
  7405. do i=1,m
  7406. ddv(i)=ddvn(i)
  7407. enddo
  7408. if(cr.ge.mxcor)goto 999
  7409. goto 50
  7410. c
  7411. c End of the correction loop, save the number of the corrections
  7412. c
  7413. 999 corr=cr
  7414. return
  7415. end
  7416. c
  7417. c ============================================================================
  7418. c Multi-centrality corrections
  7419. c
  7420. c ===========================================================================
  7421. c
  7422. subroutine cpdccd(xs,up,dspr,dsup,upinf,
  7423. x dxsn,ddvn,ddsprn,ddsupn,dxs,ddv,ddspr,ddsup,bounds,
  7424. x ecolpnt,count,pivots,vcstat,diag,odiag,rowidx,nonzeros,
  7425. x colpnt,vartyp,slktyp,barpar,corr,prstpl,dustpl)
  7426. c
  7427. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7428. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7429. common/numer/ tplus,tzer
  7430. real*8 tplus,tzer
  7431. common/predc/ target,tsmall,tlarge,center,corstp,mincc,maxcc
  7432. real*8 target,tsmall,tlarge,center,corstp
  7433. integer*4 mincc,maxcc
  7434. c
  7435. integer*4 ecolpnt(mn),count(mn),vcstat(mn),rowidx(cfree),
  7436. x pivots(mn),colpnt(n1),vartyp(n),slktyp(m),corr
  7437. real*8 xs(mn),up(mn),dspr(mn),dsup(mn),
  7438. x upinf(mn),dxsn(mn),ddvn(m),ddsprn(mn),ddsupn(mn),
  7439. x dxs(mn),ddv(m),ddspr(mn),ddsup(mn),bounds(mn),
  7440. x diag(mn),odiag(mn),nonzeros(cfree),barpar,prstpl,dustpl
  7441. c
  7442. integer*4 i,j,cr,maxccx
  7443. real*8 s,ss,ostp,ostd,prs,dus,dp
  7444. c
  7445. c ---------------------------------------------------------------------------
  7446. maxccx=maxcc
  7447. cr=0
  7448. ostp=prstpl
  7449. ostd=dustpl
  7450. if(maxcc.le.0)goto 999
  7451. cr=1
  7452. c
  7453. c Define Target
  7454. c
  7455. 1 prs=prstpl*(target+1.0d+0)+target
  7456. dus=dustpl*(target+1.0d+0)+target
  7457. if (prs.ge.1.0d+0)prs=1.0d+0
  7458. if (dus.ge.1.0d+0)dus=1.0d+0
  7459. do 10 j=1,n
  7460. if(vcstat(j).le.-2)then
  7461. dxsn(j)=0.0d+0
  7462. goto 10
  7463. endif
  7464. if(vartyp(j).eq.0)then
  7465. dxsn(j)=0.0d+0
  7466. goto 10
  7467. endif
  7468. dp=(xs(j)+prs*dxs(j))*(dspr(j)+dus*ddspr(j))
  7469. if (dp.le.tsmall*barpar)then
  7470. s=barpar-dp
  7471. else if(dp.ge.tlarge*barpar)then
  7472. s=-center*barpar
  7473. else
  7474. s=0.0d+0
  7475. endif
  7476. if(vartyp(j).gt.0)then
  7477. dxsn(j)=-s/xs(j)
  7478. goto 10
  7479. endif
  7480. dp=(up(j)+prs*(upinf(j)-dxs(j)))*(dsup(j)+dus*ddsup(j))
  7481. if (dp.le.tsmall*barpar)then
  7482. ss=barpar-dp
  7483. else if(dp.ge.tlarge*barpar)then
  7484. ss=-center*barpar
  7485. else
  7486. ss=0.0d+0
  7487. endif
  7488. dxsn(j)=-s/xs(j)+ss/up(j)
  7489. 10 continue
  7490. c
  7491. do 20 i=1,m
  7492. j=i+n
  7493. if(vcstat(j).le.-2)then
  7494. dxsn(j)=0.0d+0
  7495. goto 20
  7496. endif
  7497. if(slktyp(i).eq.0)then
  7498. dxsn(j)=0.0d+0
  7499. goto 20
  7500. endif
  7501. c
  7502. c Bounded variable
  7503. c
  7504. dp=(xs(j)+prs*dxs(j))*(dspr(j)+dus*ddspr(j))
  7505. if (dp.le.tsmall*barpar)then
  7506. s=barpar-dp
  7507. else if (dp.ge.tlarge*barpar)then
  7508. s=-center*barpar
  7509. else
  7510. s=0.0d+0
  7511. endif
  7512. if(slktyp(i).gt.0)then
  7513. dxsn(j)=s/xs(j)*odiag(j)
  7514. goto 20
  7515. endif
  7516. c
  7517. c upper bounded variable
  7518. c
  7519. dp=(up(j)+prs*(upinf(j)-dxs(j)))*(dsup(j)+dus*ddsup(j))
  7520. if (dp.le.tsmall*barpar)then
  7521. ss=barpar-dp
  7522. else if(dp.ge.tlarge*barpar)then
  7523. ss=-center*barpar
  7524. else
  7525. ss=0.0d+0
  7526. endif
  7527. dxsn(j)=(s/xs(j)-ss/up(j))*odiag(j)
  7528. 20 continue
  7529. c
  7530. c solve the augmented system
  7531. c
  7532. call citref(diag,odiag,pivots,rowidx,nonzeros,colpnt,
  7533. x ecolpnt,count,vcstat,dxsn,ddsprn,ddsupn,upinf,
  7534. x bounds,xs,up,vartyp,slktyp)
  7535. c
  7536. c Primal and dual variables
  7537. c
  7538. do 30 i=1,m
  7539. j=i+n
  7540. if(vcstat(j).le.-2)goto 30
  7541. ddvn(i)=ddv(i)+dxsn(j)
  7542. if(slktyp(i).eq.0)goto 30
  7543. dp=(xs(j)+prs*dxs(j))*(dspr(j)+dus*ddspr(j))
  7544. if (dp.le.tsmall*barpar)then
  7545. s=barpar-dp
  7546. else if (dp.ge.tlarge*barpar)then
  7547. s=-center*barpar
  7548. else
  7549. s=0.0d+0
  7550. endif
  7551. if(slktyp(i).gt.0)then
  7552. dxsn(j)=-odiag(j)*(dxsn(j)-s/xs(j))
  7553. goto 30
  7554. endif
  7555. dp=(up(j)+prs*(upinf(j)-dxs(j)))*(dsup(j)+dus*ddsup(j))
  7556. if (dp.le.tsmall*barpar)then
  7557. ss=barpar-dp
  7558. else if(dp.ge.tlarge*barpar)then
  7559. ss=-center*barpar
  7560. else
  7561. ss=0.0d+0
  7562. endif
  7563. dxsn(j)=-odiag(j)*(dxsn(j)-s/xs(j)+ss/up(j))
  7564. 30 continue
  7565. c
  7566. c Primal upper bounds, dual slacks
  7567. c
  7568. do 40 i=1,mn
  7569. if(vcstat(i).le.-2)goto 40
  7570. if(i.le.n)then
  7571. j=vartyp(i)
  7572. else
  7573. j=slktyp(i-n)
  7574. endif
  7575. if(j.eq.0)then
  7576. if(i.le.n)then
  7577. ddsprn(i)=ddsprn(i)+ddspr(i)
  7578. endif
  7579. goto 45
  7580. endif
  7581. dp=(xs(i)+prs*dxs(i))*(dspr(i)+dus*ddspr(i))
  7582. if (dp.le.tsmall*barpar)then
  7583. s=barpar-dp
  7584. else if(dp.ge.tlarge*barpar)then
  7585. s=-center*barpar
  7586. else
  7587. s=0.0d+0
  7588. endif
  7589. ddsprn(i)=(s-dspr(i)*dxsn(i))/xs(i)+ddspr(i)
  7590. if(j.lt.0)then
  7591. dp=(up(i)+prs*(upinf(i)-dxs(i)))*(dsup(i)+dus*ddsup(i))
  7592. if (dp.le.tsmall*barpar)then
  7593. ss=barpar-dp
  7594. else if(dp.ge.tlarge*barpar)then
  7595. ss=-center*barpar
  7596. else
  7597. ss=0.0d+0
  7598. endif
  7599. ddsupn(i)=(ss+dsup(i)*dxsn(i))/up(i)+ddsup(i)
  7600. endif
  7601. 45 dxsn(i)=dxsn(i)+dxs(i)
  7602. 40 continue
  7603. c
  7604. c Compute primal and dual steplengths
  7605. c
  7606. call cstpln(prstpl,xs,dxsn,up,upinf,
  7607. x dustpl,dspr,ddsprn,dsup,ddsupn,vartyp,slktyp,vcstat)
  7608. c
  7609. c Check corrections criteria
  7610. c
  7611. if(cr.gt.mincc)then
  7612. if(min(prstpl,dustpl).lt.corstp*min(ostp,ostd))then
  7613. if(min(prstpl,dustpl).lt.min(ostp,ostd))then
  7614. prstpl=ostp
  7615. dustpl=ostd
  7616. cr=cr-1
  7617. goto 999
  7618. else
  7619. maxccx=cr
  7620. endif
  7621. endif
  7622. endif
  7623. c
  7624. c Continue correcting, change the actual search direction
  7625. c
  7626. ostp=prstpl
  7627. ostd=dustpl
  7628. do i=1,mn
  7629. dxs(i)=dxsn(i)
  7630. ddspr(i)=ddsprn(i)
  7631. ddsup(i)=ddsupn(i)
  7632. enddo
  7633. do i=1,m
  7634. ddv(i)=ddvn(i)
  7635. enddo
  7636. if(cr.lt.maxccx)then
  7637. cr=cr+1
  7638. goto 1
  7639. endif
  7640. c
  7641. c End of the correction loop, save the number of the corrections
  7642. c
  7643. 999 corr=cr
  7644. return
  7645. end
  7646. c
  7647. c ============================================================================
  7648. c
  7649. c Prelev: 1 : rowsng
  7650. c 2 : colsng
  7651. c 4 : rowact
  7652. c 8 : chepdu
  7653. c 16 : duchek
  7654. c 32 : bndchk
  7655. c 64 : splchk
  7656. c 128 : freagr
  7657. c 256 : sparse
  7658. c 512 : xduchk
  7659. c
  7660. c ========================================================================
  7661. c
  7662. subroutine presol(colpnt,colidx,colnzs,rowidx,rownzs,
  7663. x collst,rowlst,colmrk,rowmrk,colsta,rowsta,
  7664. x colbeg,colend,rowbeg,rowend,
  7665. x vartyp,pmaxr,pminr,pmbig,ppbig,
  7666. x upperb,lowerb,upslck,loslck,rhs,obj,prehis,prelen,
  7667. x addobj,big,list,mrk,
  7668. x dulo,duup,dmaxc,dminc,dmbig,dpbig,prelev,code)
  7669. c
  7670. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7671. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7672. c
  7673. integer*4 colpnt(n1),colidx(nz),rowidx(nz),
  7674. x collst(n),rowlst(m),pmbig(m),ppbig(m),
  7675. x colbeg(n),colend(n),rowbeg(m),rowend(m),
  7676. x colmrk(n),rowmrk(m),colsta(n),rowsta(m),
  7677. x list(mn),mrk(mn),prehis(mn),prelen,prelev,code,
  7678. x dpbig(n),dmbig(n),vartyp(n)
  7679. real*8 colnzs(nz),rownzs(nz),pmaxr(m),pminr(m),addobj,
  7680. x upperb(n),lowerb(n),upslck(m),loslck(m),rhs(m),obj(n),
  7681. x dulo(m),duup(m),dmaxc(n),dminc(n),big
  7682. c
  7683. integer*4 i,j,k,p,o,pnt1,pnt2,pass,cnum,procn,rnum,coln,rown
  7684. real*8 sol,up,lo,tfeas,zero,lbig,bigbou,dbigbo
  7685. integer*4 dusrch,bndsrc,bndchg
  7686. character*99 buff
  7687. C CMSSW: Explicit initialization needed
  7688. pnt1=0
  7689. pnt2=0
  7690. c
  7691. c initialize : clean up the matrix and set-up row-wise structure
  7692. c
  7693. tfeas = 1.0d-08
  7694. zero = 1.0d-15
  7695. dusrch = 10
  7696. bndsrc = 5
  7697. bndchg = 6
  7698. bigbou = 1.0d+5
  7699. dbigbo = 1.0d+5
  7700. c
  7701. lbig = big*0.9d+0
  7702. pass=0
  7703. rown=0
  7704. coln=0
  7705. cnum=0
  7706. rnum=0
  7707. do i=1,mn
  7708. mrk(i)=-1
  7709. enddo
  7710. do i=1,m
  7711. pmaxr(i)=0.0d+0
  7712. pminr(i)=0.0d+0
  7713. pmbig(i)=0
  7714. ppbig(i)=0
  7715. rowend(i)=0
  7716. if(rowsta(i).gt.-2)then
  7717. rown=rown+1
  7718. rowlst(rown)=i
  7719. rowmrk(i)=0
  7720. endif
  7721. enddo
  7722. do i=1,n
  7723. dmaxc(i)=0.0d+0
  7724. dminc(i)=0.0d+0
  7725. dmbig(i)=0
  7726. dpbig(i)=0
  7727. if(colsta(i).gt.-2)then
  7728. coln=coln+1
  7729. collst(coln)=i
  7730. colmrk(i)=0
  7731. pnt1=colpnt(i)
  7732. pnt2=colpnt(i+1)-1
  7733. p=pnt2
  7734. do j=pnt2,pnt1,-1
  7735. if((rowsta(colidx(j)).le.-2).or.(abs(colnzs(j)).lt.zero))then
  7736. o=colidx(j)
  7737. sol=colnzs(j)
  7738. colidx(j)=colidx(p)
  7739. colnzs(j)=colnzs(p)
  7740. colidx(p)=o
  7741. colnzs(p)=sol
  7742. p=p-1
  7743. else
  7744. rowend(colidx(j))=rowend(colidx(j))+1
  7745. endif
  7746. enddo
  7747. colbeg(i)=pnt1
  7748. colend(i)=p
  7749. endif
  7750. enddo
  7751. pnt1=1
  7752. do j=1,rown
  7753. i=rowlst(j)
  7754. rowbeg(i)=pnt1
  7755. pnt1=pnt1+rowend(i)
  7756. rowend(i)=rowbeg(i)-1
  7757. enddo
  7758. do k=1,coln
  7759. i=collst(k)
  7760. pnt1=colbeg(i)
  7761. pnt2=colend(i)
  7762. do j=pnt1,pnt2
  7763. rowend(colidx(j))=rowend(colidx(j))+1
  7764. rowidx(rowend(colidx(j)))=i
  7765. rownzs(rowend(colidx(j)))=colnzs(j)
  7766. enddo
  7767. enddo
  7768. c
  7769. c Initialize the minimum and maximum row activity
  7770. c
  7771. sol=0.9d+0*big
  7772. o=1
  7773. do j=1,coln
  7774. i=collst(j)
  7775. pnt1=colbeg(i)
  7776. pnt2=colend(i)
  7777. up=upperb(i)
  7778. lo=lowerb(i)
  7779. call chgmxm(pnt1,pnt2,up,lo,colidx,colnzs,
  7780. x ppbig,pmaxr,pmbig,pminr,sol,o,m)
  7781. enddo
  7782. c
  7783. c Start Presolve sequence: Step 1 : ROW SINGLETONS
  7784. c
  7785. 10 procn=1
  7786. call setlst(n,m,nz,rown,rowlst,rowmrk,coln,collst,colmrk,
  7787. x procn,rowsta,colsta,rowbeg,rowend,cnum,list,mrk,pass,
  7788. x colbeg,colend,colidx)
  7789. if(coln+rown.eq.0)goto 50
  7790. if((iand(prelev,1).gt.0).and.(cnum.gt.0))then
  7791. call rowsng(n,m,mn,nz,
  7792. x colbeg,colend,colidx,colnzs,
  7793. x rowbeg,rowend,rowidx,rownzs,
  7794. x upperb,lowerb,upslck,loslck,
  7795. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7796. x coln,collst,colmrk,rown,rowlst,rowmrk,
  7797. x cnum,list,mrk,procn,
  7798. x ppbig,pmaxr,pmbig,pminr,
  7799. x lbig,tfeas,zero,code)
  7800. if(code.gt.0)goto 100
  7801. endif
  7802. c
  7803. c Step 2 : COLUMN SINGLETONS
  7804. c
  7805. procn=2
  7806. call setlst(m,n,nz,coln,collst,colmrk,rown,rowlst,rowmrk,
  7807. x procn,colsta,rowsta,colbeg,colend,cnum,list,mrk,pass,
  7808. x rowbeg,rowend,rowidx)
  7809. if(coln+rown.eq.0)goto 50
  7810. if((iand(prelev,2).gt.0).and.(cnum.gt.0))then
  7811. call colsng(n,m,mn,nz,
  7812. x colbeg,colend,colidx,colnzs,
  7813. x rowbeg,rowend,rowidx,rownzs,
  7814. x upperb,lowerb,upslck,loslck,
  7815. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7816. x coln,collst,colmrk,
  7817. x cnum,list,mrk,procn,
  7818. x ppbig,pmaxr,pmbig,pminr,
  7819. x lbig,tfeas,zero,code)
  7820. if(code.gt.0)goto 100
  7821. endif
  7822. c
  7823. c Step 3 : ROW ACTIVITY CHECK
  7824. c
  7825. procn=3
  7826. call setlst(n,m,nz,rown,rowlst,rowmrk,coln,collst,colmrk,
  7827. x procn,rowsta,colsta,rowbeg,rowend,cnum,list,mrk,pass,
  7828. x colbeg,colend,colidx)
  7829. if(coln+rown.eq.0)goto 50
  7830. if((iand(prelev,4).gt.0).and.(cnum.gt.0))then
  7831. call rowact(n,m,mn,nz,
  7832. x colbeg,colend,colidx,colnzs,
  7833. x rowbeg,rowend,rowidx,rownzs,
  7834. x upperb,lowerb,upslck,loslck,
  7835. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7836. x coln,collst,colmrk,rown,rowlst,rowmrk,
  7837. x cnum,list,mrk,procn,
  7838. x ppbig,pmaxr,pmbig,pminr,
  7839. x lbig,tfeas,code)
  7840. if(code.gt.0)goto 100
  7841. endif
  7842. c
  7843. c Step 4 : CHEAP DUAL TEST
  7844. c
  7845. procn=4
  7846. call setlst(m,n,nz,coln,collst,colmrk,rown,rowlst,rowmrk,
  7847. x procn,colsta,rowsta,colbeg,colend,cnum,list,mrk,pass,
  7848. x rowbeg,rowend,rowidx)
  7849. if(coln+rown.eq.0)goto 50
  7850. if((iand(prelev,8).gt.0).and.(cnum.gt.0))then
  7851. call chepdu(n,m,mn,nz,
  7852. x colbeg,colend,colidx,colnzs,
  7853. x rowbeg,rowend,rowidx,rownzs,
  7854. x upperb,lowerb,upslck,loslck,
  7855. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7856. x coln,collst,colmrk,rown,rowlst,rowmrk,
  7857. x cnum,list,mrk,procn,
  7858. x ppbig,pmaxr,pmbig,pminr,
  7859. x lbig,zero,code)
  7860. if(code.gt.0)goto 100
  7861. endif
  7862. c
  7863. c Step 5 : USUAL DUAL TEST
  7864. c
  7865. procn=5
  7866. call setlst(n,m,nz,rown,rowlst,rowmrk,coln,collst,colmrk,
  7867. x procn,rowsta,colsta,rowbeg,rowend,rnum,list(n+1),mrk(n+1),pass,
  7868. x colbeg,colend,colidx)
  7869. c
  7870. c Remove zero entries at the first loop from the main list
  7871. c
  7872. if (pass.eq.5)then
  7873. k=1
  7874. 5 if(k.le.coln)then
  7875. if(colmrk(collst(k)).eq.0)then
  7876. colmrk(collst(k))=-1
  7877. collst(k)=collst(coln)
  7878. coln=coln-1
  7879. else
  7880. k=k+1
  7881. endif
  7882. goto 5
  7883. endif
  7884. k=1
  7885. 20 if(k.le.rown)then
  7886. if(rowmrk(rowlst(k)).eq.0)then
  7887. rowmrk(rowlst(k))=-1
  7888. rowlst(k)=rowlst(rown)
  7889. rown=rown-1
  7890. else
  7891. k=k+1
  7892. endif
  7893. goto 20
  7894. endif
  7895. endif
  7896. c
  7897. if((iand(prelev,16).gt.0).and.(cnum+rnum.gt.0))then
  7898. call duchek(n,m,mn,nz,
  7899. x colbeg,colend,colidx,colnzs,
  7900. x rowbeg,rowend,rowidx,rownzs,
  7901. x upperb,lowerb,upslck,loslck,
  7902. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7903. x coln,collst,colmrk,rown,rowlst,rowmrk,
  7904. x cnum,list,mrk,rnum,list(n+1),mrk(n+1),procn,
  7905. x ppbig,pmaxr,pmbig,pminr,
  7906. C CMSSW: Prevent REAL*8 reusage warning (note that this is cured by
  7907. C simply using the matching temporary array already available)
  7908. C Was: dulo,duup,dmaxc,dminc,dpbig,dmbig,
  7909. x dulo,duup,dpbig,dmbig,dmaxc,dminc,
  7910. x big,lbig,tfeas,zero,dbigbo,dusrch,code,prelev)
  7911. if(code.gt.0)goto 100
  7912. endif
  7913. goto 10
  7914. c
  7915. c Bound check
  7916. c
  7917. 50 procn=6
  7918. if(iand(prelev,32).gt.0)then
  7919. call bndchk(n,m,mn,nz,
  7920. x colbeg,colend,colidx,colnzs,
  7921. x rowbeg,rowend,rowidx,rownzs,
  7922. x upperb,lowerb,upslck,loslck,
  7923. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  7924. x cnum,list,mrk,procn,dmaxc,dminc,
  7925. x ppbig,pmaxr,pmbig,pminr,dpbig,dmbig,
  7926. x big,lbig,tfeas,bndsrc,bndchg,bigbou,code)
  7927. if(code.gt.0)goto 100
  7928. endif
  7929. c
  7930. c Finding splitted free variables
  7931. c
  7932. procn=7
  7933. if(iand(prelev,64).gt.0)then
  7934. call coldbl(n,m,mn,nz,colbeg,colend,colidx,colnzs,
  7935. x rowbeg,rowend,rowidx,rownzs,upperb,lowerb,obj,colsta,
  7936. x prelen,prehis,procn,list,dmaxc,vartyp,big,lbig,tfeas,zero)
  7937. if(code.gt.0)goto 100
  7938. endif
  7939. goto 999
  7940. c
  7941. c Infeasibility detected
  7942. c
  7943. 100 if(code.eq.3)then
  7944. write(buff,'(1x,a)')'Dual infeasibility detected in presolve'
  7945. else
  7946. write(buff,'(1x,a)')'Primal infeasibility detected in presolve'
  7947. endif
  7948. call mprnt(buff)
  7949. if (procn.eq.1)then
  7950. write(buff,'(1x,a)')'Presolve process: Row singleton check'
  7951. else if (procn.eq.2)then
  7952. write(buff,'(1x,a)')'Presolve process: Column singleton check'
  7953. else if (procn.eq.3)then
  7954. write(buff,'(1x,a)')'Presolve process: Row activity check'
  7955. else if (procn.eq.4)then
  7956. write(buff,'(1x,a)')'Presolve process: Cheap dual check'
  7957. else if (procn.eq.5)then
  7958. write(buff,'(1x,a)')'Presolve process: Dual check'
  7959. else if (procn.eq.6)then
  7960. write(buff,'(1x,a)')'Presolve process: Bound check'
  7961. else if (procn.eq.7)then
  7962. write(buff,'(1x,a)')'Presolve process: Splitcol check'
  7963. endif
  7964. call mprnt(buff)
  7965. c
  7966. 999 return
  7967. end
  7968. c
  7969. c ============================================================================
  7970. c
  7971. subroutine chgmxm(pnt1,pnt2,upper,lower,idx,nonzrs,
  7972. x pbig,maxr,mbig,minr,lbig,dir,siz)
  7973. C
  7974. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7975. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  7976. c
  7977. c This subroutine changes/updates the minimum/maximum row activity
  7978. c values
  7979. c
  7980. integer*4 siz,pnt1,pnt2,idx(nz),pbig(siz),mbig(siz),dir
  7981. real*8 upper,lower,nonzrs(nz),maxr(siz),minr(siz),lbig
  7982. c
  7983. integer*4 j,k
  7984. real*8 s
  7985. c
  7986. do j=pnt1,pnt2
  7987. k=idx(j)
  7988. s=nonzrs(j)
  7989. if(s.gt.0d+0)then
  7990. if(upper.ge.lbig)then
  7991. pbig(k)=pbig(k)+dir
  7992. else
  7993. maxr(k)=maxr(k)+upper*s*dble(dir)
  7994. endif
  7995. if(lower.le.-lbig)then
  7996. mbig(k)=mbig(k)+dir
  7997. else
  7998. minr(k)=minr(k)+lower*s*dble(dir)
  7999. endif
  8000. else
  8001. if(upper.ge.lbig)then
  8002. mbig(k)=mbig(k)+dir
  8003. else
  8004. minr(k)=minr(k)+upper*s*dble(dir)
  8005. endif
  8006. if(lower.le.-lbig)then
  8007. pbig(k)=pbig(k)+dir
  8008. else
  8009. maxr(k)=maxr(k)+lower*s*dble(dir)
  8010. endif
  8011. endif
  8012. enddo
  8013. return
  8014. end
  8015. c
  8016. c ============================================================================
  8017. c
  8018. subroutine modmxm(nz,pnt1,pnt2,oldb,newb,rowidx,nonzeros,
  8019. x pbig,maxr,mbig,minr,lbig,dir,siz)
  8020. c
  8021. c This subroutine modifies the row (column) activity values
  8022. c from an old bound (oldb) to a new one (newb)
  8023. c dir= 1 update on upper bound
  8024. c dir=-1 update on lower bound
  8025. c
  8026. integer*4 nz,siz,pnt1,pnt2,rowidx(nz),pbig(siz),mbig(siz),dir
  8027. real*8 oldb,newb,nonzeros(nz),maxr(siz),minr(siz),lbig
  8028. c
  8029. integer*4 f,j,k
  8030. real*8 s,diff
  8031. c
  8032. f=0
  8033. diff=newb-oldb
  8034. if(abs(oldb).gt.lbig)then
  8035. diff=newb
  8036. f=1
  8037. if(oldb.gt.0.0d+0)then
  8038. dir=1
  8039. else
  8040. dir=-1
  8041. endif
  8042. do j=pnt1,pnt2
  8043. k=rowidx(j)
  8044. if((nonzeros(j)*dble(dir)).gt.0.0d+0)then
  8045. pbig(k)=pbig(k)-1
  8046. else
  8047. mbig(k)=mbig(k)-1
  8048. endif
  8049. enddo
  8050. endif
  8051. if(abs(newb).gt.lbig)then
  8052. diff=-oldb
  8053. f=f+2
  8054. if(newb.gt.0)then
  8055. dir=1
  8056. else
  8057. dir=-1
  8058. endif
  8059. do j=pnt1,pnt2
  8060. k=rowidx(j)
  8061. if((nonzeros(j)*dble(dir)).gt.0.0)then
  8062. pbig(k)=pbig(k)+1
  8063. else
  8064. mbig(k)=mbig(k)+1
  8065. endif
  8066. enddo
  8067. endif
  8068. if(f.lt.3)then
  8069. do j=pnt1,pnt2
  8070. k=rowidx(j)
  8071. s=nonzeros(j)
  8072. if(s.gt.0.0d+0)then
  8073. if(dir.eq.1)then
  8074. maxr(k)=maxr(k)+diff*s
  8075. else
  8076. minr(k)=minr(k)+diff*s
  8077. endif
  8078. else
  8079. if(dir.eq.1)then
  8080. minr(k)=minr(k)+diff*s
  8081. else
  8082. maxr(k)=maxr(k)+diff*s
  8083. endif
  8084. endif
  8085. enddo
  8086. endif
  8087. return
  8088. end
  8089. c
  8090. c ============================================================================
  8091. c
  8092. subroutine remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  8093. x colbeg,colend,rowbeg,rowend,rhs,pivot,traf)
  8094. c
  8095. c This subroutine removes a column from the row-wise representation
  8096. c and updates the right-hand side, if parameter traf is set
  8097. c
  8098. integer*4 m,n,nz,col,colidx(nz),rowidx(nz),
  8099. x colbeg(n),colend(n),rowbeg(m),rowend(m)
  8100. real*8 rhs(m),pivot,colnzs(nz),rownzs(nz)
  8101. logical traf
  8102. c
  8103. integer*4 i,j,k,pnt1,pnt2
  8104. real*8 sol
  8105. c
  8106. do i=colbeg(col),colend(col)
  8107. j=colidx(i)
  8108. pnt1=rowbeg(j)
  8109. pnt2=rowend(j)-1
  8110. do k=pnt1,pnt2
  8111. if(rowidx(k).eq.col)then
  8112. sol=rownzs(k)
  8113. rowidx(k)=rowidx(pnt2+1)
  8114. rownzs(k)=rownzs(pnt2+1)
  8115. rowidx(pnt2+1)=col
  8116. rownzs(pnt2+1)=sol
  8117. goto 10
  8118. endif
  8119. enddo
  8120. 10 rowend(j)=pnt2
  8121. enddo
  8122. if(traf)then
  8123. do i=colbeg(col),colend(col)
  8124. rhs(colidx(i))=rhs(colidx(i))-pivot*colnzs(i)
  8125. enddo
  8126. endif
  8127. return
  8128. end
  8129. c
  8130. c =============================================================================
  8131. c
  8132. subroutine setlst(m,n,nz,coln,collst,colmrk,rown,rowlst,rowmrk,
  8133. x procn,colsta,rowsta,colbeg,colend,cnum,list,mrk,pass,
  8134. x rowbeg,rowend,rowidx)
  8135. c
  8136. c This subroutine deletes entries from the main search list
  8137. c and set-up the local search list for the presolv subprocesses.
  8138. c
  8139. integer*4 m,n,nz,coln,collst(n),colmrk(n),procn,colsta(n),
  8140. x cnum,list(n),mrk(n),pass,colbeg(n),colend(n),
  8141. x rown,rowlst(m),rowmrk(m),rowsta(m),rowbeg(m),rowend(m),
  8142. x rowidx(nz)
  8143. c
  8144. integer*4 i,j,k,p1,p2
  8145. c
  8146. pass=pass+1
  8147. k=1
  8148. cnum=0
  8149. 10 if(k.le.coln)then
  8150. i=collst(k)
  8151. if((colsta(i).le.-2).or.(colmrk(i).eq.procn))then
  8152. collst(k)=collst(coln)
  8153. colmrk(i)=-procn
  8154. coln=coln-1
  8155. else
  8156. k=k+1
  8157. if((procn.le.2).and.(colbeg(i).ne.colend(i)))goto 10
  8158. cnum=cnum+1
  8159. list(cnum)=i
  8160. mrk(i)=pass
  8161. endif
  8162. goto 10
  8163. endif
  8164. c
  8165. k=1
  8166. 20 if(k.le.rown)then
  8167. i=rowlst(k)
  8168. if((rowsta(i).le.-2).or.(rowmrk(i).eq.procn))then
  8169. rowlst(k)=rowlst(rown)
  8170. rowmrk(i)=-procn
  8171. rown=rown-1
  8172. else
  8173. k=k+1
  8174. endif
  8175. goto 20
  8176. endif
  8177. c
  8178. c Extend lists
  8179. c
  8180. k=1
  8181. do while (k.le.rown)
  8182. p1=rowbeg(rowlst(k))
  8183. p2=rowend(rowlst(k))
  8184. do i=p1,p2
  8185. j=rowidx(i)
  8186. if((mrk(j).lt.0).and.
  8187. x ((procn.gt.2).or.(colbeg(j).eq.colend(j))))then
  8188. mrk(j)=procn
  8189. cnum=cnum+1
  8190. list(cnum)=j
  8191. endif
  8192. enddo
  8193. k=k+1
  8194. enddo
  8195. c
  8196. return
  8197. end
  8198. c
  8199. c ==========================================================================
  8200. c ===========================================================================
  8201. c
  8202. subroutine rowsng(n,m,mn,nz,
  8203. x colbeg,colend,colidx,colnzs,
  8204. x rowbeg,rowend,rowidx,rownzs,
  8205. x upb,lob,ups,los,
  8206. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  8207. x coln,collst,colmrk,rown,rowlst,rowmrk,
  8208. x cnum,list,mrk,procn,
  8209. x ppbig,pmaxr,pmbig,pminr,
  8210. x lbig,tfeas,tzer,code)
  8211. c
  8212. c This subroutine removes singleton rows and may fixes variables
  8213. c
  8214. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  8215. x rowbeg(m),rowend(m),rowidx(nz),cnum,list(m),mrk(m),
  8216. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  8217. x coln,rown,collst(n),rowlst(n),colmrk(n),rowmrk(m),
  8218. x ppbig(m),pmbig(m),code
  8219. c
  8220. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  8221. x rhs(m),obj(n),pmaxr(m),pminr(m),addobj,lbig,tfeas,tzer
  8222. c
  8223. integer*4 i,l,row,col,dir,crem,rrem
  8224. real*8 ub,lb,upper,lower,sol,pivot
  8225. logical traf
  8226. character*99 buff
  8227. c
  8228. c ---------------------------------------------------------------------------
  8229. c
  8230. rrem=0
  8231. crem=0
  8232. 10 if(cnum.ge.1)then
  8233. row=list(1)
  8234. mrk(row)=-1
  8235. list(1)=list(cnum)
  8236. cnum=cnum-1
  8237. if(rowbeg(row).eq.rowend(row))then
  8238. c
  8239. c Remove singleton row
  8240. c
  8241. col=rowidx(rowbeg(row))
  8242. pivot=rownzs(rowbeg(row))
  8243. traf=.false.
  8244. call remove(n,m,nz,row,rowidx,rownzs,colidx,colnzs,
  8245. x rowbeg,rowend,colbeg,colend,obj,lower,traf)
  8246. rrem=rrem+1
  8247. prelen=prelen+1
  8248. prehis(prelen)=row+n
  8249. rowsta(row)=-2-procn
  8250. c
  8251. c Calculate new bounds (ub,lb)
  8252. c
  8253. if(ups(row).lt.lbig)then
  8254. ub=rhs(row)+ups(row)
  8255. else
  8256. ub=ups(row)
  8257. endif
  8258. if(los(row).gt.-lbig)then
  8259. lb=rhs(row)+los(row)
  8260. else
  8261. lb=los(row)
  8262. endif
  8263. if(pivot.gt.0)then
  8264. if(ub.lt.lbig)ub=ub/pivot
  8265. if(lb.gt.-lbig)lb=lb/pivot
  8266. else
  8267. if(ub.lt.lbig)then
  8268. sol=ub/pivot
  8269. else
  8270. sol=-ub
  8271. endif
  8272. if(lb.gt.-lbig)then
  8273. ub=lb/pivot
  8274. else
  8275. ub=-lb
  8276. endif
  8277. lb=sol
  8278. endif
  8279. c
  8280. c update
  8281. c
  8282. upper=upb(col)
  8283. lower=lob(col)
  8284. dir=-1
  8285. call chgmxm(colbeg(col),colend(col),upper,lower,colidx,
  8286. x colnzs,ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  8287. if(lb.gt.lower)lower=lb
  8288. if(ub.lt.upper)upper=ub
  8289. c
  8290. c Check primal feasibility
  8291. c
  8292. if((lower-upper).gt.((abs(lower)+1.0d+0)*tfeas))then
  8293. cnum=-col
  8294. code=4
  8295. goto 100
  8296. endif
  8297. c
  8298. c Check for fix variable
  8299. c
  8300. if((upper-lower).lt.((abs(lower)+1.0d+0)*tzer))then
  8301. prelen=prelen+1
  8302. prehis(prelen)=col
  8303. colsta(col)=-2-procn
  8304. traf=.true.
  8305. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  8306. x colbeg,colend,rowbeg,rowend,rhs,lower,traf)
  8307. crem=crem+1
  8308. addobj=addobj+obj(col)*lower
  8309. do i=colbeg(col),colend(col)
  8310. l=colidx(i)
  8311. if((mrk(l).lt.0).and.(rowbeg(l).eq.rowend(l)))then
  8312. mrk(l)=procn
  8313. cnum=cnum+1
  8314. list(cnum)=l
  8315. endif
  8316. enddo
  8317. else
  8318. c
  8319. c Update bounds
  8320. c
  8321. dir=1
  8322. call chgmxm(colbeg(col),colend(col),upper,lower,colidx,
  8323. x colnzs,ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  8324. endif
  8325. lob(col)=lower
  8326. upb(col)=upper
  8327. c
  8328. c Update search lists
  8329. c
  8330. do i=colbeg(col),colend(col)
  8331. l=colidx(i)
  8332. if(rowmrk(l).lt.0)then
  8333. rown=rown+1
  8334. rowlst(rown)=l
  8335. endif
  8336. rowmrk(l)=procn
  8337. enddo
  8338. if(colsta(col).gt.-2)then
  8339. if (colmrk(col).lt.0)then
  8340. coln=coln+1
  8341. collst(coln)=col
  8342. endif
  8343. colmrk(col)=procn
  8344. endif
  8345. endif
  8346. goto 10
  8347. endif
  8348. c
  8349. 100 if(rrem+crem.gt.0)then
  8350. write(buff,'(1x,a,i5,a,i5,a)')
  8351. x 'ROWSNG:',crem,' columns,',rrem,' rows removed'
  8352. call mprnt(buff)
  8353. endif
  8354. return
  8355. end
  8356. c
  8357. c ===========================================================================
  8358. c ===========================================================================
  8359. c
  8360. subroutine colsng(n,m,mn,nz,
  8361. x colbeg,colend,colidx,colnzs,
  8362. x rowbeg,rowend,rowidx,rownzs,
  8363. x upb,lob,ups,los,
  8364. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  8365. x coln,collst,colmrk,
  8366. x cnum,list,mrk,procn,
  8367. x ppbig,pmaxr,pmbig,pminr,
  8368. x lbig,tfeas,tzer,code)
  8369. c
  8370. c This subroutine cheks singleton columns
  8371. c
  8372. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  8373. x rowbeg(m),rowend(m),rowidx(nz),cnum,list(n),mrk(n),
  8374. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  8375. x coln,collst(n),colmrk(n),ppbig(m),pmbig(m),code
  8376. c
  8377. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  8378. x rhs(m),obj(n),pmaxr(m),pminr(m),addobj,lbig,tfeas,tzer
  8379. c
  8380. integer*4 i,j,k,l,row,col,crem,rrem
  8381. real*8 ub,lb,upper,lower,sol,pivot
  8382. logical traf
  8383. character*99 buff
  8384. c
  8385. c ---------------------------------------------------------------------------
  8386. c
  8387. rrem=0
  8388. crem=0
  8389. 10 if(cnum.ge.1)then
  8390. col=list(1)
  8391. mrk(col)=-1
  8392. list(1)=list(cnum)
  8393. cnum=cnum-1
  8394. if(colbeg(col).eq.colend(col))then
  8395. row=colidx(colbeg(col))
  8396. pivot=colnzs(colbeg(col))
  8397. if(pivot.gt.0.0d+0)then
  8398. lb=lob(col)
  8399. ub=upb(col)
  8400. sol=obj(col)
  8401. else
  8402. ub=-lob(col)
  8403. lb=-upb(col)
  8404. pivot=-pivot
  8405. sol=-obj(col)
  8406. endif
  8407. if((lb.gt.-lbig).or.(ub.lt.lbig))then
  8408. c
  8409. c Compute lower bound of the LP constraint
  8410. c
  8411. if(lb.le.-lbig)then
  8412. l=pmbig(row)-1
  8413. lower=pminr(row)
  8414. else
  8415. l=pmbig(row)
  8416. lower=pminr(row)-lb*pivot
  8417. endif
  8418. if(ups(row).gt.lbig)then
  8419. l=l+1
  8420. else
  8421. lower=lower-ups(row)
  8422. endif
  8423. if(l.gt.0)lower=-lbig
  8424. c
  8425. c Compute upper bound of the LP constraint
  8426. c
  8427. if(ub.gt.lbig)then
  8428. l=ppbig(row)-1
  8429. upper=pmaxr(row)
  8430. else
  8431. l=ppbig(row)
  8432. upper=pmaxr(row)-ub*pivot
  8433. endif
  8434. if(los(row).lt.-lbig)then
  8435. l=l+1
  8436. else
  8437. upper=upper-los(row)
  8438. endif
  8439. if(l.gt.0)upper=lbig
  8440. c
  8441. c Check new upper and lower bound
  8442. c
  8443. if(lb.gt.-lbig)then
  8444. upper=(rhs(row)-upper)/pivot
  8445. if((lb-upper).gt.(abs(lb)+1.0d+0)*tfeas)goto 10
  8446. endif
  8447. if(ub.lt.lbig)then
  8448. lower=(rhs(row)-lower)/pivot
  8449. if((lower-ub).gt.(abs(ub)+1.0d+0)*tfeas)goto 10
  8450. endif
  8451. endif
  8452. c
  8453. c ( Hidden ) free singleton column found, check slacks
  8454. c
  8455. pivot=sol/pivot
  8456. if(pivot.gt.tzer)then
  8457. if(los(row).lt.-lbig)then
  8458. cnum=-col
  8459. code=3
  8460. goto 999
  8461. endif
  8462. rhs(row)=rhs(row)+los(row)
  8463. else if(pivot.lt.-tzer)then
  8464. if(ups(row).gt.lbig)then
  8465. cnum=-col
  8466. code=3
  8467. goto 999
  8468. endif
  8469. rhs(row)=rhs(row)+ups(row)
  8470. endif
  8471. c
  8472. c Column administration
  8473. c
  8474. prelen=prelen+1
  8475. prehis(prelen)=col
  8476. colsta(col)=-2-procn
  8477. traf=.false.
  8478. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  8479. x colbeg,colend,rowbeg,rowend,rhs,pivot,traf)
  8480. crem=crem+1
  8481. addobj=addobj+rhs(row)*pivot
  8482. c
  8483. c Row administration
  8484. c
  8485. prelen=prelen+1
  8486. prehis(prelen)=row+n
  8487. rowsta(row)=-2-procn
  8488. traf=.true.
  8489. call remove(n,m,nz,row,rowidx,rownzs,colidx,colnzs,
  8490. x rowbeg,rowend,colbeg,colend,obj,pivot,traf)
  8491. rrem=rrem+1
  8492. j=rowbeg(row)
  8493. k=rowend(row)
  8494. do i=j,k
  8495. l=rowidx(i)
  8496. if(colmrk(l).lt.0)then
  8497. coln=coln+1
  8498. collst(coln)=l
  8499. endif
  8500. colmrk(l)=procn
  8501. if((mrk(l).lt.0).and.(colbeg(l).eq.colend(l)))then
  8502. mrk(l)=procn
  8503. cnum=cnum+1
  8504. list(cnum)=l
  8505. endif
  8506. enddo
  8507. endif
  8508. goto 10
  8509. endif
  8510. 999 if(rrem+crem.gt.0)then
  8511. write(buff,'(1x,a,i5,a,i5,a)')
  8512. x 'COLSNG:',crem,' columns,',rrem,' rows removed'
  8513. call mprnt(buff)
  8514. endif
  8515. return
  8516. end
  8517. c
  8518. c ===========================================================================
  8519. c ===========================================================================
  8520. c
  8521. subroutine rowact(n,m,mn,nz,
  8522. x colbeg,colend,colidx,colnzs,
  8523. x rowbeg,rowend,rowidx,rownzs,
  8524. x upb,lob,ups,los,
  8525. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  8526. x coln,collst,colmrk,rown,rowlst,rowmrk,
  8527. x cnum,list,mrk,procn,
  8528. x ppbig,pmaxr,pmbig,pminr,
  8529. x lbig,tfeas,code)
  8530. c
  8531. c This subroutine removes singleton rows and may fixes variables
  8532. c
  8533. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  8534. x rowbeg(m),rowend(m),rowidx(nz),cnum,list(m),mrk(m),
  8535. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  8536. x coln,rown,collst(n),rowlst(n),colmrk(n),rowmrk(m),
  8537. x ppbig(m),pmbig(m),code
  8538. c
  8539. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  8540. x rhs(m),obj(n),pmaxr(m),pminr(m),addobj,lbig,tfeas
  8541. c
  8542. integer*4 i,j,k,l,row,col,dir,setdir,p,p1,p2,red,crem,rrem
  8543. real*8 upper,lower,pivot,eps
  8544. logical traf
  8545. character*99 buff
  8546. c
  8547. c ---------------------------------------------------------------------------
  8548. c
  8549. rrem=0
  8550. crem=0
  8551. 10 if(cnum.ge.1)then
  8552. row=list(1)
  8553. mrk(row)=-1
  8554. list(1)=list(cnum)
  8555. cnum=cnum-1
  8556. c
  8557. if(ppbig(row).le.0)then
  8558. upper=pmaxr(row)-rhs(row)
  8559. else
  8560. upper=lbig
  8561. endif
  8562. if(pmbig(row).le.0)then
  8563. lower=pminr(row)-rhs(row)
  8564. else
  8565. lower=-lbig
  8566. endif
  8567. c
  8568. c Check feasibility
  8569. c
  8570. eps=abs(rhs(row)+1.0d+0)*tfeas
  8571. if((lower-ups(row).gt.eps) .or.
  8572. x (los(row)-upper.gt.eps))then
  8573. cnum=-row-n
  8574. code=4
  8575. goto 100
  8576. endif
  8577. c
  8578. c Check redundancy
  8579. c
  8580. setdir=0
  8581. red=0
  8582. if((los(row)-lower.lt.eps) .and.
  8583. x (upper-ups(row).lt.eps))then
  8584. red=1
  8585. endif
  8586. if(ups(row)-lower.lt.eps)then
  8587. red=1
  8588. setdir=-1
  8589. else if(upper-los(row).lt.eps)then
  8590. red=1
  8591. setdir=1
  8592. endif
  8593. c
  8594. c
  8595. c
  8596. if(red.gt.0)then
  8597. prelen=prelen+1
  8598. prehis(prelen)=row+n
  8599. rowsta(row)=-2-procn
  8600. traf=.false.
  8601. call remove(n,m,nz,row,rowidx,rownzs,colidx,colnzs,
  8602. x rowbeg,rowend,colbeg,colend,obj,pivot,traf)
  8603. rrem=rrem+1
  8604. if(setdir.eq.0)then
  8605. j=rowbeg(row)
  8606. k=rowend(row)
  8607. do i=j,k
  8608. l=rowidx(i)
  8609. if(colmrk(l).lt.0)then
  8610. coln=coln+1
  8611. collst(coln)=l
  8612. endif
  8613. colmrk(l)=procn
  8614. enddo
  8615. else
  8616. dir=-1
  8617. traf=.true.
  8618. j=rowbeg(row)
  8619. k=rowend(row)
  8620. do i=j,k
  8621. col=rowidx(i)
  8622. if(rownzs(i)*dble(setdir).gt.0.0d+0)then
  8623. pivot=upb(col)
  8624. else
  8625. pivot=lob(col)
  8626. endif
  8627. p1=colbeg(col)
  8628. p2=colend(col)
  8629. call chgmxm(p1,p2,upb(col),lob(col),colidx,colnzs,
  8630. x ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  8631. addobj=addobj+pivot*obj(col)
  8632. lob(col)=pivot
  8633. upb(col)=pivot
  8634. prelen=prelen+1
  8635. prehis(prelen)=col
  8636. colsta(col)=-2-procn
  8637. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  8638. x colbeg,colend,rowbeg,rowend,rhs,pivot,traf)
  8639. crem=crem+1
  8640. p1=colbeg(col)
  8641. p2=colend(col)
  8642. do p=p1,p2
  8643. l=colidx(p)
  8644. if(rowmrk(l).lt.0)then
  8645. rown=rown+1
  8646. rowlst(rown)=l
  8647. endif
  8648. rowmrk(l)=procn
  8649. if(mrk(l).lt.0)then
  8650. mrk(l)=procn
  8651. cnum=cnum+1
  8652. list(cnum)=l
  8653. endif
  8654. enddo
  8655. enddo
  8656. endif
  8657. endif
  8658. goto 10
  8659. endif
  8660. c
  8661. 100 if(rrem+crem.gt.0)then
  8662. write(buff,'(1x,a,i5,a,i5,a)')
  8663. x 'ROWACT:',crem,' columns,',rrem,' rows removed'
  8664. call mprnt(buff)
  8665. endif
  8666. return
  8667. end
  8668. c
  8669. c ===========================================================================
  8670. c ===========================================================================
  8671. c
  8672. subroutine chepdu(n,m,mn,nz,
  8673. x colbeg,colend,colidx,colnzs,
  8674. x rowbeg,rowend,rowidx,rownzs,
  8675. x upb,lob,ups,los,
  8676. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  8677. x coln,collst,colmrk,rown,rowlst,rowmrk,
  8678. x cnum,list,mrk,procn,
  8679. x ppbig,pmaxr,pmbig,pminr,
  8680. x lbig,tzer,code)
  8681. c
  8682. c This subroutine performs the "cheap" dual tests
  8683. c
  8684. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  8685. x rowbeg(m),rowend(m),rowidx(nz),cnum,list(n),mrk(n),
  8686. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  8687. x coln,rown,collst(n),rowlst(n),colmrk(n),rowmrk(m),
  8688. x ppbig(m),pmbig(m),code
  8689. c
  8690. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  8691. x rhs(m),obj(n),pmaxr(m),pminr(m),addobj,lbig,tzer
  8692. c
  8693. integer*4 i,j,k,l,row,col,dir,p,p1,p2,mode,crem,rrem
  8694. real*8 pivot,sol
  8695. logical traf
  8696. character*99 buff
  8697. c
  8698. c ---------------------------------------------------------------------------
  8699. c
  8700. crem=0
  8701. rrem=0
  8702. 10 if(cnum.ge.1)then
  8703. col=list(1)
  8704. mrk(col)=-1
  8705. list(1)=list(cnum)
  8706. cnum=cnum-1
  8707. c
  8708. p1=colbeg(col)
  8709. p2=colend(col)
  8710. mode=0
  8711. do i=p1,p2
  8712. if (abs(colnzs(i)).gt.tzer)then
  8713. row=colidx(i)
  8714. if(ups(row).gt.lbig)then
  8715. k=1
  8716. else if(los(row).lt.-lbig)then
  8717. k=-1
  8718. else
  8719. goto 10
  8720. endif
  8721. if(colnzs(i).gt.0.0d+0)then
  8722. j=1
  8723. else
  8724. j=-1
  8725. endif
  8726. if(mode.eq.0)then
  8727. mode=j*k
  8728. if((obj(col)*dble(mode)).gt.0.0d+0)goto 10
  8729. else
  8730. if(j*k*mode.lt.0)goto 10
  8731. endif
  8732. endif
  8733. enddo
  8734. c
  8735. c Check the column
  8736. c
  8737. if(mode.gt.0)then
  8738. sol=upb(col)
  8739. else if(mode.lt.0)then
  8740. sol=lob(col)
  8741. else
  8742. if(obj(col).lt.0.0d+0)then
  8743. sol=upb(col)
  8744. else if(obj(col).gt.0.0) then
  8745. sol=lob(col)
  8746. else
  8747. sol=lob(col)
  8748. if(upb(col).ge.lbig)sol=upb(col)
  8749. endif
  8750. endif
  8751. c
  8752. c Adminisztracio
  8753. c
  8754. dir=-1
  8755. call chgmxm(p1,p2,upb(col),lob(col),colidx,colnzs,
  8756. x ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  8757. c
  8758. prelen=prelen+1
  8759. prehis(prelen)=col
  8760. colsta(col)=-2-procn
  8761. traf=.true.
  8762. if(abs(sol).gt.lbig)then
  8763. pivot=0.0d+0
  8764. else
  8765. pivot=sol
  8766. endif
  8767. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  8768. x colbeg,colend,rowbeg,rowend,rhs,pivot,traf)
  8769. crem=crem+1
  8770. c
  8771. if(abs(sol).gt.lbig)then
  8772. if(abs(obj(col)).gt.tzer)then
  8773. cnum=-col
  8774. code=3
  8775. goto 999
  8776. endif
  8777. c
  8778. c Row redundacncy with the column
  8779. c
  8780. do i=p1,p2
  8781. row=colidx(i)
  8782. if(abs(colnzs(i)).gt.tzer)then
  8783. prelen=prelen+1
  8784. prehis(prelen)=row+n
  8785. rowsta(row)=-2-procn
  8786. traf=.false.
  8787. call remove(n,m,nz,row,rowidx,rownzs,colidx,colnzs,
  8788. x rowbeg,rowend,colbeg,colend,obj,sol,traf)
  8789. rrem=rrem+1
  8790. j=rowbeg(row)
  8791. k=rowend(row)
  8792. do p=j,k
  8793. l=rowidx(p)
  8794. if(colmrk(l).lt.0)then
  8795. coln=coln+1
  8796. collst(coln)=l
  8797. endif
  8798. colmrk(l)=procn
  8799. if(mrk(l).lt.0)then
  8800. mrk(l)=procn
  8801. cnum=cnum+1
  8802. list(cnum)=l
  8803. endif
  8804. enddo
  8805. endif
  8806. enddo
  8807. else
  8808. c
  8809. c Column is fixed to one bound
  8810. c
  8811. do i=p1,p2
  8812. row=colidx(i)
  8813. if(rowmrk(row).lt.0)then
  8814. rown=rown+1
  8815. rowlst(rown)=row
  8816. endif
  8817. rowmrk(row)=procn
  8818. enddo
  8819. addobj=addobj+obj(col)*sol
  8820. lob(col)=pivot
  8821. upb(col)=pivot
  8822. endif
  8823. c
  8824. goto 10
  8825. endif
  8826. 999 if(rrem+crem.gt.0)then
  8827. write(buff,'(1x,a,i5,a,i5,a)')
  8828. x 'CHEPDU:',crem,' columns,',rrem,' rows removed'
  8829. call mprnt(buff)
  8830. endif
  8831. return
  8832. end
  8833. c
  8834. c ===========================================================================
  8835. c ===========================================================================
  8836. c
  8837. subroutine duchek(n,m,mn,nz,
  8838. x colbeg,colend,colidx,colnzs,
  8839. x rowbeg,rowend,rowidx,rownzs,
  8840. x upb,lob,ups,los,
  8841. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  8842. x coln,collst,colmrk,rown,rowlst,rowmrk,
  8843. x cnum,clist,cmrk,rnum,rlist,rmrk,procn,
  8844. x ppbig,pmaxr,pmbig,pminr,
  8845. x p,q,pbig,mbig,maxc,minc,
  8846. x big,lbig,tfeas,tzer,bigbou,search,code,prelev)
  8847. c
  8848. c This subroutine removes singleton rows and may fixes variables
  8849. c
  8850. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  8851. x rowbeg(m),rowend(m),rowidx(nz),cnum,clist(n),cmrk(n),
  8852. x rnum,rlist(m),rmrk(m),
  8853. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  8854. x coln,rown,collst(n),rowlst(n),colmrk(n),rowmrk(m),
  8855. x ppbig(m),pmbig(m),pbig(n),mbig(n),search,code,prelev
  8856. c
  8857. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  8858. x rhs(m),obj(n),pmaxr(m),pminr(m),p(m),q(m),maxc(n),minc(n),
  8859. x addobj,big,lbig,tfeas,tzer,bigbou
  8860. c
  8861. integer*4 i,j,up,row,col,dir,pnt1,pnt2,p1,p2,crem,rrem,up3,
  8862. x lstcnt
  8863. real*8 sol,toler,up1,up2
  8864. logical traf
  8865. character*99 buff
  8866. c
  8867. c ---------------------------------------------------------------------------
  8868. c
  8869. crem=0
  8870. rrem=0
  8871. do while (rnum.ge.1)
  8872. row=rlist(1)
  8873. if (ups(row).gt.lbig)then
  8874. p(row)=0.0d+0
  8875. else
  8876. p(row)=-big
  8877. endif
  8878. if(los(row).lt.-lbig)then
  8879. q(row)=0.0d+0
  8880. else
  8881. q(row)=big
  8882. endif
  8883. rmrk(row)=-1
  8884. rlist(1)=rlist(rnum)
  8885. rnum=rnum-1
  8886. enddo
  8887. cnum=0
  8888. do i=1,n
  8889. if(upb(i).lt.lbig)then
  8890. mbig(i)=1
  8891. else
  8892. mbig(i)=0
  8893. endif
  8894. if(lob(i).gt.-lbig)then
  8895. pbig(i)=1
  8896. else
  8897. pbig(i)=0
  8898. endif
  8899. maxc(i)=0.0d+0
  8900. minc(i)=0.0d+0
  8901. if((colsta(i).gt.-2).and.(upb(i)-lob(i).gt.lbig))then
  8902. cnum=cnum+1
  8903. cmrk(i)=1
  8904. clist(cnum)=i
  8905. else
  8906. cmrk(i)=-2
  8907. endif
  8908. enddo
  8909. dir=1
  8910. do i=1,m
  8911. if(rowsta(i).gt.-2)then
  8912. call chgmxm(rowbeg(i),rowend(i),q(i),p(i),rowidx,rownzs,
  8913. x pbig,maxc,mbig,minc,lbig,dir,n)
  8914. endif
  8915. enddo
  8916. c
  8917. lstcnt=0
  8918. do while (cnum.ne.lstcnt)
  8919. lstcnt=lstcnt+1
  8920. if(lstcnt.gt.n)then
  8921. lstcnt=1
  8922. search=search-1
  8923. if(search.eq.0)goto 100
  8924. endif
  8925. col=clist(lstcnt)
  8926. cmrk(col)=-1
  8927. pnt1=colbeg(col)
  8928. pnt2=colend(col)
  8929. do i=pnt1,pnt2
  8930. row=colidx(i)
  8931. c
  8932. c Compute new upper bound: up1+(obj-up2)/nzs
  8933. c
  8934. if(colnzs(i).gt.0.0d+0)then
  8935. up2=minc(col)
  8936. up3=mbig(col)
  8937. else
  8938. up2=maxc(col)
  8939. up3=pbig(col)
  8940. endif
  8941. if(p(row).lt.-lbig)then
  8942. up1=0.0d+0
  8943. up=1
  8944. else
  8945. up1=p(row)
  8946. up=0
  8947. endif
  8948. if(up.eq.up3)then
  8949. sol=up1+(obj(col)-up2)/colnzs(i)
  8950. if(abs(sol).lt.bigbou)then
  8951. if(q(row)-sol.gt.(abs(sol)+1.0d+0)*tfeas)then
  8952. p1=rowbeg(row)
  8953. p2=rowend(row)
  8954. dir=1
  8955. call modmxm(nz,p1,p2,q(row),sol,rowidx,rownzs,
  8956. x pbig,maxc,mbig,minc,lbig,dir,n)
  8957. q(row)=sol
  8958. do j=p1,p2
  8959. if(cmrk(rowidx(j)).eq.-1)then
  8960. if(upb(rowidx(j))-lob(rowidx(j)).gt.lbig)then
  8961. cnum=cnum+1
  8962. if(cnum.gt.n)cnum=1
  8963. clist(cnum)=rowidx(j)
  8964. cmrk(rowidx(j))=1
  8965. endif
  8966. endif
  8967. enddo
  8968. endif
  8969. endif
  8970. endif
  8971. c
  8972. c Compute new lower bound: up1+(obj-up2)/nzs
  8973. c
  8974. if(colnzs(i).gt.0.0d+0)then
  8975. up2=maxc(col)
  8976. up3=pbig(col)
  8977. else
  8978. up2=minc(col)
  8979. up3=mbig(col)
  8980. endif
  8981. if(q(row).gt.lbig)then
  8982. up1=0.0d+0
  8983. up=1
  8984. else
  8985. up1=q(row)
  8986. up=0
  8987. endif
  8988. if(up.eq.up3)then
  8989. sol=up1+(obj(col)-up2)/colnzs(i)
  8990. if(abs(sol).lt.bigbou)then
  8991. if(sol-p(row).gt.(abs(sol)+1.0d+0)*tfeas)then
  8992. p1=rowbeg(row)
  8993. p2=rowend(row)
  8994. dir=-1
  8995. call modmxm(nz,p1,p2,p(row),sol,rowidx,rownzs,
  8996. x pbig,maxc,mbig,minc,lbig,dir,n)
  8997. p(row)=sol
  8998. do j=p1,p2
  8999. if(cmrk(rowidx(j)).eq.-1)then
  9000. if(upb(rowidx(j))-lob(rowidx(j)).gt.lbig)then
  9001. cnum=cnum+1
  9002. if(cnum.gt.n)cnum=1
  9003. clist(cnum)=rowidx(j)
  9004. cmrk(rowidx(j))=1
  9005. endif
  9006. endif
  9007. enddo
  9008. endif
  9009. endif
  9010. endif
  9011. enddo
  9012. enddo
  9013. c
  9014. c Dual feasibility check
  9015. c
  9016. 100 do while (cnum.ne.lstcnt)
  9017. lstcnt=lstcnt+1
  9018. if(lstcnt.gt.n)lstcnt=1
  9019. cmrk(clist(lstcnt))=-1
  9020. enddo
  9021. cnum=0
  9022. do row=1,m
  9023. if(rowsta(row).gt.-2)then
  9024. if((p(row)-q(row)).gt.(abs(p(row))+1.0d+0)*tfeas)then
  9025. code=3
  9026. cnum=-row-n
  9027. goto 999
  9028. else if (iand(prelev,512).gt.0)then
  9029. if(q(row)-p(row).lt.(abs(p(row))+1.0d+0)*tfeas)then
  9030. sol=(p(row)+q(row))/2.0d+0
  9031. prelen=prelen+1
  9032. prehis(prelen)=row
  9033. rowsta(row)=-2-procn
  9034. traf=.true.
  9035. call remove(n,m,nz,row,rowidx,rownzs,colidx,colnzs,
  9036. x rowbeg,rowend,colbeg,colend,obj,sol,traf)
  9037. addobj=addobj+rhs(row)*sol
  9038. do i=rowbeg(row),rowend(row)
  9039. col=rowidx(i)
  9040. if(colmrk(col).lt.0)then
  9041. coln=coln+1
  9042. collst(coln)=col
  9043. endif
  9044. colmrk(col)=procn
  9045. enddo
  9046. rrem=rrem+1
  9047. endif
  9048. endif
  9049. endif
  9050. enddo
  9051. c
  9052. c Checking variables
  9053. c
  9054. do 10 col=1,n
  9055. if(colsta(col).le.-2)goto 10
  9056. toler=(abs(obj(col))+1.0d+0)*tfeas
  9057. if(upb(col).lt.lbig)then
  9058. i=1
  9059. else
  9060. i=0
  9061. endif
  9062. if(lob(col).gt.-lbig)then
  9063. j=1
  9064. else
  9065. j=0
  9066. endif
  9067. if((mbig(col).eq.i).and.(obj(col)-minc(col).lt.-toler))then
  9068. sol=upb(col)
  9069. else if((pbig(col).eq.j).and.(obj(col)-maxc(col).ge.toler))then
  9070. sol=lob(col)
  9071. else
  9072. goto 10
  9073. endif
  9074. c
  9075. c Variable is set to a bound
  9076. c
  9077. if(abs(sol).gt.lbig)then
  9078. if(abs(obj(col)).gt.tzer)then
  9079. cnum=-col
  9080. code=3
  9081. goto 999
  9082. endif
  9083. endif
  9084. prelen=prelen+1
  9085. prehis(prelen)=col
  9086. colsta(col)=-2-procn
  9087. traf=.true.
  9088. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  9089. x colbeg,colend,rowbeg,rowend,rhs,sol,traf)
  9090. crem=crem+1
  9091. addobj=addobj+obj(col)*sol
  9092. do i=colbeg(col),colend(col)
  9093. j=colidx(i)
  9094. if(rowmrk(j).lt.0)then
  9095. rown=rown+1
  9096. rowlst(rown)=j
  9097. endif
  9098. rowmrk(j)=procn
  9099. enddo
  9100. dir=-1
  9101. call chgmxm(colbeg(col),colend(col),upb(col),lob(col),colidx,
  9102. x colnzs,ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  9103. upb(col)=sol
  9104. lob(col)=sol
  9105. 10 continue
  9106. c
  9107. 999 if(rrem+crem.gt.0)then
  9108. write(buff,'(1x,a,i5,a,i5,a)')
  9109. x 'DUCHEK:',crem,' columns,',rrem,' rows removed'
  9110. call mprnt(buff)
  9111. endif
  9112. return
  9113. end
  9114. c
  9115. c ===========================================================================
  9116. c ===========================================================================
  9117. c
  9118. subroutine bndchk(n,m,mn,nz,
  9119. x colbeg,colend,colidx,colnzs,
  9120. x rowbeg,rowend,rowidx,rownzs,
  9121. x upb,lob,ups,los,
  9122. x rhs,obj,addobj,colsta,rowsta,prelen,prehis,
  9123. x cnum,list,mrk,procn,oldlob,oldupb,
  9124. x ppbig,pmaxr,pmbig,pminr,chglob,chgupb,
  9125. x big,lbig,tfeas,search,chgmax,bigbou,code)
  9126. c
  9127. c This subroutine checks bounds on variables
  9128. c NOTE : this subroutine destroys min and max row activity counters !
  9129. c
  9130. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  9131. x rowbeg(m),rowend(m),rowidx(nz),cnum,list(n),mrk(n),
  9132. x colsta(n),rowsta(m),prehis(mn),procn,prelen,
  9133. x ppbig(m),pmbig(m),chglob(n),chgupb(n),search,chgmax,code
  9134. c
  9135. real*8 colnzs(nz),rownzs(nz),upb(n),lob(n),ups(m),los(m),
  9136. x rhs(m),obj(n),pmaxr(m),pminr(m),addobj,big,lbig,bigbou,
  9137. x tfeas,oldlob(n),oldupb(n)
  9138. c
  9139. integer*4 i,j,up,row,col,dir,pnt1,pnt2,p1,p2,crem,rrem,up3,lstcnt
  9140. real*8 sol,toler,up1,up2
  9141. logical traf
  9142. character*99 buff
  9143. c
  9144. c ---------------------------------------------------------------------------
  9145. c
  9146. crem=0
  9147. rrem=0
  9148. cnum=0
  9149. do i=1,n
  9150. chglob(i)=0
  9151. chgupb(i)=0
  9152. oldupb(i)=upb(i)
  9153. oldlob(i)=lob(i)
  9154. enddo
  9155. do i=1,m
  9156. if(ups(i).gt.lbig)then
  9157. pmbig(i)=pmbig(i)+1
  9158. else
  9159. pminr(i)=pminr(i)-ups(i)
  9160. endif
  9161. if(los(i).lt.-lbig)then
  9162. ppbig(i)=ppbig(i)+1
  9163. else
  9164. pmaxr(i)=pmaxr(i)-los(i)
  9165. endif
  9166. if(rowsta(i).gt.-2)then
  9167. cnum=cnum+1
  9168. mrk(i)=1
  9169. list(cnum)=i
  9170. else
  9171. mrk(i)=-2
  9172. endif
  9173. enddo
  9174. c
  9175. lstcnt=0
  9176. do while (cnum.ne.lstcnt)
  9177. lstcnt=lstcnt+1
  9178. if(lstcnt.gt.m)then
  9179. lstcnt=1
  9180. search=search-1
  9181. if(search.eq.0)goto 100
  9182. endif
  9183. row=list(lstcnt)
  9184. mrk(row)=-1
  9185. pnt1=rowbeg(row)
  9186. pnt2=rowend(row)
  9187. c
  9188. do i=pnt1,pnt2
  9189. col=rowidx(i)
  9190. c
  9191. c Compute new upper bound: lo1+(rhs-up2)/nzs
  9192. c
  9193. if(rownzs(i).gt.0.0d+0)then
  9194. up2=pminr(row)
  9195. up3=pmbig(row)
  9196. else
  9197. up2=pmaxr(row)
  9198. up3=ppbig(row)
  9199. endif
  9200. if(lob(col).lt.-lbig)then
  9201. up1=0.0d+0
  9202. up=1
  9203. else
  9204. up1=lob(col)
  9205. up=0
  9206. endif
  9207. if(up.eq.up3)then
  9208. sol=up1+(rhs(row)-up2)/rownzs(i)
  9209. toler=(abs(sol)+1.0d+0)*tfeas
  9210. if(abs(sol).lt.bigbou)then
  9211. if(upb(col)-sol.gt.toler)then
  9212. chgupb(col)=chgupb(col)+1
  9213. p1=colbeg(col)
  9214. p2=colend(col)
  9215. dir=1
  9216. if(lob(col)-sol.gt.toler)then
  9217. cnum=-col
  9218. code=4
  9219. goto 999
  9220. endif
  9221. if(sol-lob(col).lt.toler)then
  9222. sol=lob(col)
  9223. endif
  9224. call modmxm(nz,p1,p2,upb(col),sol,colidx,colnzs,
  9225. x ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  9226. upb(col)=sol
  9227. if(chgupb(col).lt.chgmax)then
  9228. do j=p1,p2
  9229. if(mrk(colidx(j)).eq.-1)then
  9230. cnum=cnum+1
  9231. if(cnum.gt.m)cnum=1
  9232. list(cnum)=colidx(j)
  9233. mrk(colidx(j))=1
  9234. endif
  9235. enddo
  9236. endif
  9237. endif
  9238. endif
  9239. endif
  9240. c
  9241. c Compute new lower bound: up1+(rhs-up2)/nzs
  9242. c
  9243. if(rownzs(i).gt.0.0d+0)then
  9244. up2=pmaxr(row)
  9245. up3=ppbig(row)
  9246. else
  9247. up2=pminr(row)
  9248. up3=pmbig(row)
  9249. endif
  9250. if(upb(col).gt.lbig)then
  9251. up1=0.0d+0
  9252. up=1
  9253. else
  9254. up1=upb(col)
  9255. up=0
  9256. endif
  9257. if(up.eq.up3)then
  9258. sol=up1+(rhs(row)-up2)/rownzs(i)
  9259. toler=(abs(sol)+1.0d+0)*tfeas
  9260. if(abs(sol).lt.bigbou)then
  9261. if(sol-lob(col).gt.(abs(sol)+1.0d+0)*tfeas)then
  9262. chglob(col)=chglob(col)+1
  9263. p1=colbeg(col)
  9264. p2=colend(col)
  9265. dir=-1
  9266. if((sol-upb(col)).gt.toler)then
  9267. cnum=-col
  9268. code=4
  9269. goto 999
  9270. endif
  9271. if(upb(col)-sol.lt.toler)then
  9272. sol=upb(col)
  9273. endif
  9274. call modmxm(nz,p1,p2,lob(col),sol,colidx,colnzs,
  9275. x ppbig,pmaxr,pmbig,pminr,lbig,dir,m)
  9276. lob(col)=sol
  9277. if(chglob(col).lt.chgmax)then
  9278. do j=p1,p2
  9279. if(mrk(colidx(j)).eq.-1)then
  9280. cnum=cnum+1
  9281. if(cnum.gt.m)cnum=1
  9282. list(cnum)=colidx(j)
  9283. mrk(colidx(j))=1
  9284. endif
  9285. enddo
  9286. endif
  9287. endif
  9288. endif
  9289. endif
  9290. enddo
  9291. enddo
  9292. c
  9293. c Checking row feasibility
  9294. c
  9295. 100 cnum=0
  9296. do row=1,m
  9297. if(rowsta(row).gt.-2)then
  9298. sol=(abs(rhs(row))+1.0d+0)*tfeas
  9299. if((ppbig(row).eq.0).and.(pmaxr(row)-rhs(row).lt.-sol))then
  9300. code=3
  9301. cnum=-row-n
  9302. goto 999
  9303. endif
  9304. if((pmbig(row).eq.0).and.(rhs(row)-pminr(row).lt.-sol))then
  9305. code=3
  9306. cnum=-row-n
  9307. goto 999
  9308. endif
  9309. endif
  9310. enddo
  9311. c
  9312. c Bound check and modification
  9313. c
  9314. do col=1,n
  9315. if(colsta(col).gt.-2)then
  9316. if((lob(col)-upb(col)).gt.(abs(lob(col))+1.0d+0)*tfeas)then
  9317. code=4
  9318. cnum=-col
  9319. goto 999
  9320. else if(upb(col)-lob(col).lt.abs(lob(col)+1.0d+0)*tfeas)then
  9321. sol=(upb(col)+lob(col))/2.0d+0
  9322. prelen=prelen+1
  9323. prehis(prelen)=col
  9324. colsta(col)=-2-procn
  9325. traf=.true.
  9326. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  9327. x colbeg,colend,rowbeg,rowend,rhs,sol,traf)
  9328. crem=crem+1
  9329. addobj=addobj+obj(col)*sol
  9330. upb(col)=sol
  9331. lob(col)=sol
  9332. else
  9333. if(chglob(col).gt.0)then
  9334. if(oldlob(col).gt.-lbig)rrem=rrem+1
  9335. lob(col)=-big
  9336. endif
  9337. if(chgupb(col).gt.0)then
  9338. if(oldupb(col).lt.lbig)rrem=rrem+1
  9339. upb(col)=big
  9340. endif
  9341. endif
  9342. endif
  9343. enddo
  9344. c
  9345. 999 if(rrem+crem.gt.0)then
  9346. write(buff,'(1x,a,i5,a,i5,a)')
  9347. x 'BNDCHK:',crem,' columns,',rrem,' bounds removed'
  9348. call mprnt(buff)
  9349. endif
  9350. return
  9351. end
  9352. c
  9353. c ===========================================================================
  9354. c ============================================================================
  9355. c
  9356. subroutine coldbl(n,m,mn,nz,
  9357. x colbeg,colend,colidx,colnzs,
  9358. x rowbeg,rowend,rowidx,rownzs,
  9359. x upb,lob,obj,colsta,
  9360. x prelen,prehis,procn,mark,valc,vartyp,
  9361. x big,lbig,tfeas,tzer)
  9362. c
  9363. integer*4 n,m,mn,nz,colbeg(n),colend(n),colidx(nz),
  9364. x rowbeg(m),rowend(m),rowidx(nz),colsta(n),
  9365. x prelen,prehis(mn),procn,mark(m),vartyp(n)
  9366. real*8 obj(n),lob(n),upb(n),colnzs(nz),rownzs(nz),valc(m),
  9367. x big,lbig,tfeas,tzer
  9368. c
  9369. integer*4 i,j,k,l,col,row,pcol,pnt1,pnt2,ppnt1,ppnt2,pntt1,pntt2,
  9370. x crem,rrem,collen
  9371. real*8 sd,toler,obj1,obj2,lo1,lo2,up1,up2,sol
  9372. logical traf
  9373. character*99 buff
  9374. c
  9375. c ============================================================================
  9376. c
  9377. crem=0
  9378. rrem=0
  9379. do i=1,m
  9380. mark(i)=0
  9381. enddo
  9382. c
  9383. c Start search
  9384. c
  9385. do 25 col=1,n
  9386. if((colsta(col).gt.-2).and.(colend(col).ge.colbeg(col)))then
  9387. pnt1=colbeg(col)
  9388. pnt2=colend(col)
  9389. collen=pnt2-pnt1
  9390. do i=pnt1,pnt2
  9391. mark(colidx(i))=col
  9392. valc(colidx(i))=colnzs(i)
  9393. enddo
  9394. c
  9395. c Select row
  9396. c
  9397. row=0
  9398. l=n+1
  9399. do j=pnt1,pnt2
  9400. k=colidx(j)
  9401. if(rowend(k)-rowbeg(k).lt.l)then
  9402. l=rowend(k)-rowbeg(k)
  9403. row=k
  9404. endif
  9405. enddo
  9406. c
  9407. c Start search in the row
  9408. c
  9409. if(row.ne.0)then
  9410. pntt1=rowbeg(row)
  9411. pntt2=rowend(row)
  9412. do 15 l=pntt1,pntt2
  9413. pcol=rowidx(l)
  9414. ppnt1=colbeg(pcol)
  9415. ppnt2=colend(pcol)
  9416. if((pcol.le.col).or.(collen.ne.ppnt2-ppnt1))goto 15
  9417. do i=ppnt1,ppnt2
  9418. if(mark(colidx(i)).ne.col)goto 15
  9419. enddo
  9420. c
  9421. c Nonzero structure is O.K.
  9422. c
  9423. sd=valc(colidx(ppnt1))/colnzs(ppnt1)
  9424. toler=(abs(sd)+1.0d+0)*tzer
  9425. do i=ppnt1,ppnt2
  9426. if(abs(valc(colidx(i))/colnzs(i)-sd).gt.toler)goto 15
  9427. enddo
  9428. c
  9429. c Nonzeros are dependent, factor : sd, columns: col,pcol
  9430. c
  9431. obj1=obj(col)
  9432. obj2=obj(pcol)*sd
  9433. c
  9434. c Identical columns found
  9435. c
  9436. if(abs(obj1-obj2).le.(abs(obj1)+1.0d+0)*tfeas)then
  9437. lo1=lob(pcol)
  9438. up1=upb(pcol)
  9439. if(lob(col).lt.-lbig)then
  9440. if(sd.gt.0.0d+0)then
  9441. lo2=lob(col)
  9442. else
  9443. lo2=-lob(col)
  9444. endif
  9445. else
  9446. lo2=lob(col)/sd
  9447. endif
  9448. if(upb(col).gt.lbig)then
  9449. if(sd.gt.0.0d+0)then
  9450. up2=upb(col)
  9451. else
  9452. up2=-upb(col)
  9453. endif
  9454. else
  9455. up2=upb(col)/sd
  9456. endif
  9457. if(sd.lt.0.0d+0)then
  9458. sol=up2
  9459. up2=lo2
  9460. lo2=sol
  9461. endif
  9462. c
  9463. c Store factor and old bound info
  9464. c
  9465. obj(col)=sd
  9466. vartyp(col)=0
  9467. if(lo2.lt.-lbig)then
  9468. vartyp(col)=4
  9469. lob(col)=lo1
  9470. else
  9471. lob(col)=lo2
  9472. endif
  9473. if(up2.gt.lbig)then
  9474. vartyp(col)=vartyp(col)+8
  9475. upb(col)=up1
  9476. else
  9477. upb(col)=up2
  9478. endif
  9479. if((lo1.gt.-lbig).and.(lo2.gt.-lbig))then
  9480. lob(pcol)=lo1+lo2
  9481. else
  9482. lob(pcol)=-big
  9483. endif
  9484. if((up1.lt.lbig).and.(up2.lt.lbig))then
  9485. upb(pcol)=up1+up2
  9486. else
  9487. upb(pcol)=big
  9488. endif
  9489. prelen=prelen+1
  9490. prehis(prelen)=col
  9491. colsta(col)=-2-procn-pcol-10
  9492. traf=.false.
  9493. call remove(m,n,nz,col,colidx,colnzs,rowidx,rownzs,
  9494. x colbeg,colend,rowbeg,rowend,obj,sol,traf)
  9495. crem=crem+1
  9496. goto 25
  9497. endif
  9498. 15 continue
  9499. endif
  9500. endif
  9501. 25 continue
  9502. if(rrem+crem.gt.0)then
  9503. write(buff,'(1x,a,i5,a,i5,a)')
  9504. x 'COLDBL:',crem,' columns,',rrem,' rows removed'
  9505. call mprnt(buff)
  9506. endif
  9507. return
  9508. end
  9509. c ============================================================================
  9510. c ========================================================================
  9511. c
  9512. subroutine aggreg(colpnt,colidx,colnzs,rowidx,
  9513. x colsta,rowsta,colbeg,colend,rowbeg,rowend,
  9514. x rhs,obj,prehis,prelen,mrk,vartyp,slktyp,iwrk1,iwrk2,
  9515. x iwrk3,pivcol,pivrow,rwork,addobj,prelev,code)
  9516. c
  9517. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  9518. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  9519. c
  9520. common/numer/ tplus,tzer
  9521. real*8 tplus,tzer
  9522. c
  9523. integer*4 colpnt(n1),colidx(cfree),rowidx(rfree),
  9524. x colbeg(n),colend(n),rowbeg(m),rowend(m),slktyp(m),
  9525. x colsta(n),rowsta(m),prehis(mn),prelen,prelev,code,mrk(mn),
  9526. x iwrk1(mn),iwrk2(mn),iwrk3(mn),pivcol(n),pivrow(m),vartyp(n)
  9527. real*8 colnzs(cfree),addobj,rhs(m),obj(n),
  9528. x rwork(m)
  9529. c
  9530. real*8 reltol,abstol,redtol,filtol
  9531. integer*4 i,j,k,pnt1,pnt2,nfill,pnt,pnto,procn,fpnt
  9532. character*99 buff
  9533. c
  9534. reltol=1.0d-3
  9535. abstol=1.0d-5
  9536. redtol=1.0d-4
  9537. filtol=4.0d+0
  9538. c
  9539. if(iand(prelev,128).gt.0)then
  9540. procn=8
  9541. pnto=colpnt(1)
  9542. pnt=nz+1
  9543. do i=1,n
  9544. if(colsta(i).gt.-2)then
  9545. pnt1=colbeg(i)
  9546. pnt2=colend(i)
  9547. colbeg(i)=pnt
  9548. do j=pnt1,pnt2
  9549. colidx(pnt)=colidx(j)
  9550. colnzs(pnt)=colnzs(j)
  9551. pnt=pnt+1
  9552. enddo
  9553. colend(i)=pnt-1
  9554. pnt1=pnt2+1
  9555. else
  9556. pnt1=colpnt(i)
  9557. endif
  9558. pnt2=colpnt(i+1)-1
  9559. colpnt(i)=pnto
  9560. do j=pnt1,pnt2
  9561. colidx(pnto)=colidx(j)
  9562. colnzs(pnto)=colnzs(j)
  9563. pnto=pnto+1
  9564. enddo
  9565. enddo
  9566. colpnt(n+1)=pnto
  9567. call elimin(m,n,nz,cfree,rfree,
  9568. x colbeg,colend,rowbeg,rowend,colidx,rowidx,colnzs,colsta,rowsta,
  9569. x obj,rhs,vartyp,slktyp,
  9570. x iwrk1,iwrk2,iwrk1(n+1),iwrk2(n+1),mrk,mrk(n+1),
  9571. x iwrk3,iwrk3(n+1),rwork,pivcol,pivrow,abstol,reltol,filtol,
  9572. x pivotn,nfill,addobj,fpnt,code)
  9573. if(code.ne.0)goto 999
  9574. c
  9575. c Compute new column lengths
  9576. c
  9577. do i=1,n
  9578. iwrk1(i)=colpnt(i+1)-colpnt(i)
  9579. if(colsta(i).gt.-2)iwrk1(i)=iwrk1(i)+colend(i)-colbeg(i)+1
  9580. enddo
  9581. do j=1,pivotn
  9582. i=pivrow(j)
  9583. pnt1=rowbeg(i)
  9584. pnt2=rowend(i)
  9585. do k=pnt1,pnt2
  9586. iwrk1(colidx(k))=iwrk1(colidx(k))+1
  9587. enddo
  9588. enddo
  9589. c
  9590. c Generate new pointers for columns
  9591. c
  9592. pnt=1
  9593. do i=1,n
  9594. iwrk2(i)=pnt
  9595. pnt=pnt+iwrk1(i)
  9596. enddo
  9597. if(pnt.gt.fpnt)then
  9598. code=-2
  9599. write(buff,'(1x,a)')'Ran out of RERAL memory'
  9600. call mprnt(buff)
  9601. goto 999
  9602. endif
  9603. c
  9604. c Assemble the transformed matrix
  9605. c
  9606. do i=n,1,-1
  9607. pnt1=colpnt(i)
  9608. pnt2=colpnt(i+1)-1
  9609. pnt=iwrk2(i)+iwrk1(i)-1
  9610. do j=pnt2,pnt1,-1
  9611. colidx(pnt)=colidx(j)
  9612. colnzs(pnt)=colnzs(j)
  9613. pnt=pnt-1
  9614. enddo
  9615. if(colsta(i).gt.-2)then
  9616. fpnt=iwrk2(i)
  9617. pnt1=colbeg(i)
  9618. pnt2=colend(i)
  9619. do j=pnt1,pnt2
  9620. colidx(fpnt)=colidx(j)
  9621. colnzs(fpnt)=colnzs(j)
  9622. fpnt=fpnt+1
  9623. enddo
  9624. iwrk3(i)=fpnt
  9625. endif
  9626. enddo
  9627. colpnt(1)=1
  9628. do i=1,n
  9629. colbeg(i)=iwrk2(i)
  9630. colend(i)=iwrk3(i)-1
  9631. colpnt(i+1)=colpnt(i)+iwrk1(i)
  9632. enddo
  9633. do j=1,pivotn
  9634. i=pivrow(j)
  9635. pnt1=rowbeg(i)
  9636. pnt2=rowend(i)
  9637. do k=pnt1,pnt2
  9638. pnt=iwrk3(colidx(k))
  9639. colidx(pnt)=i
  9640. colnzs(pnt)=colnzs(k)
  9641. iwrk3(colidx(k))=pnt+1
  9642. enddo
  9643. enddo
  9644. c
  9645. do i=1,pivotn
  9646. prelen=prelen+1
  9647. prehis(prelen)=pivcol(i)
  9648. colsta(pivcol(i))=-2-procn
  9649. prelen=prelen+1
  9650. prehis(prelen)=pivrow(i)+n
  9651. rowsta(pivrow(i))=-2-procn
  9652. enddo
  9653. write(buff,'(1x,i5,a,i5,a)')pivotn,' row/cols eliminated, ',
  9654. x nfill,' fill-in created.'
  9655. call mprnt(buff)
  9656. nz=colpnt(n+1)-1
  9657. if(cfree.lt.nz*2)then
  9658. code=-2
  9659. write(buff,'(1x,a)')'Ran out of RERAL memory'
  9660. call mprnt(buff)
  9661. endif
  9662. endif
  9663. c
  9664. if(iand(prelev,256).gt.0)then
  9665. do i=1,m
  9666. rowend(i)=rowbeg(i)-1
  9667. enddo
  9668. do i=1,n
  9669. if(colsta(i).gt.-2)then
  9670. pnt1=colbeg(i)
  9671. pnt2=colend(i)
  9672. do j=pnt1,pnt2
  9673. rowend(colidx(j))=rowend(colidx(j))+1
  9674. rowidx(rowend(colidx(j)))=i
  9675. colnzs(nz+rowend(colidx(j)))=colnzs(j)
  9676. enddo
  9677. endif
  9678. enddo
  9679. call sparser(n,n1,m,nz,colpnt,colbeg,colend,colidx,colnzs,
  9680. x rowbeg,rowend,rowidx,colnzs(nz+1),colsta,rowsta,rhs,slktyp,
  9681. x mrk,mrk(n+1),tplus,tzer,redtol,reltol,abstol)
  9682. endif
  9683. c
  9684. 999 return
  9685. end
  9686. c
  9687. c ============================================================================
  9688. c
  9689. c Numerically more stable version
  9690. c
  9691. c ===========================================================================
  9692. c
  9693. subroutine sparser(n,n1,m,nz,colpnt,
  9694. x colbeg,colend,colidx,colnzs,
  9695. x rowbeg,rowend,rowidx,rownzs,
  9696. x colsta,rowsta,rhs,slktyp,
  9697. x mark,rflag,tplus,tzer,redtol,reltol,abstol)
  9698. c
  9699. integer*4 n,n1,m,nz,colpnt(n1),colbeg(n),colend(n),colidx(nz),
  9700. x rowbeg(m),rowend(m),rowidx(nz),colsta(n),rowsta(m),
  9701. x rflag(m),mark(n),slktyp(m)
  9702. real*8 colnzs(nz),rownzs(nz),rhs(m),
  9703. x tplus,tzer,redtol,reltol,abstol
  9704. c
  9705. integer*4 i,j,k,pnt1,pnt2,rpnt1,rpnt2,row,col,prow,pcol,
  9706. x pnt,ppnt1,ppnt2,elim,total,totaln,iw,rowlen
  9707. real*8 pivot,nval,tol
  9708. character*99 buff
  9709. c
  9710. c ---------------------------------------------------------------------------
  9711. c
  9712. total=0
  9713. totaln=0
  9714. tol=1.0d+0/reltol
  9715. do i=1,m
  9716. if(rowsta(i).gt.-2)then
  9717. rflag(i)=0
  9718. totaln=totaln+rowend(i)-rowbeg(i)+1
  9719. else
  9720. rflag(i)=2
  9721. endif
  9722. enddo
  9723. do i=1,n
  9724. mark(i)=0
  9725. enddo
  9726. c
  9727. 100 elim=0
  9728. do 20 row=1,m
  9729. if((rflag(row).lt.2).and.(slktyp(row).eq.0))then
  9730. iw=rflag(row)
  9731. pnt1=rowbeg(row)
  9732. pnt2=rowend(row)
  9733. rowlen=pnt2-pnt1
  9734. c
  9735. c Select the shortest column
  9736. c
  9737. col=0
  9738. k=m+1
  9739. do j=pnt1,pnt2
  9740. i=rowidx(j)
  9741. mark(i)=j
  9742. if(colend(i)-colbeg(i).lt.k)then
  9743. col=i
  9744. k=colend(i)-colbeg(i)
  9745. endif
  9746. enddo
  9747. if(col.eq.0)then
  9748. rflag(row)=1
  9749. goto 20
  9750. endif
  9751. c
  9752. c Scan the selected column
  9753. c
  9754. ppnt1=colbeg(col)
  9755. ppnt2=colend(col)
  9756. do 30 i=ppnt1,ppnt2
  9757. prow=colidx(i)
  9758. rpnt1=rowbeg(prow)
  9759. rpnt2=rowend(prow)
  9760. if((rowlen.gt.rpnt2-rpnt1).or.(iw+rflag(prow).ge.2).or.
  9761. x (row.eq.prow))goto 30
  9762. k=-1
  9763. do pnt=rpnt1,rpnt2
  9764. if(mark(rowidx(pnt)).gt.0)k=k+1
  9765. enddo
  9766. if(k.ne.rowlen)goto 30
  9767. c
  9768. c Select pivot
  9769. c
  9770. pcol=0
  9771. pivot=tol
  9772. do pnt=rpnt1,rpnt2
  9773. if(mark(rowidx(pnt)).gt.0)then
  9774. if(abs(rownzs(mark(rowidx(pnt)))).gt.abstol)then
  9775. nval=-rownzs(pnt)/rownzs(mark(rowidx(pnt)))
  9776. if(abs(nval).lt.abs(pivot))then
  9777. pivot=nval
  9778. pcol=rowidx(pnt)
  9779. endif
  9780. endif
  9781. endif
  9782. enddo
  9783. if(pcol.eq.0)goto 20
  9784. c
  9785. c Transformation
  9786. c
  9787. rflag(prow)=0
  9788. rhs(prow)=rhs(prow)+pivot*rhs(row)
  9789. do pnt=rpnt1,rpnt2
  9790. if(mark(rowidx(pnt)).gt.0)then
  9791. nval=rownzs(pnt)+pivot*rownzs(mark(rowidx(pnt)))
  9792. if(abs(nval).lt.tplus*(abs(rownzs(pnt))))nval=0.0d+0
  9793. rownzs(pnt)=nval
  9794. endif
  9795. enddo
  9796. do while (rpnt1.le.rpnt2)
  9797. if(abs(rownzs(rpnt1)).lt.tzer)then
  9798. k=rowidx(rpnt1)
  9799. rownzs(rpnt1)=rownzs(rpnt2)
  9800. rowidx(rpnt1)=rowidx(rpnt2)
  9801. rownzs(rpnt2)=0.0d+0
  9802. rowidx(rpnt2)=k
  9803. rpnt2=rpnt2-1
  9804. elim=elim+1
  9805. else
  9806. rpnt1=rpnt1+1
  9807. endif
  9808. enddo
  9809. rowend(prow)=rpnt2
  9810. 30 continue
  9811. do j=pnt1,pnt2
  9812. mark(rowidx(j))=0
  9813. enddo
  9814. rflag(row)=1
  9815. endif
  9816. 20 continue
  9817. total=total+elim
  9818. totaln=totaln-elim
  9819. if(dble(elim)/(dble(totaln)+1.0d+0).gt.redtol)goto 100
  9820. c
  9821. c making modification in the column file
  9822. c
  9823. if(total.gt.0)then
  9824. do i=1,n
  9825. mark(i)=colbeg(i)-1
  9826. enddo
  9827. do i=1,m
  9828. if(rowsta(i).gt.-2)then
  9829. pnt1=rowbeg(i)
  9830. pnt2=rowend(i)
  9831. do j=pnt1,pnt2
  9832. col=rowidx(j)
  9833. mark(col)=mark(col)+1
  9834. colidx(mark(col))=i
  9835. colnzs(mark(col))=rownzs(j)
  9836. enddo
  9837. endif
  9838. enddo
  9839. pnt=colpnt(1)
  9840. do i=1,n
  9841. iw=pnt
  9842. if(colsta(i).gt.-2)then
  9843. pnt1=colbeg(i)
  9844. pnt2=mark(i)
  9845. colbeg(i)=pnt
  9846. do j=pnt1,pnt2
  9847. colnzs(pnt)=colnzs(j)
  9848. colidx(pnt)=colidx(j)
  9849. pnt=pnt+1
  9850. enddo
  9851. pnt1=colend(i)+1
  9852. colend(i)=pnt-1
  9853. else
  9854. pnt1=colpnt(i)
  9855. endif
  9856. pnt2=colpnt(i+1)-1
  9857. do j=pnt1,pnt2
  9858. colnzs(pnt)=colnzs(j)
  9859. colidx(pnt)=colidx(j)
  9860. pnt=pnt+1
  9861. enddo
  9862. colpnt(i)=iw
  9863. enddo
  9864. colpnt(n+1)=pnt
  9865. endif
  9866. c
  9867. write(buff,'(1x,i5,a)')total,' nonzeros eliminated'
  9868. call mprnt(buff)
  9869. return
  9870. end
  9871. c
  9872. c ===========================================================================
  9873. c ===========================================================================
  9874. c
  9875. subroutine elimin(m,n,nz,cfre,rfre,
  9876. x colbeg,ccol,rowbeg,crow,colidx,rowidx,colnzs,colsta,rowsta,
  9877. x obj,rhs,vartyp,slktyp,cpermf,cpermb,rpermf,rpermb,colcan,
  9878. x mark,cfill,rfill,workr,pivcol,pivrow,abstol,reltol,filtol,
  9879. x pivotn,nfill,addobj,pnt,code)
  9880. c
  9881. integer*4 m,n,nz,cfre,rfre,colbeg(n),ccol(n),rowbeg(m),
  9882. x crow(m),colidx(cfre),rowidx(rfre),colsta(n),rowsta(m),
  9883. x cpermf(n),cpermb(n),rpermf(m),rpermb(m),colcan(n),mark(m),
  9884. x cfill(n),rfill(m),pivcol(n),pivrow(m),pivotn,code,vartyp(n),
  9885. x slktyp(m),nfill,pnt
  9886. real*8 workr(m),obj(n),rhs(m),colnzs(cfre),abstol,reltol,
  9887. x filtol,addobj
  9888. c
  9889. integer*4 i,j,k,l,p,pnt1,pnt2,ppnt1,ppnt2,pcol,prow,
  9890. x fren,cfirst,rfirst,clast,rlast,endmem,prewcol,mn,fill,
  9891. x ccfre,rcfre,rpnt1,rpnt2,ii
  9892. real*8 pivot,s
  9893. c
  9894. c ---------------------------------------------------------------------------
  9895. c
  9896. c cpermf oszloplista elore lancolasa, fejmutato cfirst
  9897. c cpermb oszloplista hatra lancolasa, fejmutato clast
  9898. c rpermf sorlista elore lancolase, fejmutato rfirst
  9899. c rpermb sorlista hatra lancolasa, fejmutato rlast
  9900. c colcan lehetseges pivot oszlopok
  9901. c ccol oszlopszamlalok
  9902. c crow sorszamlalok (vcstat)
  9903. c colbeg oszlopmutatok
  9904. c rowbeg sormutatok
  9905. c mark eliminacios integer segedtomb
  9906. c workr eliminacios real segedtomb
  9907. c cfill a sorfolytonos tarolas update-elesehez segedtomb
  9908. c rfill a sorfolytonos tarolas update-elesehez segedtomb
  9909. c pivcol
  9910. c pivrow
  9911. c
  9912. c --------------------------------------------------------------------------
  9913. pivot=0
  9914. ppnt1=0
  9915. c
  9916. c initialization
  9917. c
  9918. nfill=0
  9919. mn=m+n
  9920. endmem=cfre
  9921. fren =0
  9922. pivotn=0
  9923. cfirst=0
  9924. clast =0
  9925. rfirst=0
  9926. rlast =0
  9927. do i=1,n
  9928. if(colsta(i).gt.-2)then
  9929. if(cfirst.eq.0)then
  9930. cfirst=i
  9931. else
  9932. cpermf(clast)=i
  9933. endif
  9934. cpermb(i)=clast
  9935. clast=i
  9936. ccol(i)=ccol(i)-colbeg(i)+1
  9937. if(vartyp(i).eq.0)then
  9938. fren=fren+1
  9939. colcan(fren)=i
  9940. endif
  9941. endif
  9942. enddo
  9943. C CMSSW: Bugfix for an empty matrix, where now clast=0 causes an invalid
  9944. C memory access
  9945. if(clast.ne.0)then
  9946. cpermf(clast)=0
  9947. endif
  9948. do i=1,m
  9949. mark(i)=0
  9950. if(rowsta(i).gt.-2)then
  9951. if(rfirst.eq.0)then
  9952. rfirst=i
  9953. else
  9954. rpermf(rlast)=i
  9955. endif
  9956. rpermb(i)=rlast
  9957. rlast=i
  9958. crow(i)=crow(i)-rowbeg(i)+1
  9959. endif
  9960. enddo
  9961. rpermf(rlast)=0
  9962. c
  9963. c Elimination loop
  9964. c
  9965. 50 pcol=0
  9966. prow=0
  9967. i=-1
  9968. c
  9969. c Find pivot
  9970. c
  9971. do ii=1,fren
  9972. p=colcan(ii)
  9973. pnt1=colbeg(p)
  9974. pnt2=pnt1+ccol(p)-1
  9975. s=0.0d+0
  9976. do j=pnt1,pnt2
  9977. if(s.lt.abs(colnzs(j)))s=abs(colnzs(j))
  9978. enddo
  9979. s=s*reltol
  9980. do j=pnt1,pnt2
  9981. if(slktyp(colidx(j)).eq.0)then
  9982. if(abs(colnzs(j)).gt.abstol)then
  9983. k=(ccol(p)-1)*(crow(colidx(j))-1)
  9984. if(dble(k).lt.filtol*dble(ccol(p)+crow(colidx(j))-1))then
  9985. if((i.lt.0).or.(k.lt.i))then
  9986. if(abs(colnzs(j)).gt.s)then
  9987. i=k
  9988. pcol=p
  9989. prow=colidx(j)
  9990. pivot=colnzs(j)
  9991. ppnt1=ii
  9992. endif
  9993. else if((k.eq.i).and.(abs(pivot).lt.abs(colnzs(j))))then
  9994. pcol=p
  9995. prow=colidx(j)
  9996. pivot=colnzs(j)
  9997. ppnt1=ii
  9998. endif
  9999. endif
  10000. endif
  10001. endif
  10002. enddo
  10003. enddo
  10004. if (pcol.eq.0)goto 900
  10005. colcan(ppnt1)=colcan(fren)
  10006. fren=fren-1
  10007. pivot=1.0d+0/pivot
  10008. rcfre=rfre-rowbeg(rlast)-crow(rlast)
  10009. ccfre=endmem-colbeg(clast)-ccol(clast)
  10010. c
  10011. c compress column file
  10012. c
  10013. if(ccfre.lt.mn)then
  10014. call ccomprs(mn,cfre,ccfre,endmem,nz,
  10015. x colbeg,ccol,cfirst,cpermf,colidx,colnzs,code)
  10016. if(code.lt.0)goto 999
  10017. endif
  10018. c
  10019. c remove pcol from the cpermf lists
  10020. c
  10021. j=cpermb(pcol)
  10022. i=cpermf(pcol)
  10023. if(j.ne.0)then
  10024. cpermf(j)=i
  10025. else
  10026. cfirst=i
  10027. endif
  10028. if(i.eq.0)then
  10029. clast=j
  10030. else
  10031. cpermb(i)=j
  10032. endif
  10033. c
  10034. c remove prow from the rpermf lists
  10035. c
  10036. j=rpermb(prow)
  10037. i=rpermf(prow)
  10038. if(j.ne.0)then
  10039. rpermf(j)=i
  10040. else
  10041. rfirst=i
  10042. endif
  10043. if(i.eq.0)then
  10044. rlast=j
  10045. else
  10046. rpermb(i)=j
  10047. endif
  10048. c
  10049. c administration
  10050. c
  10051. pivotn=pivotn+1
  10052. pivcol(pivotn)=pcol
  10053. pivrow(pivotn)=prow
  10054. addobj=addobj+obj(pcol)*rhs(prow)*pivot
  10055. c
  10056. c Create pivot column
  10057. c
  10058. pnt1=colbeg(pcol)
  10059. pnt2=pnt1+ccol(pcol)-1
  10060. ppnt1=endmem-ccol(pcol)
  10061. ppnt2=ppnt1+ccol(pcol)-1
  10062. pnt=ppnt1
  10063. do j=pnt1,pnt2
  10064. k=colidx(j)
  10065. mark(k)=1
  10066. colidx(pnt)=k
  10067. colnzs(pnt)=colnzs(j)
  10068. if(k.eq.prow)then
  10069. p=pnt
  10070. workr(k)=pivot
  10071. else
  10072. workr(k)=-colnzs(j)*pivot
  10073. rhs(k)=rhs(k)+rhs(prow)*workr(k)
  10074. endif
  10075. pnt=pnt+1
  10076. c
  10077. i=rowbeg(k)
  10078. do while(rowidx(i).ne.pcol)
  10079. i=i+1
  10080. enddo
  10081. rowidx(i)=rowidx(rowbeg(k)+crow(k)-1)
  10082. rfill(k)=-1
  10083. enddo
  10084. c
  10085. colbeg(pcol)=ppnt1
  10086. j=colidx(ppnt1)
  10087. s=colnzs(ppnt1)
  10088. colidx(ppnt1)=colidx(p)
  10089. colnzs(ppnt1)=colnzs(p)
  10090. colidx(p)=j
  10091. colnzs(p)=s
  10092. ppnt1=ppnt1+1
  10093. c
  10094. c create pivot row
  10095. c
  10096. pnt1=rowbeg(prow)
  10097. crow(prow)=crow(prow)-1
  10098. pnt2=pnt1+crow(prow)-1
  10099. rowbeg(prow)=colbeg(pcol)-crow(prow)
  10100. pnt=rowbeg(prow)
  10101. do i=pnt1,pnt2
  10102. k=rowidx(i)
  10103. j=colbeg(k)
  10104. do while(colidx(j).ne.prow)
  10105. j=j+1
  10106. enddo
  10107. colidx(pnt)=k
  10108. colnzs(pnt)=colnzs(j)
  10109. pnt=pnt+1
  10110. colidx(j)=colidx(colbeg(k)+ccol(k)-1)
  10111. colnzs(j)=colnzs(colbeg(k)+ccol(k)-1)
  10112. cfill(k)=ccol(k)-1
  10113. enddo
  10114. endmem=endmem-ccol(pcol)-crow(prow)
  10115. ccfre=ccfre-ccol(pcol)-crow(prow)
  10116. c
  10117. c elimination loop
  10118. c
  10119. rpnt1=rowbeg(prow)
  10120. rpnt2=rpnt1+crow(prow)-1
  10121. do p=rpnt1,rpnt2
  10122. i=colidx(p)
  10123. s=colnzs(p)
  10124. obj(i)=obj(i)-s*obj(pcol)*pivot
  10125. fill=ccol(pcol)-1
  10126. pnt1=colbeg(i)
  10127. pnt2=pnt1+cfill(i)-1
  10128. do j=pnt1,pnt2
  10129. k=colidx(j)
  10130. if(mark(k).ne.0)then
  10131. colnzs(j)=colnzs(j)+s*workr(k)
  10132. fill=fill-1
  10133. mark(k)=0
  10134. endif
  10135. enddo
  10136. c
  10137. c compute the free space
  10138. c
  10139. j=cpermf(i)
  10140. if(j.eq.0)then
  10141. k=endmem-pnt2-1
  10142. else
  10143. k=colbeg(j)-pnt2-1
  10144. endif
  10145. c
  10146. c move column to the end of the column file
  10147. c
  10148. if(fill.gt.k)then
  10149. if (ccfre.lt.m)then
  10150. call ccomprs(mn,cfre,ccfre,endmem,nz,
  10151. x colbeg,ccol,cfirst,cpermf,colidx,colnzs,code)
  10152. if(code.lt.0)goto 999
  10153. pnt1=colbeg(i)
  10154. pnt2=pnt1+cfill(i)-1
  10155. endif
  10156. if(i.ne.clast)then
  10157. j=colbeg(clast)+ccol(clast)
  10158. colbeg(i)=j
  10159. do k=pnt1,pnt2
  10160. colidx(j)=colidx(k)
  10161. colnzs(j)=colnzs(k)
  10162. j=j+1
  10163. enddo
  10164. pnt1=colbeg(i)
  10165. pnt2=j-1
  10166. k=cpermf(i)
  10167. j=cpermb(i)
  10168. if(j.eq.0)then
  10169. cfirst=k
  10170. else
  10171. cpermf(j)=k
  10172. endif
  10173. cpermb(k)=j
  10174. cpermf(clast)=i
  10175. cpermb(i)=clast
  10176. clast=i
  10177. cpermf(clast)=0
  10178. endif
  10179. endif
  10180. c
  10181. c create fill-in
  10182. c
  10183. do k=ppnt1,ppnt2
  10184. j=colidx(k)
  10185. if(mark(j).eq.0)then
  10186. mark(j)=1
  10187. else
  10188. pnt2=pnt2+1
  10189. colnzs(pnt2)=s*workr(j)
  10190. colidx(pnt2)=j
  10191. rfill(j)=rfill(j)+1
  10192. endif
  10193. enddo
  10194. ccol(i)=pnt2-pnt1+1
  10195. if(i.eq.clast)then
  10196. ccfre=endmem-pnt2
  10197. endif
  10198. enddo
  10199. c
  10200. c make space for fills in the row file
  10201. c
  10202. do j=ppnt1,ppnt2
  10203. i=colidx(j)
  10204. mark(i)=0
  10205. c
  10206. c compute the free space
  10207. c
  10208. pnt2=rowbeg(i)+crow(i)-1
  10209. p=rpermf(i)
  10210. if(p.eq.0)then
  10211. k=rfre-pnt2-1
  10212. else
  10213. k=rowbeg(p)-pnt2-1
  10214. endif
  10215. c
  10216. c move row to the end of the row file
  10217. c
  10218. if(k.lt.rfill(i))then
  10219. if(rcfre.lt.n)then
  10220. call rcomprs(mn,rfre,
  10221. x rcfre,rowbeg,crow,rfirst,rpermf,rowidx,code)
  10222. if(code.lt.0)goto 999
  10223. endif
  10224. if(p.ne.0)then
  10225. pnt1=rowbeg(i)
  10226. pnt2=pnt1+crow(i)-1
  10227. pnt=rowbeg(rlast)+crow(rlast)
  10228. rowbeg(i)=pnt
  10229. do l=pnt1,pnt2
  10230. rowidx(pnt)=rowidx(l)
  10231. pnt=pnt+1
  10232. enddo
  10233. prewcol=rpermb(i)
  10234. if(prewcol.eq.0)then
  10235. rfirst=p
  10236. else
  10237. rpermf(prewcol)=p
  10238. endif
  10239. rpermb(p)=prewcol
  10240. rpermf(rlast)=i
  10241. rpermb(i)=rlast
  10242. rlast=i
  10243. rpermf(rlast)=0
  10244. endif
  10245. endif
  10246. crow(i)=crow(i)+rfill(i)
  10247. if(i.eq.rlast)rcfre=rfre-crow(i)-rowbeg(i)
  10248. nfill=nfill+rfill(i)+1
  10249. enddo
  10250. c
  10251. c make pointers to the end of the filled rows
  10252. c
  10253. do j=ppnt1,ppnt2
  10254. rfill(colidx(j))=rowbeg(colidx(j))+crow(colidx(j))-1
  10255. enddo
  10256. c
  10257. c generate fill-in the row file
  10258. c
  10259. do j=rpnt1,rpnt2
  10260. i=colidx(j)
  10261. pnt1=colbeg(i)+cfill(i)
  10262. pnt2=colbeg(i)+ccol(i)-1
  10263. do k=pnt1,pnt2
  10264. rowidx(rfill(colidx(k)))=i
  10265. rfill(colidx(k))=rfill(colidx(k))-1
  10266. enddo
  10267. enddo
  10268. goto 50
  10269. c
  10270. c End of the elimination, compress arrays
  10271. c
  10272. 900 call rcomprs(mn,rfre,rcfre,rowbeg,crow,rfirst,rpermf,rowidx,code)
  10273. pnt=endmem
  10274. i=clast
  10275. do while(i.ne.0)
  10276. pnt1=colbeg(i)
  10277. pnt2=pnt1+ccol(i)-1
  10278. do j=pnt2,pnt1,-1
  10279. pnt=pnt-1
  10280. colidx(pnt)=colidx(j)
  10281. colnzs(pnt)=colnzs(j)
  10282. enddo
  10283. colbeg(i)=pnt
  10284. i=cpermb(i)
  10285. enddo
  10286. c
  10287. c Make pointers form counters
  10288. c
  10289. do i=1,n
  10290. ccol(i)=colbeg(i)+ccol(i)-1
  10291. enddo
  10292. do i=1,m
  10293. crow(i)=rowbeg(i)+crow(i)-1
  10294. enddo
  10295. 999 return
  10296. end
  10297. c
  10298. c ===========================================================================
  10299. c This is a POSTSOLV procedure
  10300. c
  10301. c ========================================================================
  10302. c
  10303. subroutine pstsol(colpnt,colidx,colnzs,colsta,rowsta,
  10304. x vartyp,slktyp,upb,lob,ups,los,rhs,obj,xs,
  10305. x status,rowval,prehis,prelen,big)
  10306. c
  10307. common/dims/ n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  10308. integer*4 n,n1,m,mn,nz,cfree,pivotn,denwin,rfree
  10309. c
  10310. integer*4 colpnt(n1),colidx(nz),colsta(n),rowsta(m),
  10311. x prehis(mn),prelen,vartyp(n),slktyp(m),status(mn)
  10312. real*8 colnzs(nz),upb(n),lob(n),ups(m),los(m),
  10313. x rhs(m),obj(n),rowval(m),xs(n),big
  10314. c
  10315. integer*4 i,j,k,l,p,pnt1,pnt2,row,col
  10316. real*8 sol,lo1,lo2,up1,up2,lbig,sol1,sol2,s
  10317. c
  10318. C CMSSW: Explicit initialization needed
  10319. sol=0
  10320. lbig=0.9d+0*big
  10321. do i=1,mn
  10322. if(i.le.n)then
  10323. j=colsta(i)
  10324. else
  10325. j=rowsta(i-n)
  10326. endif
  10327. if(j.eq.-3)then
  10328. status(i)=0
  10329. else
  10330. status(i)=prelen+1
  10331. endif
  10332. enddo
  10333. c
  10334. do i=1,prelen
  10335. status(prehis(i))=i
  10336. enddo
  10337. c
  10338. do i=1,m
  10339. rowval(i)=0.0d+0
  10340. if(abs(slktyp(i)).eq.2)rhs(i)=-rhs(i)
  10341. enddo
  10342. c
  10343. do i=1,n
  10344. pnt1=colpnt(i)
  10345. pnt2=colpnt(i+1)-1
  10346. do j=pnt1,pnt2
  10347. if(abs(slktyp(colidx(j))).eq.2)then
  10348. colnzs(j)=-colnzs(j)
  10349. endif
  10350. enddo
  10351. if((status(i).gt.prelen).or.(status(i).eq.0))then
  10352. if(vartyp(i).ne.0)then
  10353. if(upb(i).lt.lbig)upb(i)=upb(i)+lob(i)
  10354. xs(i)=xs(i)+lob(i)
  10355. do j=pnt1,pnt2
  10356. rhs(colidx(j))=rhs(colidx(j))+colnzs(j)*lob(i)
  10357. enddo
  10358. endif
  10359. if(abs(vartyp(i)).eq.2)then
  10360. obj(i)=-obj(i)
  10361. upb(i)=-lob(i)
  10362. lob(i)=-big
  10363. xs(i)=-xs(i)
  10364. do j=pnt1,pnt2
  10365. colnzs(j)=-colnzs(j)
  10366. enddo
  10367. endif
  10368. do j=pnt1,pnt2
  10369. rowval(colidx(j))=rowval(colidx(j))+xs(i)*colnzs(j)
  10370. enddo
  10371. endif
  10372. enddo
  10373. c
  10374. i=prelen
  10375. do while(i.ge.1)
  10376. j=prehis(i)
  10377. if(j.le.n)then
  10378. k=-colsta(j)-2
  10379. if((k.eq.1).or.(k.eq.3).or.(k.eq.5).or.(k.eq.6))then
  10380. sol=lob(j)
  10381. xs(j)=sol
  10382. else if((k.eq.2).or.(k.eq.8))then
  10383. row=prehis(i+1)-n
  10384. l=colpnt(j)
  10385. do while(l.lt.colpnt(j+1))
  10386. if(colidx(l).eq.row)then
  10387. sol=colnzs(l)
  10388. l=colpnt(j+1)
  10389. endif
  10390. l=l+1
  10391. enddo
  10392. sol=(rhs(row)-rowval(row))/sol
  10393. xs(j)=sol
  10394. else if(k.eq.4)then
  10395. k=0
  10396. sol1=lob(j)
  10397. sol2=upb(j)
  10398. p=i+1
  10399. do while ((p.le.prelen).and.(prehis(p).gt.n).and.
  10400. x (-rowsta(prehis(p)-n)-2.eq.4))
  10401. row=prehis(p)-n
  10402. l=colpnt(j)
  10403. do while(l.lt.colpnt(j+1))
  10404. if(colidx(l).eq.row)then
  10405. sol=colnzs(l)
  10406. l=colpnt(j+1)
  10407. endif
  10408. l=l+1
  10409. enddo
  10410. if(los(row).gt.-lbig)then
  10411. s=(rhs(row)-rowval(row)+los(row))/sol
  10412. if((sol.gt.0.0d+0).and.(s.gt.sol1))then
  10413. k=1
  10414. sol1=s
  10415. endif
  10416. if((sol.lt.0.0d+0).and.(s.lt.sol2))then
  10417. k=2
  10418. sol2=s
  10419. endif
  10420. endif
  10421. if(ups(row).lt.lbig)then
  10422. s=(rhs(row)-rowval(row)+ups(row))/sol
  10423. if((sol.gt.0.0d+0).and.(s.lt.sol2))then
  10424. k=2
  10425. sol2=s
  10426. endif
  10427. if((sol.lt.0.0d+0).and.(s.gt.sol1))then
  10428. k=1
  10429. sol1=s
  10430. endif
  10431. endif
  10432. p=p+1
  10433. enddo
  10434. if(k.eq.1)sol=sol1
  10435. if(k.eq.2)sol=sol2
  10436. if(k.eq.0)then
  10437. sol=sol1
  10438. if(sol.lt.-lbig)sol=sol2
  10439. if(sol.gt.lbig)sol=0.0d+0
  10440. endif
  10441. xs(j)=sol
  10442. else if(k.gt.17)then
  10443. col=k-17
  10444. if((vartyp(j).eq.4).or.(vartyp(j).eq.12))then
  10445. lo2=-big
  10446. lo1=lob(j)
  10447. else
  10448. lo2=lob(j)
  10449. if((lo2.gt.-lbig).and.(lob(col).gt.-lbig))then
  10450. lo1=lob(col)-lo2
  10451. else
  10452. lo1=-big
  10453. endif
  10454. endif
  10455. if((vartyp(j).eq.8).or.(vartyp(j).eq.12))then
  10456. up2=big
  10457. up1=upb(j)
  10458. else
  10459. up2=upb(j)
  10460. if((up2.lt.lbig).and.(upb(col).lt.lbig))then
  10461. up1=upb(col)-up2
  10462. else
  10463. up1=big
  10464. endif
  10465. endif
  10466. lob(col)=lo1
  10467. upb(col)=up1
  10468. sol=0.0d+0
  10469. if(sol.lt.lo2)sol=lo2
  10470. if(sol.gt.up2)sol=up2
  10471. if(xs(col)-sol.lt.lo1)sol=xs(col)-lo1
  10472. if(xs(col)-sol.gt.up1)sol=xs(col)-up1
  10473. xs(j)=sol*obj(j)
  10474. xs(col)=xs(col)-sol
  10475. sol=0.0d+0
  10476. endif
  10477. l=colpnt(j)
  10478. do while(l.lt.colpnt(j+1))
  10479. row=colidx(l)
  10480. if(status(row+n).gt.status(j))then
  10481. rhs(row)=rhs(row)+colnzs(l)*sol
  10482. else
  10483. rowval(row)=rowval(row)+colnzs(l)*sol
  10484. endif
  10485. l=l+1
  10486. enddo
  10487. endif
  10488. i=i-1
  10489. enddo
  10490. c
  10491. return
  10492. end
  10493. c
  10494. c ============================================================================
  10495. subroutine mprnt(buff)
  10496. character*99 buff
  10497. common/logprt/ loglog,lfile
  10498. integer*4 loglog,lfile
  10499. c
  10500. 1 format(a79)
  10501. if((loglog.eq.1).or.(loglog.eq.3))then
  10502. write(*,1)buff
  10503. endif
  10504. if((loglog.eq.2).or.(loglog.eq.3))then
  10505. write(lfile,1)buff
  10506. endif
  10507. c
  10508. return
  10509. end
  10510. c ==========================================================================
  10511. c
  10512. subroutine timer(i)
  10513. implicit none
  10514. integer*4 i
  10515. real t
  10516. c
  10517. c --------------------------------------------------------------------------
  10518. c
  10519. c Implementation based on the Fortran 95 cpu_time()
  10520. call cpu_time(t)
  10521. i=nint(t*100.0)
  10522. end
  10523. c
  10524. c =========================================================================