LinearPrinter.println("  (expansion)(RR join weight) factors:");
LinearPrinter.println(" joiner expansion factor: " + joinerExpansionFactor); LinearPrinter.println(" Filter (expansion) factors:");
    public LinearFilterRepresentation transform() throws NoTransformPossibleException {	int filterCount = linearRepresentations.length;	LinearPrinter.println(" preparing to combine splitjoin of " +			      filterCount +			      " filters");	LinearPrinter.println("  (expansion)(RR join weight) factors:");	for (int i=0; i<filterCount; i++) {	    LinearPrinter.println("   " +				  "(" + this.expansionFactors[i] + ")" +				  "(" + this.combinationWeights[i] + ")");	}		// do the expansion	LinearFilterRepresentation[] expandedReps = new LinearFilterRepresentation[filterCount];	int totalCols = 0;	for (int i=0; i<filterCount; i++) {	    LinearPrinter.println("  expanding filter by " + this.expansionFactors[i]);	    expandedReps[i] = this.linearRepresentations[i].expand(this.expansionFactors[i]);	    totalCols += expandedReps[i].getPushCount();	}	// figure how how many columns the "stride" is (eg the sum of the weights)	int strideLength = 0;	for (int i=0; i<filterCount; i++) {	    strideLength += this.combinationWeights[i];	}	// now, create a new matrix and vector that have the appropriate size:	// cols = the sum of the number of columns in the expanded representations	// rows = (all expanded matrices have the same number of rows)	FilterMatrix expandedA = new FilterMatrix(expandedReps[0].getPeekCount(), totalCols);	FilterVector expandedb = new FilterVector(totalCols);	// now, copy the cols of the matrices (and vectors) into the expanded versions	// for each expanded matrix, copy joinWeight[i] cols into the new matrix and vector	// at an offset that makes the output work out correctly. See paper.	int startOffset = 0;	for (int i=0; i<filterCount; i++) {	    // figure out how many groups of joinWeight cols that we have	    int numGroups = expandedReps[i].getPushCount() / this.combinationWeights[i]; // total # of groups	    for (int j=0; j<numGroups; j++) {		// figure out offset into expanded A to copy the columns		int currentOffset = startOffset + j*strideLength;		// the offset into the current source matrix is j*joinWeights[i]		// the number of columns that we are copying is combination weights[i]		expandedA.copyColumnsAt(currentOffset, expandedReps[i].getA(),					j*this.combinationWeights[i],					this.combinationWeights[i]);		expandedb.copyColumnsAt(currentOffset, expandedReps[i].getb(),					j*this.combinationWeights[i],					this.combinationWeights[i]);						    }	    // update start of the offset for the next expanded rep. 	    startOffset += this.combinationWeights[i];	}	// now, return a new LinearRepresentation that represents the transformed	// splitjoin. (remember peek=pop)	return new LinearFilterRepresentation(expandedA, expandedb, expandedA.getRows());    }