public void addBias(int numInterneurons, float tauInterneurons, float tauBias, boolean excitatory, boolean optimize) throws StructuralException {
if ( !(myOrigin instanceof DecodedOrigin) || !(myTermination instanceof DecodedTermination)) {
throw new RuntimeException("This feature is only implemented for projections from DecodedOrigins to DecodedTerminations");
}
DecodedOrigin baseOrigin = (DecodedOrigin) myOrigin;
DecodedTermination baseTermination = (DecodedTermination) myTermination;
NEFEnsemble pre = (NEFEnsemble) baseOrigin.getNode();
NEFEnsemble post = (NEFEnsemble) baseTermination.getNode();
myBiasOrigin = pre.addBiasOrigin(baseOrigin, numInterneurons, getUniqueNodeName(post.getName() + "_" + baseTermination.getName()), excitatory);
myInterneurons = myBiasOrigin.getInterneurons();
myNetwork.addNode(myInterneurons);
BiasTermination[] bt = post.addBiasTerminations(baseTermination, tauBias, myBiasOrigin.getDecoders(), baseOrigin.getDecoders());
myDirectBT = bt[0];
myIndirectBT = bt[1];
if (!excitatory) {
myIndirectBT.setStaticBias(new float[]{-1});
}
float[][] tf = new float[][]{new float[]{0, 1/tauInterneurons/tauInterneurons}, new float[]{2/tauInterneurons, 1/tauInterneurons/tauInterneurons}};
myInterneuronTermination = (DecodedTermination) myInterneurons.addDecodedTermination("bias", MU.I(1), tf[0], tf[1], 0, false);
myNetwork.addProjection(myBiasOrigin, myDirectBT);
myNetwork.addProjection(myBiasOrigin, myInterneuronTermination);
myNetwork.addProjection(myInterneurons.getOrigin(NEFEnsemble.X), myIndirectBT);
if (optimize) {
float[][] baseWeights = MU.prod(post.getEncoders(), MU.prod(baseTermination.getTransform(), MU.transpose(baseOrigin.getDecoders())));
myBiasOrigin.optimizeDecoders(baseWeights, myDirectBT.getBiasEncoders(), excitatory);
myBiasOrigin.optimizeInterneuronDomain(myInterneuronTermination, myIndirectBT);
}
myBiasIsEnabled = true;