ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/rmtxop.c
(Generate patch)

Comparing ray/src/util/rmtxop.c (file contents):
Revision 2.13 by greg, Mon Aug 12 01:20:26 2019 UTC vs.
Revision 2.21 by greg, Tue Nov 21 01:30:20 2023 UTC

# Line 5 | Line 5 | static const char RCSid[] = "$Id$";
5   * General component matrix operations.
6   */
7  
8 #include <stdio.h>
8   #include <stdlib.h>
9   #include <errno.h>
10   #include "rtio.h"
# Line 15 | Line 14 | static const char RCSid[] = "$Id$";
14  
15   #define MAXCOMP         16              /* #components we support */
16  
18 static const char       stdin_name[] = "<stdin>";
19
17   /* unary matrix operation(s) */
18   typedef struct {
19          double          sca[MAXCOMP];           /* scalar coefficients */
# Line 29 | Line 26 | typedef struct {
26   /* matrix input source and requested operation(s) */
27   typedef struct {
28          const char      *inspec;                /* input specification */
29 +        RMPref          rmp;                    /* matrix preference */
30          RUNARYOP        preop;                  /* unary operation(s) */
31          RMATRIX         *mtx;                   /* original matrix if loaded */
32          int             binop;                  /* binary op with next (or 0) */
# Line 40 | Line 38 | int    verbose = 0;                    /* verbose reporting? */
38   static int
39   loadmatrix(ROPMAT *rop)
40   {
41 <        if (rop->mtx != NULL)
41 >        if (rop->mtx != NULL)           /* already loaded? */
42                  return(0);
43  
44 <        rop->mtx = rmx_load(rop->inspec == stdin_name ?
47 <                                (const char *)NULL : rop->inspec);
44 >        rop->mtx = rmx_load(rop->inspec, rop->rmp);
45          if (rop->mtx == NULL) {
46                  fputs(rop->inspec, stderr);
47                  fputs(": cannot load matrix\n", stderr);
# Line 140 | Line 137 | binaryop(const char *inspec, RMATRIX *mleft, int op, R
137  
138          if ((mleft == NULL) | (mright == NULL))
139                  return(NULL);
143
140          switch (op) {
141          case '.':                       /* concatenate */
142 <                mres = rmx_multiply(mleft, mright);
142 >                if (mleft->ncomp != mright->ncomp) {
143 >                        fputs(inspec, stderr);
144 >                        fputs(": # components do not match\n", stderr);
145 >                } else if (mleft->ncols != mright->nrows) {
146 >                        fputs(inspec, stderr);
147 >                        fputs(": mismatched dimensions\n",
148 >                                        stderr);
149 >                } else
150 >                        mres = rmx_multiply(mleft, mright);
151                  rmx_free(mleft);
152                  rmx_free(mright);
153                  if (mres == NULL) {
154                          fputs(inspec, stderr);
155 <                        if (mleft->ncols != mright->nrows)
152 <                                fputs(": mismatched dimensions for multiply\n",
153 <                                                stderr);
154 <                        else
155 <                                fputs(": concatenation failed\n", stderr);
155 >                        fputs(": concatenation failed\n", stderr);
156                          return(NULL);
157                  }
158                  if (verbose) {
# Line 229 | Line 229 | op_right2left(ROPMAT *mop)
229          int     rpos = 0;
230                                          /* find end of list */
231          while (mop[rpos].binop)
232 <                rpos++;
232 >                if (mop[rpos++].binop != '.') {
233 >                        fputs(
234 >                "Right-to-left evaluation only for matrix multiplication!\n",
235 >                                        stderr);
236 >                        return(NULL);
237 >                }
238          mright = loadop(mop+rpos);
239          while (rpos-- > 0) {
240                  if (mright == NULL)
241                          break;
242 <                mright = binaryop(mop[rpos].inspec,
242 >                mright = binaryop(mop[rpos+1].inspec,
243                                  loadop(mop+rpos), mop[rpos].binop, mright);
244          }
245          return(mright);
# Line 313 | Line 318 | main(int argc, char *argv[])
318          int     i;
319                                          /* get options and arguments */
320          for (i = 1; i < argc; i++) {
316                if (nmats >= nall)
317                        mop = grow_moparray(mop, nall += 2);
321                  if (argv[i][0] && !argv[i][1] &&
322                                  strchr(".+*/", argv[i][0]) != NULL) {
323 <                        if (mop[nmats].inspec == NULL || mop[nmats].binop) {
324 <                                fprintf(stderr, "%s: missing matrix argument\n",
325 <                                                argv[0]);
323 >                        if (!nmats || mop[nmats-1].binop) {
324 >                                fprintf(stderr,
325 >                        "%s: missing matrix argument before '%c' operation\n",
326 >                                                argv[0], argv[i][0]);
327                                  return(1);
328                          }
329 <                        mop[nmats++].binop = argv[i][0];
329 >                        mop[nmats-1].binop = argv[i][0];
330                  } else if (argv[i][0] != '-' || !argv[i][1]) {
331                          if (argv[i][0] == '-') {
332                                  if (stdin_used++) {
# Line 341 | Line 345 | main(int argc, char *argv[])
345                          int     n = argc-1 - i;
346                          switch (argv[i][1]) {   /* get option */
347                          case 'v':
348 <                                verbose = !verbose;
348 >                                verbose++;
349                                  break;
350                          case 'f':
351                                  switch (argv[i][2]) {
# Line 376 | Line 380 | main(int argc, char *argv[])
380                                          get_factors(mop[nmats].preop.cmat,
381                                                          n, argv+i+1);
382                                  break;
383 +                        case 'r':
384 +                                if (argv[i][2] == 'f')
385 +                                        mop[nmats].rmp = RMPreflF;
386 +                                else if (argv[i][2] == 'b')
387 +                                        mop[nmats].rmp = RMPreflB;
388 +                                else
389 +                                        goto userr;
390 +                                break;
391                          default:
392                                  fprintf(stderr, "%s: unknown operation '%s'\n",
393                                                  argv[0], argv[i]);
394                                  goto userr;
395                          }
396                  }
397 +                if (nmats >= nall)
398 +                        mop = grow_moparray(mop, nall += 2);
399          }
400          if (mop[0].inspec == NULL)      /* nothing to do? */
401                  goto userr;
402 +        if (mop[nmats-1].binop) {
403 +                fprintf(stderr,
404 +                        "%s: missing matrix argument after '%c' operation\n",
405 +                                argv[0], mop[nmats-1].binop);
406 +                return(1);
407 +        }
408                                          /* favor quicker concatenation */
409 <        mres = prefer_right2left(mop) ? op_right2left(mop) : op_left2right(mop);
410 <        if (!mres)
409 >        mop[nmats].mtx = prefer_right2left(mop) ? op_right2left(mop)
410 >                                                : op_left2right(mop);
411 >        if (mop[nmats].mtx == NULL)
412                  return(1);
413 +                                        /* apply trailing unary operations */
414 +        mop[nmats].inspec = "trailing_ops";
415 +        mres = loadop(mop+nmats);
416 +        if (mres == NULL)
417 +                return(1);
418                                          /* write result to stdout */
419          if (outfmt == DTfromHeader)
420                  outfmt = mres->dtype;
421 +        if ((outfmt == DTrgbe) & (mres->ncomp > 3))
422 +                outfmt = DTspec;
423          if (outfmt != DTascii)
424                  SET_FILE_BINARY(stdout);
425          newheader("RADIANCE", stdout);
# Line 404 | Line 432 | main(int argc, char *argv[])
432          return(0);
433   userr:
434          fprintf(stderr,
435 <        "Usage: %s [-v][-f[adfc][-t][-s sf .. | -c ce ..] m1 [.+*/] .. > mres\n",
435 >        "Usage: %s [-v][-f[adfc][-t][-s sf .. | -c ce ..][-rf|-rb] m1 [.+*/] .. > mres\n",
436                          argv[0]);
437          return(1);
438   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines