public static Polynom <T, R> GetGcd(Polynom <T, R> a, Polynom <T, R> b) { var _alocal = new Polynom <T, R>(a); var _zero = new Polynom <T, R>(_alocal.FRing, -1); var _one = new Polynom <T, R>(_alocal.FRing, 0); var gcd = _zero; if (_alocal.Degree < 0) { gcd = b; } else if (b.Degree < 0) { gcd = _alocal; } else { var r1 = b; var r2 = new List <Polynom <T, R> >(); var _quot = _alocal.Div(b, r2); gcd = b; var q = _zero; var temp = new List <Polynom <T, R> >(); var temp1 = _zero; while (r2.Last().Degree >= 0) { gcd = r2.Last(); q = r1.Div(r2.Last(), temp); //r1 = r2.Last(); r1 = gcd; r2 = temp; } } var _major = gcd.FCoeffs[gcd.Degree]; if (!_alocal.FRing.Equals(_major, _alocal.FRing.One)) { var _major_1 = _alocal.FRing.Reverse(_major); gcd.Mult(_major_1); } return(gcd); }
private List <Polynom <T, R> > Factorisation(Polynom <T, R> aPolynom) { if (!(aPolynom.FRing is IEnumerable <T>)) { throw new ArgumentException("Polinom's ring mast be enumerable."); } var p = (int)aPolynom.FRing.Size; var _res = new List <Polynom <T, R> >(); if (aPolynom.Degree < 2) { return(_res); } var _pring = new Rx <T, R>(aPolynom.FRing); var _derivative = aPolynom.Derivative; var _gcd = Polynom <T, R> .GetGcd(aPolynom, _derivative); if (_gcd.Degree > 0) { if (_derivative != _pring.Zero) { _res.Add(_gcd); _res.Add(aPolynom.Div(_gcd, null)); } else { p = (int)aPolynom.FRing.SimpleSubfieldSize; var c = aPolynom.Degree / p; var _pol = new Polynom <T, R>(aPolynom.FRing, c); for (var i = 0; i <= c; i++) { _pol.FCoeffs[i] = aPolynom.FRing.Pow( aPolynom.FCoeffs[p * i], this.FRing.Size / p); } for (var i = 0; i < p; i++) { _res.Add(new Polynom <T, R>(_pol)); } } return(_res); } var _aij_vals = new T[aPolynom.Degree, aPolynom.Degree]; for (var i = 1; i < aPolynom.Degree; i++) { var _pol = new Polynom <T, R>(aPolynom.FRing, i * p); _pol.FCoeffs[i] = aPolynom.FRing.Opposite(aPolynom.FRing.One); var _rem = new List <Polynom <T, R> >(); _pol.Div(aPolynom, _rem); var _ai = _rem.Last(); for (var j = 0; j <= _ai.Degree; j++) { _aij_vals[j, i - 1] = _ai.FCoeffs[j]; } } var _aij = new Matrix <T, R>(aPolynom.FRing, _aij_vals); var _matrix = Matrix <T, R> .SolveLs(_aij); var _solvation = new T[_matrix.RowCount + 1]; _solvation[0] = aPolynom.FRing.Zero; bool IsResEmpty = true; var _matrixValues = _matrix.Values; for (var i = 0; i < _matrix.RowCount; i++) { if (_solvation[i + 1] == null) { _solvation[i + 1] = aPolynom.FRing.Zero; } for (var j = 0; j < _matrix.ColumnCount; j++) { _solvation[i + 1] = aPolynom.FRing.Sum(_solvation[i + 1], _matrixValues[i, j]); } IsResEmpty = _solvation[i + 1].Equals(aPolynom.FRing.Zero); } if (!IsResEmpty) { var _pp = new Polynom <T, R>(aPolynom.FRing, _solvation); var _gcd1 = _pring.One; var _enumerable = (IEnumerable <T>) this.FRing; foreach (var _item in _enumerable) { var _ppp = new Polynom <T, R>(_pp); _ppp.FCoeffs[0] = _ppp.FRing.Sum(_item, _ppp.FCoeffs[0]); _gcd1 = Polynom <T, R> .GetGcd(aPolynom, _ppp); if (!_gcd1.Equals(_pring.One)) { _res.Add(_gcd1); var _rem = new List <Polynom <T, R> >(); var _quot = aPolynom.Div(_gcd1, _rem); _res.Add(_quot); break; } } } return(_res); }
public static Polynom <T, R> GetGcdEx(Polynom <T, R> a, Polynom <T, R> b, out Polynom <T, R> u, out Polynom <T, R> v) { var _alocal = new Polynom <T, R>(a); var _zero = new Polynom <T, R>(_alocal.FRing, -1); var _one = new Polynom <T, R>(_alocal.FRing, 0); var gcd = _zero; if (_alocal.Degree < 0) { u = _zero; v = (b.Degree < 0 ? _zero : _one); gcd = b; } else if (b.Degree < 0) { v = _zero; u = (_alocal.Degree < 0 ? _zero : _one); gcd = _alocal; } else { var r1 = b; var r2 = new List <Polynom <T, R> >(); var _quot = _alocal.Div(b, r2); gcd = b; var u1 = _one; var u2 = _zero; var v1 = _one; var v2 = _one; var q = _zero; if (r2.Last().Degree < 0) { u1 = _zero; } else { v1 = -_quot; } var temp = new List <Polynom <T, R> >(); var temp1 = _zero; while (r2.Last().Degree >= 0) { gcd = r2.Last(); q = r1.Div(r2.Last(), temp); //r1 = r2.Last(); r1 = gcd; r2 = temp; temp1 = u1; u1 = u2 - u1 * q; u2 = temp1; temp1 = v1; v1 = v2 - v1 * q; v2 = temp1; } u = u2; v = v2; } var _major = gcd.FCoeffs[gcd.Degree]; if (!_alocal.FRing.Equals(_major, _alocal.FRing.One)) { var _major_1 = _alocal.FRing.Reverse(_major); gcd.Mult(_major_1); } var _sum = u * a + v * b; _major = _sum.FCoeffs[_sum.Degree]; if (!_alocal.FRing.Equals(_major, _alocal.FRing.One)) { var _major_1 = _alocal.FRing.Reverse(_major); u.Mult(_major_1); v.Mult(_major_1); } return(gcd); }