//b / a
        private ImageOperationalValue ImageOperationalValueDivide(ImageOperationalValue a, ImageOperationalValue b)
        {
            ImageOperationalValue summ = new ImageOperationalValue();

            if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DenseMatrix))
            {
                DenseMatrix dmTmpMatrix = (DenseMatrix)a.DmImageComponent.Clone();
                dmTmpMatrix.MapInplace(new Func <double, double>((val) => { return((val == 0.0) ? (1.0) : (val)); }));
                summ.DmImageComponent = (DenseMatrix)b.DmImageComponent.PointwiseDivide(dmTmpMatrix);
            }
            else if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DoubleValue))
            {
                DenseMatrix dmTmpMatrix = (DenseMatrix)a.DmImageComponent.Clone();
                dmTmpMatrix.MapInplace(new Func <double, double>((val) => { return((val == 0.0) ? (1.0) : (val)); }));
                summ.DmImageComponent = (DenseMatrix)matrixWithValue(a.DmImageComponent, b.dNumber).PointwiseDivide(dmTmpMatrix);
            }
            else if ((b.operandType() == OperandTypes.DenseMatrix) && (a.operandType() == OperandTypes.DoubleValue))
            {
                DenseMatrix dmTmpMatrix = (DenseMatrix)matrixWithValue(b.DmImageComponent, a.dNumber);
                dmTmpMatrix.MapInplace(new Func <double, double>((val) => { return((val == 0.0) ? (1.0) : (val)); }));
                summ.DmImageComponent = (DenseMatrix)b.DmImageComponent.PointwiseDivide(dmTmpMatrix);
            }


            return(summ);
        }
        private ImageOperationalValue ImageOperationalValueSmoothCos(ImageOperationalValue a, double kernelWidth)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                // сгладить гауссом или косинусом
                int kernelHalfLength = Convert.ToInt32(kernelWidth / 2.0d);
                //double maxL = ((double)kernelHalfLength) * Math.Sqrt(2.0d);
                //DenseMatrix dmKernel = DenseMatrix.Create(2 * kernelHalfLength + 1, 2 * kernelHalfLength + 1, (r, c) =>
                //{
                //    double curDist =
                //        (new PointD(r - (double)kernelHalfLength, c - (double)kernelHalfLength)).Distance(new PointD(0.0d, 0.0d));
                //    return Math.Cos(curDist * Math.PI / (2.0d * maxL));
                //});


                DenseMatrix dmSmoothed = a.DmImageComponent.Conv2(StandardConvolutionKernels.cos, kernelHalfLength);
                res.DmImageComponent = dmSmoothed;
            }
            else
            {
                res.dNumber = a.dNumber;
            }

            return(res);
        }
        //пока что возводит в степень
        //надо посчитать Фурье, отрезать высокие гармоники, вернуть обратно
        //пока отрежем значения, лежащие за пределами интервала 3*sigma от среднего
        private ImageOperationalValue ImageOperationalValueCut(ImageOperationalValue a, double sigmaCount)
        {
            ImageOperationalValue res = new ImageOperationalValue();


            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                //DenseMatrix dmRes = (DenseMatrix)a.DmImageComponent.Clone();

                //determining the new mean value
                DenseMatrix           dmTmp = a.DmImageComponent.Copy();
                DescriptiveStatistics stats = new DescriptiveStatistics(dmTmp.Values);
                double dataMeanTmp          = stats.Mean;
                double standDevTmp          = stats.StandardDeviation;
                double deviationMarginTmp   = sigmaCount * standDevTmp;
                dmTmp.MapInplace(new Func <double, double>((dVal) =>
                {
                    if (Math.Abs(dVal - dataMeanTmp) > deviationMarginTmp)
                    {
                        //double theSign = (dVal - dataMeanTmp) / Math.Abs(dVal - dataMeanTmp);
                        // return double.NaN;
                        return(dataMeanTmp);
                    }
                    else
                    {
                        return(dVal);
                    }
                }));

                //stats = new DescriptiveStatistics(dmTmp.Values);
                //double dataMean = stats.Mean;
                //double standDev = stats.StandardDeviation;
                //double deviationMargin = sigmaCount * standDev;

                ////dmRes.MapInplace(new Func<double, double>((x) => { return Math.Pow(x, sigmaCount); }));
                ////stats = new DescriptiveStatistics(dmRes.Values);
                //dmRes.MapInplace(new Func<double,double>((dVal) =>
                //{
                //    if (Math.Abs(dVal - dataMean) > deviationMargin)
                //    {
                //        //double theSign = (dVal - dataMean)/Math.Abs(dVal - dataMean);
                //        return dataMean;
                //    }
                //    else return dVal;
                //}));

                res.DmImageComponent = dmTmp.Copy();
            }
            else
            {
                res.dNumber = a.dNumber;
            }

            return(res);
        }
        //b + a
        private ImageOperationalValue ImageOperationalValueAdd(ImageOperationalValue a, ImageOperationalValue b)
        {
            ImageOperationalValue summ = new ImageOperationalValue();

            if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DenseMatrix))
            {
                summ.DmImageComponent = a.DmImageComponent + b.DmImageComponent;
            }
            else if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DoubleValue))
            {
                summ.DmImageComponent = a.DmImageComponent + matrixWithValue(a.DmImageComponent, b.dNumber);
            }
            else if ((b.operandType() == OperandTypes.DenseMatrix) && (a.operandType() == OperandTypes.DoubleValue))
            {
                summ.DmImageComponent = b.DmImageComponent + matrixWithValue(b.DmImageComponent, a.dNumber);
            }


            return(summ);
        }
        //b * a
        private ImageOperationalValue ImageOperationalValueMult(ImageOperationalValue a, ImageOperationalValue b)
        {
            ImageOperationalValue summ = new ImageOperationalValue();

            if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DenseMatrix))
            {
                summ.DmImageComponent = (DenseMatrix)b.DmImageComponent.PointwiseMultiply(a.DmImageComponent);
            }
            else if ((a.operandType() == OperandTypes.DenseMatrix) && (b.operandType() == OperandTypes.DoubleValue))
            {
                summ.DmImageComponent = (DenseMatrix)a.DmImageComponent.PointwiseMultiply(matrixWithValue(a.DmImageComponent, b.dNumber));
            }
            else if ((b.operandType() == OperandTypes.DenseMatrix) && (a.operandType() == OperandTypes.DoubleValue))
            {
                summ.DmImageComponent = (DenseMatrix)b.DmImageComponent.PointwiseMultiply(matrixWithValue(b.DmImageComponent, a.dNumber));
            }


            return(summ);
        }
        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));
                dmGradY  = (DenseMatrix)dmGradY.Multiply(0.5d);
                dmyPlus1 = null;
                ServiceTools.FlushMemory();

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

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

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmOrig    = (DenseMatrix)a.DmImageComponent.Clone();
                DenseMatrix dmxPlus1  = (DenseMatrix)a.DmImageComponent.Clone();
                DenseMatrix dmxMinus1 = (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);
                    }
                }));

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

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

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

            return(res);
        }
        private ImageOperationalValue ImageOperationalValuePow(ImageOperationalValue a, double powerExponent)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmRes = (DenseMatrix)a.DmImageComponent.Clone();
                dmRes.MapInplace(new Func <double, double>((x) => { return(Math.Pow(x, powerExponent)); }));
                res.DmImageComponent = dmRes;
            }
            else
            {
                res.dNumber = Math.Pow(a.dNumber, powerExponent);
            }

            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);
        }
        private ImageOperationalValue ImageOperationalValueAbs(ImageOperationalValue a)
        {
            ImageOperationalValue res = new ImageOperationalValue();

            if (a.operandType() == OperandTypes.DenseMatrix)
            {
                DenseMatrix dmResLocal = (DenseMatrix)a.DmImageComponent.Clone();
                dmResLocal.MapInplace((val) => Math.Abs(val));
                res.DmImageComponent = dmResLocal;
                ServiceTools.FlushMemory();
            }
            else
            {
                res.dNumber = Math.Abs(a.dNumber);
            }

            return(res);
        }
        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);
        }