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

Comparing ray/src/util/rmatrix.c (file contents):
Revision 2.91 by greg, Wed Apr 16 20:20:14 2025 UTC vs.
Revision 2.96 by greg, Thu Apr 17 23:30:16 2025 UTC

# Line 758 | Line 758 | rmx_transfer_data(RMATRIX *rdst, RMATRIX *rsrc, int do
758   int
759   rmx_transpose(RMATRIX *rm)
760   {
761 <        RMATRIX dnew;
762 <        int     i, j;
761 >        uby8            *bmap;
762 >        rmx_dtype       val[MAXCOMP];
763 >        RMATRIX         dold;
764 >        int             i, j;
765  
766          if (!rm || !rm->mtx | (rm->ncomp > MAXCOMP))
767                  return(0);
# Line 772 | Line 774 | rmx_transpose(RMATRIX *rm)
774                  return(1);
775          }
776          if (rm->nrows == rm->ncols) {   /* square matrix case */
777 <                rmx_dtype       val[MAXCOMP];
778 <                for (j = rm->ncols; j--; )
779 <                    for (i = rm->nrows; i--; ) {
780 <                        if (i == j) continue;
779 <                        memcpy(val, rmx_val(rm,i,j),
777 >             for (i = rm->nrows; i--; )
778 >                for (j = rm->ncols; j--; ) {
779 >                    if (i == j) continue;
780 >                    memcpy(val, rmx_val(rm,i,j),
781                                  sizeof(rmx_dtype)*rm->ncomp);
782 <                        memcpy(rmx_lval(rm,i,j), rmx_val(rm,j,i),
782 >                    memcpy(rmx_lval(rm,i,j), rmx_val(rm,j,i),
783                                  sizeof(rmx_dtype)*rm->ncomp);
784 <                        memcpy(rmx_val(rm,j,i), val,
784 >                    memcpy(rmx_val(rm,j,i), val,
785                                  sizeof(rmx_dtype)*rm->ncomp);
786 <                    }
786 >                }
787                  return(1);
788          }
789 <        memset(&dnew, 0, sizeof(dnew));
790 <        dnew.ncols = rm->nrows; dnew.nrows = rm->ncols;
791 <        dnew.ncomp = rm->ncomp;
792 <        if (!rmx_prepare(&dnew))
789 > #define bmbyte(r,c)     bmap[((r)*rm->ncols+(c))>>3]
790 > #define bmbit(r,c)      (1 << ((r)*rm->ncols+(c) & 7))
791 > #define bmop(r,c, op)   (bmbyte(r,c) op bmbit(r,c))
792 > #define bmtest(r,c)     bmop(r,c,&)
793 > #define bmset(r,c)      bmop(r,c,|=)
794 >                                        /* loop completion bitmap */
795 >        bmap = (uby8 *)calloc(((size_t)rm->nrows*rm->ncols+7)>>3, 1);
796 >        if (!bmap)
797                  return(0);
798 <        dnew.info = rm->info; rm->info = NULL;
799 <        dnew.dtype = rm->dtype;
800 <        copycolor(dnew.cexp, rm->cexp);
801 <        memcpy(dnew.wlpart, rm->wlpart, sizeof(dnew.wlpart));
802 <        for (j = dnew.ncols; j--; )
803 <            for (i = dnew.nrows; i--; )
804 <                memcpy(rmx_lval(&dnew,i,j), rmx_val(rm,j,i),
805 <                                sizeof(rmx_dtype)*dnew.ncomp);
806 <                                        /* and reassign result */
807 <        return(rmx_transfer_data(rm, &dnew, 1));
798 >        dold = *rm;
799 >        rm->ncols = dold.nrows; rm->nrows = dold.ncols;
800 >        for (i = rm->nrows; i--; )      /* try every starting point */
801 >            for (j = rm->ncols; j--; ) {
802 >                int     i0, j0;
803 >                int     i1 = i;
804 >                size_t  j1 = j;
805 >                if (bmtest(i, j))
806 >                        continue;       /* traversed loop earlier */
807 >                memcpy(val, rmx_val(rm,i,j),
808 >                        sizeof(rmx_dtype)*rm->ncomp);
809 >                for ( ; ; ) {           /* new transpose loop */
810 >                    const rmx_dtype     *ds;
811 >                    i0 = i1; j0 = j1;
812 >                    ds = rmx_val(&dold, j0, i0);
813 >                    j1 = (ds - dold.mtx)/dold.ncomp;
814 >                    i1 = j1 / rm->ncols;
815 >                    j1 -= (size_t)i1*rm->ncols;
816 >                    bmset(i1, j1);      /* mark as done */
817 >                    if ((i1 == i) & (j1 == j))
818 >                        break;          /* back at start */
819 >                    memcpy(rmx_lval(rm,i0,j0), ds,
820 >                                sizeof(rmx_dtype)*rm->ncomp);
821 >                }                       /* complete the loop */
822 >                memcpy(rmx_lval(rm,i0,j0), val,
823 >                        sizeof(rmx_dtype)*rm->ncomp);
824 >            }
825 >        free(bmap);                     /* all done! */
826 >        return(1);
827 > #undef  bmbyte
828 > #undef  bmbit
829 > #undef  bmop
830 > #undef  bmtest
831 > #undef  bmset
832   }
833  
834   /* Multiply (concatenate) two matrices and allocate the result */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines