ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rmtxop.c
Revision: 2.11
Committed: Mon Aug 28 15:59:46 2017 UTC (6 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +25 -6 lines
Log Message:
Added element-wise multiplication and division to rmtxop command

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.11 static const char RCSid[] = "$Id: rmtxop.c,v 2.10 2016/08/18 17:57:57 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * General component matrix operations.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10 greg 2.11 #include <errno.h>
11 greg 2.1 #include "rtio.h"
12     #include "resolu.h"
13     #include "rmatrix.h"
14 greg 2.10 #include "platform.h"
15 greg 2.1
16     #define MAXCOMP 50 /* #components we support */
17    
18     typedef struct {
19     double sca[MAXCOMP]; /* scalar coefficients */
20     int nsf; /* number of scalars */
21     double cmat[MAXCOMP*MAXCOMP]; /* component transformation */
22     int clen; /* number of coefficients */
23 greg 2.2 int transpose; /* do transpose? */
24 greg 2.1 int op; /* '*' or '+' */
25     } ROPERAT; /* matrix operation */
26    
27     int verbose = 0; /* verbose reporting? */
28    
29     static void
30     op_default(ROPERAT *op)
31     {
32     memset(op, 0, sizeof(ROPERAT));
33 greg 2.11 op->op = '.';
34 greg 2.1 }
35    
36     static RMATRIX *
37     operate(RMATRIX *mleft, ROPERAT *op, const char *fname)
38     {
39     RMATRIX *mright = rmx_load(fname);
40 greg 2.2 RMATRIX *mtmp;
41 greg 2.1 int i;
42    
43     if (fname == NULL)
44     fname = "<stdin>";
45     if (mright == NULL) {
46     fputs(fname, stderr);
47     fputs(": cannot load matrix\n", stderr);
48     return(NULL);
49     }
50 greg 2.2 if (op->transpose) { /* transpose matrix? */
51     mtmp = rmx_transpose(mright);
52     if (mtmp == NULL) {
53 greg 2.1 fputs(fname, stderr);
54     fputs(": transpose failed\n", stderr);
55     rmx_free(mright);
56     return(NULL);
57     }
58     if (verbose) {
59     fputs(fname, stderr);
60     fputs(": transposed rows and columns\n", stderr);
61     }
62 greg 2.2 rmx_free(mright);
63     mright = mtmp;
64 greg 2.1 }
65     if (op->nsf > 0) { /* apply scalar(s) */
66     if (op->clen > 0) {
67     fputs("Options -s and -c are exclusive\n", stderr);
68     rmx_free(mright);
69     return(NULL);
70     }
71     if (op->nsf == 1) {
72     for (i = mright->ncomp; --i; )
73     op->sca[i] = op->sca[0];
74     } else if (op->nsf != mright->ncomp) {
75     fprintf(stderr, "%s: -s must have one or %d factors\n",
76     fname, mright->ncomp);
77     rmx_free(mright);
78     return(NULL);
79     }
80     if ((mleft == NULL) | (op->op != '+') &&
81     !rmx_scale(mright, op->sca)) {
82     fputs(fname, stderr);
83     fputs(": scalar operation failed\n", stderr);
84     rmx_free(mright);
85     return(NULL);
86     }
87     if (verbose) {
88     fputs(fname, stderr);
89     fputs(": applied scalar (", stderr);
90     for (i = 0; i < op->nsf; i++)
91     fprintf(stderr, " %f", op->sca[i]);
92     fputs(" )\n", stderr);
93     }
94     }
95     if (op->clen > 0) { /* apply transform */
96     if (op->clen % mright->ncomp) {
97     fprintf(stderr, "%s: -c must have N x %d coefficients\n",
98     fname, mright->ncomp);
99     rmx_free(mright);
100     return(NULL);
101     }
102     mtmp = rmx_transform(mright, op->clen/mright->ncomp, op->cmat);
103     if (mtmp == NULL) {
104     fprintf(stderr, "%s: matrix transform failed\n", fname);
105     rmx_free(mright);
106     return(NULL);
107     }
108     if (verbose)
109     fprintf(stderr, "%s: applied %d x %d transform\n",
110     fname, mtmp->ncomp, mright->ncomp);
111     rmx_free(mright);
112     mright = mtmp;
113     }
114     if (mleft == NULL) /* just one matrix */
115     return(mright);
116 greg 2.11 if (op->op == '.') { /* concatenate */
117 greg 2.1 RMATRIX *mres = rmx_multiply(mleft, mright);
118     if (mres == NULL) {
119     fputs(fname, stderr);
120     if (mleft->ncols != mright->nrows)
121     fputs(": mismatched dimensions for multiply\n",
122     stderr);
123     else
124     fputs(": concatenation failed\n", stderr);
125     rmx_free(mright);
126     return(NULL);
127     }
128     if (verbose) {
129     fputs(fname, stderr);
130     fputs(": concatenated matrix\n", stderr);
131     }
132     rmx_free(mright);
133     rmx_free(mleft);
134     mleft = mres;
135     } else if (op->op == '+') {
136     if (!rmx_sum(mleft, mright, op->nsf ? op->sca : (double *)NULL)) {
137     fputs(fname, stderr);
138     fputs(": matrix sum failed\n", stderr);
139     rmx_free(mright);
140     return(NULL);
141     }
142     if (verbose) {
143     fputs(fname, stderr);
144     fputs(": added in matrix\n", stderr);
145     }
146     rmx_free(mright);
147 greg 2.11 } else if ((op->op == '*') | (op->op == '/')) {
148     const char * tnam = (op->op == '/') ?
149     "division" : "multiplication";
150     errno = 0;
151     if (!rmx_elemult(mleft, mright, (op->op == '/'))) {
152     fprintf(stderr, "%s: element-wise %s failed\n",
153     fname, tnam);
154     rmx_free(mright);
155     return(NULL);
156     }
157     if (errno)
158     fprintf(stderr,
159     "%s: warning - error during element-wise %s\n",
160     fname, tnam);
161     else if (verbose)
162     fprintf(stderr, "%s: element-wise %s\n", fname, tnam);
163     rmx_free(mright);
164 greg 2.1 } else {
165     fprintf(stderr, "%s: unknown operation '%c'\n", fname, op->op);
166     rmx_free(mright);
167     return(NULL);
168     }
169     return(mleft);
170     }
171    
172     static int
173     get_factors(double da[], int n, char *av[])
174     {
175     int ac;
176    
177     for (ac = 0; ac < n && isflt(av[ac]); ac++)
178     da[ac] = atof(av[ac]);
179     return(ac);
180     }
181    
182     /* Load one or more matrices and operate on them, sending results to stdout */
183     int
184     main(int argc, char *argv[])
185     {
186 greg 2.7 int outfmt = DTfromHeader;
187 greg 2.1 RMATRIX *mres = NULL;
188     ROPERAT op;
189     int i;
190     /* initialize */
191     op_default(&op);
192     /* get options and arguments */
193     for (i = 1; i < argc; i++)
194 greg 2.11 if (argv[i][0] && !argv[i][1] &&
195     strchr("+*/", argv[i][0]) != NULL) {
196     op.op = argv[i][0];
197 greg 2.1 } else if (argv[i][0] != '-' || !argv[i][1]) {
198     char *fname = NULL; /* load matrix */
199     if (argv[i][0] != '-')
200     fname = argv[i];
201     mres = operate(mres, &op, fname);
202     if (mres == NULL) {
203     fprintf(stderr, "%s: operation failed on '%s'\n",
204     argv[0], argv[i]);
205     return(0);
206     }
207     op_default(&op); /* reset operator */
208     } else {
209     int n = argc-1 - i;
210     switch (argv[i][1]) { /* get option */
211     case 'v':
212     verbose = !verbose;
213     break;
214     case 'f':
215     switch (argv[i][2]) {
216     case 'd':
217     outfmt = DTdouble;
218     break;
219     case 'f':
220     outfmt = DTfloat;
221     break;
222     case 'a':
223     outfmt = DTascii;
224     break;
225     case 'c':
226     outfmt = DTrgbe;
227     break;
228     default:
229     goto userr;
230     }
231     break;
232     case 't':
233 greg 2.2 op.transpose = 1;
234 greg 2.1 break;
235     case 's':
236     if (n > MAXCOMP) n = MAXCOMP;
237     op.nsf = get_factors(op.sca, n, argv+i+1);
238     i += op.nsf;
239     break;
240     case 'c':
241     if (n > MAXCOMP*MAXCOMP) n = MAXCOMP*MAXCOMP;
242     op.clen = get_factors(op.cmat, n, argv+i+1);
243     i += op.clen;
244     break;
245     default:
246     fprintf(stderr, "%s: unknown operation '%s'\n",
247     argv[0], argv[i]);
248     goto userr;
249     }
250     }
251     if (mres == NULL) /* check that we got something */
252     goto userr;
253     /* write result to stdout */
254 greg 2.6 if (outfmt == DTfromHeader)
255     outfmt = mres->dtype;
256 greg 2.4 if (outfmt != DTascii)
257 greg 2.10 SET_FILE_BINARY(stdout);
258 greg 2.1 newheader("RADIANCE", stdout);
259     printargs(argc, argv, stdout);
260 greg 2.5 if (!rmx_write(mres, outfmt, stdout)) {
261 greg 2.1 fprintf(stderr, "%s: error writing result matrix\n", argv[0]);
262     return(1);
263     }
264 greg 2.5 /* rmx_free(mres); mres = NULL; */
265 greg 2.1 return(0);
266     userr:
267     fprintf(stderr,
268 greg 2.11 "Usage: %s [-v][-f[adfc][-t][-s sf .. | -c ce ..] m1 [+*/] .. > mres\n",
269 greg 2.1 argv[0]);
270     return(1);
271     }