private double CalculateNode(TreeNode topNode, IReadOnlyTable <double> variableTable, IReadOnlyTable <FinishedFunction> functionTable, double[] parameters) { switch (topNode) { case UndefinedVariableTreeNode vNode: { throw new Exception(String.Format("Variable \"{0}\" is not defined", vNode.Name)); } case UndefinedFunctionTreeNode fNode: { throw new Exception(String.Format("Function \"{0}\" is not defined", fNode.Name)); } case NumberTreeNode lNode: { return(lNode.Value); } case FunctionParameterTreeNode fpNode: { return(parameters[fpNode.Index]); } case FunctionIndexTreeNode iNode: { double[] localParameters = new double[iNode.Parameters.Length]; for (int p = 0; p < iNode.Parameters.Length; ++p) { localParameters[p] = CalculateNode(iNode.Parameters[p], variableTable, functionTable, parameters); } // note that we call that function with its own local parameters return(CalculateNode(functionTable[iNode.Index].TopNode.Clone(), variableTable, functionTable, localParameters)); } case VariableIndexTreeNode iNode: { return(variableTable[iNode.Index]); } case UnaryOperationTreeNode uNode: { double operand = CalculateNode(uNode.Child, variableTable, functionTable, parameters); return(uNode.Operation.Function(operand)); } case BinaryOperationTreeNode bNode: { double leftOperand = CalculateNode(bNode.LeftChild, variableTable, functionTable, parameters); double rightOperand = CalculateNode(bNode.RightChild, variableTable, functionTable, parameters); return(bNode.Operation.Function(leftOperand, rightOperand)); } default: throw new Exception("Unknown tree node"); } }
// this calculator can't work with remote functions, so it inserts function trees directly into code void ConvertAndReplaceParameters(TreeNode node, IReadOnlyTable <FinishedFunction> functionTable, MemoryStream stream, TreeNode[] parameters) { // why rewrite old code? DefaultLinker linker = new DefaultLinker(); node = linker.ReplaceParametersWithTreeNodes(node, parameters); }
private void LogChangedEntities(int userId) { foreach (var ent in DbContext.ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified)) { if (ent.Entity != null && ent.Entity is IReadOnlyTable) { IReadOnlyTable entity = (IReadOnlyTable)ent.Entity; _logger.LogTrace("Saving Entity: {name}, {id}, {state}, {userId}", ent.Metadata.Name, entity.Id, ent.State, userId); } } }
internal static bool TryGet(this IReadOnlyTable table, string key, out string?value) { if (!table.TryGet(Encoding.UTF8.GetBytes(key), out var raw)) { value = default; return(false); } value = raw == null ? null : Encoding.UTF8.GetString(raw); return(true); }
public FinishedFunction(TreeNode topNode, IReadOnlyTable <double> variableTable, IReadOnlyTable <FinishedFunction> functionTable, int parameterCount = 0) { if (!topNode.IsFinished) { throw new ArgumentException("Tree is not finished"); } TopNode = topNode ?? throw new ArgumentNullException(nameof(topNode)); VariableTable = variableTable; FunctionTable = functionTable; ParameterCount = parameterCount; }
bool IsConstant(TreeNode node, IReadOnlyTable <double> variableTable, out double constantValue) { if (node is NumberTreeNode lNode) { constantValue = lNode.Value; return(true); } else if (node is VariableIndexTreeNode viChild && variableTable != null) { constantValue = variableTable[viChild.Index]; return(true); }
protected FilesSourceBase(IReadOnlyTable table, RuntimeContext context) { _communicator = context; var sources = new List <DirectorySourceSearchOptions>(); foreach (var row in table.Rows) { sources.Add(new DirectorySourceSearchOptions(new DirectoryInfo((string)row[0]).FullName, (bool)row[1])); } _source = sources.ToArray(); }
public CsvSource(IReadOnlyTable table, RuntimeContext context) : this(context) { _files = new CsvFile[table.Count]; for (int i = 0; i < table.Count; ++i) { var row = table.Rows[i]; _files[i] = new CsvFile() { FilePath = (string)row[0], Separator = (string)row[1], HasHeader = (bool)row[2], SkipLines = (int)row[3] }; } }
internal static bool ContainsKey(this IReadOnlyTable table, string key, out bool removed) { return(table.ContainsKey(Encoding.UTF8.GetBytes(key), out removed)); }
private double[] CalculateNodeMultiple(TreeNode topNode, IReadOnlyTable <double> variableTable, IReadOnlyTable <FinishedFunction> functionTable, double[][] parameters, Queue <double[]> freeValueBuffers) { int iterations = parameters.GetLength(0); double[] result = (freeValueBuffers.Count > 0) ? freeValueBuffers.Dequeue() : new double[iterations]; switch (topNode) { case UndefinedVariableTreeNode vNode: { throw new Exception(String.Format("Variable \"{0}\" is not defined", vNode.Name)); } case UndefinedFunctionTreeNode fNode: { throw new Exception(String.Format("Function \"{0}\" is not defined", fNode.Name)); } case NumberTreeNode lNode: { for (int i = 0; i < iterations; ++i) { result[i] = lNode.Value; } return(result); } case FunctionParameterTreeNode fpNode: { for (int i = 0; i < iterations; ++i) { result[i] = parameters[i][fpNode.Index]; } return(result); } case VariableIndexTreeNode iNode: { for (int i = 0; i < iterations; ++i) { result[i] = variableTable[iNode.Index]; } return(result); } case FunctionIndexTreeNode iNode: { freeValueBuffers.Enqueue(result); // we don't need it double[][] localParameters = new double[iNode.Parameters.Length][]; for (int p = 0; p < iNode.Parameters.Length; ++p) { localParameters[p] = CalculateNodeMultiple(iNode.Parameters[p], variableTable, functionTable, parameters, freeValueBuffers); } // note that we call that function with its own local parameters return(CalculateNodeMultiple(functionTable[iNode.Index].TopNode, variableTable, functionTable, localParameters, freeValueBuffers)); } case UnaryOperationTreeNode uNode: { double[] operands = CalculateNodeMultiple(uNode.Child, variableTable, functionTable, parameters, freeValueBuffers); for (int i = 0; i < result.Length; ++i) { result[i] = uNode.Operation.Function(operands[i]); } freeValueBuffers.Enqueue(operands); return(result); } case BinaryOperationTreeNode bNode: { double[] leftOperands = CalculateNodeMultiple(bNode.LeftChild, variableTable, functionTable, parameters, freeValueBuffers); double[] rightOperands = CalculateNodeMultiple(bNode.RightChild, variableTable, functionTable, parameters, freeValueBuffers); for (int i = 0; i < result.Length; ++i) { result[i] = bNode.Operation.Function(leftOperands[i], rightOperands[i]); } freeValueBuffers.Enqueue(leftOperands); freeValueBuffers.Enqueue(rightOperands); return(result); } default: throw new Exception("Unknown tree node"); } }
public FilesSource(IReadOnlyTable table, RuntimeContext runtimeContext) : base(table, runtimeContext) { }
double[] CalculateMultipleWithBuffer(MemoryStream codeStream, IReadOnlyTable <double> table, double[][] parameters) { int iterations = parameters.GetLength(0); Stack <double[]> resultStack = new Stack <double[]>(); byte[] buffer = new byte[sizeof(double)]; // a small memory & time optimization: it allows multiple usage of number buffers after performing calculations on them Queue <double[]> freeValueBuffers = new Queue <double[]>(); while (true) { int command = codeStream.ReadByte(); if (command == -1) { throw new Exception("Can't execute next command"); } double[] values = (freeValueBuffers.Count > 0) ? freeValueBuffers.Dequeue() : new double[iterations]; if ((PostfixFunction.PostfixCommand)command == PostfixFunction.PostfixCommand.End) { return(resultStack.Pop()); } switch ((PostfixFunction.PostfixCommand)command) { case PostfixFunction.PostfixCommand.PushLiteral: { codeStream.Read(buffer, 0, sizeof(double)); double literal = BitConverter.ToDouble(buffer, 0); for (int i = 0; i < iterations; ++i) { values[i] = literal; } } break; case PostfixFunction.PostfixCommand.PushVariable: { codeStream.Read(buffer, 0, sizeof(int)); int index = BitConverter.ToInt32(buffer, 0); for (int i = 0; i < iterations; ++i) { values[i] = table[index]; } } break; case PostfixFunction.PostfixCommand.PushParameter: { codeStream.Read(buffer, 0, sizeof(int)); int index = BitConverter.ToInt32(buffer, 0); for (int i = 0; i < iterations; ++i) { values[i] = parameters[i][index]; } } break; case PostfixFunction.PostfixCommand.CalculateUnary: { double[] operands = resultStack.Pop(); codeStream.Read(buffer, 0, sizeof(int)); int id = BitConverter.ToInt32(buffer, 0); UnaryOperation operation = (UnaryOperation)Operation.AllOperations[id]; for (int i = 0; i < values.Length; ++i) { values[i] = operation.Function(operands[i]); } // add free buffer to the queue freeValueBuffers.Enqueue(operands); } break; case PostfixFunction.PostfixCommand.CalculateBinary: { // pop in reverse order! double[] rightOperands = resultStack.Pop(); double[] leftOperands = resultStack.Pop(); codeStream.Read(buffer, 0, sizeof(int)); int id = BitConverter.ToInt32(buffer, 0); BinaryOperation operation = (BinaryOperation)Operation.AllOperations[id]; for (int i = 0; i < values.Length; ++i) { values[i] = operation.Function(leftOperands[i], rightOperands[i]); } // add free buffers to the queue freeValueBuffers.Enqueue(rightOperands); freeValueBuffers.Enqueue(leftOperands); } break; } resultStack.Push(values); } }
public static void PrintTable <T>(IReadOnlyTable <T> table) { var columnInfo = Enumerable.Range(0, table.Columns.Count).Select(c => { var isNumeric = true; var maxScale = 0; for (var r = 0; r < table.Rows.Count; r++) { switch (table.Rows[r].Values[c]) { case sbyte sb: var sql = new SqlDecimal(sb); goto PrintTable_SqlDecimal; case byte ub: sql = new SqlDecimal(ub); goto PrintTable_SqlDecimal; case short ss: sql = new SqlDecimal(ss); goto PrintTable_SqlDecimal; case ushort us: sql = new SqlDecimal(us); goto PrintTable_SqlDecimal; case int si: sql = new SqlDecimal(si); goto PrintTable_SqlDecimal; case uint ui: sql = new SqlDecimal(ui); goto PrintTable_SqlDecimal; case long sl: sql = new SqlDecimal(sl); goto PrintTable_SqlDecimal; case ulong ul: sql = new SqlDecimal(Convert.ToDecimal(ul)); goto PrintTable_SqlDecimal; case decimal m: sql = new SqlDecimal(m); PrintTable_SqlDecimal: maxScale = Math.Max(maxScale, sql.Scale); break; case float f: case double d: maxScale = Math.Max(maxScale, 3); //constant floating-point precision break; default: isNumeric = false; break; } } return(IsNumeric: isNumeric, MaxScale: maxScale); }).ToList(); var values = table.Rows.Select(r => r.Values.Select((v, i) => { if (columnInfo[i].IsNumeric && v != null) { return(Convert.ToDecimal(v).ToString(string.Format("#,##0.{0}", new string('0', columnInfo[i].MaxScale)))); } return(v?.ToString()); }).ToList()).ToList(); var columnWidths = Enumerable.Range(0, table.Columns.Count).Select(i => Math.Max(table.Columns[i].Name.Length, values.Max(r => r[i]?.Length) ?? 0)).ToList(); Console.WriteLine("*** {0} ***", table.Name); Console.WriteLine(); Console.WriteLine(string.Join(" | ", table.Columns.Select((c, i) => string.Format(columnInfo[i].IsNumeric ? "{1}{0}" : "{0}{1}", c.Name, new string(' ', columnWidths[i] - c.Name.Length))))); Console.WriteLine(new string('-', columnWidths.Sum() + (columnWidths.Count - 1) * 3)); foreach (var row in values) { Console.WriteLine(string.Join(" | ", row.Select((v, i) => string.Format($"{{0,{(columnInfo[i].IsNumeric ? columnWidths[i] : -columnWidths[i])}}}", v)))); } Console.WriteLine(); Console.WriteLine(); }
void ConvertRecursion(TreeNode node, IReadOnlyTable <FinishedFunction> functionTable, MemoryStream stream) { switch (node) { case UndefinedVariableTreeNode vNode: { throw new Exception(String.Format("Variable \"{0}\" is not defined", vNode.Name)); } case UndefinedFunctionTreeNode fNode: { throw new Exception(String.Format("Function \"{0}\" is not defined", fNode.Name)); } case NumberTreeNode lNode: { stream.WriteByte((byte)PostfixFunction.PostfixCommand.PushLiteral); stream.Write(BitConverter.GetBytes(lNode.Value), 0, sizeof(double)); } break; case FunctionParameterTreeNode fpNode: { stream.WriteByte((byte)PostfixFunction.PostfixCommand.PushParameter); stream.Write(BitConverter.GetBytes(fpNode.Index), 0, sizeof(int)); } break; case VariableIndexTreeNode iNode: { stream.WriteByte((byte)PostfixFunction.PostfixCommand.PushVariable); stream.Write(BitConverter.GetBytes(iNode.Index), 0, sizeof(int)); } break; case FunctionIndexTreeNode fiNode: { TreeNode nodeToInsert = functionTable[fiNode.Index].TopNode.Clone(); ConvertAndReplaceParameters(nodeToInsert, functionTable, stream, fiNode.Parameters); ConvertRecursion(nodeToInsert, functionTable, stream); } break; case UnaryOperationTreeNode uNode: { ConvertRecursion(uNode.Child, functionTable, stream); stream.WriteByte((byte)PostfixFunction.PostfixCommand.CalculateUnary); stream.Write(BitConverter.GetBytes(uNode.Operation.Id), 0, sizeof(int)); } break; case BinaryOperationTreeNode bNode: { // push in normal order, pop in reverse! ConvertRecursion(bNode.LeftChild, functionTable, stream); ConvertRecursion(bNode.RightChild, functionTable, stream); stream.WriteByte((byte)PostfixFunction.PostfixCommand.CalculateBinary); stream.Write(BitConverter.GetBytes(bNode.Operation.Id), 0, sizeof(int)); } break; } }
bool IsNaN(TreeNode node, IReadOnlyTable <double> variableTable) { return(IsConstantValueOf(node, Double.NaN, variableTable)); }
bool IsOne(TreeNode node, IReadOnlyTable <double> variableTable) { return(IsConstantValueOf(node, 1.0, variableTable)); }
bool IsConstantValueOf(TreeNode node, double value, IReadOnlyTable <double> variableTable) { return(IsConstant(node, variableTable, out double constantValue) && constantValue == value); }
public void VisualizeAsTreeRecursion(TreeNode node, IReadOnlyTable <double> variableTable, IReadOnlyTable <FinishedFunction> functionTable, bool recursivelyVisualiseFunctions, string colorStr) { for (int i = 0; i < colorStr.Length; ++i) { if (colorStr[i] == '0') { Console.ForegroundColor = ConsoleColor.Gray; } if (colorStr[i] == '1') { Console.ForegroundColor = ConsoleColor.Red; } if (colorStr[i] == '2') { Console.ForegroundColor = ConsoleColor.Yellow; } if (colorStr[i] == '3') { Console.ForegroundColor = ConsoleColor.Magenta; } Console.Write("| "); Console.ResetColor(); } switch (node) { case NumberTreeNode lTreeNode: { Console.WriteLine(lTreeNode.Value.ToString("G7", System.Globalization.CultureInfo.InvariantCulture)); } break; case UndefinedVariableTreeNode vTreeNode: { Console.ForegroundColor = ConsoleColor.Gray; Console.WriteLine(vTreeNode.Name); Console.ResetColor(); } break; case FunctionParameterTreeNode fpTreeNode: { Console.ForegroundColor = ConsoleColor.DarkGreen; Console.WriteLine(String.Format("${0}", fpTreeNode.Index)); Console.ResetColor(); } break; case VariableIndexTreeNode iTreeNode: { Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(String.Format("V:{0}", iTreeNode.Index)); Console.ResetColor(); } break; case FunctionIndexTreeNode fiTreeNode: { if (recursivelyVisualiseFunctions) { TreeNode clone = functionTable[fiTreeNode.Index].TopNode.Clone(); DefaultLinker linker = new DefaultLinker(); clone = linker.ReplaceParametersWithTreeNodes(clone, fiTreeNode.Parameters); VisualizeAsTreeRecursion(clone, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr); } else { Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine(String.Format("[F:{0}]", fiTreeNode.Index)); foreach (TreeNode child in fiTreeNode.Parameters) { VisualizeAsTreeRecursion(child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '3'); } Console.ResetColor(); } } break; case UndefinedFunctionTreeNode fTreeNode: { Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine(String.Format("{0}()", fTreeNode.Name)); Console.ResetColor(); foreach (TreeNode child in fTreeNode.Parameters) { VisualizeAsTreeRecursion(child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '0'); } break; } case UnaryOperationTreeNode uTreeNode: { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(String.Format("[{0}]", uTreeNode.Operation.FunctionName)); Console.ResetColor(); VisualizeAsTreeRecursion(uTreeNode.Child, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '1'); break; } case BinaryOperationTreeNode bTreeNode: { Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(String.Format("[{0}]", bTreeNode.Operation.FunctionName)); Console.ResetColor(); VisualizeAsTreeRecursion(bTreeNode.LeftChild, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '2'); VisualizeAsTreeRecursion(bTreeNode.RightChild, variableTable, functionTable, recursivelyVisualiseFunctions, colorStr + '2'); break; } } /* * for (int i = 0; i < level; ++i) * { * Console.Write("| "); * } * Console.WriteLine(); */ }