/// <summary>Compute conceptions</summary> /// <param name="Sigs"></param> /// <param name="N"></param> /// <param name="fCR1"></param> private double ComputeConception(double[] Sigs, int N, ref double fCR1) { double fCR_N; if (Sigs[0] < 5.0) { fCR_N = StdMath.SIG(1.0, Sigs); } else { fCR_N = 0.0; } if (N == 1) { fCR1 = fCR_N; } if (1.0 - fCR1 < 0) { throw new Exception("Power of negative number attempted in computeConception():1.0-fCR1"); } return(StdMath.XDiv(fCR_N, fCR1) * (1.0 - StdMath.Pow(1.0 - fCR1, NC))); }
/// <summary> /// Split the age group by age. If ByAge=TRUE, oldest animals are placed in the result. /// If ByAge=FALSE, the age structures are made the same as far as possible. /// </summary> /// <param name="numMale">Number of male</param> /// <param name="numFemale">Number of female</param> /// <param name="ByAge">Split by age</param> /// <returns></returns> public AgeList Split(int numMale, int numFemale, bool ByAge) { int[,] TransferNo; // 0,x =male, 1,x =female int[] TotalNo = new int[2]; int[] TransfersReqd = new int[2]; int[] TransfersDone = new int[2]; double[] TransferPropn = new double[2]; int iAnimal, iFirst, iLast; int idx, jdx; AgeList result = new AgeList(RandFactory); // Create a list with the same age for (idx = 0; idx <= this.Count - 1; idx++) // structure but no animals { result.Input(this.FData[idx].AgeDays, 0, 0); } TransfersReqd[0] = numMale; TransfersReqd[1] = numFemale; TransferNo = new int[2, this.Count]; // Assume that this zeros TransferNo for (jdx = 0; jdx <= 1; jdx++) { TransfersDone[jdx] = 0; } if (ByAge) { // If ByAge=TRUE, oldest animals are placed in Result for (idx = this.Count - 1; idx >= 0; idx--) { TransferNo[0, idx] = Math.Min(TransfersReqd[0] - TransfersDone[0], this.FData[idx].NumMales); TransferNo[1, idx] = Math.Min(TransfersReqd[1] - TransfersDone[1], this.FData[idx].NumFemales); for (jdx = 0; jdx <= 1; jdx++) { TransfersDone[jdx] += TransferNo[jdx, idx]; } } } else { // If ByAge=FALSE, the age structures are made the same as far as possible this.GetOlder(-1, ref TotalNo[0], ref TotalNo[1]); for (jdx = 0; jdx <= 1; jdx++) { TransfersReqd[jdx] = Math.Min(TransfersReqd[jdx], TotalNo[jdx]); TransferPropn[jdx] = StdMath.XDiv(TransfersReqd[jdx], TotalNo[jdx]); } for (idx = 0; idx <= this.Count - 1; idx++) { TransferNo[0, idx] = Convert.ToInt32(Math.Round(TransferPropn[0] * this.FData[idx].NumMales), CultureInfo.InvariantCulture); TransferNo[1, idx] = Convert.ToInt32(Math.Round(TransferPropn[1] * this.FData[idx].NumFemales), CultureInfo.InvariantCulture); for (jdx = 0; jdx <= 1; jdx++) { TransfersDone[jdx] += TransferNo[jdx, idx]; } } for (jdx = 0; jdx <= 1; jdx++) { // Randomly allocate roundoff errors while (TransfersDone[jdx] < TransfersReqd[jdx]) // Too few transfers { iAnimal = Convert.ToInt32(Math.Min(Math.Truncate(this.RandFactory.RandomValue() * (TotalNo[jdx] - TransfersDone[jdx])), (TotalNo[jdx] - TransfersDone[jdx]) - 1), CultureInfo.InvariantCulture); idx = -1; iLast = 0; do { idx++; iFirst = iLast; if (jdx == 0) { iLast = iFirst + (this.FData[idx].NumMales - TransferNo[jdx, idx]); } else { iLast = iFirst + (this.FData[idx].NumFemales - TransferNo[jdx, idx]); } //// until (Idx = Count-1) or ((iAnimal >= iFirst) and (iAnimal < iLast)); }while ((idx != this.Count - 1) && ((iAnimal < iFirst) || (iAnimal >= iLast))); TransferNo[jdx, idx]++; TransfersDone[jdx]++; } while (TransfersDone[jdx] > TransfersReqd[jdx]) { // Too many transfers iAnimal = Convert.ToInt32(Math.Min(Math.Truncate(this.RandFactory.RandomValue() * TransfersDone[jdx]), TransfersDone[jdx] - 1), CultureInfo.InvariantCulture); idx = -1; iLast = 0; do { idx++; iFirst = iLast; iLast = iFirst + TransferNo[jdx, idx]; //// until (Idx = Count-1) or ((iAnimal >= iFirst) and (iAnimal < iLast)); }while ((idx != this.Count - 1) && ((iAnimal < iFirst) || (iAnimal >= iLast))); TransferNo[jdx, idx]--; TransfersDone[jdx]--; } } } for (idx = 0; idx <= this.Count - 1; idx++) // Carry out transfers { this.FData[idx].NumMales -= TransferNo[0, idx]; result.FData[idx].NumMales += TransferNo[0, idx]; this.FData[idx].NumFemales -= TransferNo[1, idx]; result.FData[idx].NumFemales += TransferNo[1, idx]; } this.Pack(); // Clear away empty entries in both lists result.Pack(); return(result); }
/// <summary> /// Change the numbers of male and female animals to new values. /// </summary> /// <param name="numMales">New total number of male animals to place in the list</param> /// <param name="numFemales">New total number of female animals to place in the list</param> public void Resize(int numMales, int numFemales) { int CurrM = 0; int CurrF = 0; int MLeft; int FLeft; int idx; this.Pack(); // Ensure there are no empty list members if (this.Count == 0) // Hard to do anything with no age info { Input(365 * 3, numMales, numFemales); } else if (this.Count == 1) { this.FData[0].NumMales = numMales; this.FData[0].NumFemales = numFemales; } else { this.GetOlder(-1, ref CurrM, ref CurrF); // Work out number of animals currently in the list MLeft = numMales; FLeft = numFemales; for (idx = 0; idx <= this.Count - 1; idx++) { if ((numMales == 0) || (CurrM > 0)) { this.FData[idx].NumMales = Convert.ToInt32(Math.Truncate(numMales * StdMath.XDiv(this.FData[idx].NumMales, CurrM)), CultureInfo.InvariantCulture); } else { this.FData[idx].NumMales = Convert.ToInt32(Math.Truncate(numMales * StdMath.XDiv(this.FData[idx].NumFemales, CurrF)), CultureInfo.InvariantCulture); } if ((numFemales == 0) || (CurrF > 0)) { this.FData[idx].NumFemales = Convert.ToInt32(Math.Truncate(numFemales * StdMath.XDiv(this.FData[idx].NumFemales, CurrF)), CultureInfo.InvariantCulture); } else { this.FData[idx].NumFemales = Convert.ToInt32(Math.Truncate(numFemales * StdMath.XDiv(this.FData[idx].NumMales, CurrM)), CultureInfo.InvariantCulture); } MLeft -= this.FData[idx].NumMales; FLeft -= this.FData[idx].NumFemales; } idx = this.Count - 1; // Add the "odd" animals into the oldest groups as evenly as possible while ((MLeft > 0) || (FLeft > 0)) { if (MLeft > 0) { this.FData[idx].NumMales++; MLeft--; } if (FLeft > 0) { this.FData[idx].NumFemales++; FLeft--; } idx--; if (idx < 0) { idx = this.Count - 1; } } } this.Pack(); }