/// <summary> /// Efectua a combinação de vectores, colocando o resultado no primeiro. /// </summary> /// <typeparam name="T">O tipo dos objectos que constituem as entradas dos vectores.</typeparam> /// <param name="replacementArray">O vector a ser substituído.</param> /// <param name="combinationArray">O vector a ser combinado.</param> /// <param name="firstFactor">O primeiro factor.</param> /// <param name="secondFactor">O segundo factor.</param> /// <param name="ring">O objecto responsáel pelas operações sobre as entradas dos vectores.</param> private void CombineArrays <T>( T[] replacementArray, T[] combinationArray, T firstFactor, T secondFactor, IRing <T> ring) { var length = replacementArray.Length; for (int i = 0; i < length; ++i) { var firstValue = ring.Multiply(firstFactor, replacementArray[i]); var secondValue = ring.Multiply(secondFactor, combinationArray[i]); replacementArray[i] = ring.Add(firstValue, secondValue); } }
/// <summary> /// Obtém o produto do número complexo actual com outro número complexo. /// </summary> /// <param name="right">O outro número complexo.</param> /// <param name="ring">O anel responsável pelas operações.</param> /// <returns>O resultado do produto.</returns> /// <exception cref="ArgumentNullException">Se algum dos argumentos for nulo.</exception> public ComplexNumber <ObjectType> Multiply(ComplexNumber <ObjectType> right, IRing <ObjectType> ring) { if (ring == null) { throw new ArgumentNullException("ring"); } else if (right == null) { throw new ArgumentNullException("right"); } else { var result = new ComplexNumber <ObjectType>(); result.realPart = ring.Add( ring.Multiply(this.realPart, right.realPart), ring.AdditiveInverse(ring.Multiply(this.imaginaryPart, right.imaginaryPart))); result.imaginaryPart = ring.Add(ring.Multiply( this.realPart, right.imaginaryPart), ring.Multiply(this.imaginaryPart, right.realPart)); return(result); } }
public static T DefaultPow <T>(this IRing <T> ring, T t, int n) { T b = t; T result = ring.One; while (n != 0) { if (n % 2 != 0) { result = ring.Multiply(result, b); } if (n == 1) { break; } n /= 2; b = ring.Multiply(b, b); } return(result); }
/// <summary> /// Obtém o produto da matriz corrente com outra matriz. /// </summary> /// <param name="right">A outra matriz.</param> /// <param name="ring">O anel.</param> /// <returns>O resultado do produto.</returns> public ArrayMathMatrix <ObjectType> ParallelMultiply( ArrayMathMatrix <ObjectType> right, IRing <ObjectType> ring) { if (right == null) { throw new ArgumentNullException("right"); } else if (ring == null) { throw new ArgumentNullException("ring"); } else { var columnNumber = this.numberOfColumns; var lineNumber = right.numberOfColumns; if (columnNumber != lineNumber) { throw new MathematicsException("To multiply two matrices, the number of columns of the first must match the number of lines of second."); } else { var firstDimension = this.numberOfLines; var secondDimension = right.numberOfColumns; var result = new ArrayMathMatrix <ObjectType>( firstDimension, secondDimension); Parallel.For(0, firstDimension, i => { for (int j = 0; j < secondDimension; ++j) { var addResult = ring.AdditiveUnity; for (int k = 0; k < columnNumber; ++k) { var multResult = ring.Multiply( this.elements[i][k], right.elements[k][j]); addResult = ring.Add(addResult, multResult); } result.elements[i][j] = addResult; } }); return(result); } } }
/// <summary> /// Multiplica os valores da linha pelo escalar definido. /// </summary> /// <param name="line">A linha a ser considerada.</param> /// <param name="scalar">O escalar a ser multiplicado.</param> /// <param name="ring">O objecto responsável pela operações de multiplicação e determinação da unidade aditiva.</param> public virtual void ScalarLineMultiplication( int line, ObjectType scalar, IRing <ObjectType> ring) { if (line < 0 || line >= this.elements.Length) { throw new ArgumentOutOfRangeException("line"); } else if (ring == null) { throw new ArgumentNullException("ring"); } else if (scalar == null) { throw new ArgumentNullException("scalar"); } else { var currentLineValue = this.elements[line]; // Se o escalar proporcionado for uma unidade aditiva, a linha irá conter todos os valores. if (ring.IsAdditiveUnity(scalar)) { var lineLength = currentLineValue.Length; for (int i = 0; i < lineLength; ++i) { currentLineValue[i] = scalar; } } else if (!ring.IsMultiplicativeUnity(scalar)) { var lineLength = currentLineValue.Length; for (int i = 0; i < lineLength; ++i) { var columnValue = currentLineValue[i]; if (!ring.IsAdditiveUnity(columnValue)) { columnValue = ring.Multiply(scalar, columnValue); currentLineValue[i] = columnValue; } } } } }
/// <summary> /// Multiplica os valores da linha pelo escalar definido. /// </summary> /// <param name="line">A linha a ser considerada.</param> /// <param name="scalar">O escalar a ser multiplicado.</param> /// <param name="ring">O objecto responsável pela operações de multiplicação e determinação da unidade aditiva.</param> public void ScalarLineMultiplication(int line, CoeffType scalar, IRing<CoeffType> ring) { var dimension = this.diagonalElements.Length; if (ring == null) { throw new ArgumentNullException("ring"); } else if (line < 0 || line >= dimension) { throw new ArgumentOutOfRangeException("line"); } else { this.diagonalElements[line] = ring.Multiply( this.diagonalElements[line], scalar); } }
/// <summary> /// Multiplica os valores da linha pelo escalar definido. /// </summary> /// <param name="line">A linha a ser considerada.</param> /// <param name="scalar">O escalar a ser multiplicado.</param> /// <param name="ring">O objecto responsável pela operações de multiplicação e determinação da unidade aditiva.</param> public override void ScalarLineMultiplication(int line, CoeffType scalar, IRing <CoeffType> ring) { if (ring == null) { throw new ArgumentNullException("ring"); } else if (line < 0 || line >= this.numberOfLines) { throw new ArgumentOutOfRangeException("line"); } else { var currentLine = this.elements[line]; for (int i = 0; i < this.numberOfColumns; ++i) { currentLine[i] = ring.Multiply(currentLine[i], scalar); } } }
/// <summary> /// Substitui a linha especificada por uma combinação linear desta com uma outra. Por exemplo, li = a * li + b * lj, isto é, /// a linha i é substituída pela soma do produto de a pela linha i com o produto de b peloa linha j. /// </summary> /// <param name="i">A linha a ser substituída.</param> /// <param name="j">A linha a ser combinada.</param> /// <param name="a">O escalar a ser multiplicado pela primeira linha.</param> /// <param name="b">O escalar a ser multiplicado pela segunda linha.</param> /// <param name="ring">O objecto responsável pelas operações sobre os coeficientes.</param> public void CombineLines(int i, int j, int a, int b, IRing <int> ring) { var lineslength = this.bitMatrix.Length; if (i < 0 || i >= lineslength) { throw new ArgumentNullException("i"); } else if (j < 0 || j >= lineslength) { throw new ArgumentNullException("j"); } else if (ring == null) { throw new ArgumentNullException("ring"); } else { var replacementLine = this.bitMatrix[i]; if (ring.IsAdditiveUnity(a)) { if (ring.IsAdditiveUnity(b)) { var replacementLineLenght = replacementLine.Count; for (int k = 0; k < replacementLineLenght; ++k) { replacementLine[k] = a; } } else if (ring.IsMultiplicativeUnity(b)) { var combinationLine = this.bitMatrix[j]; var replacementLineLenght = replacementLine.Count; for (int k = 0; k < replacementLineLenght; ++k) { replacementLine[k] = combinationLine[k]; } } else { var combinationLine = this.bitMatrix[j]; var replacementLineLenght = replacementLine.Count; for (int k = 0; k < replacementLineLenght; ++k) { var value = combinationLine[k]; if (ring.IsAdditiveUnity(value)) { replacementLine[k] = value; } else if (ring.IsMultiplicativeUnity(value)) { replacementLine[k] = b; } else { replacementLine[k] = ring.Multiply(b, value); } } } } else { if (ring.IsAdditiveUnity(b)) { if (!ring.IsMultiplicativeUnity(a)) { var replacementLineLenght = replacementLine.Count; for (int k = 0; k < replacementLineLenght; ++k) { var value = replacementLine[k]; replacementLine[k] = ring.Multiply(a, value); } } } else if (ring.IsMultiplicativeUnity(b)) { var combinationLine = this.bitMatrix[j]; var replacementLineLenght = replacementLine.Count; if (ring.IsMultiplicativeUnity(a)) { for (int k = 0; k < replacementLineLenght; ++k) { replacementLine[k] = ring.Add(replacementLine[k], combinationLine[k]); } } else { for (int k = 0; k < replacementLineLenght; ++k) { var replacementValue = ring.Multiply(replacementLine[k], a); replacementLine[k] = ring.Add(replacementValue, combinationLine[k]); } } } else { var combinationLine = this.bitMatrix[j]; var replacementLineLenght = replacementLine.Count; for (int k = 0; k < replacementLineLenght; ++k) { var replacementValue = ring.Multiply(replacementLine[k], a); var combinationValue = ring.Multiply(combinationLine[k], b); replacementLine[k] = ring.Add(replacementValue, combinationValue); } } } } }
/// <summary> /// Substitui a linha especificada por uma combinação linear desta com uma outra. Por exemplo, li = a * li + b * lj, isto é, /// a linha i é substituída pela soma do produto de a pela linha i com o produto de b peloa linha j. /// </summary> /// <param name="i">A linha a ser substituída.</param> /// <param name="j">A linha a ser combinada.</param> /// <param name="a">O escalar a ser multiplicado pela primeira linha.</param> /// <param name="b">O escalar a ser multiplicado pela segunda linha.</param> /// <param name="ring">O objecto responsável pelas operações sobre os coeficientes.</param> public void CombineLines(long i, long j, ObjectType a, ObjectType b, IRing <ObjectType> ring) { var lineslength = this.elements.LongLength; if (i < 0 || i >= lineslength) { throw new ArgumentNullException("i"); } else if (j < 0 || j >= lineslength) { throw new ArgumentNullException("j"); } else if (a == null) { throw new ArgumentNullException("a"); } else if (b == null) { throw new ArgumentNullException("b"); } else if (ring == null) { throw new ArgumentNullException("ring"); } else { var replacementLine = this.elements[i]; if (ring.IsAdditiveUnity(a)) { if (ring.IsAdditiveUnity(b)) { var replacementLineLenght = replacementLine.LongLength; for (var k = 0L; k < replacementLineLenght; ++k) { replacementLine[k] = a; } } else if (ring.IsMultiplicativeUnity(b)) { var combinationLine = this.elements[j]; var replacementLineLenght = replacementLine.LongLength; for (int k = 0; k < replacementLineLenght; ++k) { replacementLine[k] = combinationLine[k]; } } else { var combinationLine = this.elements[j]; var replacementLineLenght = replacementLine.LongLength; for (var k = 0L; k < replacementLineLenght; ++k) { var value = combinationLine[k]; if (ring.IsAdditiveUnity(value)) { replacementLine[k] = value; } else if (ring.IsMultiplicativeUnity(value)) { replacementLine[k] = b; } else { replacementLine[k] = ring.Multiply(b, value); } } } } else { if (ring.IsAdditiveUnity(b)) { if (!ring.IsMultiplicativeUnity(a)) { var replacementLineLenght = replacementLine.LongLength; for (var k = 0L; k < replacementLineLenght; ++k) { var value = replacementLine[k]; replacementLine[k] = ring.Multiply(a, value); } } } else if (ring.IsMultiplicativeUnity(b)) { var combinationLine = this.elements[j]; var replacementLineLenght = replacementLine.LongLength; if (ring.IsMultiplicativeUnity(a)) { for (var k = 0L; k < replacementLineLenght; ++k) { replacementLine[k] = ring.Add(replacementLine[k], combinationLine[k]); } } else { for (var k = 0L; k < replacementLineLenght; ++k) { var replacementValue = ring.Multiply(replacementLine[k], a); replacementLine[k] = ring.Add(replacementValue, combinationLine[k]); } } } else { var combinationLine = this.elements[j]; var replacementLineLenght = replacementLine.LongLength; for (var k = 0L; k < replacementLineLenght; ++k) { var replacementValue = ring.Multiply(replacementLine[k], a); var combinationValue = ring.Multiply(combinationLine[k], b); replacementLine[k] = ring.Add(replacementValue, combinationValue); } } } } }