// DETERMINANT
        // first row expansion
        public IComplexNumber Determinant(IComplexMatrix matrix)
        {
            if (matrix.IsScalar())
            {
                return matrix.getElement(0, 0);
            }

            if (matrix.IsSquare())
            {
                IComplexNumber result = ComplexNumberFactory.GenerateZero();
                //IComplexNumber negative = ComplexNumberFactory.Operations.SignReversal(ComplexNumberFactory.generateIdentity());
                IComplexMatrix tempMatrix;
                IComplexNumber tempDeterminant;
                //IComplexNumber tempCoefficient;

                int count = matrix.getNumCols();
                for (int pos = 0; pos < count; pos++)
                {
                    tempMatrix = ComplexMatrixFactory.Operations.RemoveRowCol(matrix, 0, pos);
                    tempDeterminant = ComplexMatrixFactory.Operations.Determinant(tempMatrix);
                    //tempCoefficient = ComplexNumberFactory.Operations.Power(negative, pos);
                    if (pos % 2 == 0)
                    { result = ComplexNumberFactory.Operations.Add(result, tempDeterminant); }
                    else
                    { result = ComplexNumberFactory.Operations.Substract(result, tempDeterminant); }

                }

                return result;
            }

            throw new ExceptionMatrixDimension();
        }
        // CONJUGATE
        public IComplexMatrix Conjugate(IComplexMatrix matrix)
        {
            int maxRow = matrix.getNumRows();
            int maxCol = matrix.getNumCols();
            IComplexMatrix resultMatrix = ComplexMatrixFactory.GenerateComplexMatrix(maxRow, maxCol, false);
            IComplexNumber coefficient;

            for (int i = 0; i < maxRow; i++)
            {
                for (int j = 0; j < maxCol; j++)
                {
                    coefficient = ComplexNumberFactory.Operations.Conjugate(matrix.getElement(i, j));
                    resultMatrix.setElement(coefficient, i, j);
                }
            }

            return resultMatrix;
        }
        // ADDITION
        public IComplexMatrix Add(IComplexMatrix matrixA, IComplexMatrix matrixB)
        {
            int maxRow = System.Math.Min(matrixA.getNumRows(), matrixB.getNumRows());
            int maxCol = System.Math.Min(matrixA.getNumCols(), matrixB.getNumCols());
            //if (matrixA.getNumRows() != matrixB.getNumCols()) { throw new ExceptionMatrixDimension(); };

            IComplexMatrix resultMatrix = ComplexMatrixFactory.GenerateComplexMatrix(maxRow, maxCol, false);
            IComplexNumber coefficientA, coefficientB;
            IComplexNumber addition;
            for (int i = 0; i < maxRow; i++)
            {
                for (int j = 0; j < maxCol; j++)
                {
                    coefficientA = matrixA.getElement(i, j);
                    coefficientB = matrixB.getElement(i, j);
                    addition = ComplexNumberFactory.Operations.Add(coefficientA, coefficientB);
                    resultMatrix.setElement(addition, i, j);
                }
            }

            return resultMatrix;
        }
        // TRACE
        public IComplexNumber Trace(IComplexMatrix matrix)
        {
            int vectorLength = System.Math.Min(matrix.getNumRows(), matrix.getNumCols());

            IComplexNumber addition;
            IComplexNumber element;

            addition = ComplexNumberFactory.GenerateZero();
            for (int k = 0; k < vectorLength; k++)
            {
                element = matrix.getElement(k, k);

                addition = ComplexNumberFactory.Operations.Add(addition, element);
            }

            return addition;
        }
        // TENSOR PRODUCT
        public IComplexMatrix Tensor(IComplexMatrix matrixA, IComplexMatrix matrixB)
        {
            int maxRow = matrixA.getNumRows() * matrixB.getNumRows();
            int maxCol = matrixA.getNumCols() * matrixB.getNumCols();

            IComplexMatrix resultMatrix = ComplexMatrixFactory.GenerateComplexMatrix(maxRow, maxCol, false);
            IComplexNumber coefficient;

            for (int Ai = 0; Ai < matrixA.getNumRows(); Ai++)
            {
                for (int Aj = 0; Aj < matrixA.getNumCols(); Aj++)
                {
                    for (int Bi = 0; Bi < matrixB.getNumRows(); Bi++)
                    {
                        for (int Bj = 0; Bj < matrixB.getNumCols(); Bj++)
                        {
                            coefficient = ComplexNumberFactory.Operations.Multiplication(matrixA.getElement(Ai, Aj), matrixB.getElement(Bi, Bj));
                            resultMatrix.setElement(coefficient, Ai * matrixB.getNumRows() + Bi, Aj * matrixB.getNumCols() + Bj);
                        }
                    }
                }
            }

            return resultMatrix;
        }
        // REMOVEROWCOL
        public IComplexMatrix RemoveRowCol(IComplexMatrix matrix, int row, int col)
        {
            int maxRow = matrix.getNumRows() - 1;
            int maxCol = matrix.getNumCols() - 1;
            IComplexMatrix resultMatrix = ComplexMatrixFactory.GenerateComplexMatrix(maxCol, maxRow, false);
            IComplexNumber coefficient;

            int a, b;
            a = 0;
            for (int i = 0; i < maxRow; i++)
            {
                b = 0;
                for (int j = 0; j < maxCol; j++)
                {
                    if ((i != row) && (j != col))
                    {
                        coefficient = matrix.getElement(i, j);
                        resultMatrix.setElement(coefficient, a, b);
                    }
                    else
                    {
                        a--;
                        b--;
                    }
                    b++;
                }
                a++;
            }

            return resultMatrix;
        }
 public double PoweredNormEuclidean(IComplexMatrix matrix)
 {
     double result = 0;
     for (int i = 0; i < matrix.getNumRows(); i++)
     {
         for (int j = 0; j < matrix.getNumCols(); j++)
         {
             result += ComplexNumberFactory.Operations.PoweredNormEuclidean(matrix.getElement(i, j));
         }
     }
     return result;
 }
        // INNER PRODUCT
        public IComplexMatrix Multiplication(IComplexMatrix matrixA, IComplexMatrix matrixB)
        {
            int maxRow = System.Math.Min(matrixA.getNumRows(), matrixB.getNumRows());
            int maxCol = System.Math.Min(matrixA.getNumCols(), matrixB.getNumCols());
            //if (matrixA.getNumRows() != matrixB.getNumCols()) { throw new ExceptionMatrixDimension(); };

            IComplexMatrix resultMatrix = ComplexMatrixFactory.GenerateComplexMatrix(maxRow, maxCol, false);
            IComplexMatrix vectorA, vectorB;
            IComplexNumber coefficient;
            for (int i = 0; i < maxRow; i++)
            {
                for (int j = 0; j < maxCol; j++)
                {
                    vectorA = matrixA.extractRowAsVector(i);
                    vectorB = matrixB.extractColAsVector(j);
                    coefficient = ComplexMatrixFactory.Operations.Dot(vectorA, vectorB);
                    resultMatrix.setElement(coefficient, i, j);
                }
            }

            return resultMatrix;
        }
        // TRANSPOSE
        public IComplexMatrix Transpose(IComplexMatrix matrix)
        {
            int maxRow = matrix.getNumRows();
            int maxCol = matrix.getNumCols();
            IComplexMatrix resultMatrix = FactoryComplexMatrix.generateComplexMatrix(maxCol, maxRow, false);
            IComplexNumber coefficient;

            for (int i = 0; i < maxRow; i++)
            {
                for (int j = 0; j < maxCol; j++)
                {
                    coefficient = FactoryComplexNumber.Operations.SignReversal(matrix.getElement(i, j));
                    resultMatrix.setElement(coefficient, j, i);
                }
            }

            return resultMatrix;
        }
        // UTILITY PRODUCT
        public IComplexMatrix Multiplication(IComplexNumber number, IComplexMatrix matrix)
        {
            int maxRow = matrix.getNumRows();
            int maxCol = matrix.getNumCols();

            IComplexMatrix resultMatrix = FactoryComplexMatrix.generateComplexMatrix(maxRow, maxCol, false);
            IComplexNumber coefficient;

            for (int i = 0; i < maxRow; i++)
            {
                for (int j = 0; j < maxCol; j++)
                {
                    coefficient = FactoryComplexNumber.Operations.Multiplication(number, matrix.getElement(i, j));
                    resultMatrix.setElement(coefficient, i, j);
                }
            }

            return resultMatrix;
        }