lemon-project-template-glpk

annotate deps/glpk/src/glphbm.c @ 11:4fc6ad2fb8a6

Test GLPK in src/main.cc
author Alpar Juttner <alpar@cs.elte.hu>
date Sun, 06 Nov 2011 21:43:29 +0100
parents
children
rev   line source
alpar@9 1 /* glphbm.c */
alpar@9 2
alpar@9 3 /***********************************************************************
alpar@9 4 * This code is part of GLPK (GNU Linear Programming Kit).
alpar@9 5 *
alpar@9 6 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
alpar@9 7 * 2009, 2010, 2011 Andrew Makhorin, Department for Applied Informatics,
alpar@9 8 * Moscow Aviation Institute, Moscow, Russia. All rights reserved.
alpar@9 9 * E-mail: <mao@gnu.org>.
alpar@9 10 *
alpar@9 11 * GLPK is free software: you can redistribute it and/or modify it
alpar@9 12 * under the terms of the GNU General Public License as published by
alpar@9 13 * the Free Software Foundation, either version 3 of the License, or
alpar@9 14 * (at your option) any later version.
alpar@9 15 *
alpar@9 16 * GLPK is distributed in the hope that it will be useful, but WITHOUT
alpar@9 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
alpar@9 18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
alpar@9 19 * License for more details.
alpar@9 20 *
alpar@9 21 * You should have received a copy of the GNU General Public License
alpar@9 22 * along with GLPK. If not, see <http://www.gnu.org/licenses/>.
alpar@9 23 ***********************************************************************/
alpar@9 24
alpar@9 25 #define _GLPSTD_ERRNO
alpar@9 26 #define _GLPSTD_STDIO
alpar@9 27 #include "glphbm.h"
alpar@9 28 #include "glpenv.h"
alpar@9 29
alpar@9 30 /***********************************************************************
alpar@9 31 * NAME
alpar@9 32 *
alpar@9 33 * hbm_read_mat - read sparse matrix in Harwell-Boeing format
alpar@9 34 *
alpar@9 35 * SYNOPSIS
alpar@9 36 *
alpar@9 37 * #include "glphbm.h"
alpar@9 38 * HBM *hbm_read_mat(const char *fname);
alpar@9 39 *
alpar@9 40 * DESCRIPTION
alpar@9 41 *
alpar@9 42 * The routine hbm_read_mat reads a sparse matrix in the Harwell-Boeing
alpar@9 43 * format from a text file whose name is the character string fname.
alpar@9 44 *
alpar@9 45 * Detailed description of the Harwell-Boeing format recognised by this
alpar@9 46 * routine is given in the following report:
alpar@9 47 *
alpar@9 48 * I.S.Duff, R.G.Grimes, J.G.Lewis. User's Guide for the Harwell-Boeing
alpar@9 49 * Sparse Matrix Collection (Release I), TR/PA/92/86, October 1992.
alpar@9 50 *
alpar@9 51 * RETURNS
alpar@9 52 *
alpar@9 53 * If no error occured, the routine hbm_read_mat returns a pointer to
alpar@9 54 * a data structure containing the matrix. In case of error the routine
alpar@9 55 * prints an appropriate error message and returns NULL. */
alpar@9 56
alpar@9 57 struct dsa
alpar@9 58 { /* working area used by routine hbm_read_mat */
alpar@9 59 const char *fname;
alpar@9 60 /* name of input text file */
alpar@9 61 FILE *fp;
alpar@9 62 /* stream assigned to input text file */
alpar@9 63 int seqn;
alpar@9 64 /* card sequential number */
alpar@9 65 char card[80+1];
alpar@9 66 /* card image buffer */
alpar@9 67 int fmt_p;
alpar@9 68 /* scale factor */
alpar@9 69 int fmt_k;
alpar@9 70 /* iterator */
alpar@9 71 int fmt_f;
alpar@9 72 /* format code */
alpar@9 73 int fmt_w;
alpar@9 74 /* field width */
alpar@9 75 int fmt_d;
alpar@9 76 /* number of decimal places after point */
alpar@9 77 };
alpar@9 78
alpar@9 79 /***********************************************************************
alpar@9 80 * read_card - read next data card
alpar@9 81 *
alpar@9 82 * This routine reads the next 80-column card from the input text file
alpar@9 83 * and stores its image into the character string card. If the card was
alpar@9 84 * read successfully, the routine returns zero, otherwise non-zero. */
alpar@9 85
alpar@9 86 static int read_card(struct dsa *dsa)
alpar@9 87 { int k, c;
alpar@9 88 dsa->seqn++;
alpar@9 89 memset(dsa->card, ' ', 80), dsa->card[80] = '\0';
alpar@9 90 k = 0;
alpar@9 91 for (;;)
alpar@9 92 { c = fgetc(dsa->fp);
alpar@9 93 if (ferror(dsa->fp))
alpar@9 94 { xprintf("%s:%d: read error - %s\n", dsa->fname, dsa->seqn,
alpar@9 95 strerror(errno));
alpar@9 96 return 1;
alpar@9 97 }
alpar@9 98 if (feof(dsa->fp))
alpar@9 99 { if (k == 0)
alpar@9 100 xprintf("%s:%d: unexpected EOF\n", dsa->fname,
alpar@9 101 dsa->seqn);
alpar@9 102 else
alpar@9 103 xprintf("%s:%d: missing final LF\n", dsa->fname,
alpar@9 104 dsa->seqn);
alpar@9 105 return 1;
alpar@9 106 }
alpar@9 107 if (c == '\r') continue;
alpar@9 108 if (c == '\n') break;
alpar@9 109 if (iscntrl(c))
alpar@9 110 { xprintf("%s:%d: invalid control character 0x%02X\n",
alpar@9 111 dsa->fname, dsa->seqn, c);
alpar@9 112 return 1;
alpar@9 113 }
alpar@9 114 if (k == 80)
alpar@9 115 { xprintf("%s:%d: card image too long\n", dsa->fname,
alpar@9 116 dsa->seqn);
alpar@9 117 return 1;
alpar@9 118 }
alpar@9 119 dsa->card[k++] = (char)c;
alpar@9 120 }
alpar@9 121 return 0;
alpar@9 122 }
alpar@9 123
alpar@9 124 /***********************************************************************
alpar@9 125 * scan_int - scan integer value from the current card
alpar@9 126 *
alpar@9 127 * This routine scans an integer value from the current card, where fld
alpar@9 128 * is the name of the field, pos is the position of the field, width is
alpar@9 129 * the width of the field, val points to a location to which the scanned
alpar@9 130 * value should be stored. If the value was scanned successfully, the
alpar@9 131 * routine returns zero, otherwise non-zero. */
alpar@9 132
alpar@9 133 static int scan_int(struct dsa *dsa, char *fld, int pos, int width,
alpar@9 134 int *val)
alpar@9 135 { char str[80+1];
alpar@9 136 xassert(1 <= width && width <= 80);
alpar@9 137 memcpy(str, dsa->card + pos, width), str[width] = '\0';
alpar@9 138 if (str2int(strspx(str), val))
alpar@9 139 { xprintf("%s:%d: field `%s' contains invalid value `%s'\n",
alpar@9 140 dsa->fname, dsa->seqn, fld, str);
alpar@9 141 return 1;
alpar@9 142 }
alpar@9 143 return 0;
alpar@9 144 }
alpar@9 145
alpar@9 146 /***********************************************************************
alpar@9 147 * parse_fmt - parse Fortran format specification
alpar@9 148 *
alpar@9 149 * This routine parses the Fortran format specification represented as
alpar@9 150 * character string which fmt points to and stores format elements into
alpar@9 151 * appropriate static locations. Should note that not all valid Fortran
alpar@9 152 * format specifications may be recognised. If the format specification
alpar@9 153 * was recognised, the routine returns zero, otherwise non-zero. */
alpar@9 154
alpar@9 155 static int parse_fmt(struct dsa *dsa, char *fmt)
alpar@9 156 { int k, s, val;
alpar@9 157 char str[80+1];
alpar@9 158 /* first character should be left parenthesis */
alpar@9 159 if (fmt[0] != '(')
alpar@9 160 fail: { xprintf("hbm_read_mat: format `%s' not recognised\n", fmt);
alpar@9 161 return 1;
alpar@9 162 }
alpar@9 163 k = 1;
alpar@9 164 /* optional scale factor */
alpar@9 165 dsa->fmt_p = 0;
alpar@9 166 if (isdigit((unsigned char)fmt[k]))
alpar@9 167 { s = 0;
alpar@9 168 while (isdigit((unsigned char)fmt[k]))
alpar@9 169 { if (s == 80) goto fail;
alpar@9 170 str[s++] = fmt[k++];
alpar@9 171 }
alpar@9 172 str[s] = '\0';
alpar@9 173 if (str2int(str, &val)) goto fail;
alpar@9 174 if (toupper((unsigned char)fmt[k]) != 'P') goto iter;
alpar@9 175 dsa->fmt_p = val, k++;
alpar@9 176 if (!(0 <= dsa->fmt_p && dsa->fmt_p <= 255)) goto fail;
alpar@9 177 /* optional comma may follow scale factor */
alpar@9 178 if (fmt[k] == ',') k++;
alpar@9 179 }
alpar@9 180 /* optional iterator */
alpar@9 181 dsa->fmt_k = 1;
alpar@9 182 if (isdigit((unsigned char)fmt[k]))
alpar@9 183 { s = 0;
alpar@9 184 while (isdigit((unsigned char)fmt[k]))
alpar@9 185 { if (s == 80) goto fail;
alpar@9 186 str[s++] = fmt[k++];
alpar@9 187 }
alpar@9 188 str[s] = '\0';
alpar@9 189 if (str2int(str, &val)) goto fail;
alpar@9 190 iter: dsa->fmt_k = val;
alpar@9 191 if (!(1 <= dsa->fmt_k && dsa->fmt_k <= 255)) goto fail;
alpar@9 192 }
alpar@9 193 /* format code */
alpar@9 194 dsa->fmt_f = toupper((unsigned char)fmt[k++]);
alpar@9 195 if (!(dsa->fmt_f == 'D' || dsa->fmt_f == 'E' ||
alpar@9 196 dsa->fmt_f == 'F' || dsa->fmt_f == 'G' ||
alpar@9 197 dsa->fmt_f == 'I')) goto fail;
alpar@9 198 /* field width */
alpar@9 199 if (!isdigit((unsigned char)fmt[k])) goto fail;
alpar@9 200 s = 0;
alpar@9 201 while (isdigit((unsigned char)fmt[k]))
alpar@9 202 { if (s == 80) goto fail;
alpar@9 203 str[s++] = fmt[k++];
alpar@9 204 }
alpar@9 205 str[s] = '\0';
alpar@9 206 if (str2int(str, &dsa->fmt_w)) goto fail;
alpar@9 207 if (!(1 <= dsa->fmt_w && dsa->fmt_w <= 255)) goto fail;
alpar@9 208 /* optional number of decimal places after point */
alpar@9 209 dsa->fmt_d = 0;
alpar@9 210 if (fmt[k] == '.')
alpar@9 211 { k++;
alpar@9 212 if (!isdigit((unsigned char)fmt[k])) goto fail;
alpar@9 213 s = 0;
alpar@9 214 while (isdigit((unsigned char)fmt[k]))
alpar@9 215 { if (s == 80) goto fail;
alpar@9 216 str[s++] = fmt[k++];
alpar@9 217 }
alpar@9 218 str[s] = '\0';
alpar@9 219 if (str2int(str, &dsa->fmt_d)) goto fail;
alpar@9 220 if (!(0 <= dsa->fmt_d && dsa->fmt_d <= 255)) goto fail;
alpar@9 221 }
alpar@9 222 /* last character should be right parenthesis */
alpar@9 223 if (!(fmt[k] == ')' && fmt[k+1] == '\0')) goto fail;
alpar@9 224 return 0;
alpar@9 225 }
alpar@9 226
alpar@9 227 /***********************************************************************
alpar@9 228 * read_int_array - read array of integer type
alpar@9 229 *
alpar@9 230 * This routine reads an integer array from the input text file, where
alpar@9 231 * name is array name, fmt is Fortran format specification that controls
alpar@9 232 * reading, n is number of array elements, val is array of integer type.
alpar@9 233 * If the array was read successful, the routine returns zero, otherwise
alpar@9 234 * non-zero. */
alpar@9 235
alpar@9 236 static int read_int_array(struct dsa *dsa, char *name, char *fmt,
alpar@9 237 int n, int val[])
alpar@9 238 { int k, pos;
alpar@9 239 char str[80+1];
alpar@9 240 if (parse_fmt(dsa, fmt)) return 1;
alpar@9 241 if (!(dsa->fmt_f == 'I' && dsa->fmt_w <= 80 &&
alpar@9 242 dsa->fmt_k * dsa->fmt_w <= 80))
alpar@9 243 { xprintf(
alpar@9 244 "%s:%d: can't read array `%s' - invalid format `%s'\n",
alpar@9 245 dsa->fname, dsa->seqn, name, fmt);
alpar@9 246 return 1;
alpar@9 247 }
alpar@9 248 for (k = 1, pos = INT_MAX; k <= n; k++, pos++)
alpar@9 249 { if (pos >= dsa->fmt_k)
alpar@9 250 { if (read_card(dsa)) return 1;
alpar@9 251 pos = 0;
alpar@9 252 }
alpar@9 253 memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w);
alpar@9 254 str[dsa->fmt_w] = '\0';
alpar@9 255 strspx(str);
alpar@9 256 if (str2int(str, &val[k]))
alpar@9 257 { xprintf(
alpar@9 258 "%s:%d: can't read array `%s' - invalid value `%s'\n",
alpar@9 259 dsa->fname, dsa->seqn, name, str);
alpar@9 260 return 1;
alpar@9 261 }
alpar@9 262 }
alpar@9 263 return 0;
alpar@9 264 }
alpar@9 265
alpar@9 266 /***********************************************************************
alpar@9 267 * read_real_array - read array of real type
alpar@9 268 *
alpar@9 269 * This routine reads a real array from the input text file, where name
alpar@9 270 * is array name, fmt is Fortran format specification that controls
alpar@9 271 * reading, n is number of array elements, val is array of real type.
alpar@9 272 * If the array was read successful, the routine returns zero, otherwise
alpar@9 273 * non-zero. */
alpar@9 274
alpar@9 275 static int read_real_array(struct dsa *dsa, char *name, char *fmt,
alpar@9 276 int n, double val[])
alpar@9 277 { int k, pos;
alpar@9 278 char str[80+1], *ptr;
alpar@9 279 if (parse_fmt(dsa, fmt)) return 1;
alpar@9 280 if (!(dsa->fmt_f != 'I' && dsa->fmt_w <= 80 &&
alpar@9 281 dsa->fmt_k * dsa->fmt_w <= 80))
alpar@9 282 { xprintf(
alpar@9 283 "%s:%d: can't read array `%s' - invalid format `%s'\n",
alpar@9 284 dsa->fname, dsa->seqn, name, fmt);
alpar@9 285 return 1;
alpar@9 286 }
alpar@9 287 for (k = 1, pos = INT_MAX; k <= n; k++, pos++)
alpar@9 288 { if (pos >= dsa->fmt_k)
alpar@9 289 { if (read_card(dsa)) return 1;
alpar@9 290 pos = 0;
alpar@9 291 }
alpar@9 292 memcpy(str, dsa->card + dsa->fmt_w * pos, dsa->fmt_w);
alpar@9 293 str[dsa->fmt_w] = '\0';
alpar@9 294 strspx(str);
alpar@9 295 if (strchr(str, '.') == NULL && strcmp(str, "0"))
alpar@9 296 { xprintf("%s(%d): can't read array `%s' - value `%s' has no "
alpar@9 297 "decimal point\n", dsa->fname, dsa->seqn, name, str);
alpar@9 298 return 1;
alpar@9 299 }
alpar@9 300 /* sometimes lower case letters appear */
alpar@9 301 for (ptr = str; *ptr; ptr++)
alpar@9 302 *ptr = (char)toupper((unsigned char)*ptr);
alpar@9 303 ptr = strchr(str, 'D');
alpar@9 304 if (ptr != NULL) *ptr = 'E';
alpar@9 305 /* value may appear with decimal exponent but without letters
alpar@9 306 E or D (for example, -123.456-012), so missing letter should
alpar@9 307 be inserted */
alpar@9 308 ptr = strchr(str+1, '+');
alpar@9 309 if (ptr == NULL) ptr = strchr(str+1, '-');
alpar@9 310 if (ptr != NULL && *(ptr-1) != 'E')
alpar@9 311 { xassert(strlen(str) < 80);
alpar@9 312 memmove(ptr+1, ptr, strlen(ptr)+1);
alpar@9 313 *ptr = 'E';
alpar@9 314 }
alpar@9 315 if (str2num(str, &val[k]))
alpar@9 316 { xprintf(
alpar@9 317 "%s:%d: can't read array `%s' - invalid value `%s'\n",
alpar@9 318 dsa->fname, dsa->seqn, name, str);
alpar@9 319 return 1;
alpar@9 320 }
alpar@9 321 }
alpar@9 322 return 0;
alpar@9 323 }
alpar@9 324
alpar@9 325 HBM *hbm_read_mat(const char *fname)
alpar@9 326 { struct dsa _dsa, *dsa = &_dsa;
alpar@9 327 HBM *hbm = NULL;
alpar@9 328 dsa->fname = fname;
alpar@9 329 xprintf("hbm_read_mat: reading matrix from `%s'...\n",
alpar@9 330 dsa->fname);
alpar@9 331 dsa->fp = fopen(dsa->fname, "r");
alpar@9 332 if (dsa->fp == NULL)
alpar@9 333 { xprintf("hbm_read_mat: unable to open `%s' - %s\n",
alpar@9 334 dsa->fname, strerror(errno));
alpar@9 335 goto fail;
alpar@9 336 }
alpar@9 337 dsa->seqn = 0;
alpar@9 338 hbm = xmalloc(sizeof(HBM));
alpar@9 339 memset(hbm, 0, sizeof(HBM));
alpar@9 340 /* read the first heading card */
alpar@9 341 if (read_card(dsa)) goto fail;
alpar@9 342 memcpy(hbm->title, dsa->card, 72), hbm->title[72] = '\0';
alpar@9 343 strtrim(hbm->title);
alpar@9 344 xprintf("%s\n", hbm->title);
alpar@9 345 memcpy(hbm->key, dsa->card+72, 8), hbm->key[8] = '\0';
alpar@9 346 strspx(hbm->key);
alpar@9 347 xprintf("key = %s\n", hbm->key);
alpar@9 348 /* read the second heading card */
alpar@9 349 if (read_card(dsa)) goto fail;
alpar@9 350 if (scan_int(dsa, "totcrd", 0, 14, &hbm->totcrd)) goto fail;
alpar@9 351 if (scan_int(dsa, "ptrcrd", 14, 14, &hbm->ptrcrd)) goto fail;
alpar@9 352 if (scan_int(dsa, "indcrd", 28, 14, &hbm->indcrd)) goto fail;
alpar@9 353 if (scan_int(dsa, "valcrd", 42, 14, &hbm->valcrd)) goto fail;
alpar@9 354 if (scan_int(dsa, "rhscrd", 56, 14, &hbm->rhscrd)) goto fail;
alpar@9 355 xprintf("totcrd = %d; ptrcrd = %d; indcrd = %d; valcrd = %d; rhsc"
alpar@9 356 "rd = %d\n", hbm->totcrd, hbm->ptrcrd, hbm->indcrd,
alpar@9 357 hbm->valcrd, hbm->rhscrd);
alpar@9 358 /* read the third heading card */
alpar@9 359 if (read_card(dsa)) goto fail;
alpar@9 360 memcpy(hbm->mxtype, dsa->card, 3), hbm->mxtype[3] = '\0';
alpar@9 361 if (strchr("RCP", hbm->mxtype[0]) == NULL ||
alpar@9 362 strchr("SUHZR", hbm->mxtype[1]) == NULL ||
alpar@9 363 strchr("AE", hbm->mxtype[2]) == NULL)
alpar@9 364 { xprintf("%s:%d: matrix type `%s' not recognised\n",
alpar@9 365 dsa->fname, dsa->seqn, hbm->mxtype);
alpar@9 366 goto fail;
alpar@9 367 }
alpar@9 368 if (scan_int(dsa, "nrow", 14, 14, &hbm->nrow)) goto fail;
alpar@9 369 if (scan_int(dsa, "ncol", 28, 14, &hbm->ncol)) goto fail;
alpar@9 370 if (scan_int(dsa, "nnzero", 42, 14, &hbm->nnzero)) goto fail;
alpar@9 371 if (scan_int(dsa, "neltvl", 56, 14, &hbm->neltvl)) goto fail;
alpar@9 372 xprintf("mxtype = %s; nrow = %d; ncol = %d; nnzero = %d; neltvl ="
alpar@9 373 " %d\n", hbm->mxtype, hbm->nrow, hbm->ncol, hbm->nnzero,
alpar@9 374 hbm->neltvl);
alpar@9 375 /* read the fourth heading card */
alpar@9 376 if (read_card(dsa)) goto fail;
alpar@9 377 memcpy(hbm->ptrfmt, dsa->card, 16), hbm->ptrfmt[16] = '\0';
alpar@9 378 strspx(hbm->ptrfmt);
alpar@9 379 memcpy(hbm->indfmt, dsa->card+16, 16), hbm->indfmt[16] = '\0';
alpar@9 380 strspx(hbm->indfmt);
alpar@9 381 memcpy(hbm->valfmt, dsa->card+32, 20), hbm->valfmt[20] = '\0';
alpar@9 382 strspx(hbm->valfmt);
alpar@9 383 memcpy(hbm->rhsfmt, dsa->card+52, 20), hbm->rhsfmt[20] = '\0';
alpar@9 384 strspx(hbm->rhsfmt);
alpar@9 385 xprintf("ptrfmt = %s; indfmt = %s; valfmt = %s; rhsfmt = %s\n",
alpar@9 386 hbm->ptrfmt, hbm->indfmt, hbm->valfmt, hbm->rhsfmt);
alpar@9 387 /* read the fifth heading card (optional) */
alpar@9 388 if (hbm->rhscrd <= 0)
alpar@9 389 { strcpy(hbm->rhstyp, "???");
alpar@9 390 hbm->nrhs = 0;
alpar@9 391 hbm->nrhsix = 0;
alpar@9 392 }
alpar@9 393 else
alpar@9 394 { if (read_card(dsa)) goto fail;
alpar@9 395 memcpy(hbm->rhstyp, dsa->card, 3), hbm->rhstyp[3] = '\0';
alpar@9 396 if (scan_int(dsa, "nrhs", 14, 14, &hbm->nrhs)) goto fail;
alpar@9 397 if (scan_int(dsa, "nrhsix", 28, 14, &hbm->nrhsix)) goto fail;
alpar@9 398 xprintf("rhstyp = `%s'; nrhs = %d; nrhsix = %d\n",
alpar@9 399 hbm->rhstyp, hbm->nrhs, hbm->nrhsix);
alpar@9 400 }
alpar@9 401 /* read matrix structure */
alpar@9 402 hbm->colptr = xcalloc(1+hbm->ncol+1, sizeof(int));
alpar@9 403 if (read_int_array(dsa, "colptr", hbm->ptrfmt, hbm->ncol+1,
alpar@9 404 hbm->colptr)) goto fail;
alpar@9 405 hbm->rowind = xcalloc(1+hbm->nnzero, sizeof(int));
alpar@9 406 if (read_int_array(dsa, "rowind", hbm->indfmt, hbm->nnzero,
alpar@9 407 hbm->rowind)) goto fail;
alpar@9 408 /* read matrix values */
alpar@9 409 if (hbm->valcrd <= 0) goto done;
alpar@9 410 if (hbm->mxtype[2] == 'A')
alpar@9 411 { /* assembled matrix */
alpar@9 412 hbm->values = xcalloc(1+hbm->nnzero, sizeof(double));
alpar@9 413 if (read_real_array(dsa, "values", hbm->valfmt, hbm->nnzero,
alpar@9 414 hbm->values)) goto fail;
alpar@9 415 }
alpar@9 416 else
alpar@9 417 { /* elemental (unassembled) matrix */
alpar@9 418 hbm->values = xcalloc(1+hbm->neltvl, sizeof(double));
alpar@9 419 if (read_real_array(dsa, "values", hbm->valfmt, hbm->neltvl,
alpar@9 420 hbm->values)) goto fail;
alpar@9 421 }
alpar@9 422 /* read right-hand sides */
alpar@9 423 if (hbm->nrhs <= 0) goto done;
alpar@9 424 if (hbm->rhstyp[0] == 'F')
alpar@9 425 { /* dense format */
alpar@9 426 hbm->nrhsvl = hbm->nrow * hbm->nrhs;
alpar@9 427 hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double));
alpar@9 428 if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl,
alpar@9 429 hbm->rhsval)) goto fail;
alpar@9 430 }
alpar@9 431 else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'A')
alpar@9 432 { /* sparse format */
alpar@9 433 /* read pointers */
alpar@9 434 hbm->rhsptr = xcalloc(1+hbm->nrhs+1, sizeof(int));
alpar@9 435 if (read_int_array(dsa, "rhsptr", hbm->ptrfmt, hbm->nrhs+1,
alpar@9 436 hbm->rhsptr)) goto fail;
alpar@9 437 /* read sparsity pattern */
alpar@9 438 hbm->rhsind = xcalloc(1+hbm->nrhsix, sizeof(int));
alpar@9 439 if (read_int_array(dsa, "rhsind", hbm->indfmt, hbm->nrhsix,
alpar@9 440 hbm->rhsind)) goto fail;
alpar@9 441 /* read values */
alpar@9 442 hbm->rhsval = xcalloc(1+hbm->nrhsix, sizeof(double));
alpar@9 443 if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsix,
alpar@9 444 hbm->rhsval)) goto fail;
alpar@9 445 }
alpar@9 446 else if (hbm->rhstyp[0] == 'M' && hbm->mxtype[2] == 'E')
alpar@9 447 { /* elemental format */
alpar@9 448 hbm->rhsval = xcalloc(1+hbm->nrhsvl, sizeof(double));
alpar@9 449 if (read_real_array(dsa, "rhsval", hbm->rhsfmt, hbm->nrhsvl,
alpar@9 450 hbm->rhsval)) goto fail;
alpar@9 451 }
alpar@9 452 else
alpar@9 453 { xprintf("%s:%d: right-hand side type `%c' not recognised\n",
alpar@9 454 dsa->fname, dsa->seqn, hbm->rhstyp[0]);
alpar@9 455 goto fail;
alpar@9 456 }
alpar@9 457 /* read starting guesses */
alpar@9 458 if (hbm->rhstyp[1] == 'G')
alpar@9 459 { hbm->nguess = hbm->nrow * hbm->nrhs;
alpar@9 460 hbm->sguess = xcalloc(1+hbm->nguess, sizeof(double));
alpar@9 461 if (read_real_array(dsa, "sguess", hbm->rhsfmt, hbm->nguess,
alpar@9 462 hbm->sguess)) goto fail;
alpar@9 463 }
alpar@9 464 /* read solution vectors */
alpar@9 465 if (hbm->rhstyp[2] == 'X')
alpar@9 466 { hbm->nexact = hbm->nrow * hbm->nrhs;
alpar@9 467 hbm->xexact = xcalloc(1+hbm->nexact, sizeof(double));
alpar@9 468 if (read_real_array(dsa, "xexact", hbm->rhsfmt, hbm->nexact,
alpar@9 469 hbm->xexact)) goto fail;
alpar@9 470 }
alpar@9 471 done: /* reading has been completed */
alpar@9 472 xprintf("hbm_read_mat: %d cards were read\n", dsa->seqn);
alpar@9 473 fclose(dsa->fp);
alpar@9 474 return hbm;
alpar@9 475 fail: /* something wrong in Danish kingdom */
alpar@9 476 if (hbm != NULL)
alpar@9 477 { if (hbm->colptr != NULL) xfree(hbm->colptr);
alpar@9 478 if (hbm->rowind != NULL) xfree(hbm->rowind);
alpar@9 479 if (hbm->rhsptr != NULL) xfree(hbm->rhsptr);
alpar@9 480 if (hbm->rhsind != NULL) xfree(hbm->rhsind);
alpar@9 481 if (hbm->values != NULL) xfree(hbm->values);
alpar@9 482 if (hbm->rhsval != NULL) xfree(hbm->rhsval);
alpar@9 483 if (hbm->sguess != NULL) xfree(hbm->sguess);
alpar@9 484 if (hbm->xexact != NULL) xfree(hbm->xexact);
alpar@9 485 xfree(hbm);
alpar@9 486 }
alpar@9 487 if (dsa->fp != NULL) fclose(dsa->fp);
alpar@9 488 return NULL;
alpar@9 489 }
alpar@9 490
alpar@9 491 /***********************************************************************
alpar@9 492 * NAME
alpar@9 493 *
alpar@9 494 * hbm_free_mat - free sparse matrix in Harwell-Boeing format
alpar@9 495 *
alpar@9 496 * SYNOPSIS
alpar@9 497 *
alpar@9 498 * #include "glphbm.h"
alpar@9 499 * void hbm_free_mat(HBM *hbm);
alpar@9 500 *
alpar@9 501 * DESCRIPTION
alpar@9 502 *
alpar@9 503 * The hbm_free_mat routine frees all the memory allocated to the data
alpar@9 504 * structure containing a sparse matrix in the Harwell-Boeing format. */
alpar@9 505
alpar@9 506 void hbm_free_mat(HBM *hbm)
alpar@9 507 { if (hbm->colptr != NULL) xfree(hbm->colptr);
alpar@9 508 if (hbm->rowind != NULL) xfree(hbm->rowind);
alpar@9 509 if (hbm->rhsptr != NULL) xfree(hbm->rhsptr);
alpar@9 510 if (hbm->rhsind != NULL) xfree(hbm->rhsind);
alpar@9 511 if (hbm->values != NULL) xfree(hbm->values);
alpar@9 512 if (hbm->rhsval != NULL) xfree(hbm->rhsval);
alpar@9 513 if (hbm->sguess != NULL) xfree(hbm->sguess);
alpar@9 514 if (hbm->xexact != NULL) xfree(hbm->xexact);
alpar@9 515 xfree(hbm);
alpar@9 516 return;
alpar@9 517 }
alpar@9 518
alpar@9 519 /* eof */