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");
            }
        }
Beispiel #2
0
        // 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);
        }
Beispiel #3
0
 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);
         }
     }
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
 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);
     }
Beispiel #7
0
        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();
        }
Beispiel #8
0
        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]
                };
            }
        }
Beispiel #9
0
 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");
            }
        }
Beispiel #11
0
 public FilesSource(IReadOnlyTable table, RuntimeContext runtimeContext)
     : base(table, runtimeContext)
 {
 }
Beispiel #12
0
        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();
        }
Beispiel #14
0
        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();
             */
        }