* @see ca.nengo.model.ExpandableNode#addTermination(java.lang.String, float[][], float, boolean)
*/
public synchronized Termination addHPESTermination(String name, float[][] weights, float tauPSC, boolean modulatory, float[] theta) throws StructuralException {
//TODO: check name for duplicate
if (myExpandableNodes.length != weights.length) {
throw new StructuralException(weights.length + " sets of weights given for "
+ myExpandableNodes.length + " expandable nodes");
}
int dimension = weights[0].length;
Termination[] components = new Termination[myExpandableNodes.length];
for (int i = 0; i < myExpandableNodes.length; i++) {
if (weights[i].length != dimension) {
throw new StructuralException("Equal numbers of weights are needed for termination onto each node");
}
components[i] = myExpandableNodes[i].addTermination(name, new float[][]{weights[i]}, tauPSC, modulatory);
}
PlasticEnsembleTermination result;
// Make sure that the components are plastic, otherwise make a non-plastic termination
if (isPopulationPlastic(components)) {
PlasticNodeTermination[] pnts = new PlasticNodeTermination[components.length];
for (int i=0; i<components.length; i++) {
pnts[i] = (PlasticNodeTermination) components[i];
}
result = new hPESTermination(this, name, pnts, theta);
// Set the number of tasks equal to the number of threads
int numTasks = ca.nengo.util.impl.NodeThreadPool.getNumJavaThreads();
numTasks = numTasks < 1 ? 1 : numTasks;
LearningTask[] tasks = new LearningTask[numTasks];
int termsPerTask = (int) Math.ceil((float) components.length / (float) numTasks);
int termOffset = 0;
int termStartIndex, termEndIndex;
for (int i = 0; i < numTasks; i++) {
termStartIndex = termOffset;
termEndIndex = components.length - termOffset >= termsPerTask ? termOffset + termsPerTask : components.length;
termOffset += termsPerTask;
tasks[i] = new LearningTask(this, result, termStartIndex, termEndIndex);
}
addTasks(tasks);
} else {
throw new StructuralException("Ensemble contains non-plastic node terminations");
}
myPlasticEnsembleTerminations.put(name, result);
fireVisibleChangeEvent();