Example how to factor (4*y^2-5*x*y+x^2) ?
axkr opened this issue · 10 comments
Can you provide an example in Java how to factor
(4*y^2-5*x*y+x^2)
into (x-4*y)*(x-y)
?
I've used ring Frac(Z[x, y])
.
Can you also provide an example factoring for GaussianRationals?
For example x^2+1
into (-I+x)*(I+x)
with I
as imaginary unit.
Hi!
Thanks for writing. You are right, that was a bug in the first case related to the irreducibility test of bivariate polynomials based on Newton polytops (in your example the polygon was singular - just a line). I fixed it in the develop - let me know if you need a release.
To factor this poly you can do e.g.:
implicit val ring = MultivariateRing(Q, Array("x", "y"))
val factors = ring.factor(ring("4*y^2-5*x*y+x^2"))
println(ring.stringify(factors))
For GaussianRationals
you can do e.g.:
// by default imaginary unit will be denoted as "i" at stdout
implicit val ring = UnivariateRing(GaussianRationals, "x")
val poly = ring("x^2+1")
val factors = ring.factor(poly)
println(ring.stringify(factors))
For other algebraic number fields you can do e.g.:
// define minimal polynomial which generate number filed
val minimalPoly = UnivariateRing(Q, "x")("x^2 - 2")
// Field of rational numbers extended with square root of 2 (denoted as "sqrt2")
val numberField = AlgebraicNumberField(minimalPoly, "sqrt2")
// polynomial ring
implicit val ring = UnivariateRing(numberField, "x")
val poly = ring("x^2-2")
val factors = ring.factor(poly)
println(ring.stringify(factors))
Rings support multiple field extensions and factorization of multivariate polynomials as well. You can find more examples of number fields here: https://rings.readthedocs.io/en/latest/guide.html#algebraic-number-fields-and-field-extensions
There you can also find Java examples. Let me know if I can help you further.
Yes would be nice if you can create a new Maven release.
@axkr Yep, just released v2.5.4)
I must admit I'm using your experimental implementation from rings25
branch in the current master
branch:
but didn't know anymore the idea for converting to GaussianRationals polynomials?
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java
index 51b2e1d..9286572 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Algebra.java
@@ -41,4 +41,5 @@
import org.matheclipse.core.convert.JASModInteger;
import org.matheclipse.core.convert.VariablesSet;
+import org.matheclipse.core.convert.rings.SymjaRings;
import org.matheclipse.core.eval.EvalAttributes;
import org.matheclipse.core.eval.EvalEngine;
@@ -5446,12 +5447,9 @@
GenPolynomial<Complex<BigRational>> polyRat = jas.expr2JAS(expr, numeric2Rational);
return engine.evaluate(factorComplex((IAST) expr, polyRat, jas, head, cfac));
- } else {
- JASConvert<BigRational> jas = new JASConvert<BigRational>(varList, BigRational.ZERO);
- GenPolynomial<BigRational> polyRat = jas.expr2JAS(expr, numeric2Rational);
- return factorRational(polyRat, jas, head);
- // IExpr temp = SymjaRings.FactorOverQ((IAST) expr, false);
- // if (temp != null && temp.isPresent()) {
- // return temp;
- // }
+ } else {
+ IExpr temp = SymjaRings.FactorOverQ((IAST) expr, false);
+ if (temp != null && temp.isPresent()) {
+ return temp;
+ }
}
} catch (RuntimeException rex) {
In SymjaRings
already contains methods for working in extension fields. So, to factor with GaussianRationals
you can just use SymjaRings.FactorOverExtension(...)
etc. You can find real Symja examples in tests:
All SymjaRings
methods for extensions will capture GaussianRationals
automatically (I
) is you pass automatic = true
, but for other extensions, you have to provide generating elements explicitly (see e.g. SymjaRingsTest.test4
).
So in you Algebra
class you can just call
IExpr factorization = SymjaRings.FactorOverExtension(IExpr expression , IExp[] extensions, boolean automatic, boolean factorSquareFree)
Array extensions
may be empty (equivalent to just Extension->Automatic). Specify factorSquareFree=true
if you need just a square free decomposition. Specify automatic = true
if you want that algebraic expressions meet in expression captured automatically. Always specify extensions = { IExpr.ImaginatyUnit }
if you want to force GaussianRationals.
All conversions are already implemented in SymjaRings.FactorOverExtension
.
Factoring x-I*y
gives -I*(I*x+y)
.
Could you add an option to avoid -I,I,-1,1
as factors
I'm afraid it is not as easy as might look. Monicization is a necessary step for all factoring algorithms; it is used in dozens of places, so it would be quite tedious to propagate such option in Rings (if that makes sense at all). However, if you need to keep lead term unfactored, you can easily perform check in Symja, and e.g. add after this line:
if (factors.size() == 1)
factors = FactorDecomposition.of(ring, rExpr);
Created a new branch rings254
and implemented FactorDecomposition usage:
The following code will not work:
(factors.unit.equals(F.CN1) || //
factors.unit.equals(F.CNI) || //
factors.unit.equals(F.CI))) {
equals
will always return false, because objects have different types (unit is of Rings
type R
and F.CNI
is of type IExpr
).
Probably it is better to check the resulting IASTAppendable
:
if (result.size() == 2) {
if (result.get(0).equals(F.CN1) || //
result.get(0).equals(F.CNI) || //
result.get(0).equals(F.CI)))
return expr;
}