new JIntLiteral(N+x-1),
new JIntLiteral((N+x-1)*numWeightFields),
    private void makeReplacement(SIRFilter self) {	LinearPrinter.println(" processing " + self.getIdent());	/* if we don't have a linear form for this stream, we are done. */	if(!this.linearityInformation.hasLinearRepresentation(self)) {	    LinearPrinter.println("  aborting -- not linear");	    return;	}	LinearFilterRepresentation linearRep = this.linearityInformation.getLinearRepresentation(self);	/* if this filter doesn't have a pop of one, we abort. **/	if (linearRep.getPopCount() != 1) {	    LinearPrinter.println("  aborting -- filter is not FIR (pop = " +				  linearRep.getPopCount() + ")"); 	    return;	}		/* if there is not a real valued FIR (all coefficients are real), we are done. */	if (!linearRep.isPurelyReal()) {	    LinearPrinter.println("  aborting -- filter has non real coefficients."); 	    return;	}			/** if doing clever replacement, don't do small FIRs. **/	if (linearRep.getPeekCount() < minFIRSize) { 	    LinearPrinter.println("  aborting -- fir size too small: " +				  linearRep.getPeekCount() + ". needs to be at least " +				  minFIRSize);	    return;	}	/** set the target FFT size appropriately if it hasn't already been set */	int targetNumberOfOutputs = fftSizeFactor * linearRep.getPeekCount();	LinearPrinter.println("  target output size: " + targetNumberOfOutputs);		/* now is when we get to the fun part, we have a linear representation	 * that computes an FIR (ef pop 1, push 1, peek x) and we want to replace it with an FFT.	 * Note that N is the block size of the input that we are looking at. */	int x = linearRep.getPeekCount();	int N = calculateN(targetNumberOfOutputs,x);	int filterSize = N+2*(x-1); // this is the size of the overall filter	LinearPrinter.println("  creating frequency filter.\n" +			      "   N+(x-1)=" + (N+x-1) + " (outputs per steady state)\n" + 			      "   x=" + x + " (peek, original filter size)\n" +			      "   filterSize=" + filterSize + " (FFT size)");		/////////////// Create the new fields for this filter.	int numWeightFields = linearRep.getPushCount(); // Eg the number of columns in the matrix	JFieldDeclaration[] newFields = self.getFields();		/* make the fields to hold the transform of the weights. Note that the	   weights are stored in "half complex array" format which is the output format	   generated by FFTW. The first weight field corresponds to the weight field of	   the right most column, the next weight field corresponds to the weight field	   of the next right most column, etc. */	JVariableDefinition[] weightFields = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    weightFields[i] = makeWeightField(FILTER_WEIGHTS_PREFIX + "_" + i);	    newFields = appendFieldDeclaration(newFields, weightFields[i]);	}		/* make the fields to hold the partial results between executions. These	   fields are also stored in half complex array format, and each corresponds	   to the same column as does the weight fields. */	JVariableDefinition[] partialFields = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    partialFields[i] = makeWeightField(PARTIAL_BUFFER_PREFIX + "_" + i);	    newFields = appendFieldDeclaration(newFields, partialFields[i]);	}	/* make the input and temp buffer fields. */	JVariableDefinition inputBufferField  = makeWeightField(INPUT_BUFFER_NAME);	newFields = appendFieldDeclaration(newFields, inputBufferField);	JVariableDefinition tempBufferField  = makeWeightField(TEMP_BUFFER_NAME);	newFields = appendFieldDeclaration(newFields, tempBufferField); 	/** make enough output buffers to hold the appropriate outputs. **/	JVariableDefinition outputBufferFields[] = new JVariableDefinition[numWeightFields];	for (int i=0; i<numWeightFields; i++) {	    outputBufferFields[i] = makeWeightField(OUTPUT_BUFFER_NAME + "_" + i);	    newFields = appendFieldDeclaration(newFields, outputBufferFields[i]);	}				/* make a new init function */	JMethodDeclaration freqInit = makeNewInit(linearRep,						  weightFields, partialFields,						  inputBufferField, tempBufferField,						  outputBufferFields,						  filterSize, x);		/* make the init work function */	JMethodDeclaration freqInitWork = makeNewWork(INITWORK,						      weightFields, partialFields,						      inputBufferField, tempBufferField,						      outputBufferFields,						      filterSize, x, N);		/* make a new work function */	JMethodDeclaration freqWork = makeNewWork(WORK,						  weightFields, partialFields,						  inputBufferField, tempBufferField,						  outputBufferFields,						  filterSize, x, N);			LinearPrinter.println("  done building new IR nodes for " + self.getIdent());		LinearPrinter.println("  creating new two stage filter...");	// Create a new filter that contains all of the new pieces that we have built	SIRTwoStageFilter freqFilter;	/* Note, we need to have initPeek-initPop == peek-Pop for some scheduling reason	 * so therefore, we set the peek rate of the work function to be N+2(x-1) even though	 * it really only needs to be N+x-1.*/	freqFilter = new SIRTwoStageFilter(self.getParent(),              /* parent */					   "TwoStageFreq" + self.getIdent(),/* ident */					   newFields,                     /* fields */					   new JMethodDeclaration[0],     /* methods -- init, work, and initWork are special*/					   new JIntLiteral(N+x-1),        /* peek (w/ extra x-1 window...)*/					   new JIntLiteral(N+x-1),        /* pop */					   new JIntLiteral(N+x-1),        /* push */					   freqWork,                      /* work */					   N+x-1,                         /* initPeek */					   N+x-1,                         /* initPop */					   N+x-1,                         /* initPush */					   freqInitWork,                  /* initWork */					   self.getInputType(),           /* input type */					   self.getOutputType());         /* output type */	// need to explicitly set the init function	freqFilter.setInit(freqInit);		// now replace the current filter (self) with the frequency version	self.getParent().replace(self, freqFilter);		LinearPrinter.println("  done replacing.");	    }