/// <summary> /// Calculate trophic evenness using the Rao Index /// </summary> /// <param name="ecosystemModelGrid">The model grid</param> /// <param name="cellIndices">The list of indices of cells to be run in the current simulation</param> /// <param name="cellIndex">The index of the current cell within the list of cells to be run</param> /// <returns>Trophic evenness</returns> public double CalculateFunctionalEvennessRao(ModelGrid ecosystemModelGrid, FunctionalGroupDefinitions cohortDefinitions, List <uint[]> cellIndices, int cellIndex, string trait) { //Get the cohorts for the specified cell GridCellCohortHandler CellCohorts = ecosystemModelGrid.GetGridCellCohorts(cellIndices[cellIndex][0], cellIndices[cellIndex][1]); double[] EvennessValues = new double[2]; double[,] Distances = new double[CellCohorts.GetNumberOfCohorts(), CellCohorts.GetNumberOfCohorts()]; double[] FunctionalTrait = new double[CellCohorts.GetNumberOfCohorts()]; double MaxModelTraitValue = 0; double MinModelTraitValue = 0; // Construct a vector of cohort biomass (in case we want to weight by them) double[] CohortTotalBiomasses = new double[CellCohorts.GetNumberOfCohorts()]; int CohortNumberCounter = 0; switch (trait.ToLower()) { case "biomass": for (int fg = 0; fg < CellCohorts.Count; fg++) { foreach (Cohort c in CellCohorts[fg]) { FunctionalTrait[CohortNumberCounter] = c.IndividualBodyMass; CohortTotalBiomasses[CohortNumberCounter] = (c.IndividualBodyMass + c.IndividualReproductivePotentialMass) * c.CohortAbundance; CohortNumberCounter++; } } //Define upper and lower limits for body mass MinModelTraitValue = cohortDefinitions.GetBiologicalPropertyAllFunctionalGroups("minimum mass").Min(); MaxModelTraitValue = cohortDefinitions.GetBiologicalPropertyAllFunctionalGroups("maximum mass").Max(); break; case "trophic index": for (int fg = 0; fg < CellCohorts.Count; fg++) { foreach (Cohort c in CellCohorts[fg]) { FunctionalTrait[CohortNumberCounter] = c.IndividualBodyMass; CohortTotalBiomasses[CohortNumberCounter] = (c.IndividualBodyMass + c.IndividualReproductivePotentialMass) * c.CohortAbundance; CohortNumberCounter++; } } MinModelTraitValue = MinTI; MaxModelTraitValue = MaxTI; break; } Distances = CalculateDistanceMatrix(FunctionalTrait, MaxModelTraitValue, MinModelTraitValue); return(RaoEntropy(Distances, CohortTotalBiomasses)); }
/// <summary> /// Calculates functional diversity of cohorts in a grid cell as functional richness and functional diveregence (using the Rao Index) /// </summary> /// <param name="ecosystemModelGrid">The model grid</param> /// <param name="cohortDefinitions">The functional group definitions for cohorts in the model</param> /// <param name="cellIndices">The list of cell indices in the current model simulation</param> /// <param name="cellIndex">The index of the current cell within the list of cells to run</param> /// <returns>A pair of values representing the functional richness and functional divergence (functional richness currently disabled!)</returns> public double[] CalculateFunctionalDiversity(ModelGrid ecosystemModelGrid, FunctionalGroupDefinitions cohortDefinitions, List <uint[]> cellIndices, int cellIndex) { //Get the cohorts for the specified cell GridCellCohortHandler CellCohorts = ecosystemModelGrid.GetGridCellCohorts(cellIndices[cellIndex][0], cellIndices[cellIndex][1]); //Variable to hold the functional richness value for the current cohorts double FunctionalRichness; //Variable to hold the functional divergence value for the current cohorts double RaoFunctionalDivergence = 0.0; double[,] Distances = new double[CellCohorts.GetNumberOfCohorts(), CellCohorts.GetNumberOfCohorts()]; List <string> AllTraitNames = cohortDefinitions.GetAllTraitNames().ToList(); AllTraitNames.Remove("realm"); AllTraitNames.Remove("heterotroph/autotroph"); AllTraitNames.Remove("diet"); string[] TraitNames = AllTraitNames.ToArray(); //Define upper and lower limits for body mass double MinMass = cohortDefinitions.GetBiologicalPropertyAllFunctionalGroups("minimum mass").Min(); double MaxMass = cohortDefinitions.GetBiologicalPropertyAllFunctionalGroups("maximum mass").Max(); //Define upp and lower limits for trophic index double MaxTI = 40.0; double MinTI = 1.0; // Construct an array of functional trait values for each cohort // Rows are specific cohorts // Columns are the functional traits (these include different types: // quantative: current mass, trophic index // nominal: diet, reproductive strategy, mobility, metabolism Tuple <double[], string[]>[] CohortFunctionalTraits = new Tuple <double[], string[]> [CellCohorts.GetNumberOfCohorts()]; double[] IndividualBodyMasses = new double[CellCohorts.GetNumberOfCohorts()]; double[] TrophicIndex = new double[CellCohorts.GetNumberOfCohorts()]; string[][] CohortNominalTraitValues = new string[TraitNames.Length][]; for (int i = 0; i < TraitNames.Length; i++) { CohortNominalTraitValues[i] = new string[CellCohorts.GetNumberOfCohorts()]; } // Construct a vector of cohort biomass (in case we want to weight by them) double[] CohortTotalBiomasses = new double[CellCohorts.GetNumberOfCohorts()]; string[] TraitValues = new string[TraitNames.Length]; double[] QuantitativeTraitValues = new double[2]; int CohortNumberCounter = 0; for (int fg = 0; fg < CellCohorts.Count; fg++) { foreach (Cohort c in CellCohorts[fg]) { TraitValues = cohortDefinitions.GetTraitValues(TraitNames, fg); for (int ii = 0; ii < TraitValues.Length; ii++) { CohortNominalTraitValues[ii][CohortNumberCounter] = TraitValues[ii]; } IndividualBodyMasses[CohortNumberCounter] = c.IndividualBodyMass; TrophicIndex[CohortNumberCounter] = c.TrophicIndex; QuantitativeTraitValues[0] = c.IndividualBodyMass; QuantitativeTraitValues[1] = c.TrophicIndex; CohortFunctionalTraits[CohortNumberCounter] = new Tuple <double[], string[]>(QuantitativeTraitValues, TraitValues); CohortTotalBiomasses[CohortNumberCounter] = (c.IndividualBodyMass + c.IndividualReproductivePotentialMass) * c.CohortAbundance; CohortNumberCounter++; } } List <double[, ]> DistanceList = new List <double[, ]>(); DistanceList.Add(CalculateDistanceMatrix(IndividualBodyMasses, MaxMass, MinMass)); DistanceList.Add(CalculateDistanceMatrix(TrophicIndex, MaxTI, MinTI)); foreach (string[] t in CohortNominalTraitValues) { DistanceList.Add(CalculateDistanceMatrix(t)); } Distances = CalculateAggregateDistance(DistanceList); RaoFunctionalDivergence = RaoEntropy(Distances, CohortTotalBiomasses); return(new double[] { 0.0, RaoFunctionalDivergence }); }