public void Dispose()
 {
     //imgR.Dispose();
     //imgG.Dispose();
     //imgB.Dispose();
     dmR   = null;
     dmG   = null;
     dmB   = null;
     dmRes = null;
     ServiceTools2G.FlushMemory();
     //throw new NotImplementedException();
 }
        private ImageOperationalValue ImageOperationalValueDDY(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmOrig   = (DenseMatrix)a.DmImageComponent.Clone();
                DenseMatrix dmyPlus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmyPlus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row < dmyPlus1.RowCount - 1)
                    {
                        return(dmOrig[row + 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmyMinus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmyMinus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row > 0)
                    {
                        return(dmOrig[row - 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));



                DenseMatrix dmGradY = dmyPlus1 - dmyMinus1;
                dmGradY.MapInplace(new Func <double, double>(x => x / 2.0d));
                dmyPlus1 = null;
                ServiceTools2G.FlushMemory();

                res.DmImageComponent = dmGradY;
                dmGradY = null;
                ServiceTools2G.FlushMemory();
            }
            else
            {
                res.dNumber = 0.0d;
            }

            return(res);
        }
        private ImageOperationalValue ImageOperationalValueMean(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix           dmResLocal = (DenseMatrix)a.DmImageComponent.Clone();
                DescriptiveStatistics stat       = new DescriptiveStatistics(dmResLocal.Values);
                res.dNumber = stat.Mean;
                ServiceTools2G.FlushMemory();
            }
            else
            {
                res.dNumber = a.dNumber;
            }

            return(res);
        }
        private ImageOperationalValue ImageOperationalValueSqrt(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmResLocal = (DenseMatrix)a.DmImageComponent.Clone();
                dmResLocal.MapInplace(new Func <double, double>((val) => Math.Pow(val, 0.5d)));
                res.DmImageComponent = dmResLocal;
                ServiceTools2G.FlushMemory();
            }
            else
            {
                res.dNumber = Math.Sqrt(a.dNumber);
            }

            return(res);
        }
        public static DenseMatrix sRGBluminanceFrom_sRGB(DenseMatrix dmR, DenseMatrix dmG, DenseMatrix dmB)
        {
            //Y_lin = 0.2126 R_lin + 0.7152 G_lin + 0.0722 B_lin


            DenseMatrix dmLuminance;
            DenseMatrix dmLin = (DenseMatrix)dmR.Clone();

            dmLin.MapInplace(new Func <double, double>((val) => val / 255.0d));
            dmLin.MapInplace(new Func <double, double>(sRGBtoLinear));
            dmLin.MapInplace(new Func <double, double>((val) => 0.2126d * val));
            dmLuminance = (DenseMatrix)dmLin.Clone();

            ServiceTools2G.FlushMemory();

            dmLin = (DenseMatrix)dmG.Clone();
            dmLin.MapInplace(new Func <double, double>((val) => val / 255.0d));
            dmLin.MapInplace(new Func <double, double>(sRGBtoLinear));
            dmLin.MapInplace(new Func <double, double>((val) => 0.7152d * val));
            dmLuminance = dmLuminance + dmLin;

            ServiceTools2G.FlushMemory();

            dmLin = (DenseMatrix)dmB.Clone();
            dmLin.MapInplace(new Func <double, double>((val) => val / 255.0d));
            dmLin.MapInplace(new Func <double, double>(sRGBtoLinear));
            dmLin.MapInplace(new Func <double, double>((val) => 0.0722d * val));
            dmLuminance = dmLuminance + dmLin;

            ServiceTools2G.FlushMemory();

            dmLuminance.MapInplace(new Func <double, double>(LinearTo_sRGB));
            dmLuminance.MapInplace(new Func <double, double>((val) => val * 255.0d));

            return(dmLuminance);
        }
        private ImageOperationalValue ImageOperationalValueGrad5p(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmOrig   = a.DmImageComponent.Copy();
                DenseMatrix dmyPlus1 = a.DmImageComponent.Copy();
                dmyPlus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row < dmyPlus1.RowCount - 1)
                    {
                        return(dmOrig[row + 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));
                DenseMatrix dmyPlus2 = a.DmImageComponent.Copy();
                dmyPlus2.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row < dmyPlus2.RowCount - 2)
                    {
                        return(dmOrig[row + 2, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmyMinus1 = a.DmImageComponent.Copy();
                dmyMinus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row > 1)
                    {
                        return(dmOrig[row - 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));
                DenseMatrix dmyMinus2 = a.DmImageComponent.Copy();
                dmyMinus2.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row > 2)
                    {
                        return(dmOrig[row - 2, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));


                DenseMatrix dmGradY = dmyMinus2 - 8.0d * dmyMinus1 + 8.0d * dmyPlus1 - dmyPlus2;
                dmGradY.MapInplace(x => x / 12.0d);

                dmyPlus1  = null;
                dmyMinus1 = null;
                dmyPlus2  = null;
                dmyMinus2 = null;
                ServiceTools2G.FlushMemory();

                DenseMatrix dmxPlus1 = a.DmImageComponent.Copy();
                dmxPlus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column < dmxPlus1.ColumnCount - 1)
                    {
                        return(dmOrig[row, column + 1]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmxPlus2 = a.DmImageComponent.Copy();
                dmxPlus2.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column < dmxPlus2.ColumnCount - 2)
                    {
                        return(dmOrig[row, column + 2]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmxMinus1 = a.DmImageComponent.Copy();
                dmxMinus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column > 1)
                    {
                        return(dmOrig[row, column - 1]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmxMinus2 = a.DmImageComponent.Copy();
                dmxMinus2.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column > 2)
                    {
                        return(dmOrig[row, column - 2]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmGradX = dmxMinus2 - 8.0d * dmxMinus1 + 8.0d * dmxPlus1 - dmxPlus2;
                dmGradX.MapInplace(x => x / 12.0d);

                dmxPlus1  = null;
                dmxMinus1 = null;
                dmxMinus2 = null;
                dmxPlus2  = null;
                ServiceTools2G.FlushMemory();

                res.lDMOtherComponents = new List <DenseMatrix>()
                {
                    dmGradX, dmGradY
                };
                ServiceTools2G.FlushMemory();
            }
            else
            {
                res.dNumber = 0.0d;
            }

            return(res);
        }
        private ImageOperationalValue ImageOperationalValueGrad(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmOrig   = (DenseMatrix)a.DmImageComponent.Clone();
                DenseMatrix dmyPlus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmyPlus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row < dmyPlus1.RowCount - 1)
                    {
                        return(dmOrig[row + 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmyMinus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmyMinus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (row > 1)
                    {
                        return(dmOrig[row - 1, column]);
                    }
                    else
                    {
                        return(val);
                    }
                }));



                //DenseMatrix dmRes = DenseMatrix.Create(dmyPlus1.RowCount, dmyPlus1.ColumnCount, new Func<int,int,double>((x, y) => 0.0d));
                DenseMatrix dmGradY = (dmyPlus1 - dmyMinus1);
                dmGradY.MapInplace(new Func <double, double>(x => x / 2.0d));
                //dmGradY.MapInplace(new Func<double,double>((val) => val/2.0d));

                dmyPlus1 = null;
                //dmyMinus1 = null;
                ServiceTools2G.FlushMemory();

                DenseMatrix dmxPlus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmxPlus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column < dmxPlus1.ColumnCount - 1)
                    {
                        return(dmOrig[row, column + 1]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmxMinus1 = (DenseMatrix)a.DmImageComponent.Clone();
                dmxMinus1.MapIndexedInplace(new Func <int, int, double, double>((row, column, val) =>
                {
                    if (column > 1)
                    {
                        return(dmOrig[row, column - 1]);
                    }
                    else
                    {
                        return(val);
                    }
                }));

                DenseMatrix dmGradX = dmxPlus1 - dmxMinus1;
                dmGradX.MapInplace(new Func <double, double>(x => x / 2.0d));
                //dmGradX.MapInplace(new Func<double, double>((val) => val/2.0d));

                dmxPlus1 = null;
                //dmxMinus1 = null;
                ServiceTools2G.FlushMemory();

                dmGradY.MapInplace(new Func <double, double>((val) => val * val));
                dmGradX.MapInplace(new Func <double, double>((val) => val * val));
                DenseMatrix dmRes = dmGradX + dmGradY;
                dmRes.MapInplace(new Func <double, double>(val => Math.Sqrt(val)));
                //dmRes.MapIndexedInplace(new Func<int,int,double,double>((x, y, val) => { return x+y; }));
                res.DmImageComponent = dmRes;
                dmGradY = null;
                dmGradX = null;
                ServiceTools2G.FlushMemory();
            }
            else
            {
                res.dNumber = 0.0d;
            }

            return(res);
        }
        public void RPNeval(bool forceUsingDistributedMatrixes = false)
        {
            dmRes    = null;
            resValue = 0.0d;
            String input = exprString; //.Replace(" ", "");

            if (!forceUsingDistributedMatrixes)
            {
                if (dmR == null)
                {
                    dmR = ImageProcessing2G.DenseMatrixFromImage(imgR);
                }
                if (dmG == null)
                {
                    dmG = ImageProcessing2G.DenseMatrixFromImage(imgG);
                }
                if (dmB == null)
                {
                    dmB = ImageProcessing2G.DenseMatrixFromImage(imgB);
                }
                dmY = sRGBluminanceFrom_sRGB(dmR, dmG, dmB);
            }

            PostfixNotation rpn = new PostfixNotation();

            string[] converted2RPN = rpn.ConvertToPostfixNotation(input);

            Stack <ImageOperationalValue> stack = new Stack <ImageOperationalValue>();
            Queue <string> queue = new Queue <string>(converted2RPN);
            string         str   = queue.Dequeue();

            while (queue.Count >= 0)
            {
                if (!rpn.operators.Contains(str))
                {
                    pushImageToStackByColorChar(stack, str);
                    if (queue.Count > 0)
                    {
                        try
                        {
                            str = queue.Dequeue();
                        }
                        catch (Exception)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    ImageOperationalValue summ = null;
                    try
                    {
                        switch (str)
                        {
                        case "+":
                        {
                            ImageOperationalValue a = stack.Pop();
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueAdd(a, b);        // b + a
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "-":
                        {
                            ImageOperationalValue a = stack.Pop();
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueSubtract(a, b);        // b - a
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "*":
                        {
                            ImageOperationalValue a = stack.Pop();
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueMult(a, b);        // b * a
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "/":
                        {
                            ImageOperationalValue a = stack.Pop();
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueDivide(a, b);        // b / a
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "^":
                        {
                            double a = stack.Pop().dNumber;
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValuePow(b, a);        // b ^ a
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "grad":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueGrad(a);        // grad(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "grad5p":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueGrad5p(a);        // grad 5-point(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "ddx":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueDDX(a);        // d(a)/dx
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "ddy":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueDDY(a);        // d(a)/dy
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "sqrt":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueSqrt(a);        // grad(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "mean":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueMean(a);        // mean(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "stddev":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueSigm(a);        // mean(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "abs":
                        {
                            ImageOperationalValue a = stack.Pop();
                            summ = ImageOperationalValueAbs(a);        // abs(a)
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "%":
                        {
                            double a = stack.Pop().dNumber;
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueCut(b, a);        // b cut a - cuts "b" matrix elements using "a"*sigma limit of distribution. remember 3-sigma rule?
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        case "smoothcos":
                        {
                            double a = stack.Pop().dNumber;
                            ImageOperationalValue b = stack.Pop();
                            summ = ImageOperationalValueSmoothCos(b, a);        // b cut a - cuts "b" matrix elements using "a"-nodes spreading cos-based kernel
                            ServiceTools2G.FlushMemory(null, "");
                            break;
                        }

                        default:
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                    stack.Push(summ);
                    if (queue.Count > 0)
                    {
                        str = queue.Dequeue();
                    }
                    else
                    {
                        break;
                    }
                }
            }
            //return Convert.ToDecimal(stack.Pop());
            ImageOperationalValue theResult = stack.Pop();

            dmRes    = theResult.DmImageComponent;
            resValue = theResult.dNumber;
            lDMRes   = theResult.lDMOtherComponents;

            if (dmRes != null)
            {
                minValue = dmRes.Values.Min();
                maxValue = dmRes.Values.Max();
            }
            else
            {
                minValue = resValue;
                maxValue = resValue;
            }

            //ThreadSafeOperations.SetTextTB(tbLog, Environment.NewLine + "min value: " + Math.Round(minValue, 2).ToString(), false);
            //ThreadSafeOperations.SetTextTB(tbLog, "max value: " + Math.Round(maxValue, 2).ToString(), true);

            ServiceTools2G.FlushMemory(null, "");
        }