/// <summary> /// Create a copy /// </summary> /// <param name="srcList">The source agelist</param> /// <param name="randomFactory">The random number object</param> public AgeList(AgeList srcList, MyRandom randomFactory) { int idx; this.RandFactory = randomFactory; this.SetCount(srcList.Count); for (idx = 0; idx <= srcList.Count - 1; idx++) { this.FData[idx] = srcList.FData[idx]; } }
/// <summary> /// Add all elements of OtherAges into the object. Unlike AnimalGroup.Merge, /// AgeList.Merge does not free otherAges. /// </summary> /// <param name="otherAges">The other agelist</param> public void Merge(AgeList otherAges) { int idx; for (idx = 0; idx <= otherAges.Count - 1; idx++) { Input(otherAges.FData[idx].AgeDays, otherAges.FData[idx].NumMales, otherAges.FData[idx].NumFemales); } }
/// <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); }