________________
| |
---------------- |
| | |
| Parent Table |_|
| |
----------------
/ Table Id [ptt1]
/ attr 1
/ attr 2
/ ....
\/ ....
________________ attr n
| |
---------------- |
| | |
| Child Table |_|
| |
----------------
Table Id [ptt1]
attr 1
attr 2
....
....
attr m
________________
| |
---------------- |
| | |
| Join Table |_|
| |
----------------
Table Id
Fkey Table 1
Fkey Table 2
attr 1
attr 2
....
....
attr p
p = parent,
c = child,
cfield = field in child table
pfield = field in parent table
join_2_loop(view_name, RO, EL, ROid, ROid, key_compare)
{
if(key_compare(&ROcurr->MAid, MAcurr) == 0)
{
JA_elt = pr_create(JA);
pr_set_key(JA_elt, MAid, ROcurr->MAid);
pr_set_key(JA_elt, ROid, ROcurr->ROid);
pr_set_int(JA_elt, rowndx, ROcurr->rowndx);
pr_set_key(JA_elt, ELid, ELcurr->ELid);
pr_set_key(JA_elt, COid, ELcurr->COid);
pr_set_int(JA_elt, evalue, ELcurr->evalue);
pr_add(view_name,JA,JA_elt);
}
}
join_2_loop(view_name, JA, CO, COid, COid, key_compare)
{
pr_set_key(JAcurr, COid, COcurr->COid);
pr_set_int(JAcurr, colndx, COcurr->colndx);
}
}
join_2_loop(view_name, CO, EL, COid, COid, key_compare)
{
if(key_compare(&COcurr->MAid, MAcurr) == 0)
{
JB_elt = pr_create(JB);
pr_set_key(JB_elt, MAid, COcurr->MAid);
pr_set_key(JB_elt, COid, COcurr->COid);
pr_set_int(JB_elt, colndx, COcurr->colndx);
pr_set_key(JB_elt, ELid, ELcurr->ELid);
pr_set_key(JB_elt, ROid, ELcurr->ROid);
pr_set_int(JB_elt, evalue, ELcurr->evalue);
pr_add(view_name,JB,JB_elt);
}
}
join_2_loop(view_name, JB, RO, ROid, ROid, key_compare)
{
pr_set_key(JBcurr, ROid, ROcurr->ROid);
pr_set_int(JBcurr, rowndx, ROcurr->rowndx);
}
}
1 2 3 10 40
4 5 6 20 50
30 60
Data File:MA010001 MATRIX_A 10 10 MA010002 MATRIX_B 10 10 RO010001 MA010001 1 RO010002 MA010001 2 RO010003 MA010002 1 RO010004 MA010002 2 RO010005 MA010002 3 CO010001 MA010001 1 CO010002 MA010001 2 CO010003 MA010001 3 CO010004 MA010002 1 CO010005 MA010002 2 EL010001 RO010001 CO010001 1 EL010002 RO010001 CO010002 2 EL010003 RO010001 CO010003 3 EL010004 RO010002 CO010001 4 EL010005 RO010002 CO010002 5 EL010006 RO010002 CO010003 6 EL010007 RO010003 CO010004 10 EL010008 RO010003 CO010005 20 EL010009 RO010004 CO010004 30 EL010010 RO010004 CO010005 40 EL010011 RO010005 CO010004 50 EL010012 RO010005 CO010005 60
/*-----------------------------------------------------------------------*/ /* University of Massachusetts Lowell */ /* Department of Computer Science */ /* */ /* */ /* File : newmatrixtest.c */ /* Summary: This file uses the files generated by chgen */ /*-----------------------------------------------------------------------*/ #define MAIN #include#include "matrix.h" struct MA *MA_elt; struct RO *RO_elt; struct CO *CO_elt; struct JA *JA_elt; struct JB *JB_elt; void InitSystem (char *, char *); void LoadDatabase (char *, char *); void PrintMatrices (char *); void MultiplyMatrices2 (char *, char *, char *, char *); void GetDimensions (char *, char *, int *, int *); void AddMatrix (char *, char *, int, int); void AddRow (char *, char *, int); void AddColumn (char *, char *, int); void AddElement (char *, char *, int, int, int); void JoinLoop2_MA (char *, char *); void JoinLoop2_MB (char *, char *); void FirstElmtJA (char *, char *); void FirstElmtJB (char *, char *); void AdvJAcurr (struct JA *); void AdvJBcurr (struct JB *); void main (int arc, char *argv[]) { char* view_name; InitSystem("matrix.viewdefs","matrix2.dat"); LoadDatabase("Matrices","matrix2.dat"); PrintMatrices("Matrices"); printf(" \n"); JoinLoop2_MA("Matrices", "MATRIX_A"); JoinLoop2_MB("Matrices", "MATRIX_B"); pr_dump("Matrices","matrix2a.dat",1,"w"); MultiplyMatrices2("Matrices","MATRIX_A","MATRIX_B","MATRIX_C"); pr_dump("NewMatrices","matrix2b.dat",1,"w"); PrintMatrices("Matrices"); printf("==== T H E E N D ====\n"); } /* main */ void InitSystem(view_defs, filename) char *view_defs, *filename; { printf("Initialization:\n"); printf("---------------\n"); pr_init(view_defs, filename); } /* InitSystem */ void LoadDatabase(view_name,filename) char *view_name, *filename; { printf("Load existing Database: %s\n",filename); pr_load(view_name,filename); printf("Finished loading existing database: %s\n\n",filename); } /* LoadDatabase */ void PrintMatrices(view_name) char *view_name; { table_loop(view_name, MA) { printf("\n\nMatrix: %s BY ROWS\n", MAcurr->mname); child_loop(MA, RO, ROid, MAid) { child_loop(RO, EL, ELid, ROid) { printf("ROW index: %d ", ROcurr->rowndx); printf("ELEMENT value: %d\n", ELcurr->evalue); } } printf("\n\nMatrix: %s BY COLUMNS\n", MAcurr->mname); child_loop(MA, CO, COid, MAid) { child_loop(CO, EL, ELid, COid) { printf("CO index: %d ", COcurr->colndx); printf("ELEMENT value: %d\n", ELcurr->evalue); } } } printf("\n"); } /* PrintMatrices */ void JoinLoop2_MA(view_name, filename) char *view_name, *filename; { find_str_loop(view_name, MA, mname, filename) { break; } join_2_loop(view_name, RO, EL, ROid, ROid, key_compare) { if(key_compare(&ROcurr->MAid, MAcurr) == 0) { JA_elt = pr_create(JA); pr_set_key(JA_elt, MAid, ROcurr->MAid); pr_set_key(JA_elt, ROid, ROcurr->ROid); pr_set_int(JA_elt, rowndx, ROcurr->rowndx); pr_set_key(JA_elt, ELid, ELcurr->ELid); pr_set_key(JA_elt, COid, ELcurr->COid); pr_set_int(JA_elt, evalue, ELcurr->evalue); pr_add(view_name,JA,JA_elt); } } join_2_loop(view_name, JA, CO, COid, COid, key_compare) { pr_set_key(JAcurr, COid, COcurr->COid); pr_set_int(JAcurr, colndx, COcurr->colndx); } } /* JoinLoop2_MA */ void JoinLoop2_MB(view_name, filename) char *view_name, *filename; { find_str_loop(view_name, MA, mname, filename) { break; } join_2_loop(view_name, CO, EL, COid, COid, key_compare) { if(key_compare(&COcurr->MAid, MAcurr) == 0) { JB_elt = pr_create(JB); pr_set_key(JB_elt, MAid, COcurr->MAid); pr_set_key(JB_elt, COid, COcurr->COid); pr_set_int(JB_elt, colndx, COcurr->colndx); pr_set_key(JB_elt, ELid, ELcurr->ELid); pr_set_key(JB_elt, ROid, ELcurr->ROid); pr_set_int(JB_elt, evalue, ELcurr->evalue); pr_add(view_name,JB,JB_elt); } } join_2_loop(view_name, JB, RO, ROid, ROid, key_compare) { pr_set_key(JBcurr, ROid, ROcurr->ROid); pr_set_int(JBcurr, rowndx, ROcurr->rowndx); } } /* JoinLoop2_MB */ void GetDimensions( view_name, matrix_name, nrow, ncol ) char *view_name, *matrix_name; int *nrow, *ncol; { table_loop(view_name, MA) { if ( !strcmp (matrix_name, MAcurr->mname) ) { *nrow = MAcurr->rowdim; *ncol = MAcurr->coldim; return; } } } /* GetDimensions */ void AddMatrix (view_name, matrix_name, nrow, ncol) char *view_name, *matrix_name; int nrow, ncol; { MA_elt = pr_create(MA); pr_set_str ( MA_elt, mname, matrix_name); pr_set_int ( MA_elt, rowdim, nrow); pr_set_int ( MA_elt, coldim, ncol); pr_add ( view_name, MA, MA_elt ); } /* AddMatrix */ void AddRow (view_name, matrix_name, nrow ) char *view_name, *matrix_name; int nrow; { RO_elt = pr_create(RO); pr_set_key ( RO_elt, MAid, pr_get_key(MA_elt, MAid) ); pr_set_int ( RO_elt, rowndx, nrow ); pr_add ( view_name, RO, RO_elt ); } /* AddRow */ void AddColumn (view_name, matrix_name, ncol ) char *view_name, *matrix_name; int ncol; { CO_elt = pr_create(CO); pr_set_key ( CO_elt, MAid, pr_get_key(MA_elt, MAid) ); pr_set_int ( CO_elt, colndx, ncol ); pr_add ( view_name, CO, CO_elt ); } /* AddColumn */ void AddElement(view_name, matrix_name, nrow, ncol, element) char *view_name, *matrix_name; int nrow, ncol, element; { struct EL *EL_elt = pr_create(EL); pr_set_key (EL_elt, ROid, pr_get_key(RO_elt, ROid)); pr_set_key (EL_elt, COid, pr_get_key(CO_elt, COid)); pr_set_int (EL_elt, evalue, element); /* pr_set_int (EL_elt, rowidx, nrow); pr_set_int (EL_elt, colidx, ncol); */ pr_add( view_name, EL, EL_elt); } /* AddElement */ void MultiplyMatrices2(view_name, matrix1, matrix2, matrix3) char *view_name, *matrix1, *matrix2, *matrix3; { int n, m, p, q, prod, s; struct JA *JAinit, *JAprev; struct JB *JBinit, *JBprev; GetDimensions(view_name, matrix1, &n,&p); GetDimensions(view_name, matrix2, &q,&m); if ( n==0 || m==0 || p==0 || q==0 || p!=q ) { printf("Error: Can'not multiply %s(%d,%d) by %s(%d,%d)", matrix1, n, p, matrix2, q, m); return; } AddMatrix(view_name, matrix3, n, m); FirstElmtJA(view_name, matrix1); FirstElmtJB(view_name, matrix2); JAinit = JAcurr; JBinit = JBcurr; prod = 0; while(JAcurr != NULL) /* begin row file */ { /* new row */ JAprev = JAcurr; JBcurr = JBinit; while(JBcurr != NULL) /* begin column file */ { /* new column */ JAcurr = JAprev; JBprev = JBcurr; while((JBcurr != NULL) && /* not eof cols */ (JAcurr != NULL) && /* not eof rows */ (JBcurr->colndx == JBprev->colndx) && /* same col? */ (JAcurr->rowndx == JAprev->rowndx)) /* same row? */ { /* same column */ /* check if there is a match */ if(JAcurr->colndx == JBcurr->rowndx) { prod += JAcurr->evalue * JBcurr->evalue; AdvJAcurr(JAcurr); AdvJBcurr(JBcurr); s = 0; } else { s = 1; if(JAcurr->colndx > JBcurr->rowndx) { AdvJBcurr(JBcurr); } else { AdvJAcurr(JAcurr); } } } /* while */ if(prod != 0 ) { /* add new row, col, evalue */ AddRow (view_name, matrix3, JAprev->rowndx); AddColumn (view_name, matrix3, JBprev->colndx); AddElement(view_name, matrix3, JAprev->rowndx, JBprev->colndx, prod); prod = 0; } if(JAcurr == NULL) { /* at eof of rows */ if(JBcurr == NULL) { /* at eof of cols */ break; } else { /* not at end of cols */ if((JBcurr->next_ptr == NULL) && (s == 0)) {/* already at end of col */ JBcurr = NULL; break; } if(JBcurr->colndx != JBprev->colndx) { /* already in new column */ /* break; */ } else { /* advance to next column */ while((JBcurr->colndx == JBprev->colndx) && (JBcurr->next_ptr != NULL)) { AdvJBcurr(JBcurr); } } } } else { /* not at eof of rows */ if(JBcurr == NULL) { /* at eof of cols */ while((JAcurr->rowndx == JAprev->rowndx) && (JAcurr->next_ptr != NULL)) { AdvJAcurr(JAcurr); } break; } else { /* not at eof of cols */ if((JBcurr->next_ptr == NULL) && (s == 1)) {/* already at end of col */ JBcurr = NULL; break; } if(JBcurr->colndx != JBprev->colndx) { /* already in new column */ /* don't do anything */ } else { /* advance to next column */ while((JBcurr->colndx == JBprev->colndx) && (JBcurr->next_ptr != NULL)) { AdvJBcurr(JBcurr); } } } } }/* end col file */ } /* end row file */ } /* MultiplyMatrices2 */ void FirstElmtJA(view_name, filename) char *view_name, *filename; { find_str_loop(view_name, MA, mname, filename) { break; } find_key_loop(view_name, JA, MAid, MAcurr->MAid) { break; } } /* FirstElmtJA */ void FirstElmtJB(view_name, filename) char *view_name, *filename; { find_str_loop(view_name, MA, mname, filename) { break; } find_key_loop(view_name, JB, MAid, MAcurr->MAid) { break; } } /* FirstElmtJB */ void AdvJAcurr(JAc) struct JA *JAc; { JAcurr = JAcurr->next_ptr; /* next elmt in row */ } /* AdvJAcurr */ void AdvJBcurr(JBc) struct JB *JBc; { JBcurr = JBcurr->next_ptr; /* next elmt in col */ } /* AdvJBcurr */
MA010001 MATRIX_A 10 10 MA010002 MATRIX_B 10 10 RO010001 MA010001 1 RO010002 MA010001 2 RO010003 MA010002 1 RO010004 MA010002 2 RO010005 MA010002 3 CO010001 MA010001 1 CO010002 MA010001 2 CO010003 MA010001 3 CO010004 MA010002 1 CO010005 MA010002 2 EL010001 RO010001 CO010001 1 EL010002 RO010001 CO010002 2 EL010003 RO010001 CO010003 3 EL010004 RO010002 CO010001 4 EL010005 RO010002 CO010002 5 EL010006 RO010002 CO010003 6 EL010007 RO010003 CO010004 10 EL010008 RO010003 CO010005 20 EL010009 RO010004 CO010004 30 EL010010 RO010004 CO010005 40 EL010011 RO010005 CO010004 50 EL010012 RO010005 CO010005 60 JA000001 MA010001 1 1 1 JA000002 MA010001 1 2 2 JA000003 MA010001 1 3 3 JA000004 MA010001 2 1 4 JA000005 MA010001 2 2 5 JA000006 MA010001 2 3 6 JB000007 MA010002 1 1 10 JB000008 MA010002 2 1 30 JB000009 MA010002 3 1 50 JB000010 MA010002 1 2 20 JB000011 MA010002 2 2 40 JB000012 MA010002 3 2 60Tables after computing the product of the matrices:
MA010001 MATRIX_A 10 10 MA010002 MATRIX_B 10 10 MA010003 MATRIX_C 10 10 RO010001 MA010001 1 RO010002 MA010001 2 RO010003 MA010002 1 RO010004 MA010002 2 RO010005 MA010002 3 RO010006 MA010003 1 RO010007 MA010003 1 RO010008 MA010003 2 RO010009 MA010003 2 CO010001 MA010001 1 CO010002 MA010001 2 CO010003 MA010001 3 CO010004 MA010002 1 CO010005 MA010002 2 CO010006 MA010003 1 CO010007 MA010003 2 CO010008 MA010003 1 CO010009 MA010003 2 EL010001 RO010001 CO010001 1 EL010002 RO010001 CO010002 2 EL010003 RO010001 CO010003 3 EL010004 RO010002 CO010001 4 EL010005 RO010002 CO010002 5 EL010006 RO010002 CO010003 6 EL010007 RO010003 CO010004 10 EL010008 RO010003 CO010005 20 EL010009 RO010004 CO010004 30 EL010010 RO010004 CO010005 40 EL010011 RO010005 CO010004 50 EL010012 RO010005 CO010005 60 EL010013 RO010006 CO010006 220 EL010014 RO010007 CO010007 280 EL010015 RO010008 CO010008 490 EL010016 RO010009 CO010009 640 JA000001 MA010001 EL010001 RO010001 CO010001 1 1 1 JA000002 MA010001 EL010002 RO010001 CO010002 1 2 2 JA000003 MA010001 EL010003 RO010001 CO010003 1 3 3 JA000004 MA010001 EL010004 RO010002 CO010001 2 1 4 JA000005 MA010001 EL010005 RO010002 CO010002 2 2 5 JA000006 MA010001 EL010006 RO010002 CO010003 2 3 6 JB000001 MA010002 EL010007 RO010003 CO010004 1 1 10 JB000002 MA010002 EL010009 RO010004 CO010004 2 1 30 JB000003 MA010002 EL010011 RO010005 CO010004 3 1 50 JB000004 MA010002 EL010008 RO010003 CO010005 1 2 20 JB000005 MA010002 EL010010 RO010004 CO010005 2 2 40 JB000006 MA010002 EL010012 RO010005 CO010005 3 2 60
Matrix: MATRIX_A
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 0 0 0 0 0 0 |
1 | 0 1 2 3 0 0 0 0 0 0 |
2 | 0 4 5 6 0 0 0 0 0 0 |
3 | 0 0 0 0 0 0 0 0 0 0 |
4 | 0 0 0 0 0 0 0 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 0 0 0 0 0 0 0 0 0 0 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 0 0 0 0 0 0 |
9 | 0 0 0 0 0 0 0 0 0 0 |
------------------------------------------
Matrix: MATRIX_B
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 0 0 0 0 0 0 |
1 | 0 10 20 0 0 0 0 0 0 0 |
2 | 0 30 40 0 0 0 0 0 0 0 |
3 | 0 50 60 0 0 0 0 0 0 0 |
4 | 0 0 0 0 0 0 0 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 0 0 0 0 0 0 0 0 0 0 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 0 0 0 0 0 0 |
9 | 0 0 0 0 0 0 0 0 0 0 |
------------------------------------------
Matrix: MATRIX_C
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 0 0 0 0 0 0 |
1 | 0 220 280 0 0 0 0 0 0 0 |
2 | 0 490 640 0 0 0 0 0 0 0 |
3 | 0 0 0 0 0 0 0 0 0 0 |
4 | 0 0 0 0 0 0 0 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 0 0 0 0 0 0 0 0 0 0 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 0 0 0 0 0 0 |
9 | 0 0 0 0 0 0 0 0 0 0 |
------------------------------------------
4.1. Description.
The join_3_loop macro is defined as a concurrent pair of child-loops over
two child-sets. The child tables contains respective fields, by which
the both tables are sorted, and whose equality is the join criterion.
The macro advances the pointers correctly when the join criterion is
not satisfied, and ends when one or both of the child tables have been
traversed completely. The following diagram shows a possible table
configuration where the join_3_loop macro is applicable.
--------- ----------
| ptt1 | | ptt2 |
| | | |
--------- ----------
\ /
\ /
\/ \/
------------
|ctt1/ctt2 |
|..........|
| f1/f2 |
------------
- "Initialize JOINMATCH (integer flag to indicate matching) to zero"
- for ( "Initialize pointers to child-tables";
"No end child-table1 and no end child-table2";
"Advance pointers to child-tables if necessary" )
if ( "Matching field-table1 with field-table2" )
v = var,
ptr = pointer,
p = parent,
c = child,
tt = table abbreviation,
pkey = primary key,
fkey = foreign key,
cfkey2p = child's fkey to parent,
pfkey2c = parent's fkey to child;
#define join_3_loop(ptt1,vpptr1,ptt2,vpptr2,ctt1,vcptr1,cfkey2p1,\
ctt2,vcptr2,cfkey2p2,f1,f2)\
for(vcptr1=vpptr1->ctt1##id_fcp, vcptr2=vpptr2->ctt2##id_fcp;\
((struct ptt1 *)vcptr1!=vpptr1) && ((struct ptt2 *)vcptr2!=vpptr2);\
(vcptr1 = (JOINMATCH || (vcptr1->f1 < vcptr2->f2))\
?(struct ctt1 *)vcptr1->cfkey2p1##_fpp : vcptr1),\
(vcptr2 = (JOINMATCH || (vcptr1->f1 > vcptr2->f2))\
?(struct ctt2 *)vcptr2->cfkey2p2##_fpp : vcptr2))\
if((JOINMATCH=(vcptr1->f1==vcptr2->f2)))
Declaration: int JOINMATCH=0;
Parameters:
ptt1 - parent table 1,
vpptr1 - variable parent pointer 1,
ptt2 - parent table 2,
vpptr2 - variable parent pointer 2,
ctt1 - child table 1,
vcptr1 - variable child pointer 1,
cfkey2p1 - child's foreign key to parent 1,
ctt2 - child table 2,
vcprt2 - variable child pointer 2,
cfkey2p2 - child's foreign key to parent 2,
f1 - field name child 1 to be matched,
f2 - field name child 2 to be matched.
A matrix product can be built by concurrently iterating over rows RO of
MAtrix1 and columns CO of MAtrix2, and for each RO,CO pair performing
the dot product by looping simultaneously over the RO->EL child set
and the CO->EL child set.
4.6.1 Data Schema Model.
The data schema model to represent sparse matrices is shown below.
------------
| MA |
|..........|
| MAid |
| mname |
| rowdim |
| coldim |
------------
| |
------------ -------------
| |
\/ \/
----------- ------------
| RO | | CO |
|.........| |..........|
| ROid | | COid |
| MAid | | MAid |
| rowndx | | colndx |
----------- ------------
| |
| |
------------- -------------
| |
\/ \/
-------------
| EL |
|...........|
| ELid |
| ROid |
| COid |
| evalue |
| rowidx |
| colidx |
-------------
MA010001 MATRIX_A 10 10 MA010002 MATRIX_B 10 10 RO010001 MA010001 1 RO010002 MA010001 3 RO010003 MA010001 6 RO010004 MA010002 0 RO010005 MA010002 2 RO010006 MA010002 3 RO010007 MA010002 4 RO010008 MA010002 8 RO010009 MA010002 9 CO010001 MA010001 0 CO010002 MA010001 2 CO010003 MA010001 3 CO010004 MA010001 4 CO010005 MA010001 5 CO010006 MA010001 8 CO010007 MA010001 9 CO010008 MA010002 0 CO010009 MA010002 4 CO010010 MA010002 6 EL010001 RO010001 CO010003 1 1 3 EL010002 RO010002 CO010001 2 3 0 EL010003 RO010002 CO010002 3 3 2 EL010004 RO010002 CO010004 4 3 4 EL010005 RO010002 CO010005 5 3 5 EL010006 RO010002 CO010006 6 3 8 EL010007 RO010002 CO010007 7 3 9 EL010008 RO010003 CO010001 8 6 0 EL010009 RO010003 CO010007 9 6 9 EL010010 RO010006 CO010008 30 3 0 EL010011 RO010004 CO010009 10 0 4 EL010012 RO010005 CO010009 20 2 4 EL010013 RO010008 CO010009 50 8 4 EL010014 RO010009 CO010009 60 9 4 EL010015 RO010007 CO010010 40 4 6
/*-----------------------------------------------------------------------*/ /* University of Massachusetts Lowell */ /* Department of Computer Science */ /* */ /* */ /* File : matrixtest.c */ /* Summary: This file uses the files generated by chgen */ /*-----------------------------------------------------------------------*/ #define MAIN #include#include "matrix.h" struct MA *MA_elt; struct RO *RO_elt; struct CO *CO_elt; void InitSystem (char *, char *); void LoadDatabase (char *, char *); void PrintMatrices (char *); void MultiplyMatrices (char *, char *, char *, char *); void GetDimensions (char *, char *, int *, int *); void AddMatrix (char *, char *, int, int); void AddRow (char *, char *, int); void AddColumn (char *, char *, int); void AddElement (char *, char *, int, int, int); void main (int arc, char *argv[]) { InitSystem("matrix.viewdefs","matrix.dat"); LoadDatabase("Matrices","matrix.dat"); PrintMatrices("Matrices"); MultiplyMatrices("Matrices","MATRIX_A","MATRIX_B","MATRIX_C"); PrintMatrices("Matrices"); } void InitSystem(view_defs, filename) char *view_defs, *filename; { printf("Initialization:\n"); printf("---------------\n"); pr_init(view_defs, filename); } void LoadDatabase(view_name,filename) char *view_name, *filename; { printf("Load existing Database: %s\n",filename); pr_load(view_name,filename); printf("Finished loading existing database: %s\n\n",filename); } void PrintMatrices(view_name) char *view_name; { table_loop(view_name, MA) { printf("\n\nMatrix: %s BY ROWS\n", MAcurr->mname); child_loop(MA, RO, ROid, MAid) { child_loop(RO, EL, ELid, ROid) { printf("ROW index: %d ", ROcurr->rowndx); printf("ELEMENT value: %d\n", ELcurr->evalue); } } printf("\n\nMatrix: %s BY COLUMNS\n", MAcurr->mname); child_loop(MA, CO, COid, MAid) { child_loop(CO, EL, ELid, COid) { printf("CO index: %d ", COcurr->colndx); printf("ELEMENT value: %d\n", ELcurr->evalue); } } } printf("\n"); } void MultiplyMatrices(view_name, matrix1, matrix2, matrix3) char *view_name, *matrix1, *matrix2, *matrix3; { int n, m, p, q; struct RO *ROcurr_aux; struct CO *COcurr_aux; struct EL *ELptr1, *ELptr2; struct MA *MAcurr_aux; GetDimensions(view_name, matrix1, &n,&p); GetDimensions(view_name, matrix2, &q,&m); if ( n==0 || m==0 || p==0 || q==0 || p!=q ) { printf("Error: Can'not multiply %s(%d,%d) by %s(%d,%d)", matrix1, n, p, matrix2, q, m); return; } AddMatrix(view_name, matrix3, n, m); table_loop(view_name, MA) { if ( !strcmp (matrix1, MAcurr->mname) ) { child_loop(MA, RO, ROid, MAid) { ROcurr_aux = ROcurr; MAcurr_aux = MAcurr; table_loop(view_name, MA) { if ( !strcmp (matrix2, MAcurr->mname) ) { child_loop(MA, CO, COid, MAid) { int dotprod=0, JOINMATCH=0; COcurr_aux = COcurr; join_3_loop(RO,ROcurr_aux,CO,COcurr_aux,\ EL,ELptr1,ROid,\ EL,ELptr2,COid,\ colidx,rowidx) { dotprod += ELptr1->evalue * ELptr2->evalue; } if ( dotprod != 0 ) { AddRow (view_name, matrix3, ROcurr->rowndx); AddColumn (view_name, matrix3, COcurr->colndx); AddElement(view_name, matrix3,ROcurr->rowndx, COcurr->colndx, dotprod); } COcurr = COcurr_aux; /*reset pointer to CO table */ } } } ROcurr = ROcurr_aux; /* reset pointer to RO table */ MAcurr = MAcurr_aux; /* reset pointer to MA table */ } } } } void GetDimensions( view_name, matrix_name, nrow, ncol ) char *view_name, *matrix_name; int *nrow, *ncol; { table_loop(view_name, MA) { if ( !strcmp (matrix_name, MAcurr->mname) ) { *nrow = MAcurr->rowdim; *ncol = MAcurr->coldim; return; } } } void AddMatrix (view_name, matrix_name, nrow, ncol) char *view_name, *matrix_name; int nrow, ncol; { MA_elt = pr_create(MA); pr_set_str ( MA_elt, mname, matrix_name); pr_set_int ( MA_elt, rowdim, nrow); pr_set_int ( MA_elt, coldim, ncol); pr_add ( view_name, MA, MA_elt ); } void AddRow (view_name, matrix_name, nrow ) char *view_name, *matrix_name; int nrow; { RO_elt = pr_create(RO); pr_set_key ( RO_elt, MAid, pr_get_key(MA_elt, MAid) ); pr_set_int ( RO_elt, rowndx, nrow ); pr_add ( view_name, RO, RO_elt ); } void AddColumn (view_name, matrix_name, ncol ) char *view_name, *matrix_name; int ncol; { CO_elt = pr_create(CO); pr_set_key ( CO_elt, MAid, pr_get_key(MA_elt, MAid) ); pr_set_int ( CO_elt, colndx, ncol ); pr_add ( view_name, CO, CO_elt ); } void AddElement(view_name, matrix_name, nrow, ncol, element) char *view_name, *matrix_name; int nrow, ncol, element; { struct EL *EL_elt = pr_create(EL); pr_set_key (EL_elt, ROid, pr_get_key(RO_elt, ROid)); pr_set_key (EL_elt, COid, pr_get_key(CO_elt, COid)); pr_set_int (EL_elt, evalue, element); pr_set_int (EL_elt, rowidx, nrow); pr_set_int (EL_elt, colidx, ncol); pr_add( view_name, EL, EL_elt); }
Matrix: MATRIX_A BY ROWS ROW index: 1 ELEMENT value: 1 ROW index: 3 ELEMENT value: 2 ROW index: 3 ELEMENT value: 3 ROW index: 3 ELEMENT value: 4 ROW index: 3 ELEMENT value: 5 ROW index: 3 ELEMENT value: 6 ROW index: 3 ELEMENT value: 7 ROW index: 6 ELEMENT value: 8 ROW index: 6 ELEMENT value: 9 Matrix: MATRIX_A BY COLUMNS CO index: 0 ELEMENT value: 2 CO index: 0 ELEMENT value: 8 CO index: 2 ELEMENT value: 3 CO index: 3 ELEMENT value: 1 CO index: 4 ELEMENT value: 4 CO index: 5 ELEMENT value: 5 CO index: 8 ELEMENT value: 6 CO index: 9 ELEMENT value: 7 CO index: 9 ELEMENT value: 9 Matrix: MATRIX_B BY ROWS ROW index: 0 ELEMENT value: 10 ROW index: 2 ELEMENT value: 20 ROW index: 3 ELEMENT value: 30 ROW index: 4 ELEMENT value: 40 ROW index: 8 ELEMENT value: 50 ROW index: 9 ELEMENT value: 60 Matrix: MATRIX_B BY COLUMNS CO index: 0 ELEMENT value: 30 CO index: 4 ELEMENT value: 10 CO index: 4 ELEMENT value: 20 CO index: 4 ELEMENT value: 50 CO index: 4 ELEMENT value: 60 CO index: 6 ELEMENT value: 40 Matrix: MATRIX_C BY ROWS ROW index: 1 ELEMENT value: 30 ROW index: 3 ELEMENT value: 800 ROW index: 3 ELEMENT value: 160 ROW index: 6 ELEMENT value: 620 Matrix: MATRIX_C BY COLUMNS CO index: 0 ELEMENT value: 30 CO index: 4 ELEMENT value: 800 CO index: 6 ELEMENT value: 160 CO index: 4 ELEMENT value: 620This output can logically be viewed as follows:
Matrix: MATRIX_A
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 0 0 0 0 0 0 |
1 | 0 0 0 1 0 0 0 0 0 0 |
2 | 0 0 0 0 0 0 0 0 0 0 |
3 | 2 0 3 0 4 5 0 0 6 7 |
4 | 0 0 0 0 0 0 0 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 8 0 0 0 0 0 0 0 0 9 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 0 0 0 0 0 0 |
9 | 0 0 0 0 0 0 0 0 0 0 |
------------------------------------------
Matrix: MATRIX_B
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 10 0 0 0 0 0 |
1 | 0 0 0 0 0 0 0 0 0 0 |
2 | 0 0 0 0 20 0 0 0 0 0 |
3 | 30 0 0 0 0 0 0 0 0 0 |
4 | 0 0 0 0 0 0 40 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 0 0 0 0 0 0 0 0 0 0 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 50 0 0 0 0 0 |
9 | 0 0 0 0 60 0 0 0 0 0 |
------------------------------------------
Matrix: MATRIX_C
0 1 2 3 4 5 6 7 8 9
------------------------------------------
0 | 0 0 0 0 0 0 0 0 0 0 |
1 | 30 0 0 0 0 0 0 0 0 0 |
2 | 0 0 0 0 0 0 0 0 0 0 |
3 | 0 0 0 0 800 0 160 0 0 0 |
4 | 0 0 0 0 0 0 0 0 0 0 |
5 | 0 0 0 0 0 0 0 0 0 0 |
6 | 0 0 0 0 620 0 0 0 0 0 |
7 | 0 0 0 0 0 0 0 0 0 0 |
8 | 0 0 0 0 0 0 0 0 0 0 |
9 | 0 0 0 0 0 0 0 0 0 0 |
------------------------------------------
5 References