source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/sba-1.3/sba_crsm.c @ 37

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

Added original make3d

File size: 5.9 KB
Line 
1/////////////////////////////////////////////////////////////////////////////////
2////
3////  CRS sparse matrices manipulation routines
4////  Copyright (C) 2004  Manolis Lourakis (lourakis@ics.forth.gr)
5////  Institute of Computer Science, Foundation for Research & Technology - Hellas
6////  Heraklion, Crete, Greece.
7////
8////  This program is free software; you can redistribute it and/or modify
9////  it under the terms of the GNU General Public License as published by
10////  the Free Software Foundation; either version 2 of the License, or
11////  (at your option) any later version.
12////
13////  This program is distributed in the hope that it will be useful,
14////  but WITHOUT ANY WARRANTY; without even the implied warranty of
15////  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16////  GNU General Public License for more details.
17////
18///////////////////////////////////////////////////////////////////////////////////
19
20#include <stdio.h>
21#include <stdlib.h>
22
23#include "sba.h"
24
25static void sba_crsm_print(struct sba_crsm *sm, FILE *fp);
26static void sba_crsm_build(struct sba_crsm *sm, int *m, int nr, int nc);
27
28/* allocate a sparse CRS matrix */
29void sba_crsm_alloc(struct sba_crsm *sm, int nr, int nc, int nnz)
30{
31int msz;
32
33  sm->nr=nr;
34  sm->nc=nc;
35  sm->nnz=nnz;
36  msz=2*nnz+nr+1;
37  sm->val=(int *)malloc(msz*sizeof(int));  /* required memory is allocated in a single step */
38  if(!sm->val){
39    fprintf(stderr, "memory allocation request failed in sba_crsm_alloc() [nr=%d, nc=%d, nnz=%d]\n", nr, nc, nnz);
40    exit(1);
41  }
42  sm->colidx=sm->val+nnz;
43  sm->rowptr=sm->colidx+nnz;
44}
45
46/* free a sparse CRS matrix */
47void sba_crsm_free(struct sba_crsm *sm)
48{
49  sm->nr=sm->nc=sm->nnz=-1;
50  free(sm->val);
51  sm->val=sm->colidx=sm->rowptr=NULL;
52}
53
54static void sba_crsm_print(struct sba_crsm *sm, FILE *fp)
55{
56register int i;
57
58  fprintf(fp, "matrix is %dx%d, %d non-zeros\nval: ", sm->nr, sm->nc, sm->nnz);
59  for(i=0; i<sm->nnz; ++i)
60    fprintf(fp, "%d ", sm->val[i]);
61  fprintf(fp, "\ncolidx: ");
62  for(i=0; i<sm->nnz; ++i)
63    fprintf(fp, "%d ", sm->colidx[i]);
64  fprintf(fp, "\nrowptr: ");
65  for(i=0; i<=sm->nr; ++i)
66    fprintf(fp, "%d ", sm->rowptr[i]);
67  fprintf(fp, "\n");
68}
69
70/* build a sparse CRS matrix from a dense one. intended to serve as an example for sm creation */
71static void sba_crsm_build(struct sba_crsm *sm, int *m, int nr, int nc)
72{
73int nnz;
74register int i, j, k;
75
76  /* count nonzeros */
77  for(i=nnz=0; i<nr; ++i)
78    for(j=0; j<nc; ++j)
79      if(m[i*nc+j]!=0) ++nnz;
80
81  sba_crsm_alloc(sm, nr, nc, nnz);
82
83  /* fill up the sm structure */
84  for(i=k=0; i<nr; ++i){
85    sm->rowptr[i]=k;
86    for(j=0; j<nc; ++j)
87      if(m[i*nc+j]!=0){
88        sm->val[k]=m[i*nc+j];
89        sm->colidx[k++]=j;
90      }
91  }
92  sm->rowptr[nr]=nnz;
93}
94
95/* returns the index of the (i, j) element. No bounds checking! */
96int sba_crsm_elmidx(struct sba_crsm *sm, int i, int j)
97{
98register int low, high, mid;
99
100  low=sm->rowptr[i];
101  high=sm->rowptr[i+1]-1;
102
103  /* binary search for finding the element at column j */
104  while(low<=high){
105    if(j<sm->colidx[low] || j>sm->colidx[high]) return -1; /* not found */
106   
107    mid=(low+high)>>1; //(low+high)/2;
108    if(j<sm->colidx[mid])
109        high=mid-1;
110    else if(j>sm->colidx[mid])
111        low=mid+1;
112    else
113      return mid;
114  }
115
116  return -1; /* not found */
117}
118
119/* returns the number of nonzero elements in row i and
120 * fills up the vidxs and jidxs arrays with the val and column
121 * indexes of the elements found, respectively.
122 * vidxs and jidxs are assumed preallocated and of max. size sm->nc
123 */
124int sba_crsm_row_elmidxs(struct sba_crsm *sm, int i, int *vidxs, int *jidxs)
125{
126register int j, k;
127
128  for(j=sm->rowptr[i], k=0; j<sm->rowptr[i+1]; ++j, ++k){
129    vidxs[k]=j;
130    jidxs[k]=sm->colidx[j];
131  }
132
133  return k;
134}
135
136/* returns the number of nonzero elements in col j and
137 * fills up the vidxs and iidxs arrays with the val and row
138 * indexes of the elements found, respectively.
139 * vidxs and iidxs are assumed preallocated and of max. size sm->nr
140 */
141int sba_crsm_col_elmidxs(struct sba_crsm *sm, int j, int *vidxs, int *iidxs)
142{
143register int *nextrowptr=sm->rowptr+1;
144register int i, l;
145register int low, high, mid;
146
147  for(i=l=0; i<sm->nr; ++i){
148    low=sm->rowptr[i];
149    high=nextrowptr[i]-1;
150
151    /* binary search attempting to find an element at column j */
152    while(low<=high){
153      if(j<sm->colidx[low] || j>sm->colidx[high]) break; /* not found */
154
155      mid=(low+high)>>1; //(low+high)/2;
156      if(j<sm->colidx[mid])
157          high=mid-1;
158      else if(j>sm->colidx[mid])
159          low=mid+1;
160      else{ /* found */
161        vidxs[l]=mid;
162        iidxs[l++]=i;
163        break;
164      }
165    }
166  }
167
168  return l;
169}
170
171/* a more straighforward (but slower) implementation of the above function */
172/***
173int sba_crsm_col_elmidxs(struct sba_crsm *sm, int j, int *vidxs, int *iidxs)
174{
175register int i, k, l;
176
177  for(i=l=0; i<sm->nr; ++i)
178    for(k=sm->rowptr[i]; k<sm->rowptr[i+1]; ++k)
179      if(sm->colidx[k]==j){
180        vidxs[l]=k;
181        iidxs[l++]=i;
182      }
183
184  return l;
185}
186***/
187
188#if 0
189
190/* sample code using the above routines */
191
192main()
193{
194int mat[7][6]={
195    {10, 0, 0, 0, -2, 0},
196    {3,  9, 0, 0,  0, 3},
197    {0,  7, 8, 7,  0, 0},
198    {3,  0, 8, 7,  5, 0},
199    {0,  8, 0, 9,  9, 13},
200    {0,  4, 0, 0,  2, -1},
201    {3,  7, 0, 9,  2, 0}
202};
203
204struct sba_crsm sm;
205int i, j, k, l;
206int vidxs[7], /* max(6, 7) */
207    jidxs[6], iidxs[7];
208
209
210  sba_crsm_build(&sm, mat[0], 7, 6);
211  sba_crsm_print(&sm, stdout);
212
213  for(i=0; i<7; ++i){
214    for(j=0; j<6; ++j)
215      printf("%3d ", ((k=sba_crsm_elmidx(&sm, i, j))!=-1)? sm.val[k] : 0);
216    printf("\n");
217  }
218
219  for(i=0; i<7; ++i){
220    k=sba_crsm_row_elmidxs(&sm, i, vidxs, jidxs);
221    printf("row %d\n", i);
222    for(l=0; l<k; ++l){
223      j=jidxs[l];
224      printf("%d %d  ", j, sm.val[vidxs[l]]);
225    }
226    printf("\n");
227  }
228
229  for(j=0; j<6; ++j){
230    k=sba_crsm_col_elmidxs(&sm, j, vidxs, iidxs);
231    printf("col %d\n", j);
232    for(l=0; l<k; ++l){
233      i=iidxs[l];
234      printf("%d %d  ", i, sm.val[vidxs[l]]);
235    }
236    printf("\n");
237  }
238
239  sba_crsm_free(&sm);
240}
241#endif
Note: See TracBrowser for help on using the repository browser.