/// <summary> /// Convert a range specification into factor values. /// </summary> /// <param name="specification">The specification to examine</param> private List <CompositeFactor> RangeSpecificationToFactorValues(string specification) { List <CompositeFactor> values = new List <CompositeFactor>(); // Format of a range: // value1 to value2 step increment. string path = specification; string rangeString = StringUtilities.SplitOffAfterDelimiter(ref path, "="); string[] rangeBits = rangeString.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); double from = Convert.ToDouble(rangeBits[0], CultureInfo.InvariantCulture); double to = Convert.ToDouble(rangeBits[2], CultureInfo.InvariantCulture); double step = Convert.ToDouble(rangeBits[4], CultureInfo.InvariantCulture); if ((from < to && step < 0) || (from > to && step > 0)) { throw new InvalidOperationException($"Unbounded factor specification: {specification}"); } for (double value = from; value <= to; value += step) { var newFactor = new CompositeFactor(this, path.Trim(), value.ToString()); newFactor.Children.AddRange(Children); values.Add(newFactor); } return(values); }
/// <summary> /// /// </summary> /// <param name="compositeFactor"></param> /// <returns></returns> public IEnumerable <CompositeFactor> ExpandFactor(CompositeFactor compositeFactor) { var childCompositeFactors = Apsim.Children(compositeFactor, typeof(CompositeFactor)).Cast <CompositeFactor>(); if (childCompositeFactors.Count() > 0) { var newFactorValues = new List <CompositeFactor>(); foreach (var child in childCompositeFactors) { var newCompositeFactor = new CompositeFactor(this, compositeFactor.Paths, compositeFactor.Values) { Name = compositeFactor.Name + child.Name, Specifications = child.Specifications }; newCompositeFactor.Children.AddRange(child.Children); newFactorValues.Add(newCompositeFactor); } return(newFactorValues); } else { return new CompositeFactor[] { compositeFactor } }; }
/// <summary> /// Convert a simple specification into factor values. /// </summary> /// <param name="specification">The specification to examine</param> private List <CompositeFactor> SetSpecificationToFactorValues(string specification) { List <CompositeFactor> returnValues = new List <CompositeFactor>(); // Can be multiple values on specification line, separated by commas. Return a separate // factor value for each value. string path = specification; string value = StringUtilities.SplitOffAfterDelimiter(ref path, "=").Trim(); if (value == null) { throw new Exception("Cannot find any values on the specification line: " + specification); } string[] values = value.Split(",".ToCharArray()); foreach (var val in values) { var newFactor = new CompositeFactor(this, path.Trim(), val.Trim()); newFactor.Children.AddRange(Children); returnValues.Add(newFactor); } return(returnValues); }