source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/lightspeed/matfile.c @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 8.8 KB
Line 
1/* matfile utility program     
2 * Allows you to read and write MAT files from the command line.
3 * Useful for manipulating large data structures via a combination of
4 * unix and matlab commands.
5 * Run without arguments for a description of usage.
6 * The file test_matfile.mat is provided for you to play with.
7 *
8 * Thomas P Minka 3/25/99
9 * 1/29/00 added sparse matrices
10 */
11
12#include <stdio.h>
13#include <ctype.h>  /* for isspace() */
14#include "mat.h"
15
16#define Allocate(n,t) (t*)malloc((n)*sizeof(t))
17#define Reallocate(p, n, t) ((p)=(t*)realloc((p),(n)*sizeof(t)))
18
19void directory(MATFile *pmat)
20{
21  int i;
22#if 0
23  int ndir;
24  char **dir;
25  dir = matGetDir(pmat, &ndir);
26  if (dir == NULL) {
27    fprintf(stderr, "Error reading directory\n");
28    exit(1);
29  }
30  for (i=0; i < ndir; i++) {
31    printf("%s\n",dir[i]);
32  }
33#else
34  const char *name;
35  printf("Name\t\t  Size  \t     Bytes\tClass\n\n");
36  for (i=0;;i++) {
37    mxArray *pa = matGetNextVariableInfo(pmat, &name);
38    int ndims;
39    const int *dims;
40    int size;
41    if(pa == NULL) {
42      break;
43    }
44    printf("%-10s  ", name);
45    ndims = mxGetNumberOfDimensions(pa);
46    dims = mxGetDimensions(pa);
47    for(i=0;i<ndims;i++) {
48      if(i == 0) printf("%10d", dims[i]);
49      else printf("x%d", dims[i]);
50    }
51    if(mxIsSparse(pa)) {
52      size = mxGetNzmax(pa)*(mxGetElementSize(pa) + sizeof(int));
53      size += (mxGetN(pa)+1)*sizeof(int);
54    } 
55    else {
56      size = mxGetNumberOfElements(pa)*mxGetElementSize(pa);
57    }
58    printf("\t%10d", size);
59    printf("\t%s", mxGetClassName(pa));
60    if(mxIsFromGlobalWS(pa)) printf(" (global)");
61    printf("\n");
62  } 
63#endif
64}
65
66void extract(MATFile *pmat, char *var)
67{
68  mxArray *pa = matGetArray(pmat, var);
69  int ndims;
70  if(pa == NULL) {
71    fprintf(stderr, "There is no variable named %s\n", var);
72    exit(1);
73  }
74  ndims = mxGetNumberOfDimensions(pa);
75  if(ndims > 2) {
76    fprintf(stderr, "Cannot handle more than two dimensions.  Sorry.\n");
77    exit(1);
78  }
79  if(mxIsSparse(pa)) {
80    fprintf(stderr, "Cannot extract sparse matrices.  Sorry.\n");
81    exit(1);
82  }
83  if(mxIsComplex(pa)) {
84    fprintf(stderr, "Cannot extract complex matrices.  Sorry.\n");
85    exit(1);
86  }
87  if(mxIsDouble(pa)) {
88    int i, j;
89    const int *dims = mxGetDimensions(pa);
90    for(i=0;i<dims[0];i++) {
91      double *p = mxGetPr(pa) + i;
92      for(j=0;j<dims[1];j++) {
93        printf("%g ", *p);
94        p += dims[0];
95      }
96      printf("\n");
97    }
98  }
99  else {
100    fprintf(stderr, "Can only handle double-precision variables.  Sorry.\n");
101    exit(1);
102  }
103  mxFree(pa);
104}
105
106/****************************************************************************/
107
108typedef struct DoubleArray {
109  double *d;
110  int len, bufsize;
111} DoubleArray;
112
113DoubleArray *DoubleArray_Create(void) 
114{
115  DoubleArray *a = Allocate(1, struct DoubleArray);
116  a->bufsize = 32;
117  a->len = 0;
118  a->d = Allocate(a->bufsize, double);
119  return a;
120}
121
122void DoubleArray_Free(DoubleArray *a)
123{
124  free(a->d);
125  free(a);
126}
127
128void DoubleArray_Set(DoubleArray *a, int index, double value)
129{
130  if(index >= a->bufsize) {
131    do {
132      a->bufsize *= 2;
133    } while(index >= a->bufsize);
134    Reallocate(a->d, a->bufsize, double);
135  }
136  if(index >= a->len) a->len = index+1;
137  a->d[index] = value;
138}
139
140/****************************************************************************/
141
142typedef struct IntArray {
143  int *d;
144  int len, bufsize;
145} IntArray;
146
147IntArray *IntArray_Create(void) 
148{
149  IntArray *a = Allocate(1, struct IntArray);
150  a->bufsize = 32;
151  a->len = 0;
152  a->d = Allocate(a->bufsize, int);
153  return a;
154}
155
156void IntArray_Free(IntArray *a)
157{
158  free(a->d);
159  free(a);
160}
161
162void IntArray_Set(IntArray *a, int index, int value)
163{
164  if(index >= a->bufsize) {
165    do {
166      a->bufsize *= 2;
167    } while(index >= a->bufsize);
168    Reallocate(a->d, a->bufsize, int);
169  }
170  if(index >= a->len) a->len = index+1;
171  a->d[index] = value;
172}
173
174/****************************************************************************/
175
176typedef void ScanFunc(int r, int c, double d, void *info);
177
178void scan(int *rows_return, int *cols_return, ScanFunc *f, void *info)
179{
180  int rows, cols, i;
181  double d;
182  FILE *fp = stdin;
183
184  /* Use the first line to determine the number of columns */
185  for(i=0;;) {
186    int c = getc(fp);
187    if(c == '\n') break;
188    if(isspace(c)) continue;
189    ungetc(c, fp);
190    if(fscanf(fp, "%lg", &d) < 1) {
191      fprintf(stderr, "scan failed: expected a real number\n");
192      goto error;
193    }
194    f(0, i, d, info);
195    i++;
196  }
197  cols = i;
198 
199  /* Read the rest of the lines */
200  for(rows=1;;rows++) {
201    int j;
202    for(j = 0; j < cols; j++) {
203      if(fscanf(fp, "%lg", &d) < 1) {
204        if(!feof(fp)) {
205          fprintf(stderr, "scan failed: expected a real number\n");
206          goto error;
207        }
208        else if(j > 0) {
209          fprintf(stderr, "scan failed: unexpected end of file\n");
210          goto error;
211        }
212        break;
213      }
214      f(rows, j, d, info);
215    }
216    if(feof(fp)) break;
217  }
218  *rows_return = rows;
219  *cols_return = cols;
220error:
221  return;
222}
223
224void transpose(double *dest, double *src, int rows, int cols)
225{
226  double *dest_save = dest;
227  int i,j;
228  for(i=0;i<rows;i++) {
229    dest = dest_save + i;
230    for(j=0;j<cols;j++) {
231      *dest = *src++;
232      dest += rows;
233    }
234  }
235}
236
237struct FullInfo {
238  DoubleArray *a;
239  int index;
240};
241
242void ScanFull(int r, int c, double d, struct FullInfo *info)
243{
244  DoubleArray_Set(info->a, info->index++, d);
245}
246
247struct SparseInfo {
248  DoubleArray *data;
249  IntArray *ir, *jc;
250  int next_row;
251  int index;
252};
253
254void ScanSparse(int r, int c, double d, struct SparseInfo *info)
255{
256  if(d == 0) return;
257  DoubleArray_Set(info->data, info->index, d);
258  IntArray_Set(info->ir, info->index, c);
259  /* start of new row? */
260  if(r >= info->next_row) {
261    /* fill in all rows up to r */
262    for(; info->next_row <= r; info->next_row++) {
263      IntArray_Set(info->jc, info->next_row, info->index);
264    }
265  }
266  info->index++;
267}
268
269void update(MATFile *pmat, char *var, int global, int sparse)
270{
271  int rows, cols, status;
272  mxArray *pa;
273  if(sparse) {
274    int nzmax;
275    struct SparseInfo *info = Allocate(1, struct SparseInfo);
276    info->index = 0;
277    info->next_row = 0;
278    info->data = DoubleArray_Create();
279    info->ir = IntArray_Create();
280    info->jc = IntArray_Create();
281
282    scan(&rows, &cols, (ScanFunc*)ScanSparse, info);
283    /* fill out jc */
284    for(; info->next_row <= rows; info->next_row++) {
285      IntArray_Set(info->jc, info->next_row, info->index);
286    }
287    /* note rows and cols are swapped */
288    nzmax = info->index;
289    if(rows > nzmax) nzmax = rows;
290    pa = mxCreateSparse(cols, rows, nzmax, mxREAL);
291    memcpy(mxGetPr(pa), info->data->d, info->index*sizeof(double));
292    memcpy(mxGetIr(pa), info->ir->d, info->index*sizeof(int));
293    memcpy(mxGetJc(pa), info->jc->d, (rows+1)*sizeof(int));
294
295    DoubleArray_Free(info->data);
296    IntArray_Free(info->ir);
297    IntArray_Free(info->jc);
298    free(info);
299  }
300  else {
301    struct FullInfo *info = Allocate(1, struct FullInfo);
302    info->a = DoubleArray_Create();
303    info->index = 0;
304    scan(&rows, &cols, (ScanFunc*)ScanFull, info);
305    pa = mxCreateDoubleMatrix(rows, cols, mxREAL);
306    transpose(mxGetPr(pa), info->a->d, rows, cols);
307    DoubleArray_Free(info->a);
308    free(info);
309  }
310  mxSetName(pa, var);
311  if(global) status = matPutArrayAsGlobal(pmat, pa);
312  else status = matPutArray(pmat, pa);
313  if(status) {
314    fprintf(stderr, "matPutArray failed\n");
315    exit(1);
316  }
317}
318
319void delete(MATFile *pmat, char *var)
320{
321  if(matDeleteArray(pmat, var)) {
322    fprintf(stderr, "matDeleteArray failed\n");
323    exit(1);
324  }
325}
326
327void printUsage(void)
328{
329  fprintf(stderr, "matfile utility program by Thomas P Minka\n");
330  fprintf(stderr, "\nusage: matfile cmd file [var]\n\n");
331  fprintf(stderr, "cmd is one of\n");
332  fprintf(stderr, "\tt\tList the contents of file\n");
333  fprintf(stderr, "\tx\tExtract var and print on stdout\n");
334  fprintf(stderr, "\tu\tUpdate var from stdin\n");
335  fprintf(stderr, "\tug\tSame as u but make var global\n");
336  fprintf(stderr, "\tus\tSame as u but make var sparse (result will be transposed)\n");
337  fprintf(stderr, "\td\tDelete var\n");
338  exit(1);
339}
340
341int main(int argc, char *argv[])
342{
343  MATFile *pmat;
344  char *cmd, *file;
345
346  if(argc < 3) {
347    printUsage();
348  }
349  cmd = argv[1];
350  file = argv[2];
351
352  if((cmd[0] == 'u') || (cmd[0] == 'd')) {
353    pmat = matOpen(file, "u");
354    if((pmat == NULL) && (cmd[0] == 'u')) {
355      pmat = matOpen(file, "w");
356    }
357  }
358  else {
359    pmat = matOpen(file, "r");
360  }
361  if(pmat == NULL) {
362    fprintf(stderr, "Cannot open file %s: ", file);
363    perror("");
364    exit(1);
365  }
366
367  switch(cmd[0]) {
368  case 't':
369    if(argc != 3) printUsage();
370    directory(pmat);
371    break;
372  case 'x':
373    if(argc != 4) printUsage();
374    extract(pmat, argv[3]);
375    break;
376  case 'u':
377    if(argc != 4) printUsage();
378    update(pmat, argv[3], cmd[1] == 'g', cmd[1] == 's');
379    break;
380  case 'd':
381    if(argc != 4) printUsage();
382    delete(pmat, argv[3]);
383    break;
384  default:
385    fprintf(stderr, "Unknown command `%s'\n", cmd);
386  }
387
388  matClose(pmat);
389  exit(0);
390}
Note: See TracBrowser for help on using the repository browser.