/// <summary> /// Uses the primary input in evalInput to depermine which curve equation needs to be /// evaluated. Then evaluates the appropriate curve equation using the given input. /// </summary> /// <param name="evalInput">Stores info neede to evaluate an expression</param> /// <returns> /// Returns the output of the evaluated equation. The return status will not be valid if /// the equation could not be evaluated. /// </returns> public ReturnStatus <double> Evaluate(EvaluationCurveInput evalInput) { var erroneousPoints = new HashSet <int>(); var controlPointValuesStatus = CalculateControlPointValues(evalInput.VariableParamInfoList, evalInput.TransformParamInfoList, evalInput.PointEquations, ref erroneousPoints); if (controlPointValuesStatus.IsValid) { EvaluationCurveJob evalCurveJob = new EvaluationCurveJob(); string expressionStr = GetCurveExpressionString(evalInput.getPrimaryInputVal(), controlPointValuesStatus.Value, evalInput.CurveEquations); var returnedExpression = CreateExpressionFromString(expressionStr, EvalType.Curve); if (returnedExpression.IsValid) { evalCurveJob.Configure(evalInput, controlPointValuesStatus.Value, returnedExpression.Value); evalCurveJob.Execute(); if (evalCurveJob.OutputIsValid) { return(new ReturnStatus <double>(evalCurveJob.OutputVal, true)); } } } return(new ReturnStatus <double>(double.NaN, false)); }
/// <summary> /// Uses the primary input in evalInput to depermine which curve equation needs to be /// evaluated. Then evaluates the appropriate curve equation using the given input. /// </summary> /// <param name="evalInput">Stores info neede to evaluate an expression</param> /// <returns> /// Returns the output of the evaluated equation. The return status will not be valid if /// the equation could not be evaluated. /// </returns> public ReturnStatus<double> Evaluate(EvaluationCurveInput evalInput) { var erroneousPoints = new HashSet<int>(); var controlPointValuesStatus = CalculateControlPointValues(evalInput.VariableParamInfoList, evalInput.TransformParamInfoList, evalInput.PointEquations, ref erroneousPoints); if (controlPointValuesStatus.IsValid) { EvaluationCurveJob evalCurveJob = new EvaluationCurveJob(); string expressionStr = GetCurveExpressionString(evalInput.getPrimaryInputVal(), controlPointValuesStatus.Value, evalInput.CurveEquations); var returnedExpression = CreateExpressionFromString(expressionStr, EvalType.Curve); if (returnedExpression.IsValid) { evalCurveJob.Configure(evalInput, controlPointValuesStatus.Value, returnedExpression.Value); evalCurveJob.Execute(); if (evalCurveJob.OutputIsValid) { return new ReturnStatus<double>(evalCurveJob.OutputVal, true); } } } return new ReturnStatus<double>(double.NaN, false); }
protected ReturnStatus <XyPoint <double> > evaluateCurveAtXVal(double inputXVal, int curveIndex, IMappingEntry mappingEntry, List <MssParamInfo> variableParamInfoList, List <XyPoint <double> > controlPointList) { //For each sample point data1 data2 and data3 will be set to the X value of the //sample point. double relData1 = inputXVal; double relData2 = inputXVal; double relData3 = inputXVal; IStaticMssMsgInfo inMsgInfo = Factory_StaticMssMsgInfo.Create(mappingEntry.InMssMsgRange.MsgType); //If curXVal is outside of the relative input range for data 1 then set //relData1 to NaN double max = (double)inMsgInfo.MaxData1Value; double min = (double)inMsgInfo.MinData1Value; double bottom = (double)mappingEntry.InMssMsgRange.Data1RangeBottom; double top = (double)mappingEntry.InMssMsgRange.Data1RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData1 = double.NaN; } //If curXVal is outside of the relative input range for data 2 then set relData2 //to NaN max = (double)inMsgInfo.MaxData2Value; min = (double)inMsgInfo.MinData2Value; bottom = (double)mappingEntry.InMssMsgRange.Data2RangeBottom; top = (double)mappingEntry.InMssMsgRange.Data2RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData2 = double.NaN; } var evalInput = new EvaluationCurveInput(); evalInput.Init( relData1, relData2, relData3, variableParamInfoList, mappingEntry); var evalJob = new EvaluationCurveJob(); var returnedExpression = CreateExpressionFromString(mappingEntry.CurveShapeInfo.CurveEquations[curveIndex], EvalType.Curve); if (returnedExpression.IsValid == false) { return(new ReturnStatus <XyPoint <double> >()); } evalJob.Configure(evalInput, controlPointList, returnedExpression.Value); evalJob.Execute(); if (evalJob.OutputIsValid) { var curPoint = new XyPoint <double>(inputXVal, evalJob.OutputVal); return(new ReturnStatus <XyPoint <double> >(curPoint)); } else { return(new ReturnStatus <XyPoint <double> >()); } }
/// <summary> /// Evaluates the equations for the given mappingEntry. All control point equations will /// be evaluated and returned pointList. Curve equations will be evaluated at equally spaced /// sample points and the return values will be returned in curveYValues. This function is /// used by the GUI to create the graph representing the transformation on a mapping. /// </summary> /// <param name="xDistanceBetweenPoints"> /// The maximum horizontal distance between any two points. /// </param> /// <param name="variableParamInfoList"> /// A list of cloned variable parameter info for each variable parameter. /// </param> /// <param name="mappingEntry"> /// The mapping entry to evaluate equations for. /// </param> /// <param name="controlPointList"> /// The evaluated control points are returned in this list /// </param> /// <param name="curvePointsByCurveList"> /// This will contain the evaluated list of XyPoints for each curve. /// </param> /// <param name="erroneousControlPointIndexSet"> /// empty if all points had valid equations. Otherwise the index of at least one point with an invalid equation. /// </param> /// <param name="erroneousCurveIndexSet"> /// -1 if there is an invalid control point or if all curve equations are valid. Otherwise /// the index of the first curve with an invalid equation. /// </param> /// <returns> /// true if all equations could be evaluated and false otherwise. The out parameters are only /// garunteed to be valid if the return value is true. /// </returns> public bool SampleExpressionWithDefaultInputValues( double xDistanceBetweenPoints, List <MssParamInfo> variableParamInfoList, IMappingEntry mappingEntry, out List <XyPoint <double> > controlPointList, out List <List <XyPoint <double> > > curvePointsByCurveList, out HashSet <int> erroneousControlPointIndexSet, out HashSet <int> erroneousCurveIndexSet ) { Logger.HighVolume(23, String.Format("Sampling Expression - xGap: {0}, variableParamInfo: {1}", xDistanceBetweenPoints, EnumerableUtils.ToString(variableParamInfoList))); erroneousControlPointIndexSet = new HashSet <int>(); erroneousCurveIndexSet = new HashSet <int>(); //Initialize this list from an array so that elements can be set directly in parallel. curvePointsByCurveList = new List <List <XyPoint <double> > >(new List <XyPoint <double> > [mappingEntry.CurveShapeInfo.CurveEquations.Count]); EvaluationCurveJob evalJob = new EvaluationCurveJob(); var controlPointValuesStatus = CalculateControlPointValues( variableParamInfoList, mappingEntry.CurveShapeInfo.ParamInfoList, mappingEntry.CurveShapeInfo.PointEquations, ref erroneousControlPointIndexSet); controlPointList = controlPointValuesStatus.Value; //Need to make a second version of these variable as out parameters cannot be used in Parallel.For loops. List <XyPoint <double> > controlPointList2 = controlPointList; List <List <XyPoint <double> > > curvePointsByCurveList2 = curvePointsByCurveList; HashSet <int> erroneousCurveIndexSet2 = erroneousCurveIndexSet; if (controlPointValuesStatus.IsValid == false) { return(false); } int numCurves = mappingEntry.CurveShapeInfo.CurveEquations.Count; bool noErrorsEncountered = true; Parallel.For(0, numCurves, (curveIndex, loopState) => { double curveStartXVal = 0; double curveEndXVal = 1; if (curveIndex > 0) { curveStartXVal = controlPointList2[curveIndex - 1].X; } if (curveIndex < numCurves - 1) { curveEndXVal = controlPointList2[curveIndex].X; } int numPointsInCurve = (int)((curveEndXVal - curveStartXVal) / xDistanceBetweenPoints) + 1; Logger.HighVolume(24, string.Format("Sampling curve {0}. Points in curve: {1}", curveIndex, numPointsInCurve)); if (numPointsInCurve == 0) { return; } List <XyPoint <double> > curCurvePoints = new List <XyPoint <double> >(new XyPoint <double> [numPointsInCurve]); curvePointsByCurveList2[curveIndex] = curCurvePoints; //Evaluates the first point in the curve before createing threads to evaluate the //rest of the points. If evaluating each point is going to throw an exception then //this will improve performance by letting the code exit early. var firstEvalStatus = evaluateCurveAtXVal(curveStartXVal, curveIndex, mappingEntry, variableParamInfoList, controlPointList2); if (firstEvalStatus.IsValid == false) { lock (erroneousCurveIndexSet2) { Logger.HighVolume(25, string.Format("Sampling exiting early as first eval status for curve {0} was invalid", curveIndex)); erroneousCurveIndexSet2.Add(curveIndex); noErrorsEncountered = false; loopState.Stop(); return; } } curCurvePoints[0] = firstEvalStatus.Value; Parallel.For(1, numPointsInCurve, pointIndex => { //Calling loopState.Stop() does not immedateally stop all threads so that they //exit without doing any more processing. if (loopState.ShouldExitCurrentIteration) { return; } double curXVal = curveStartXVal + (pointIndex * xDistanceBetweenPoints); var evalStatus = evaluateCurveAtXVal(curXVal, curveIndex, mappingEntry, variableParamInfoList, controlPointList2); if (evalStatus.IsValid == false) { lock (erroneousCurveIndexSet2) { Logger.HighVolume(25, string.Format("Sampling exiting. point {0} for curve {1} was invalid.", pointIndex, curveIndex)); erroneousCurveIndexSet2.Add(curveIndex); noErrorsEncountered = false; loopState.Stop(); return; } } curCurvePoints[pointIndex] = evalStatus.Value; }); }); return(noErrorsEncountered); }
protected ReturnStatus<XyPoint<double>> evaluateCurveAtXVal(double inputXVal, int curveIndex, IMappingEntry mappingEntry, List<MssParamInfo> variableParamInfoList, List<XyPoint<double>> controlPointList) { //For each sample point data1 data2 and data3 will be set to the X value of the //sample point. double relData1 = inputXVal; double relData2 = inputXVal; double relData3 = inputXVal; IStaticMssMsgInfo inMsgInfo = Factory_StaticMssMsgInfo.Create(mappingEntry.InMssMsgRange.MsgType); //If curXVal is outside of the relative input range for data 1 then set //relData1 to NaN double max = (double)inMsgInfo.MaxData1Value; double min = (double)inMsgInfo.MinData1Value; double bottom = (double)mappingEntry.InMssMsgRange.Data1RangeBottom; double top = (double)mappingEntry.InMssMsgRange.Data1RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData1 = double.NaN; } //If curXVal is outside of the relative input range for data 2 then set relData2 //to NaN max = (double)inMsgInfo.MaxData2Value; min = (double)inMsgInfo.MinData2Value; bottom = (double)mappingEntry.InMssMsgRange.Data2RangeBottom; top = (double)mappingEntry.InMssMsgRange.Data2RangeTop; if (inputXVal < ((bottom - min) / (max - min + 1)) || inputXVal > ((top - min) / (max - min + 1))) { relData2 = double.NaN; } var evalInput = new EvaluationCurveInput(); evalInput.Init( relData1, relData2, relData3, variableParamInfoList, mappingEntry); var evalJob = new EvaluationCurveJob(); var returnedExpression = CreateExpressionFromString(mappingEntry.CurveShapeInfo.CurveEquations[curveIndex], EvalType.Curve); if (returnedExpression.IsValid == false) { return new ReturnStatus<XyPoint<double>>(); } evalJob.Configure(evalInput, controlPointList, returnedExpression.Value); evalJob.Execute(); if (evalJob.OutputIsValid) { var curPoint = new XyPoint<double>(inputXVal, evalJob.OutputVal); return new ReturnStatus<XyPoint<double>>(curPoint); } else { return new ReturnStatus<XyPoint<double>>(); } }
/// <summary> /// Evaluates the equations for the given mappingEntry. All control point equations will /// be evaluated and returned pointList. Curve equations will be evaluated at equally spaced /// sample points and the return values will be returned in curveYValues. This function is /// used by the GUI to create the graph representing the transformation on a mapping. /// </summary> /// <param name="xDistanceBetweenPoints"> /// The maximum horizontal distance between any two points. /// </param> /// <param name="variableParamInfoList"> /// A list of cloned variable parameter info for each variable parameter. /// </param> /// <param name="mappingEntry"> /// The mapping entry to evaluate equations for. /// </param> /// <param name="controlPointList"> /// The evaluated control points are returned in this list /// </param> /// <param name="curvePointsByCurveList"> /// This will contain the evaluated list of XyPoints for each curve. /// </param> /// <param name="erroneousControlPointIndexSet"> /// empty if all points had valid equations. Otherwise the index of at least one point with an invalid equation. /// </param> /// <param name="erroneousCurveIndexSet"> /// -1 if there is an invalid control point or if all curve equations are valid. Otherwise /// the index of the first curve with an invalid equation. /// </param> /// <returns> /// true if all equations could be evaluated and false otherwise. The out parameters are only /// garunteed to be valid if the return value is true. /// </returns> public bool SampleExpressionWithDefaultInputValues( double xDistanceBetweenPoints, List<MssParamInfo> variableParamInfoList, IMappingEntry mappingEntry, out List<XyPoint<double>> controlPointList, out List<List<XyPoint<double>>> curvePointsByCurveList, out HashSet<int> erroneousControlPointIndexSet, out HashSet<int> erroneousCurveIndexSet ) { Logger.HighVolume(23, String.Format("Sampling Expression - xGap: {0}, variableParamInfo: {1}", xDistanceBetweenPoints, EnumerableUtils.ToString(variableParamInfoList))); erroneousControlPointIndexSet = new HashSet<int>(); erroneousCurveIndexSet = new HashSet<int>(); //Initialize this list from an array so that elements can be set directly in parallel. curvePointsByCurveList = new List<List<XyPoint<double>>>(new List<XyPoint<double>>[mappingEntry.CurveShapeInfo.CurveEquations.Count]); EvaluationCurveJob evalJob = new EvaluationCurveJob(); var controlPointValuesStatus = CalculateControlPointValues( variableParamInfoList, mappingEntry.CurveShapeInfo.ParamInfoList, mappingEntry.CurveShapeInfo.PointEquations, ref erroneousControlPointIndexSet); controlPointList = controlPointValuesStatus.Value; //Need to make a second version of these variable as out parameters cannot be used in Parallel.For loops. List<XyPoint<double>> controlPointList2 = controlPointList; List<List<XyPoint<double>>> curvePointsByCurveList2 = curvePointsByCurveList; HashSet<int> erroneousCurveIndexSet2 = erroneousCurveIndexSet; if (controlPointValuesStatus.IsValid == false) { return false; } int numCurves = mappingEntry.CurveShapeInfo.CurveEquations.Count; bool noErrorsEncountered = true; Parallel.For(0, numCurves, (curveIndex, loopState) => { double curveStartXVal = 0; double curveEndXVal = 1; if (curveIndex > 0) { curveStartXVal = controlPointList2[curveIndex - 1].X; } if (curveIndex < numCurves - 1) { curveEndXVal = controlPointList2[curveIndex].X; } int numPointsInCurve = (int)((curveEndXVal - curveStartXVal) / xDistanceBetweenPoints) + 1; Logger.HighVolume(24, string.Format("Sampling curve {0}. Points in curve: {1}", curveIndex, numPointsInCurve)); if (numPointsInCurve == 0) { return; } List<XyPoint<double>> curCurvePoints = new List<XyPoint<double>>(new XyPoint<double>[numPointsInCurve]); curvePointsByCurveList2[curveIndex] = curCurvePoints; //Evaluates the first point in the curve before createing threads to evaluate the //rest of the points. If evaluating each point is going to throw an exception then //this will improve performance by letting the code exit early. var firstEvalStatus = evaluateCurveAtXVal(curveStartXVal, curveIndex, mappingEntry, variableParamInfoList, controlPointList2); if (firstEvalStatus.IsValid == false) { lock (erroneousCurveIndexSet2) { Logger.HighVolume(25, string.Format("Sampling exiting early as first eval status for curve {0} was invalid", curveIndex)); erroneousCurveIndexSet2.Add(curveIndex); noErrorsEncountered = false; loopState.Stop(); return; } } curCurvePoints[0] = firstEvalStatus.Value; Parallel.For(1, numPointsInCurve, pointIndex => { //Calling loopState.Stop() does not immedateally stop all threads so that they //exit without doing any more processing. if (loopState.ShouldExitCurrentIteration) { return; } double curXVal = curveStartXVal + (pointIndex * xDistanceBetweenPoints); var evalStatus = evaluateCurveAtXVal(curXVal, curveIndex, mappingEntry, variableParamInfoList, controlPointList2); if (evalStatus.IsValid == false) { lock (erroneousCurveIndexSet2) { Logger.HighVolume(25, string.Format("Sampling exiting. point {0} for curve {1} was invalid.", pointIndex, curveIndex)); erroneousCurveIndexSet2.Add(curveIndex); noErrorsEncountered = false; loopState.Stop(); return; } } curCurvePoints[pointIndex] = evalStatus.Value; }); }); return noErrorsEncountered; }