/// <summary> /// AddFunctions(EqCompiler): registers all the functions in the library with /// the provided compiler instance. /// </summary> /// <param name="eq"> /// An incoming instance of the equation compiler. /// </param> /// <example> /// <code> /// EqCompiler comp = new EqCompiler("sqrt(a+b)"); /// CFunctionLibrary.AddFunctions( comp ); /// comp.Compile(); /// </code> /// </example> public static void AddFunctions(EqCompiler eq) { eq.AddFunction(new CAbs()); eq.AddFunction(new CAcos()); eq.AddFunction(new CAsin()); eq.AddFunction(new CAtan()); eq.AddFunction(new CCeiling()); eq.AddFunction(new CCos()); eq.AddFunction(new CCosh()); eq.AddFunction(new CExp()); eq.AddFunction(new CFloor()); eq.AddFunction(new CLog()); eq.AddFunction(new CLog10()); eq.AddFunction(new CMax()); eq.AddFunction(new CMin()); eq.AddFunction(new CRound()); eq.AddFunction(new CSign()); eq.AddFunction(new CSin()); eq.AddFunction(new CSinh()); eq.AddFunction(new CSqrt()); eq.AddFunction(new CTan()); eq.AddFunction(new CTanh()); eq.AddFunction(new CIf()); }
public void CompileTest() { Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR"); string testEquation = "3.2+2"; EqCompiler compiler = new EqCompiler(testEquation, true); compiler.Compile(); Assert.AreEqual(5.2, compiler.Calculate()); }
public static void getEquationInterpolation(string equationString, double startTime, double endTime, int nSamples, int startIndex, double[]output, List<Variable> existingVariables, List<Waveform> existingCommonWaveforms, double wfDuration) { string status = getEquationStatusString(equationString, existingVariables, existingCommonWaveforms); if (status == "Valid equation.") { // HERE WE GO! dotMath.EqCompiler eq = new EqCompiler(equationString, true); // This should not fail, because if it did we would have caught it with the status check eq.Compile(); string [] foundvars = eq.GetVariableList(); Dictionary<string, Waveform> waveformDependentVariables = new Dictionary<string, Waveform>(); bool usingTimeVariable = false; bool usingCommonWaveforms = false; if (foundvars != null) { foreach (string varname in foundvars) { bool variableMapped = false; if (varname != "t") { foreach (Variable var in existingVariables) { if (var.VariableName == varname) { eq.SetVariable(varname, var.VariableValue); variableMapped = true; } } } if (varname == "t") { usingTimeVariable = true; variableMapped = true; } // variable named varname has not yet been mapped. Thus it must be a common waveform if (!variableMapped) { if (existingCommonWaveforms != null) { foreach (Waveform wf in existingCommonWaveforms) { if (wf.WaveformName == varname) { if (!waveformDependentVariables.ContainsKey(varname)) { waveformDependentVariables.Add(varname, wf); usingCommonWaveforms = true; } } } } } } } Dictionary<Waveform, double[]> commonWaveformInterpolations = new Dictionary<Waveform, double[]>(); if (usingCommonWaveforms) { foreach (Waveform wf in waveformDependentVariables.Values) { WaveformEquationInterpolator.stackCount++; if (stackCount > 40) { stackCount = 0; throw new InvalidDataException("Stack count has reached 40 when attempting to interpolation an equation waveform. You have probably created a recursive reference loop using waveform equations. Please remove the offending circular references. Aborting interpolation."); } double[] interpol = wf.getInterpolation(nSamples, startTime, endTime, existingVariables, existingCommonWaveforms); commonWaveformInterpolations.Add(wf, interpol); stackCount--; } } for (int i = 0; i < nSamples; i++) { if (usingTimeVariable) { double time = i * (endTime - startTime) / (double)nSamples + startTime; if (time > wfDuration) time = wfDuration; eq.SetVariable("t", time); } if (usingCommonWaveforms) { foreach (string vname in waveformDependentVariables.Keys) { eq.SetVariable(vname, commonWaveformInterpolations[waveformDependentVariables[vname]][i]); } } try { double val = eq.Calculate(); if ((!double.IsInfinity(val)) && (!double.IsNaN(val))) { output[i + startIndex] = eq.Calculate(); } } catch (Exception) { return; } } } }
public static string getEquationStatusString(string equationString, List<Variable> existingVariables, List<Waveform> existingCommonWaveforms) { dotMath.EqCompiler eq = new EqCompiler(equationString, true); try { eq.Compile(); } catch (Exception e) { return e.Message; } string[] foundvars = eq.GetVariableList(); if (foundvars != null) { List<string> foundVariables = new List<string>(eq.GetVariableList()); List<string> existingVariableNames = new List<string>(); List<string> existingCommonWaveformNames = new List<string>(); foreach (Variable var in existingVariables) { if (!existingVariableNames.Contains(var.VariableName)) { existingVariableNames.Add(var.VariableName); } } if (existingCommonWaveforms != null) { foreach (Waveform wf in existingCommonWaveforms) { if (!existingCommonWaveformNames.Contains(wf.WaveformName)) { existingCommonWaveformNames.Add(wf.WaveformName); } } } foreach (string foundVariableName in foundVariables) { if (foundVariableName != "t") { if (!(existingVariableNames.Contains(foundVariableName))) { if (!existingCommonWaveformNames.Contains(foundVariableName)) { return "No variable or common waveform found with name " + foundVariableName; } } } } } return "Valid equation."; }
/// <summary> /// AddFunctions(EqCompiler): registers all the functions in the library with /// the provided compiler instance. /// </summary> /// <param name="eq"> /// An incoming instance of the equation compiler. /// </param> /// <example> /// <code> /// EqCompiler comp = new EqCompiler("sqrt(a+b)"); /// CFunctionLibrary.AddFunctions( comp ); /// comp.Compile(); /// </code> /// </example> public static void AddFunctions( EqCompiler eq ) { eq.AddFunction( new CAbs() ); eq.AddFunction( new CAcos()); eq.AddFunction( new CAsin()); eq.AddFunction( new CAtan()); eq.AddFunction( new CCeiling()); eq.AddFunction( new CCos()); eq.AddFunction( new CCosh()); eq.AddFunction( new CExp()); eq.AddFunction( new CFloor()); eq.AddFunction( new CLog()); eq.AddFunction( new CLog10()); eq.AddFunction( new CMax() ); eq.AddFunction( new CMin() ); eq.AddFunction( new CRound()); eq.AddFunction( new CSign()); eq.AddFunction( new CSin()); eq.AddFunction( new CSinh()); eq.AddFunction( new CSqrt()); eq.AddFunction( new CTan()); eq.AddFunction( new CTanh()); eq.AddFunction( new CIf() ); }