home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / xspread3.0.zoo / matrix.c < prev    next >
C/C++ Source or Header  |  1994-04-29  |  34KB  |  1,006 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Command routines
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *
  10.  *        $Revision: 6.21 A $
  11.  *
  12.  *        Modified by Dan Coppersmith, 5/94
  13.  */
  14.  
  15. #include <sys/types.h>
  16. #include <ctype.h>
  17. #include "config.h"
  18. #ifdef DOINGX
  19. #include <stdio.h>
  20. #else
  21. #include <curses.h>
  22. #endif
  23.  
  24. #include "sc.h"
  25.  
  26. /* next two structures move to sc.h by Bob Parbs 12-92 */
  27. /*struct m_range_sd {             
  28.        int ssr,ser,ssc,sec;
  29.        int dsr,der,dsc,dec;
  30.       };*/
  31. /*struct m_range {
  32.        int sr,er,sc,ec;
  33.       };*/
  34. struct m_range_sd *rge_sd;
  35. struct m_range *rge_s1, *rge_s2, *rge_d;
  36.  
  37. /*#define MAXCOLS 702*/   /* temp adds by Bob Parbs 12-92 */
  38. /*#define MAXROWS 2500*/
  39.  
  40. #ifdef __STDC__
  41. void get_trans();
  42. struct m_range_sd *find_rge(char *);
  43. int convert(int, char [], int );
  44. void transpose(int, int, int, int, int, int);
  45. void get_add();
  46. struct m_range *findrge(char *);
  47. void addmatrix(int, int, int, int, int, int,int,int,int,int);
  48. void get_sub();
  49. void submatrix(int, int, int, int, int, int,int,int,int,int); 
  50. void get_mult();
  51. void multmatrix1(int, int, int, int, int, int,int ,int ,int ,int ); 
  52. void multmatrix(int , int , int , int , int , int ,int ,int ,int ,int ); 
  53. void get_invert(); 
  54. void invertmatrix(int , int , int , int , int , int ); 
  55. #endif
  56.  
  57. /***************************************************************************/
  58. /*                                                                         */
  59. /* The following function calculate the transpose matrix of the input one  */
  60. /*                                                                         */
  61. /*                                            -Fang Wang   12/91           */
  62. /***************************************************************************/
  63. /* REG_LEN moved to sc.h by Bob Parbs 12-92 */
  64. /*#define REG_LEN 28  length of input range string*/
  65. void get_trans()      /* void added by Bob Parbs 12-92 */
  66. {
  67.     char s[100];
  68.     struct m_range_sd *find_rge(), *rge_sd;
  69.     struct ent *dv1,*dv2,*v1,*v2;
  70.     int minsr, minsc;
  71.     int maxsr, maxsc;
  72.     int mindr, mindc;
  73.     int maxdr, maxdc;
  74.     int vr, vc;
  75.     int r, c;
  76.  
  77.   sprintf(s, "transpose [dest_range src_range] ");
  78.   get_str(s,REG_LEN);
  79.   rge_sd=find_rge(s);
  80.   /*check for input error*/
  81.   if (rge_sd == NULL) {
  82.       error ("Input syntax");
  83.       return;
  84.    } 
  85.     dv1=lookat(rge_sd->dsr,rge_sd->dsc);
  86.     dv2=lookat(rge_sd->der,rge_sd->dec);
  87.     v1=lookat(rge_sd->ssr,rge_sd->ssc);
  88.     v2=lookat(rge_sd->ser,rge_sd->sec);
  89.     mindr = dv1->row;
  90.     mindc = dv1->col;
  91.     maxdr = dv2->row;
  92.     maxdc = dv2->col;
  93.     if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r;
  94.     if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c;
  95.     maxsr = v2->row;
  96.     maxsc = v2->col;
  97.     minsr = v1->row;
  98.     minsc = v1->col;
  99.     if (minsr>maxsr) r = maxsr, maxsr = minsr, minsr = r;
  100.     if (minsc>maxsc) c = maxsc, maxsc = minsc, minsc = c;
  101.     /*if (maxdr >= MAXROWS  || maxdc >= MAXCOLS) {
  102.         error ("The table can't be any bigger");
  103.         return;
  104.     }*/   /* commented out by Bob Parbs 12-92 */
  105.     /*check for the matching of size of matrices*/
  106.     if (((maxsr-minsr) != (maxdc-mindc)) || ((maxsc-minsc) != (maxdr-mindr)))
  107.     {
  108.         error("Destination matrix range, source matrix range don't match");
  109.         return;
  110.     }
  111.     erase_area(mindr, mindc, maxdr, maxdc); /*clear the des. area*/
  112.     if (minsr == maxsr && minsc == maxsc) {
  113.         /* Source is a single cell */
  114.         for(vr = mindr; vr <= maxdr; vr++)
  115.             for (vc = mindc; vc <= maxdc; vc++)
  116.                 transpose(vr, vc, minsr, minsc, maxsr, maxsc);
  117.     } else if (minsr == maxsr) {
  118.         /* Source is a single row */
  119.         for (vc = mindc; vc <= maxdc; vc++)
  120.             transpose( mindr,vc, minsr, minsc, maxsr, maxsc);
  121.     } else if (minsc == maxsc) {
  122.         /* Source is a single column */
  123.         for (vr = mindr; vr <= maxdr; vr++)
  124.             transpose(vr, mindc, minsr, minsc, maxsr, maxsc);
  125.     } else {
  126.         /* Everything else */
  127.         transpose(mindr, mindc, minsr, minsc, maxsr, maxsc);
  128.     }
  129. }
  130.  
  131. /*#ifdef notdef  SILLY PEOPLE... */
  132. /***************************************************************************/
  133. /*                                                                         */
  134. /* The following function find the range upper left corner row,upper col   */
  135. /* and  bottom right corner row and col.                                   */
  136. /*                                                                         */
  137. /*                                            -Fang Wang   12/91           */
  138. /***************************************************************************/
  139.  
  140. /* ROWLIM, COLIM moved to sc.h by Bob Parbs 12-92 */
  141. /*#define ROWLIM 4 size of the array stores col label*/
  142. /*#define COLIM 3 size of the array stores row label*/
  143. struct m_range_sd *find_rge(s)
  144. char *s;
  145.  
  146. { char col[COLIM],row[ROWLIM];
  147.   int i, j, mtemp[9];
  148.   struct m_range_sd *rge_sd;
  149.  
  150.   for (i=0;i<=8;i++)
  151.      mtemp[i] = 0;
  152.   j = 0;
  153.   while (*s != '\0') {
  154.      i = 0;
  155.      if ((*s == ':') || (*s == ' '))  s++;
  156.      while (((*s <= 'Z') && (*s >= 'A')) || ((*s <= 'z') && (*s >= 'a')))
  157.           col[i++] = *(s++);
  158.      col[i] = '\0';
  159.      if ((strlen(col) == 0 ) || (strlen(col) > (COLIM-1)))
  160.          return(NULL);
  161.      mtemp[j++] = convert(26,col,strlen(col));
  162.      i = 0;
  163.      while ((*s<='9') && (*s>='0'))
  164.           row[i++] = *(s++);
  165.      row[i] = '\0';
  166.      if ((strlen(row) == 0 ) || (strlen(row) > (ROWLIM-1)))
  167.          return(NULL);
  168.      mtemp[j++] = convert(10,row,strlen(row));
  169.   } /* end of while*/
  170.   /* altered by Bob Parbs */
  171.   rge_sd = (struct m_range_sd *) scxmalloc(sizeof(struct m_range_sd));
  172.   rge_sd->dsc = mtemp[0];
  173.   rge_sd->dsr = mtemp[1];
  174.   rge_sd->dec = mtemp[2];
  175.   rge_sd->der = mtemp[3];
  176.   rge_sd->ssc = mtemp[4];
  177.   rge_sd->ssr = mtemp[5];
  178.   rge_sd->sec = mtemp[6];
  179.   rge_sd->ser = mtemp[7];
  180.   return(rge_sd);
  181. }
  182.  
  183. /***************************************************************************
  184.  *                                                                         *
  185.  *    Convert the col, row into integer.                                   *
  186.  *                                     -Fang Wang  12/91                   *
  187.  **************************************************************************/
  188.  
  189. int convert( base, s, size)
  190. int base,size;
  191. char s[];
  192.  
  193. { int val, i;
  194.   int temp;
  195.  
  196.   temp = 0;
  197.   val = 0;
  198.   for (i=0; (i<size) && (s[i] != '\0'); i++) {
  199.       if (((s[i]<='Z') && (s[i]>='A')) || ((s[i]<='z') && (s[i]>='a'))) {
  200.           if (islower(s[i]))
  201.                s[i] = toupper(s[i]);
  202.       val = (temp*base) + ( s[i]-'A');
  203.       temp = temp + 1;
  204.       }
  205.       else if ((s[i]<='9') && (s[i]>='0'))
  206.           val = (val*base) + (s[i]-'0');
  207.    }
  208.    return (val);
  209. }
  210. /*#endif*/
  211.  
  212. /***************************************************************************
  213.  *                                                                         *
  214.  *    Calculates the transpose matrix.                                     *
  215.  *                                                                         *
  216.  *                                     -Fang Wang  12/91                   *
  217.  **************************************************************************/
  218.  
  219.  
  220. void transpose(vr, vc, minsr, minsc, maxsr, maxsc) /* void added Bob Parbs */
  221. int vr, vc, minsr, minsc, maxsr, maxsc;
  222. {
  223.     register struct ent *p;
  224.     register struct ent *n;
  225.     register int sr, sc;
  226.     register int dr, dc;
  227.  
  228.     for (dc=vc, sr=minsr; sr<=maxsr; sr++, dc++) 
  229.        for (dr=vr, sc=minsc; sc<=maxsc; sc++, dr++) {
  230.             n = lookat (dr, dc);
  231.             (void) clearent(n);
  232.             if (p = *ATBL(tbl, sr, sc))
  233.                 copyent( n, p, dr - sr, dc - sc);
  234.         }
  235. }
  236.  
  237.  
  238. /***************************************************************************
  239.  *                                                                         *
  240.  *    Add two matrices.                                                    *
  241.  *                                                                         *
  242.  *                                     -Fang Wang  12/91                   *
  243.  ***************************************************************************/
  244.  
  245. /* TSSIZE move to sc.h Bob Parbs 12-92 */
  246. /*#define TSSIZE 15*/
  247. void get_add()       /* void added Bob Parbs 12-92 */
  248. {
  249.   char s[100];
  250.   struct m_range *findrge(),*rge_s1,*rge_s2,*rge_d;
  251.   struct ent *dmin,*dmax,*s1min,*s1max,*s2min,*s2max;
  252.   int mins1r, mins1c;
  253.   int maxs1r, maxs1c;
  254.   int mins2r, mins2c;
  255.   int maxs2r, maxs2c;
  256.   int mindr, mindc;
  257.   int maxdr, maxdc;
  258.   int vr, vc;
  259.   int r, c;
  260.  
  261. /*#ifdef notdef*/
  262.   sprintf(s,"1st matrix range:");
  263.   get_str(s,TSSIZE);
  264.   rge_s1 = findrge(s);
  265.   if (rge_s1 == NULL) {
  266.      error("Input syntax error");
  267.      return;
  268.   }
  269.   clearlines(0,0);
  270.   sprintf(s,"2nd matrix range:");
  271.   get_str(s,TSSIZE);
  272.   rge_s2 = findrge(s);
  273.   if (rge_s2 == NULL) {
  274.      error("Input syntax error");
  275.      return;
  276.   }
  277.   clearlines(0,0);
  278.   sprintf(s,"result matrix range:");
  279.   get_str(s,TSSIZE);
  280.   rge_d = findrge(s);
  281.   if (rge_d == NULL) {
  282.      error("Input syntax error");
  283.      return;
  284.   }
  285. /*#endif*/
  286.   dmin=lookat(rge_d->sr,rge_d->sc);
  287.   dmax=lookat(rge_d->er,rge_d->ec);
  288.   s1min=lookat(rge_s1->sr,rge_s1->sc);
  289.   s1max=lookat(rge_s1->er,rge_s1->ec);
  290.   s2min=lookat(rge_s2->sr,rge_s2->sc);
  291.   s2max=lookat(rge_s2->er,rge_s2->ec);
  292.   mindr=dmin->row;
  293.   mindc=dmin->col;
  294.   maxdr=dmax->row;
  295.   maxdc=dmax->col;
  296.   if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r;
  297.   if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c;
  298.   maxs1r = s1max->row;
  299.   maxs1c = s1max->col;
  300.   mins1r = s1min->row;
  301.   mins1c = s1min->col;
  302.   maxs2r = s2max->row;
  303.   maxs2c = s2max->col;
  304.   mins2r = s2min->row;
  305.   mins2c = s2min->col;
  306.   if (mins1r>maxs1r) r = maxs1r, maxs1r = mins1r, mins1r = r;
  307.   if (mins1c>maxs1c) c = maxs1c, maxs1c = mins1c, mins1c = c;
  308.   if (mins2r>maxs2r) r = maxs2r, maxs2r = mins2r, mins2r = r;
  309.   if (mins2c>maxs2c) c = maxs2c, maxs2c = mins2c, mins2c = c;
  310.   /*if (maxdr >= MAXROWS  ||
  311.          maxdc >= MAXCOLS) {
  312.      error ("The table can't be any bigger");
  313.      return;
  314.   }*/         /* commented out by Bob Parbs 12-92 */
  315.   if (((maxs1r-mins1r) != (maxs2r-mins2r)) ||
  316.                       ((maxs2c-mins2c) != (maxs1c-mins1c))) {
  317.       error("Size of two matrices don't match, can't be added");
  318.       return;
  319.      }
  320.   if (((maxs1r-mins1r) != (maxdr-mindr)) ||
  321.                       ((maxdc-mindc) != (maxs1c-mins1c))) {
  322.       error("Size of source and destination matrices don't match");
  323.       return;
  324.      }
  325.   erase_area(mindr, mindc, maxdr, maxdc);
  326.   if (mins1r == maxs1r && mins1c == maxs1c && mins2r == maxs2r &&
  327.         mins2c == maxs2c )  {
  328.         /* Source is a single cell */
  329.         for(vr = mindr; vr <= maxdr; vr++)
  330.             for (vc = mindc; vc <= maxdc; vc++)
  331.                addmatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,
  332.                                  mins2r, mins2c, maxs2r, maxs2c);
  333.     } else if (mins1r == maxs1r && mins2r == maxs2r) {
  334.         /* Source is a single row */
  335.         for (vr = mindr; vr <= maxdr; vr++)
  336.                addmatrix(vr,mindc, mins1r, mins1c, maxs1r, maxs1c,
  337.                                  mins2r, mins2c, maxs2r, maxs2c);
  338.     } else if (mins1c == maxs1c && mins2c == maxs2c ) {
  339.         /* Source is a single column */
  340.         for (vc = mindc; vc <= maxdc; vc++)
  341.            addmatrix(mindr, vc, mins1r, mins1c, maxs1r, maxs1c,
  342.                                  mins2r, mins2c, maxs2r, maxs2c);
  343.     } else {
  344.         /* Everything else */
  345.         addmatrix(mindr, mindc, mins1r, mins1c, maxs1r, maxs1c,
  346.                                  mins2r, mins2c, maxs2r, maxs2c);
  347.     }
  348. }
  349.  
  350. /*#ifdef notdef  SILLY */
  351. /***************************************************************************
  352.  *                                                                         *
  353.  *    Get range for when input one by one.                                 *
  354.  *                                                                         *
  355.  *                                     -Fang Wang  12/91                   *
  356.  ***************************************************************************/
  357. /* ROWLIM, COLIM moved to sc.h Bob Parbs 12-92 */
  358. /*#define ROWLIM 4*/
  359. /*#define COLIM 3*/
  360.  
  361. struct m_range *findrge(s)
  362. char *s;
  363.  
  364. { char col[COLIM],row[ROWLIM];
  365.   int i, j, mtemp[5];
  366.   struct m_range *rge;
  367.  
  368.   for (i=0;i<=4;i++)
  369.      mtemp[i] = 0;
  370.   j = 0;
  371.   while (*s != '\0') {
  372.      i = 0;
  373.      if (*s == ':')  s++;
  374.      while (((*s <= 'Z') && (*s >= 'A')) || ((*s <= 'z') && (*s >= 'a')))
  375.           col[i++] = *(s++);
  376.      col[i] = '\0';
  377.      if ((strlen(col) == 0 ) || (strlen(col) > (COLIM-1)))
  378.           return(NULL);
  379.      mtemp[j++] = convert(26,col,strlen(col));
  380.      i = 0;
  381.      while ((*s<='9') && (*s>='0'))
  382.           row[i++] = *(s++);
  383.      row[i] = '\0';
  384.      if ((strlen(row) == 0 ) || (strlen(row) > (ROWLIM-1)))
  385.          return(NULL);
  386.      mtemp[j++] = convert(10,row,strlen(row)); 
  387.   } /* end of while*/
  388.   /* altered by Bob Parbs 12-92 */
  389.   rge = (struct m_range *) scxmalloc(sizeof(struct m_range));
  390.   rge->sc = mtemp[0];
  391.   rge->sr = mtemp[1];
  392.   rge->ec = mtemp[2];
  393.   rge->er = mtemp[3];
  394.   return(rge);
  395. /*#endif*/
  396.  
  397. /***************************************************************************
  398.  *                                                                         *
  399.  *    Calculates addition of two matrices.                                 *
  400.  *                                                                         *
  401.  *                                     -Fang Wang  12/91                   *
  402.  ***************************************************************************/
  403.  
  404. /* Function now works 12-92 Bob Parbs */
  405.  
  406. /* MAXSS no longer needed Bob Parbs 12-92 */
  407. /*#define MAXSS 2000*/
  408. void addmatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c)
  409. /* void added Bob Parbs 12-92 */
  410. int vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c;
  411. {
  412.     register struct ent *p1,*p2;
  413.     register struct ent *n;
  414.     register int s1r, s1c, s2r, s2c;
  415.     register int dr, dc;
  416.     /*int i,j;*/    /* no longer needed B.P. */
  417.     /*int list1[MAXSS],list2[MAXSS];*/ /*commented out by Bob Parbs 12-92 */
  418.  
  419.     /* lists no longer needed as values added to dest as read */
  420.     /* used to only add int parts, now adds entire entries  Bob Parbs */
  421.  
  422.  
  423.     /* following loops to fill list1, list 2 no longer needed B.P. */ 
  424.      /*for (i=0;i<=MAXSS;i++)
  425.         {
  426.             list1[i] = 0;
  427.             list2[i] = 0;
  428.         } 
  429.      i = 0;
  430.      for (s1r=mins1r;s1r<=maxs1r;s1r++)
  431.         for (s1c=mins1c;s1c<=maxs1c;s1c++)
  432.             if ((p1 = *ATBL(tbl, s1r, s1c)) && p1->flags&is_valid)
  433.                    list1[i++] = p1->v;
  434.      j = 0;
  435.      for (s2r=mins2r;s2r<=maxs2r;s2r++)
  436.         for (s2c=mins2c;s2c<=maxs2c;s2c++)
  437.             if ((p2 = *ATBL(tbl, s2r, s2c)) && p2->flags&is_valid)
  438.                   list2[j++] = p2->v;
  439.      for (i=0;i<=MAXSS;i++)
  440.           list1[i] = list1[i] + list2[i];
  441.      i = 0;*/
  442.  
  443.      /* altered the following to add entries as read  Bob Parbs 12-92 */
  444.      /* add much shorter now and works correctly B.P. */
  445.  
  446.      for (dr=vr, s1r=mins1r,s2r=mins2r; s1r<=maxs1r; s1r++,dr++,s2r++)
  447.        for (dc=vc, s1c=mins1c,s2c=mins2c; s1c<=maxs1c; s1c++, dc++,s2c++) {
  448.             n = lookat (dr, dc);
  449.             (void) clearent(n);
  450.             if ((p2 = *ATBL(tbl,s2r,s2c))&&(p2->flags&is_valid)){
  451.             if ((p1 = *ATBL(tbl, s1r, s1c)) && (p1->flags&is_valid))
  452.                 {
  453.                    copyent( n, p1, dr - s1r, dc - s1c);
  454.                    n->v = (p1->v+p2->v);
  455.                  }}
  456.             }
  457. }
  458.  
  459. /***************************************************************************
  460.  *                                                                         *
  461.  *    Subtraction of two matrices.                                         *
  462.  *                                                                         *
  463.  *                                     -Fang Wang  12/91                   *
  464.  ***************************************************************************/
  465. /* TSSIZE moved to sc.h Bob Parbs 12-92 */
  466. /*#define TSSIZE 15*/
  467. void get_sub()    /* void added Bob Parbs 12-92 */
  468. {
  469.   char s[100];
  470.   struct m_range *findrgt(),*rge_s1,*rge_s2;
  471.   struct ent *dmin,*dmax,*s1min,*s1max,*s2min,*s2max;
  472.   int mins1r, mins1c;
  473.   int maxs1r, maxs1c;
  474.   int mins2r, mins2c;
  475.   int maxs2r, maxs2c;
  476.   int mindr, mindc;
  477.   int maxdr, maxdc;
  478.   int vr, vc;
  479.   int r, c;
  480.  
  481.   sprintf(s,"1st matrix range:");
  482.   get_str(s,TSSIZE);
  483.   rge_s1 = findrge(s);
  484.   if (rge_s1 == NULL ) {
  485.      error ("Input syntax error");
  486.      return;
  487.   }
  488.   clearlines(0,0);
  489.   sprintf(s,"2nd matrix range:");
  490.   get_str(s,TSSIZE);
  491.   rge_s2 = findrge(s);
  492.   if (rge_s2 == NULL ) {
  493.      error ("Input syntax error");
  494.      return;
  495.   }
  496.   clearlines(0,0);
  497.   sprintf(s,"result matrix range:");
  498.   get_str(s,TSSIZE);
  499.   rge_d = findrge(s);
  500.   if (rge_s2 == NULL ) {
  501.      error ("Input syntax error");
  502.      return;
  503.   }
  504.   dmin=lookat(rge_d->sr,rge_d->sc);
  505.   dmax=lookat(rge_d->er,rge_d->ec);
  506.   s1min=lookat(rge_s1->sr,rge_s1->sc);
  507.   s1max=lookat(rge_s1->er,rge_s1->ec);
  508.   s2min=lookat(rge_s2->sr,rge_s2->sc);
  509.   s2max=lookat(rge_s2->er,rge_s2->ec);
  510.   mindr=dmin->row;
  511.   mindc=dmin->col;
  512.   maxdr=dmax->row;
  513.   maxdc=dmax->col;
  514.   if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r;
  515.   if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c;
  516.   maxs1r = s1max->row;
  517.   maxs1c = s1max->col;
  518.   mins1r = s1min->row;
  519.   mins1c = s1min->col;
  520.   maxs2r = s2max->row;
  521.   maxs2c = s2max->col;
  522.   mins2r = s2min->row;
  523.   mins2c = s2min->col;
  524.   if (mins1r>maxs1r) r = maxs1r, maxs1r = mins1r, mins1r = r;
  525.   if (mins1c>maxs1c) c = maxs1c, maxs1c = mins1c, mins1c = c;
  526.   if (mins2r>maxs2r) r = maxs2r, maxs2r = mins2r, mins2r = r;
  527.   if (mins2c>maxs2c) c = maxs2c, maxs2c = mins2c, mins2c = c;
  528.   /*if (maxdr >= MAXROWS  ||
  529.          maxdc >= MAXCOLS) {
  530.      error ("The table can't be any bigger");
  531.      return;
  532.   }*/       /* commented out by Bob Parbs 12-92 */
  533.   if (((maxs1r-mins1r) != (maxs2r-mins2r)) ||
  534.                       ((maxs2c-mins2c) != (maxs1c-mins1c))) {
  535.       error("Size of two matrices don't match, can't be subtracted");
  536.       return;
  537.      }
  538.   if (((maxs1r-mins1r) != (maxdr-mindr)) ||
  539.                       ((maxdc-mindc) != (maxs1c-mins1c))) {
  540.       error("Size of source and destination matrices don't match");
  541.       return;
  542.      }
  543.   erase_area(mindr, mindc, maxdr, maxdc);
  544.     if (mins1r == maxs1r && mins1c == maxs1c && mins2r == maxs2r &&
  545.         mins2c == maxs2c )  {
  546.         /* Source is a single cell */
  547.         for(vr = mindr; vr <= maxdr; vr++)
  548.             for (vc = mindc; vc <= maxdc; vc++)
  549.                submatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,
  550.                                  mins2r, mins2c, maxs2r, maxs2c);
  551.     } else if (mins1r == maxs1r && mins2r == maxs2r) {
  552.         /* Source is a single row */
  553.         for (vr = mindr; vr <= maxdr; vr++)
  554.                submatrix(vr, mindc, mins1r, mins1c, maxs1r, maxs1c,
  555.                                  mins2r, mins2c, maxs2r, maxs2c);
  556.     } else if (mins1c == maxs1c && mins2c == maxs2c ) {
  557.         /* Source is a single column */
  558.         for (vc = mindc; vc <= maxdc; vc++)
  559.            submatrix(mindr, vc, mins1r, mins1c, maxs1r, maxs1c,
  560.                                  mins2r, mins2c, maxs2r, maxs2c);
  561.     } else {
  562.         /* Everything else */
  563.         submatrix(mindr, mindc, mins1r, mins1c, maxs1r, maxs1c,
  564.                                  mins2r, mins2c, maxs2r, maxs2c);
  565.     }
  566.  
  567. }
  568.  
  569. /***************************************************************************
  570.  *                                                                         *
  571.  *    Calculates Subtraction of two matrices.                              *
  572.  *                                                                         *
  573.  *                                     -Fang Wang  12/91                   *
  574.  ***************************************************************************/
  575.  
  576. /* Function now works 12-92 by Bob Parbs */
  577.  
  578. /* MAXSS no longer needed, similar changes as to addmatrix Bob Parbs 12-92 */
  579. /*#define MAXSS 2000*/
  580. void submatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c)
  581. /* void added Bob Parbs 12-92 */
  582. int vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c;
  583. {
  584.     register struct ent *p1,*p2;
  585.     register struct ent *n;
  586.     register int s1r, s1c, s2r, s2c;
  587.     register int dr, dc;
  588.     /*int i,j;*/                       /* no longer needed B.P. */
  589.     /*int list1[MAXSS],list2[MAXSS];*/ /* no longer needed B.P. */
  590.  
  591.     /* following loops to fill list1,list2 no longer needed Bob Parbs 12-92 */ 
  592.     /*for (i=0;i<=MAXSS;i++)
  593.         {
  594.             list1[i] = 0;
  595.             list2[i] = 0;
  596.         }
  597.     i = 0;
  598.     for (s1r=mins1r;s1r<=maxs1r;s1r++)
  599.         for (s1c=mins1c;s1c<=maxs1c;s1c++)
  600.             if ((p1 = *ATBL(tbl, s1r, s1c)) && p1->flags&is_valid)
  601.                    list1[i++] = p1->v;
  602.     j = 0;
  603.     for (s2r=mins2r;s2r<=maxs2r;s2r++)
  604.         for (s2c=mins2c;s2c<=maxs2c;s2c++)
  605.             if ((p2 = *ATBL(tbl, s2r, s2c)) && p2->flags&is_valid)
  606.                   list2[j++] = p2->v;
  607.     for (i=0;i<=MAXSS;i++)
  608.           list1[i] = list1[i] - list2[i];
  609.     i = 0;*/
  610.  
  611.     /* following loop modified to subtract entries as read Bob Parbs 12-92 */
  612.  
  613.     for (dr=vr, s1r=mins1r,s2r=mins2r; s1r<=maxs1r; s1r++,dr++,s2r++)
  614.        for (dc=vc, s1c=mins1c,s2c=mins2c; s1c<=maxs1c; s1c++, dc++,s2c++) {
  615.             n = lookat (dr, dc);
  616.             (void) clearent(n);
  617.             if ((p2 = *ATBL(tbl,s2r,s2c))&&(p2->flags&is_valid)){
  618.             if ((p1 = *ATBL(tbl, s1r, s1c)) && (p1->flags&is_valid))
  619.                 {
  620.                    copyent( n, p1, dr - s1r, dc - s1c);
  621.                    n->v = (p1->v-p2->v);
  622.                  }}
  623.             }
  624. }
  625. /***************************************************************************
  626.  *                                                                         *
  627.  *    Multiplication of two matrices.                                      *
  628.  *                                                                         *
  629.  *                                     -Fang Wang  12/91                   *
  630.  ***************************************************************************/
  631. /* TSSIZE moved to sc.h Bob Parbs 12-92*/
  632. /*#define TSSIZE 15*/
  633. void get_mult()     /* void added Bob Parbs 12-92 */
  634. {
  635.   char s[100];
  636.   struct m_range *findrge(),*rge_s1,*rge_s2,*rge_d;
  637.   struct ent *dmin,*dmax,*s1min,*s1max,*s2min,*s2max;
  638.   int mins1r, mins1c;
  639.   int maxs1r, maxs1c;
  640.   int mins2r, mins2c;
  641.   int maxs2r, maxs2c;
  642.   int mindr, mindc;
  643.   int maxdr, maxdc;
  644.   int vr, vc;
  645.   int r, c;
  646.  
  647.   sprintf(s,"1st matrix range:");
  648.   get_str(s,TSSIZE);
  649.   rge_s1 = findrge(s);
  650.   if (rge_s1 == NULL) {
  651.      error("Input syntax error");
  652.      return;
  653.   }
  654.   clearlines(0,0);
  655.   sprintf(s,"2nd matrix range:");
  656.   get_str(s,TSSIZE);
  657.   rge_s2 = findrge(s);
  658.   if (rge_s2 == NULL) {
  659.      error("Input syntax error");
  660.      return;
  661.   }
  662.   clearlines(0,0);
  663.   sprintf(s,"result matrix range:");
  664.   get_str(s,TSSIZE);
  665.   rge_d = findrge(s);
  666.   if (rge_d == NULL) {
  667.      error("Input syntax error");
  668.      return;
  669.   }
  670.   dmin=lookat(rge_d->sr,rge_d->sc);
  671.   dmax=lookat(rge_d->er,rge_d->ec);
  672.   s1min=lookat(rge_s1->sr,rge_s1->sc);
  673.   s1max=lookat(rge_s1->er,rge_s1->ec);
  674.   s2min=lookat(rge_s2->sr,rge_s2->sc);
  675.   s2max=lookat(rge_s2->er,rge_s2->ec);
  676.   mindr=dmin->row;
  677.   mindc=dmin->col;
  678.   maxdr=dmax->row;
  679.   maxdc=dmax->col;
  680.   if (mindr>maxdr) r = maxdr, maxdr = mindr, mindr = r;
  681.   if (mindc>maxdc) c = maxdc, maxdc = mindc, mindc = c;
  682.   maxs1r = s1max->row;
  683.   maxs1c = s1max->col;
  684.   mins1r = s1min->row;
  685.   mins1c = s1min->col;
  686.   maxs2r = s2max->row;
  687.   maxs2c = s2max->col;
  688.   mins2r = s2min->row;
  689.   mins2c = s2min->col;
  690.   if (mins1r>maxs1r) r = maxs1r, maxs1r = mins1r, mins1r = r;
  691.   if (mins1c>maxs1c) c = maxs1c, maxs1c = mins1c, mins1c = c;
  692.   if (mins2r>maxs2r) r = maxs2r, maxs2r = mins2r, mins2r = r;
  693.   if (mins2c>maxs2c) c = maxs2c, maxs2c = mins2c, mins2c = c;
  694.   /*if (maxdr >= MAXROWS  ||
  695.          maxdc >= MAXCOLS) {
  696.      error ("The table can't be any bigger");
  697.      return;
  698.   } */        /* commented out by Bob Parbs 12-92 */
  699.   if ((maxs1c-mins1c) != (maxs2r-mins2r))
  700.        {
  701.            error ("The size of two matrices doesn't match,cann't multply");
  702.            return;
  703.        }
  704.   if (((maxs1r-mins1r) != (maxdr-mindr)) ||
  705.                       ((maxdc-mindc) != (maxs2c-mins2c))) {
  706.       error("Size of source and destination matrices don't match");
  707.       return;
  708.      }
  709.   erase_area(mindr, mindc, maxdr, maxdc);
  710.     if (mins1r == maxs1r && mins1c == maxs1c && mins2r == maxs2r &&
  711.         mins2c == maxs2c )  {
  712.        /* Source is a single cell */
  713.         for(vr = mindr; vr <= maxdr; vr++)
  714.             for (vc = mindc; vc <= maxdc; vc++)
  715.               multmatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,
  716.                                  mins2r, mins2c, maxs2r, maxs2c);
  717.     }
  718. /* else if ((mins2c==maxs2c) && (mins1r != maxs1r)) {
  719.          for (vr=mindr;vr<=maxdr;vc++)
  720.               multmatrix1(vr,mindc,mins1r,mins1c,maxs1r,maxs1c, 
  721.                                       mins2r,mins2c,maxs2r,maxs2c);
  722.     }
  723. */
  724.  else {
  725.         /* Everything else */
  726.         multmatrix(mindr, mindc, mins1r, mins1c, maxs1r, maxs1c,
  727.                                  mins2r, mins2c, maxs2r, maxs2c);
  728.     }
  729. }
  730.  
  731.  
  732. /*
  733. #define MINMAX 25
  734. multmatrix1 (vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c)
  735. int vr,vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c;
  736. {
  737.     register struct ent *p1,*p2;
  738.     register struct ent *n;
  739.     register int s1r, s1c, s2r, s2c;
  740.     register int dr, dc;
  741.     double sum;
  742.     int i,j,k;
  743.     double list1[MINMAX][MINMAX];
  744.     int list2[MINMAX];
  745.     int list3[MINMAX];
  746.  
  747.     for (i=0;i<MINMAX;i++)
  748.       {
  749.           list2[MINMAX] = 0;
  750.           for (j=0;j<MINMAX;j++)
  751.               list1[i][j] = 0;
  752.       }
  753.      i = 0;
  754.      for (s1r=mins1r;s1r<=maxs1r;s1r++)
  755.        {
  756.         j = 0;
  757.         for (s1c=mins1c;s1c<=maxs1c;s1c++)
  758.             {
  759.                if ((p1 = *ATBL(tbl, s1r, s1c)) && p1->flags&is_valid)
  760.                     list1[i][j++] = p1->v;
  761.             }
  762.         i++;
  763.        }
  764.      j = 0;
  765.      for (s2r=mins2r;s2r<=maxs2r;s2r++)
  766.             if ((p2 = *ATBL(tbl, s2r, mins2c)) && p2->flags&is_valid)
  767.                   list2[j++] = p2->v;
  768.      for (i=0;i<MINMAX;i++)
  769.         {
  770.             sum = 0;
  771.             for (k=0;k<MINMAX;k++)
  772.                sum = sum + list1[i][k] * list2[k];
  773.             list3[i++] = sum;
  774.         }
  775.      i = 0;
  776.      for (dr=vr, s1r=mins1r; s1r<=maxs1r; s1r++,dr++)
  777.          {
  778.              n = lookat (dr, vc);
  779.             (void) clearent(n);
  780.             if ((p1 = *ATBL(tbl, s1r, mins1c)) && (p1->flags&is_valid))
  781.                 {
  782.                    copyent( n, p1, dr - s1r, dc - s1c);
  783.                    n->v = list3[i++];
  784.                  }
  785.        }
  786. }
  787.  
  788.  
  789. */
  790. /***************************************************************************
  791.  *                                                                         *
  792.  *    Calcultes Multiplication of two matrices.                            *
  793.  *                                                                         *
  794.  *                                     -Fang Wang  12/91                   *
  795.  ***************************************************************************/
  796. /* MINMAX moved to sc.h Bob Parbs 12-92 */
  797. /*#define MINMAX 25*/
  798. void multmatrix(vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c)
  799. /* void added Bob Parbs 12-92 */
  800. int vr, vc, mins1r, mins1c, maxs1r, maxs1c,mins2r,mins2c,maxs2r,maxs2c;
  801. {
  802.     register struct ent *p1,*p2;
  803.     register struct ent *n;
  804.     register int s1r, s1c, s2r, s2c;
  805.     register int dr, dc;
  806.     double sum;
  807.     int i,j,k;
  808.     double list1[MINMAX][MINMAX];
  809.     double list2[MINMAX][MINMAX];
  810.     double list3[MINMAX][MINMAX];
  811.  
  812.      for (i=0;i<MINMAX;i++)
  813.        for (j=0;j<MINMAX;j++)
  814.         {
  815.             list1[i][j] = 0;
  816.             list2[i][j] = 0;
  817.             list3[i][j] = 0;
  818.         }
  819.      i = 0;
  820.      for (s1r=mins1r;s1r<=maxs1r;s1r++)
  821.        {
  822.         j = 0;
  823.         for (s1c=mins1c;s1c<=maxs1c;s1c++) 
  824.                if ((p1 = *ATBL(tbl, s1r, s1c)) && p1->flags&is_valid)
  825.                     list1[i][j++] = p1->v;
  826.         i++;
  827.        }
  828.           
  829.      i = 0;
  830.      for (s2r=mins2r;s2r<=maxs2r;s2r++)
  831.        {
  832.          j = 0;
  833.          for (s2c=mins2c;s2c<=maxs2c;s2c++)
  834.             if ((p2 = *ATBL(tbl, s2r, s2c)) && p2->flags&is_valid)
  835.                   list2[i][j++] = p2->v;
  836.          i++;
  837.        }
  838.      for (i=0;i<MINMAX;i++)
  839.            for (j=0;j<MINMAX;j++)
  840.               {
  841.                  sum = 0;
  842.                  for (k=0;k<MINMAX;k++)
  843.                      sum = sum + (list1[i][k]) * (list2[k][j]);
  844.                  list3[i][j] = sum;
  845.                }
  846.      i = 0;
  847.      for (dr=vr, s1r=mins1r; s1r<=maxs1r; s1r++,dr++)
  848.        {
  849.           j = 0;
  850.           for (dc=vc, s1c=mins2c; s1c<=maxs2c; s1c++, dc++) {
  851.             n = lookat (dr, dc);
  852.             (void) clearent(n);
  853.             if ((p1 = *ATBL(tbl, s1r, s1c)) && (p1->flags&is_valid))
  854.                 {
  855.                    copyent( n, p1, dr - s1r, dc - s1c);
  856.                    n->v = list3[i][j++];
  857.                  }
  858.             }
  859.            i++;
  860.        }
  861. }
  862.  
  863.  
  864. /***************************************************************************
  865.  *                                                                         *
  866.  *    Invert the matrix.                                                    *
  867.  *                                                                         *
  868.  *                                     -Fang Wang  12/91                   *
  869.  ***************************************************************************/
  870. /* REG_LEN moved to sc.h Bob Parbs 12-92 */
  871. /*#define REG_LEN 28*/
  872. void get_invert()     /* void added Bob Parbs 12-92 */
  873. {
  874.   char s[100];
  875.   struct m_range_sd *find_rge();
  876.   struct ent *dv1,*dv2,*v1,*v2;
  877.   int minsr, minsc;
  878.   int maxsr, maxsc;
  879.   int mindr, mindc;
  880.   int maxdr, maxdc;
  881.   int vr, vc;
  882.   int r, c;
  883.  
  884.  
  885.   sprintf(s, "invert [dest_range src_range] ");
  886.   get_str(s,REG_LEN);
  887.   rge_sd=find_rge(s);
  888.   if (rge_sd == NULL) {
  889.       error("Input syntax error");
  890.       return;
  891.   }
  892.  
  893. /* FIXME-real stuff (use this, or something close...:-)
  894.         maxr = e->e.o.right->e.r.right.vp -> row;
  895.         maxc = e->e.o.right->e.r.right.vp -> col;
  896.         minr = e->e.o.right->e.r.left.vp -> row;
  897.         minc = e->e.o.right->e.r.left.vp -> col;
  898.         if (minr>maxr) r = maxr, maxr = minr, minr = r;
  899.         if (minc>maxc) c = maxc, maxc = minc, minc = c;
  900. */
  901.   dv1=lookat(rge_sd->dsr,rge_sd->dsc);
  902.   dv2=lookat(rge_sd->der,rge_sd->dec);
  903.   v1=lookat(rge_sd->ssr,rge_sd->ssc);
  904.   v2=lookat(rge_sd->ser,rge_sd->sec);
  905.   mindr = dv1->row;
  906.   mindc = dv1->col;
  907.   maxdr = dv2->row;
  908.   maxdc = dv2->col;
  909.   if (mindr>maxdr)
  910.   {    r = maxdr, maxdr = mindr, mindr = r;
  911.   }
  912.   if (mindc>maxdc)
  913.   {    c = maxdc, maxdc = mindc, mindc = c;
  914.   }
  915.   maxsr = v2->row;
  916.   maxsc = v2->col;
  917.   minsr = v1->row;
  918.   minsc = v1->col;
  919.   if (minsr>maxsr) r = maxsr, maxsr = minsr, minsr = r;
  920.   if (minsc>maxsc) c = maxsc, maxsc = minsc, minsc = c;
  921.   /*if (maxdr >= MAXROWS  ||
  922.          maxdc >= MAXCOLS) {
  923.      error ("The table can't be any bigger");
  924.      return;
  925.   }*/   /* commented out by Bob Parbs 12-92 */
  926.   if (((maxsr-minsr) != (maxdr-mindr)) ||
  927.                       ((maxdc-mindc) != (maxsc-minsc))) {
  928.       error("Size of source and destination matrices don't match");
  929.       return;
  930.      }
  931.   erase_area(mindr, mindc, maxdr, maxdc);
  932.   if (minsr == maxsr && minsc == maxsc) {
  933.         /* Source is a single cell */
  934.         for(vr = mindr; vr <= maxdr; vr++)
  935.             for (vc = mindc; vc <= maxdc; vc++)
  936.                invertmatrix(vr, vc, minsr, minsc, maxsr, maxsc);
  937.    } else {
  938.         /* Everything else */
  939.         invertmatrix(mindr, mindc, minsr, minsc, maxsr, maxsc);
  940.    }
  941. }
  942.  
  943. /***************************************************************************
  944.  *                                                                         *
  945.  *    Calcultes the inversion of the matrix.                               *
  946.  *                                                                         *
  947.  *                                     -Fang Wang  12/91                   *
  948.  ***************************************************************************/
  949. /* MAXROW, MAXCOL moved to sc.h Bob Parbs 12-92 */
  950. /*#define MAXROW 30*/
  951. /*#define MAXCOL 30*/
  952. void invertmatrix(vr, vc, minsr, minsc, maxsr, maxsc)/* void added Bob Parbs*/
  953. int vr, vc, minsr, minsc, maxsr, maxsc;
  954. {
  955.     register struct ent *p;
  956.     register struct ent *q;
  957.     register int sr, sc;
  958.     register int dr, dc;
  959.     double list[MAXROW][MAXCOL];
  960.     /* changed from MAXROWS, MAXCOLS B.P. */
  961.     int i,j,k,m,n;
  962.     int rowlim,collim;
  963.     double temp;
  964.    
  965.     for (i=0; i<((maxsr-minsr)*2+1); i++)
  966.       for (j=0; j<((maxsc-minsc)*2+1); j++)
  967.           list[i][j] = 0;
  968.     rowlim = maxsr-minsr+1;
  969.     collim = maxsc-minsc+1;
  970.     for (i=0;i<rowlim;i++)
  971.        for (j=0;j<collim;j++)
  972.           if (i==j)  list[i][j] = 1;
  973.  
  974.     for (i=0,sr=minsr;(i<rowlim) && (sr<=maxsr); i++,sr++)
  975.        for (j=collim,sc=minsc;(j<(2*collim)) && (sc<=maxsc); j++,sc++)
  976.            if ((p = *ATBL(tbl, sr, sc)) && p->flags&is_valid)
  977.                 list[i][j] = p->v;
  978.     for (j=collim; j<(2*collim); j++)  {
  979.         k = j-collim;
  980.         temp = list[k][j];
  981.         for (i=0; i<(2*collim); i++)
  982.             list[k][i] = list[k][i] / temp;
  983.         for (m=0; m < rowlim; m++)
  984.             for (n=0; n<(2*collim); n++)
  985.                if (( m != k ) && ( n != j )) 
  986.                   list[m][n] = list[m][n]-list[k][n]*list[m][j];
  987.     }
  988.     i = 0;
  989.     for (dr=vr, sr=minsr; sr<=maxsr; sr++,dr++)
  990.        {
  991.           j = 0;
  992.           for (dc=vc, sc=minsc; sc<=maxsc; sc++, dc++) {
  993.             q = lookat (dr, dc);
  994.             (void) clearent(q);
  995.             if ((p = *ATBL(tbl, sr, sc)) && (p->flags&is_valid))
  996.                 {
  997.                    copyent( q, p, dr - sr, dc - sc);
  998.                    q->v = list[i][j++];
  999.                  }
  1000.             }
  1001.            i++;
  1002.        }
  1003. }
  1004. /*#endif*/
  1005.