Changeset: e2f972312557 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=e2f972312557
Modified Files:
        monetdb5/modules/mal/Tests/array04.mal
        monetdb5/modules/mal/array.mx
Branch: sciql
Log Message:

Addition of the embedding operator
The mapping of one array into another is derived. This can be used
to prepare an array for tiled aggregation.


diffs (143 lines):

diff --git a/monetdb5/modules/mal/Tests/array04.mal 
b/monetdb5/modules/mal/Tests/array04.mal
--- a/monetdb5/modules/mal/Tests/array04.mal
+++ b/monetdb5/modules/mal/Tests/array04.mal
@@ -1,4 +1,4 @@
-# tiling operations
+# tiling operations over fixed arrays
 
 #create array v(i int dimension[0:1:4], payload:int)
 v:= array.series(0,1,6,1,1);
@@ -35,3 +35,20 @@
 
 gs:= array.sum(mv,template);
 io.print(gs);
+
+# first create the larger array N[-1:1:5][-1:1:5]
+nx:= array.series(-1,1,5,6,1);
+ny:= array.series(-1,1,5,1,6);
+nv:= array.filler(nx,nil:int);
+io.print(nx,ny,nv);
+
+#derive the mapping from cell id in N into M
+map:= array.embed(nx,ny,mx,my);
+io.print(map);
+rv:= array.replace(nv,map,mv);
+
+#now produce the tiled sum over the enlarged one
+template:= array.map(nx,ny,t0,t1);
+io.print(template);
+gs:= array.sum(nv,template);
+io.print(gs);
diff --git a/monetdb5/modules/mal/array.mx b/monetdb5/modules/mal/array.mx
--- a/monetdb5/modules/mal/array.mx
+++ b/monetdb5/modules/mal/array.mx
@@ -98,6 +98,15 @@
 address ARRAYtilesSum
 comment "Construct the sum over all tiles";
 
+pattern sum(cells:bat[:oid,:any_1], template:bat[:oid,:oid]):bat[:oid,:any_1]
+address ARRAYtilesSum
+comment "Construct the sum over all tiles, but take also care of the 
boundaries in each dimension,
+which is expressed in the number of eligible cells.";
+
+pattern embed(shapes:bat[:oid,:any]...):bat[:oid,:oid]
+address ARRAYembed
+comment "Take two shapes N and M and derive a mapping between the elements 
based on the index values.
+It can be used to create an embedding of values from one array into another.";
 @- Implementation
 @include ../mal/prelude.mx
 @h
@@ -132,6 +141,7 @@
 array_export str ARRAYreplaceScalar(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr p);
 array_export str ARRAYtiles(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 array_export str ARRAYtilesSum(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
+array_export str ARRAYembed(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 
 @= array_defs
 array_export str ARRAYseries_@1(int *ret, @1 *start, @1 *step, @1 *stop, int 
*grp, int *series);
@@ -583,6 +593,7 @@
                BBPreleaseref(b->batCacheid);
                throw(MAL, "array.tiles", RUNTIME_OBJECT_MISSING);
        }
+
        bn = BATnew(TYPE_oid, TYPE_@1, TRUE);
        bi = bat_iterator(b);
        br = bat_iterator(bt);
@@ -608,6 +619,10 @@
        BBPreleaseref(bt->batCacheid);
        return MAL_SUCCEED;
 }
+@-
+The compilating factor is that in general the tile enumeration is dense, while
+the tile structure can go over its boundaries. For this to control, we first
+embed the array into a slightly larger array, filled with nulls.
 
 @c
 @:tilesAggr(sht)@
@@ -634,6 +649,66 @@
        }
        return MAL_SUCCEED;
 }
+
+str
+ARRAYembed(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+{
+       BAT **b, *bn = NULL, *bo;
+       int i,n = 0, error = FALSE;
+
+       (void) cntxt;
+       (void) mb;
+       if ( (pci->argc - pci->retc) % 2 != 0)
+               throw(MAL, "array.map", "Unbalanced index arguments");
+
+       b= (BAT**) GDKzalloc(sizeof(BAT*) * pci->argc-pci->retc);
+       if( b == NULL)
+               throw(MAL, "array.embed", MAL_MALLOC_FAIL);
+
+       for ( i=pci->retc; i< pci->argc; i++){
+               if ((b[n++] = BATdescriptor(*(int*)getArgReference(stk,pci,i))) 
== NULL) {
+                       for ( n--; n>= 0; n--)
+                               BBPreleaseref(b[n]->batCacheid);
+                       GDKfree(b);
+                       throw(MAL, "array.embed", RUNTIME_OBJECT_MISSING);
+               }
+       }
+       /* type check the shapes and prepare iterators */
+       for ( i= 0; i< n/2; i++) 
+               error |= b[i]->ttype != b[i+n/2]->ttype;
+
+       if ( error ){
+               for ( n--; n>= 0; n--)
+                       BBPreleaseref(b[n]->batCacheid);
+               GDKfree(b);
+               throw(MAL, "array.embed", "Incompatible index types");
+       }
+
+       /* select the oids we need by searching all matching index vectors */
+       bn = b[0];
+       for ( i=0; i<n/2; i++){
+               bo = BATsemijoin(b[i],bn);
+               bn= BATmirror(BATsemijoin(BATmirror(bo), BATmirror(b[i+n/2])));
+               BBPreleaseref(bo->batCacheid);
+               bo = b[i+n/2];
+       }
+
+       if ( BATcount(bn) == BATcount(b[n/2]) ) {
+               bn = BATmark(bn,0);
+               BBPkeepref(bn->batCacheid);
+               *(int*) getArgReference(stk,pci,0) = bn->batCacheid;
+       } else {
+               error = TRUE;
+               BBPreleaseref(bn->batCacheid);
+       }
+
+       for ( n--; n>= 0; n--)
+               BBPreleaseref(b[n]->batCacheid);
+       GDKfree(b);
+       if( error)
+               throw(MAL,"map.embed","incomplete embedding");
+       return MAL_SUCCEED;
+}
 @-
 The printing stuff is postponed to the future. Then it also needs
 a solution to the GDKout issues.
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to