sprow.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. /**************************************************************************
  2. **
  3. ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
  4. **
  5. ** Meschach Library
  6. **
  7. ** This Meschach Library is provided "as is" without any express
  8. ** or implied warranty of any kind with respect to this software.
  9. ** In particular the authors shall not be liable for any direct,
  10. ** indirect, special, incidental or consequential damages arising
  11. ** in any way from use of the software.
  12. **
  13. ** Everyone is granted permission to copy, modify and redistribute this
  14. ** Meschach Library, provided:
  15. ** 1. All copies contain this copyright notice.
  16. ** 2. All modified copies shall carry a notice stating who
  17. ** made the last modification and the date of such modification.
  18. ** 3. No charge is made for this software or works derived from it.
  19. ** This clause shall not be construed as constraining other software
  20. ** distributed on the same medium as this software, nor is a
  21. ** distribution fee considered a charge.
  22. **
  23. ***************************************************************************/
  24. /*
  25. Sparse rows package
  26. See also: sparse.h, matrix.h
  27. */
  28. #include <stdio.h>
  29. #include <math.h>
  30. #include <stdlib.h>
  31. #include "sparse.h"
  32. static char rcsid[] = "$Id: sprow.c,v 1.1 1994/01/13 05:35:36 des Exp $";
  33. #define MINROWLEN 10
  34. #ifndef MEX
  35. /* sprow_dump - prints relevant information about the sparse row r */
  36. #ifndef ANSI_C
  37. void sprow_dump(fp,r)
  38. FILE *fp;
  39. SPROW *r;
  40. #else
  41. void sprow_dump(FILE *fp, const SPROW *r)
  42. #endif
  43. {
  44. int j_idx;
  45. row_elt *elts;
  46. fprintf(fp,"SparseRow dump:\n");
  47. if ( ! r )
  48. { fprintf(fp,"*** NULL row ***\n"); return; }
  49. fprintf(fp,"row: len = %d, maxlen = %d, diag idx = %d\n",
  50. r->len,r->maxlen,r->diag);
  51. fprintf(fp,"element list @ 0x%lx\n",(long)(r->elt));
  52. if ( ! r->elt )
  53. {
  54. fprintf(fp,"*** NULL element list ***\n");
  55. return;
  56. }
  57. elts = r->elt;
  58. for ( j_idx = 0; j_idx < r->len; j_idx++, elts++ )
  59. fprintf(fp,"Col: %d, Val: %g, nxt_row = %d, nxt_idx = %d\n",
  60. elts->col,elts->val,elts->nxt_row,elts->nxt_idx);
  61. fprintf(fp,"\n");
  62. }
  63. #endif /* MEX */
  64. /* sprow_idx -- get index into row for a given column in a given row
  65. -- return -1 on error
  66. -- return -(idx+2) where idx is index to insertion point */
  67. #ifndef ANSI_C
  68. int sprow_idx(r,col)
  69. SPROW *r;
  70. int col;
  71. #else
  72. int sprow_idx(const SPROW *r, int col)
  73. #endif
  74. {
  75. register int lo, hi, mid;
  76. int tmp;
  77. register row_elt *r_elt;
  78. /*******************************************
  79. if ( r == (SPROW *)NULL )
  80. return -1;
  81. if ( col < 0 )
  82. return -1;
  83. *******************************************/
  84. r_elt = r->elt;
  85. if ( r->len <= 0 )
  86. return -2;
  87. /* try the hint */
  88. /* if ( hint >= 0 && hint < r->len && r_elt[hint].col == col )
  89. return hint; */
  90. /* otherwise use binary search... */
  91. /* code from K&R Ch. 6, p. 125 */
  92. lo = 0; hi = r->len - 1; mid = lo;
  93. while ( lo <= hi )
  94. {
  95. mid = (hi + lo)/2;
  96. if ( (tmp=r_elt[mid].col-col) > 0 )
  97. hi = mid-1;
  98. else if ( tmp < 0 )
  99. lo = mid+1;
  100. else /* tmp == 0 */
  101. return mid;
  102. }
  103. tmp = r_elt[mid].col - col;
  104. if ( tmp > 0 )
  105. return -(mid+2); /* insert at mid */
  106. else /* tmp < 0 */
  107. return -(mid+3); /* insert at mid+1 */
  108. }
  109. /* sprow_get -- gets, initialises and returns a SPROW structure
  110. -- max. length is maxlen */
  111. #ifndef ANSI_C
  112. SPROW *sprow_get(maxlen)
  113. int maxlen;
  114. #else
  115. SPROW *sprow_get(int maxlen)
  116. #endif
  117. {
  118. SPROW *r;
  119. if ( maxlen < 0 )
  120. error(E_NEG,"sprow_get");
  121. r = NEW(SPROW);
  122. if ( ! r )
  123. error(E_MEM,"sprow_get");
  124. else if (mem_info_is_on()) {
  125. mem_bytes(TYPE_SPROW,0,sizeof(SPROW));
  126. mem_numvar(TYPE_SPROW,1);
  127. }
  128. r->elt = NEW_A(maxlen,row_elt);
  129. if ( ! r->elt )
  130. error(E_MEM,"sprow_get");
  131. else if (mem_info_is_on()) {
  132. mem_bytes(TYPE_SPROW,0,maxlen*sizeof(row_elt));
  133. }
  134. r->len = 0;
  135. r->maxlen = maxlen;
  136. r->diag = -1;
  137. return r;
  138. }
  139. /* sprow_xpd -- expand row by means of realloc()
  140. -- type must be TYPE_SPMAT if r is a row of a SPMAT structure,
  141. otherwise it must be TYPE_SPROW
  142. -- returns r */
  143. #ifndef ANSI_C
  144. SPROW *sprow_xpd(r,n,type)
  145. SPROW *r;
  146. int n,type;
  147. #else
  148. SPROW *sprow_xpd(SPROW *r, int n, int type)
  149. #endif
  150. {
  151. int newlen;
  152. if ( ! r ) {
  153. r = NEW(SPROW);
  154. if (! r )
  155. error(E_MEM,"sprow_xpd");
  156. else if ( mem_info_is_on()) {
  157. if (type != TYPE_SPMAT && type != TYPE_SPROW)
  158. warning(WARN_WRONG_TYPE,"sprow_xpd");
  159. mem_bytes(type,0,sizeof(SPROW));
  160. if (type == TYPE_SPROW)
  161. mem_numvar(type,1);
  162. }
  163. }
  164. if ( ! r->elt )
  165. {
  166. r->elt = NEW_A((unsigned)n,row_elt);
  167. if ( ! r->elt )
  168. error(E_MEM,"sprow_xpd");
  169. else if (mem_info_is_on()) {
  170. mem_bytes(type,0,n*sizeof(row_elt));
  171. }
  172. r->len = 0;
  173. r->maxlen = n;
  174. return r;
  175. }
  176. if ( n <= r->len )
  177. newlen = max(2*r->len + 1,MINROWLEN);
  178. else
  179. newlen = n;
  180. if ( newlen <= r->maxlen )
  181. {
  182. MEM_ZERO((char *)(&(r->elt[r->len])),
  183. (newlen-r->len)*sizeof(row_elt));
  184. r->len = newlen;
  185. }
  186. else
  187. {
  188. if (mem_info_is_on()) {
  189. mem_bytes(type,r->maxlen*sizeof(row_elt),
  190. newlen*sizeof(row_elt));
  191. }
  192. r->elt = RENEW(r->elt,newlen,row_elt);
  193. if ( ! r->elt )
  194. error(E_MEM,"sprow_xpd");
  195. r->maxlen = newlen;
  196. r->len = newlen;
  197. }
  198. return r;
  199. }
  200. /* sprow_resize -- resize a SPROW variable by means of realloc()
  201. -- n is a new size
  202. -- returns r */
  203. #ifndef ANSI_C
  204. SPROW *sprow_resize(r,n,type)
  205. SPROW *r;
  206. int n,type;
  207. #else
  208. SPROW *sprow_resize(SPROW *r, int n, int type)
  209. #endif
  210. {
  211. if (n < 0)
  212. error(E_NEG,"sprow_resize");
  213. if ( ! r )
  214. return sprow_get(n);
  215. if (n == r->len)
  216. return r;
  217. if ( ! r->elt )
  218. {
  219. r->elt = NEW_A((unsigned)n,row_elt);
  220. if ( ! r->elt )
  221. error(E_MEM,"sprow_resize");
  222. else if (mem_info_is_on()) {
  223. mem_bytes(type,0,n*sizeof(row_elt));
  224. }
  225. r->maxlen = r->len = n;
  226. return r;
  227. }
  228. if ( n <= r->maxlen )
  229. r->len = n;
  230. else
  231. {
  232. if (mem_info_is_on()) {
  233. mem_bytes(type,r->maxlen*sizeof(row_elt),
  234. n*sizeof(row_elt));
  235. }
  236. r->elt = RENEW(r->elt,n,row_elt);
  237. if ( ! r->elt )
  238. error(E_MEM,"sprow_resize");
  239. r->maxlen = r->len = n;
  240. }
  241. return r;
  242. }
  243. /* release a row of a matrix */
  244. #ifndef ANSI_C
  245. int sprow_free(r)
  246. SPROW *r;
  247. #else
  248. int sprow_free(SPROW *r)
  249. #endif
  250. {
  251. if ( ! r )
  252. return -1;
  253. if (mem_info_is_on()) {
  254. mem_bytes(TYPE_SPROW,sizeof(SPROW),0);
  255. mem_numvar(TYPE_SPROW,-1);
  256. }
  257. if ( r->elt )
  258. {
  259. if (mem_info_is_on()) {
  260. mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt),0);
  261. }
  262. free((char *)r->elt);
  263. }
  264. free((char *)r);
  265. return 0;
  266. }
  267. /* sprow_merge -- merges r1 and r2 into r_out
  268. -- cannot be done in-situ
  269. -- type must be TYPE_SPMAT or TYPE_SPROW depending on
  270. whether r_out is a row of a SPMAT structure
  271. or a SPROW variable
  272. -- returns r_out */
  273. #ifndef ANSI_C
  274. SPROW *sprow_merge(r1,r2,r_out,type)
  275. SPROW *r1, *r2, *r_out;
  276. int type;
  277. #else
  278. SPROW *sprow_merge(const SPROW *r1, const SPROW *r2, SPROW *r_out, int type)
  279. #endif
  280. {
  281. int idx1, idx2, idx_out, len1, len2, len_out;
  282. row_elt *elt1, *elt2, *elt_out;
  283. if ( ! r1 || ! r2 )
  284. error(E_NULL,"sprow_merge");
  285. if ( ! r_out )
  286. r_out = sprow_get(MINROWLEN);
  287. if ( r1 == r_out || r2 == r_out )
  288. error(E_INSITU,"sprow_merge");
  289. /* Initialise */
  290. len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
  291. idx1 = idx2 = idx_out = 0;
  292. elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt;
  293. while ( idx1 < len1 || idx2 < len2 )
  294. {
  295. if ( idx_out >= len_out )
  296. { /* r_out is too small */
  297. r_out->len = idx_out;
  298. r_out = sprow_xpd(r_out,0,type);
  299. len_out = r_out->len;
  300. elt_out = &(r_out->elt[idx_out]);
  301. }
  302. if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
  303. {
  304. elt_out->col = elt1->col;
  305. elt_out->val = elt1->val;
  306. if ( elt1->col == elt2->col && idx2 < len2 )
  307. { elt2++; idx2++; }
  308. elt1++; idx1++;
  309. }
  310. else
  311. {
  312. elt_out->col = elt2->col;
  313. elt_out->val = elt2->val;
  314. elt2++; idx2++;
  315. }
  316. elt_out++; idx_out++;
  317. }
  318. r_out->len = idx_out;
  319. return r_out;
  320. }
  321. /* sprow_copy -- copies r1 and r2 into r_out
  322. -- cannot be done in-situ
  323. -- type must be TYPE_SPMAT or TYPE_SPROW depending on
  324. whether r_out is a row of a SPMAT structure
  325. or a SPROW variable
  326. -- returns r_out */
  327. #ifndef ANSI_C
  328. SPROW *sprow_copy(r1,r2,r_out,type)
  329. SPROW *r1, *r2, *r_out;
  330. int type;
  331. #else
  332. SPROW *sprow_copy(const SPROW *r1, const SPROW *r2, SPROW *r_out, int type)
  333. #endif
  334. {
  335. int idx1, idx2, idx_out, len1, len2, len_out;
  336. row_elt *elt1, *elt2, *elt_out;
  337. if ( ! r1 || ! r2 )
  338. error(E_NULL,"sprow_copy");
  339. if ( ! r_out )
  340. r_out = sprow_get(MINROWLEN);
  341. if ( r1 == r_out || r2 == r_out )
  342. error(E_INSITU,"sprow_copy");
  343. /* Initialise */
  344. len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
  345. idx1 = idx2 = idx_out = 0;
  346. elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt;
  347. while ( idx1 < len1 || idx2 < len2 )
  348. {
  349. while ( idx_out >= len_out )
  350. { /* r_out is too small */
  351. r_out->len = idx_out;
  352. r_out = sprow_xpd(r_out,0,type);
  353. len_out = r_out->maxlen;
  354. elt_out = &(r_out->elt[idx_out]);
  355. }
  356. if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
  357. {
  358. elt_out->col = elt1->col;
  359. elt_out->val = elt1->val;
  360. if ( elt1->col == elt2->col && idx2 < len2 )
  361. { elt2++; idx2++; }
  362. elt1++; idx1++;
  363. }
  364. else
  365. {
  366. elt_out->col = elt2->col;
  367. elt_out->val = 0.0;
  368. elt2++; idx2++;
  369. }
  370. elt_out++; idx_out++;
  371. }
  372. r_out->len = idx_out;
  373. return r_out;
  374. }
  375. /* sprow_mltadd -- sets r_out <- r1 + alpha.r2
  376. -- cannot be in situ
  377. -- only for columns j0, j0+1, ...
  378. -- type must be TYPE_SPMAT or TYPE_SPROW depending on
  379. whether r_out is a row of a SPMAT structure
  380. or a SPROW variable
  381. -- returns r_out */
  382. #ifndef ANSI_C
  383. SPROW *sprow_mltadd(r1,r2,alpha,j0,r_out,type)
  384. SPROW *r1, *r2, *r_out;
  385. double alpha;
  386. int j0, type;
  387. #else
  388. SPROW *sprow_mltadd(const SPROW *r1,const SPROW *r2, double alpha,
  389. int j0, SPROW *r_out, int type)
  390. #endif
  391. {
  392. int idx1, idx2, idx_out, len1, len2, len_out;
  393. row_elt *elt1, *elt2, *elt_out;
  394. if ( ! r1 || ! r2 )
  395. error(E_NULL,"sprow_mltadd");
  396. if ( r1 == r_out || r2 == r_out )
  397. error(E_INSITU,"sprow_mltadd");
  398. if ( j0 < 0 )
  399. error(E_BOUNDS,"sprow_mltadd");
  400. if ( ! r_out )
  401. r_out = sprow_get(MINROWLEN);
  402. /* Initialise */
  403. len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
  404. /* idx1 = idx2 = idx_out = 0; */
  405. idx1 = sprow_idx(r1,j0);
  406. idx2 = sprow_idx(r2,j0);
  407. idx_out = sprow_idx(r_out,j0);
  408. idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
  409. idx2 = (idx2 < 0) ? -(idx2+2) : idx2;
  410. idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
  411. elt1 = &(r1->elt[idx1]);
  412. elt2 = &(r2->elt[idx2]);
  413. elt_out = &(r_out->elt[idx_out]);
  414. while ( idx1 < len1 || idx2 < len2 )
  415. {
  416. if ( idx_out >= len_out )
  417. { /* r_out is too small */
  418. r_out->len = idx_out;
  419. r_out = sprow_xpd(r_out,0,type);
  420. len_out = r_out->maxlen;
  421. elt_out = &(r_out->elt[idx_out]);
  422. }
  423. if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
  424. {
  425. elt_out->col = elt1->col;
  426. elt_out->val = elt1->val;
  427. if ( idx2 < len2 && elt1->col == elt2->col )
  428. {
  429. elt_out->val += alpha*elt2->val;
  430. elt2++; idx2++;
  431. }
  432. elt1++; idx1++;
  433. }
  434. else
  435. {
  436. elt_out->col = elt2->col;
  437. elt_out->val = alpha*elt2->val;
  438. elt2++; idx2++;
  439. }
  440. elt_out++; idx_out++;
  441. }
  442. r_out->len = idx_out;
  443. return r_out;
  444. }
  445. /* sprow_add -- sets r_out <- r1 + r2
  446. -- cannot be in situ
  447. -- only for columns j0, j0+1, ...
  448. -- type must be TYPE_SPMAT or TYPE_SPROW depending on
  449. whether r_out is a row of a SPMAT structure
  450. or a SPROW variable
  451. -- returns r_out */
  452. #ifndef ANSI_C
  453. SPROW *sprow_add(r1,r2,j0,r_out,type)
  454. SPROW *r1, *r2, *r_out;
  455. int j0, type;
  456. #else
  457. SPROW *sprow_add(const SPROW *r1,const SPROW *r2,
  458. int j0, SPROW *r_out, int type)
  459. #endif
  460. {
  461. int idx1, idx2, idx_out, len1, len2, len_out;
  462. row_elt *elt1, *elt2, *elt_out;
  463. if ( ! r1 || ! r2 )
  464. error(E_NULL,"sprow_add");
  465. if ( r1 == r_out || r2 == r_out )
  466. error(E_INSITU,"sprow_add");
  467. if ( j0 < 0 )
  468. error(E_BOUNDS,"sprow_add");
  469. if ( ! r_out )
  470. r_out = sprow_get(MINROWLEN);
  471. /* Initialise */
  472. len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
  473. /* idx1 = idx2 = idx_out = 0; */
  474. idx1 = sprow_idx(r1,j0);
  475. idx2 = sprow_idx(r2,j0);
  476. idx_out = sprow_idx(r_out,j0);
  477. idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
  478. idx2 = (idx2 < 0) ? -(idx2+2) : idx2;
  479. idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
  480. elt1 = &(r1->elt[idx1]);
  481. elt2 = &(r2->elt[idx2]);
  482. elt_out = &(r_out->elt[idx_out]);
  483. while ( idx1 < len1 || idx2 < len2 )
  484. {
  485. if ( idx_out >= len_out )
  486. { /* r_out is too small */
  487. r_out->len = idx_out;
  488. r_out = sprow_xpd(r_out,0,type);
  489. len_out = r_out->maxlen;
  490. elt_out = &(r_out->elt[idx_out]);
  491. }
  492. if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
  493. {
  494. elt_out->col = elt1->col;
  495. elt_out->val = elt1->val;
  496. if ( idx2 < len2 && elt1->col == elt2->col )
  497. {
  498. elt_out->val += elt2->val;
  499. elt2++; idx2++;
  500. }
  501. elt1++; idx1++;
  502. }
  503. else
  504. {
  505. elt_out->col = elt2->col;
  506. elt_out->val = elt2->val;
  507. elt2++; idx2++;
  508. }
  509. elt_out++; idx_out++;
  510. }
  511. r_out->len = idx_out;
  512. return r_out;
  513. }
  514. /* sprow_sub -- sets r_out <- r1 - r2
  515. -- cannot be in situ
  516. -- only for columns j0, j0+1, ...
  517. -- type must be TYPE_SPMAT or TYPE_SPROW depending on
  518. whether r_out is a row of a SPMAT structure
  519. or a SPROW variable
  520. -- returns r_out */
  521. #ifndef ANSI_C
  522. SPROW *sprow_sub(r1,r2,j0,r_out,type)
  523. SPROW *r1, *r2, *r_out;
  524. int j0, type;
  525. #else
  526. SPROW *sprow_sub(const SPROW *r1, const SPROW *r2,
  527. int j0, SPROW *r_out, int type)
  528. #endif
  529. {
  530. int idx1, idx2, idx_out, len1, len2, len_out;
  531. row_elt *elt1, *elt2, *elt_out;
  532. if ( ! r1 || ! r2 )
  533. error(E_NULL,"sprow_sub");
  534. if ( r1 == r_out || r2 == r_out )
  535. error(E_INSITU,"sprow_sub");
  536. if ( j0 < 0 )
  537. error(E_BOUNDS,"sprow_sub");
  538. if ( ! r_out )
  539. r_out = sprow_get(MINROWLEN);
  540. /* Initialise */
  541. len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen;
  542. /* idx1 = idx2 = idx_out = 0; */
  543. idx1 = sprow_idx(r1,j0);
  544. idx2 = sprow_idx(r2,j0);
  545. idx_out = sprow_idx(r_out,j0);
  546. idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
  547. idx2 = (idx2 < 0) ? -(idx2+2) : idx2;
  548. idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
  549. elt1 = &(r1->elt[idx1]);
  550. elt2 = &(r2->elt[idx2]);
  551. elt_out = &(r_out->elt[idx_out]);
  552. while ( idx1 < len1 || idx2 < len2 )
  553. {
  554. if ( idx_out >= len_out )
  555. { /* r_out is too small */
  556. r_out->len = idx_out;
  557. r_out = sprow_xpd(r_out,0,type);
  558. len_out = r_out->maxlen;
  559. elt_out = &(r_out->elt[idx_out]);
  560. }
  561. if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) )
  562. {
  563. elt_out->col = elt1->col;
  564. elt_out->val = elt1->val;
  565. if ( idx2 < len2 && elt1->col == elt2->col )
  566. {
  567. elt_out->val -= elt2->val;
  568. elt2++; idx2++;
  569. }
  570. elt1++; idx1++;
  571. }
  572. else
  573. {
  574. elt_out->col = elt2->col;
  575. elt_out->val = -elt2->val;
  576. elt2++; idx2++;
  577. }
  578. elt_out++; idx_out++;
  579. }
  580. r_out->len = idx_out;
  581. return r_out;
  582. }
  583. /* sprow_smlt -- sets r_out <- alpha*r1
  584. -- can be in situ
  585. -- only for columns j0, j0+1, ...
  586. -- returns r_out */
  587. #ifndef ANSI_C
  588. SPROW *sprow_smlt(r1,alpha,j0,r_out,type)
  589. SPROW *r1, *r_out;
  590. double alpha;
  591. int j0, type;
  592. #else
  593. SPROW *sprow_smlt(const SPROW *r1, double alpha, int j0, SPROW *r_out, int type)
  594. #endif
  595. {
  596. int idx1, idx_out, len1;
  597. row_elt *elt1, *elt_out;
  598. if ( ! r1 )
  599. error(E_NULL,"sprow_smlt");
  600. if ( j0 < 0 )
  601. error(E_BOUNDS,"sprow_smlt");
  602. if ( ! r_out )
  603. r_out = sprow_get(MINROWLEN);
  604. /* Initialise */
  605. len1 = r1->len;
  606. idx1 = sprow_idx(r1,j0);
  607. idx_out = sprow_idx(r_out,j0);
  608. idx1 = (idx1 < 0) ? -(idx1+2) : idx1;
  609. idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out;
  610. elt1 = &(r1->elt[idx1]);
  611. r_out = sprow_resize(r_out,idx_out+len1-idx1,type);
  612. elt_out = &(r_out->elt[idx_out]);
  613. for ( ; idx1 < len1; elt1++,elt_out++,idx1++,idx_out++ )
  614. {
  615. elt_out->col = elt1->col;
  616. elt_out->val = alpha*elt1->val;
  617. }
  618. r_out->len = idx_out;
  619. return r_out;
  620. }
  621. #ifndef MEX
  622. /* sprow_foutput -- print a representation of r on stream fp */
  623. #ifndef ANSI_C
  624. void sprow_foutput(fp,r)
  625. FILE *fp;
  626. SPROW *r;
  627. #else
  628. void sprow_foutput(FILE *fp, const SPROW *r)
  629. #endif
  630. {
  631. int i, len;
  632. row_elt *e;
  633. if ( ! r )
  634. {
  635. fprintf(fp,"SparseRow: **** NULL ****\n");
  636. return;
  637. }
  638. len = r->len;
  639. fprintf(fp,"SparseRow: length: %d\n",len);
  640. for ( i = 0, e = r->elt; i < len; i++, e++ )
  641. fprintf(fp,"Column %d: %g, next row: %d, next index %d\n",
  642. e->col, e->val, e->nxt_row, e->nxt_idx);
  643. }
  644. #endif
  645. /* sprow_set_val -- sets the j-th column entry of the sparse row r
  646. -- Note: destroys the usual column & row access paths */
  647. #ifndef ANSI_C
  648. double sprow_set_val(r,j,val)
  649. SPROW *r;
  650. int j;
  651. double val;
  652. #else
  653. double sprow_set_val(SPROW *r, int j, double val)
  654. #endif
  655. {
  656. int idx, idx2, new_len;
  657. if ( ! r )
  658. error(E_NULL,"sprow_set_val");
  659. idx = sprow_idx(r,j);
  660. if ( idx >= 0 )
  661. { r->elt[idx].val = val; return val; }
  662. /* else */ if ( idx < -1 )
  663. {
  664. /* shift & insert new value */
  665. idx = -(idx+2); /* this is the intended insertion index */
  666. if ( r->len >= r->maxlen )
  667. {
  668. r->len = r->maxlen;
  669. new_len = max(2*r->maxlen+1,5);
  670. if (mem_info_is_on()) {
  671. mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt),
  672. new_len*sizeof(row_elt));
  673. }
  674. r->elt = RENEW(r->elt,new_len,row_elt);
  675. if ( ! r->elt ) /* can't allocate */
  676. error(E_MEM,"sprow_set_val");
  677. r->maxlen = 2*r->maxlen+1;
  678. }
  679. for ( idx2 = r->len-1; idx2 >= idx; idx2-- )
  680. MEM_COPY((char *)(&(r->elt[idx2])),
  681. (char *)(&(r->elt[idx2+1])),sizeof(row_elt));
  682. /************************************************************
  683. if ( idx < r->len )
  684. MEM_COPY((char *)(&(r->elt[idx])),(char *)(&(r->elt[idx+1])),
  685. (r->len-idx)*sizeof(row_elt));
  686. ************************************************************/
  687. r->len++;
  688. r->elt[idx].col = j;
  689. r->elt[idx].nxt_row = -1;
  690. r->elt[idx].nxt_idx = -1;
  691. return r->elt[idx].val = val;
  692. }
  693. /* else -- idx == -1, error in index/matrix! */
  694. return 0.0;
  695. }