public override bool Equals(object obj)
        {
            MatrixDimensions d = obj as MatrixDimensions;

            if (d != null)
            {
                if (d.rows == rows && d.cols == cols)
                {
                    return(true);
                }
            }
            return(false);
        }
        public static void TestMatrixMultiplication()
        {
            MatrixMultiplication matMul = new MatrixMultiplication();

            MatrixDimensions[] mats = new MatrixDimensions[] { new MatrixDimensions(1, 2), new MatrixDimensions(2, 3), new MatrixDimensions(3, 4) };
            Console.WriteLine("the minimum number of multiplications needed is {0}", matMul.LeastNumOfOperationsInMatrixChainMultiplication(mats));

            mats = new MatrixDimensions[] { new MatrixDimensions(10, 30), new MatrixDimensions(30, 5), new MatrixDimensions(5, 60) };
            Console.WriteLine("the minimum number of multiplications needed is {0}", matMul.LeastNumOfOperationsInMatrixChainMultiplication(mats));

            mats = new MatrixDimensions[] { new MatrixDimensions(40, 20), new MatrixDimensions(20, 30), new MatrixDimensions(30, 10), new MatrixDimensions(10, 30) };
            Console.WriteLine("the minimum number of multiplications needed is {0}", matMul.LeastNumOfOperationsInMatrixChainMultiplication(mats));
        }
        /// <summary>
        /// Получает  группу переналадок  по его имени в Preactor поле Name,
        /// attributeNChangeoverMatrixStr  только для получения данных, для создания использовать только attribute1ChangeoverMatrix
        /// </summary>
        /// <param name="chOvName">Имя  группы переналадок  в преакторе поле Name</param>
        /// <returns></returns>
        public ChangeoverGroupDTO GetByNo(string chOvName)
        {
            logger.Trace($"Получение  группы переналадок  по номеру начато {chOvName}");
            string requestStr = $"~{{$Name}}~==~{chOvName}~";
            int    recordNo   = _preactor.FindMatchingRecord(_entityName, 0, requestStr);
            int    firstRecNo = recordNo;
            Dictionary <MatrixDimensions, TimeSpan> attribute1ChangeoverMatrix = new Dictionary <MatrixDimensions, TimeSpan>();
            Dictionary <MatrixDimensions, TimeSpan> attribute2ChangeoverMatrix = new Dictionary <MatrixDimensions, TimeSpan>();
            Dictionary <MatrixDimensions, TimeSpan> attribute3ChangeoverMatrix = new Dictionary <MatrixDimensions, TimeSpan>();
            Dictionary <MatrixDimensions, TimeSpan> attribute4ChangeoverMatrix = new Dictionary <MatrixDimensions, TimeSpan>();
            Dictionary <MatrixDimensions, TimeSpan> attribute5ChangeoverMatrix = new Dictionary <MatrixDimensions, TimeSpan>();

            Dictionary <MatrixStringDimensions, TimeSpan> attribute1ChangeoverMatrixStr = new Dictionary <MatrixStringDimensions, TimeSpan>();
            Dictionary <MatrixStringDimensions, TimeSpan> attribute2ChangeoverMatrixStr = new Dictionary <MatrixStringDimensions, TimeSpan>();
            Dictionary <MatrixStringDimensions, TimeSpan> attribute3ChangeoverMatrixStr = new Dictionary <MatrixStringDimensions, TimeSpan>();
            Dictionary <MatrixStringDimensions, TimeSpan> attribute4ChangeoverMatrixStr = new Dictionary <MatrixStringDimensions, TimeSpan>();
            Dictionary <MatrixStringDimensions, TimeSpan> attribute5ChangeoverMatrixStr = new Dictionary <MatrixStringDimensions, TimeSpan>();

            if (recordNo < 0)
            {
                return(null);
            }

            MatrixDimensions    size1       = _preactor.MatrixFieldSize(_entityName, "Attribute 1 Changeover Matrix", recordNo);
            MatrixDimensions    size2       = _preactor.MatrixFieldSize(_entityName, "Attribute 2 Changeover Matrix", recordNo);
            MatrixDimensions    size3       = _preactor.MatrixFieldSize(_entityName, "Attribute 3 Changeover Matrix", recordNo);
            MatrixDimensions    size4       = _preactor.MatrixFieldSize(_entityName, "Attribute 4 Changeover Matrix", recordNo);
            MatrixDimensions    size5       = _preactor.MatrixFieldSize(_entityName, "Attribute 5 Changeover Matrix", recordNo);
            AttributeRepo       attrRepo    = new AttributeRepo(_preactor);
            List <AttributeDTO> attrService = attrRepo.GetAll().ToList();
            string xStr;
            string yStr;

            for (int indexX = 1; indexX <= size1.X; indexX++)
            {
                for (int indexY = 1; indexY <= size1.Y; indexY++)
                {
                    try
                    {
                        double value = _preactor.ReadFieldDouble(_entityName, "Attribute 1 Changeover Matrix", recordNo, indexX, indexY);
                        attribute1ChangeoverMatrix.Add(new MatrixDimensions(indexX, indexY), TimeSpan.FromDays(value));
                        xStr = attrService[0].Attribute1.FirstOrDefault(x => x.OrderNumber == indexX).Name;
                        yStr = attrService[0].Attribute1.FirstOrDefault(x => x.OrderNumber == indexY).Name;
                        attribute1ChangeoverMatrixStr.Add(new MatrixStringDimensions(xStr, yStr), TimeSpan.FromDays(value));
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message + " (ChangeoverGroup matrix1) " + ex.TargetSite.Name + " ChangeoverGroup name" + chOvName);
                    }
                }
            }
            for (int indexX = 1; indexX <= size2.X; indexX++)
            {
                for (int indexY = 1; indexY <= size2.Y; indexY++)
                {
                    try
                    {
                        double value = _preactor.ReadFieldDouble(_entityName, "Attribute 2 Changeover Matrix", recordNo, indexX, indexY);
                        attribute2ChangeoverMatrix.Add(new MatrixDimensions(indexX, indexY), TimeSpan.FromDays(value));
                        xStr = attrService[1].Attribute2.FirstOrDefault(x => x.OrderNumber == indexX).Name;
                        yStr = attrService[1].Attribute2.FirstOrDefault(x => x.OrderNumber == indexY).Name;
                        attribute1ChangeoverMatrixStr.Add(new MatrixStringDimensions(xStr, yStr), TimeSpan.FromDays(value));
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message + " (ChangeoverGroup matrix2) " + ex.TargetSite.Name + " ChangeoverGroup name" + chOvName);
                    }
                }
            }
            for (int indexX = 1; indexX <= size3.X; indexX++)
            {
                for (int indexY = 1; indexY <= size3.Y; indexY++)
                {
                    try
                    {
                        double value = _preactor.ReadFieldDouble(_entityName, "Attribute 3 Changeover Matrix", recordNo, indexX, indexY);
                        attribute3ChangeoverMatrix.Add(new MatrixDimensions(indexX, indexY), TimeSpan.FromDays(value));
                        xStr = attrService[2].Attribute3.FirstOrDefault(x => x.OrderNumber == indexX).Name;
                        yStr = attrService[2].Attribute3.FirstOrDefault(x => x.OrderNumber == indexY).Name;
                        attribute1ChangeoverMatrixStr.Add(new MatrixStringDimensions(xStr, yStr), TimeSpan.FromDays(value));
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message + " (ChangeoverGroup matrix3) " + ex.TargetSite.Name + " ChangeoverGroup name" + chOvName);
                    }
                }
            }
            for (int indexX = 1; indexX <= size4.X; indexX++)
            {
                for (int indexY = 1; indexY <= size4.Y; indexY++)
                {
                    try
                    {
                        double value = _preactor.ReadFieldDouble(_entityName, "Attribute 4 Changeover Matrix", recordNo, indexX, indexY);
                        attribute4ChangeoverMatrix.Add(new MatrixDimensions(indexX, indexY), TimeSpan.FromDays(value));
                        xStr = attrService[3].Attribute4.FirstOrDefault(x => x.OrderNumber == indexX).Name;
                        yStr = attrService[3].Attribute4.FirstOrDefault(x => x.OrderNumber == indexY).Name;
                        attribute1ChangeoverMatrixStr.Add(new MatrixStringDimensions(xStr, yStr), TimeSpan.FromDays(value));
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message + " (ChangeoverGroup matrix4) " + ex.TargetSite.Name + " ChangeoverGroup name" + chOvName);
                    }
                }
            }
            for (int indexX = 1; indexX <= size5.X; indexX++)
            {
                for (int indexY = 1; indexY <= size5.Y; indexY++)
                {
                    try
                    {
                        double value = _preactor.ReadFieldDouble(_entityName, "Attribute 5 Changeover Matrix", recordNo, indexX, indexY);
                        attribute5ChangeoverMatrix.Add(new MatrixDimensions(indexX, indexY), TimeSpan.FromDays(value));
                        xStr = attrService[4].Attribute5.FirstOrDefault(x => x.OrderNumber == indexX).Name;
                        yStr = attrService[4].Attribute5.FirstOrDefault(x => x.OrderNumber == indexY).Name;
                        attribute1ChangeoverMatrixStr.Add(new MatrixStringDimensions(xStr, yStr), TimeSpan.FromDays(value));
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex.Message + " (ChangeoverGroup matrix5) " + ex.TargetSite.Name + " ChangeoverGroup name" + chOvName);
                    }
                }
            }


            int      id        = 0;
            string   _chOvName = "";
            TimeSpan attr1CT   = default(TimeSpan);
            TimeSpan attr2CT   = default(TimeSpan);
            TimeSpan attr3CT   = default(TimeSpan);
            TimeSpan attr4CT   = default(TimeSpan);
            TimeSpan attr5CT   = default(TimeSpan);

            try
            {
                id        = _preactor.ReadFieldInt(_entityName, "Number", firstRecNo);
                _chOvName = _preactor.ReadFieldString(_entityName, "Name", firstRecNo);
                attr1CT   = TimeSpan.FromDays(_preactor.ReadFieldDouble(_entityName, "Attribute 1 Changeover Time", firstRecNo));
                attr2CT   = TimeSpan.FromDays(_preactor.ReadFieldDouble(_entityName, "Attribute 2 Changeover Time", firstRecNo));
                attr3CT   = TimeSpan.FromDays(_preactor.ReadFieldDouble(_entityName, "Attribute 3 Changeover Time", firstRecNo));
                attr4CT   = TimeSpan.FromDays(_preactor.ReadFieldDouble(_entityName, "Attribute 4 Changeover Time", firstRecNo));
                attr5CT   = TimeSpan.FromDays(_preactor.ReadFieldDouble(_entityName, "Attribute 5 Changeover Time", firstRecNo));
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message + " (header)" + ex.TargetSite.Name + " ChangeoverGroup" + chOvName);
            }
            ChangeoverGroupDTO result = new ChangeoverGroupDTO()
            {
                Id   = id,
                Name = _chOvName,
                Attribute1ChangeoverTime      = attr1CT,
                Attribute2ChangeoverTime      = attr2CT,
                Attribute3ChangeoverTime      = attr3CT,
                Attribute4ChangeoverTime      = attr4CT,
                Attribute5ChangeoverTime      = attr5CT,
                Attribute1ChangeoverMatrix    = attribute1ChangeoverMatrix,
                Attribute2ChangeoverMatrix    = attribute2ChangeoverMatrix,
                Attribute3ChangeoverMatrix    = attribute3ChangeoverMatrix,
                Attribute4ChangeoverMatrix    = attribute4ChangeoverMatrix,
                Attribute5ChangeoverMatrix    = attribute5ChangeoverMatrix,
                Attribute1ChangeoverMatrixStr = attribute1ChangeoverMatrixStr,
                Attribute2ChangeoverMatrixStr = attribute2ChangeoverMatrixStr,
                Attribute3ChangeoverMatrixStr = attribute3ChangeoverMatrixStr,
                Attribute4ChangeoverMatrixStr = attribute4ChangeoverMatrixStr,
                Attribute5ChangeoverMatrixStr = attribute5ChangeoverMatrixStr
            };

            logger.Trace($"Получение ChangeoverGroup по имени завершено {chOvName}");
            return(result);
        }