package structures;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import main.Initializable;
import main.InitializationException;
import main.Main;
public class Mitral implements Initializable
{
private ArrayList<Column> columnsAffected;
private HashMap<Granule, Double> granulesAffected;
private boolean initialized = false;
private int parentColumnIndex = -1;
private double mitralToGranuleWeight = 1.00;
/**
* Makes empty Mitral cell with default MTG Weight = 1.00
*/
public Mitral()
{
mitralToGranuleWeight = 1.00;
}
/**
* Makes Mitral cell with MTG weight drawn from distribution
*
* @param g - Gaussian from which weight is taken
*/
public Mitral(util.Gaussian g)
{
this.mitralToGranuleWeight = g.getRandomValue();
}
/**
* Makes Mitral cell with specified MTG weight
*
* @param mtgweight - the MTG weight
*/
public Mitral(double mtgweight)
{
this.mitralToGranuleWeight = mtgweight;
}
/**
* Chooses how many columns to affect in the network
*
* Bounded from 0 to XX.XX% of the number of columns in the network
*
* @param n - the network environment the columns exist in
*/
private void chooseColumnsToAffect(Network n)
{
//Choose X% of columns to affect
Random r = new Random();
//TODO Variable connectivity dependent on network variable
int numToAffect = (int) Math.floor(n.getNumCols()*n.getMitralToColumnConnectivity());
columnsAffected = new ArrayList<Column>(numToAffect);
ArrayList<Integer> chosenIndexes = new ArrayList<Integer>();
//Choose columns which to affect (exclude self)
for (int x = numToAffect; x > 0; x--)
{
int indexChosen;
do{
indexChosen = r.nextInt(n.getNumCols());
}while(chosenIndexes.contains(indexChosen) || indexChosen == this.parentColumnIndex);
this.columnsAffected.add(n.getColumn(indexChosen));
chosenIndexes.add(indexChosen);
}
//DEBUG
if(main.Main.VERBOSE)
{
System.out.print("\nMitral cell "+this.toString()+" affects columns:");
for(int a : chosenIndexes)
{
System.out.print(" "+a+" ");
}
System.out.println();
}
//LOG
if (Main.LOG_WRITER != null)
{
Main.attemptNewLineToLog();
Main.attemptWriteToLog("Mitral cell "+this.toString()+" affects columns:");
for(int a : chosenIndexes)
{
Main.attemptWriteToLog(" "+a+" ");
}
Main.attemptNewLineToLog();
}
return;
}
public ArrayList<Column> getColumnsAffected()
{
return this.columnsAffected;
}
public double getToGranuleWeight(Granule g)
{
Double d = this.granulesAffected.get(g);
if (d == null)
return 0.0;
else
return d;
}
/**
* Determines effect this MitralCell has on Granules in other Columns
* @param n
*/
private void setMitralToGranuleWeights(Network n)
{
this.granulesAffected = new HashMap<Granule, Double>(this.columnsAffected.size());
this.mitralToGranuleWeight = n.getMitralToGranuleWeights().getRandomValue();
for (Column c : this.columnsAffected)
{
for (Granule g : c.getGranules())
{
//MitralToGranuleWeight is internal field, default 1.00
double weight = mitralToGranuleWeight;
this.granulesAffected.put(g, weight);
//DEBUG
if(main.Main.VERBOSE)
{
System.out.println("\t"+this.toString()+" weight to "+g.stringRepresentation+" is "+weight);
}
//LOG
if (Main.LOG_WRITER != null)
{
Main.attemptNewLineToLog();
Main.attemptWriteToLog(("\t"+this.toString()+" weight to "+g.stringRepresentation+" is "+weight));
}
}
}
return;
}
/**
* Initializes mitral cell connections, weights
*
* In order:
* - Chooses columns which are to be affected by this mitral cell
* - Sets the weights for connections to granule cells
*
* @param network - the Network wherein this mitral cell lives
*
* */
public void initialize(Object network) throws InitializationException
{
Network n;
if(network instanceof Network)
n = (Network) network;
else
throw new InitializationException("Paramater not of type Network: Aborting Mitral initialization");
//Choose which columns to affect
this.chooseColumnsToAffect(n);
//Choose granule weights
this.setMitralToGranuleWeights(n);
initialized = true;
}
public void setParentIndex(int n)
{
this.parentColumnIndex = n;
}
@Override
public String toString()
{
return this.parentColumnIndex+"-M";
}
public boolean isInitialized()
{
return this.initialized;
}
}