Skip to content

Commit

Permalink
Improve SquareFreeQ for fractions and gaussian integer numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
axkr committed Dec 2, 2023
1 parent 4aafb6b commit 429e811
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5164,30 +5164,81 @@ private static final class SquareFreeQ extends AbstractFunctionEvaluator {

@Override
public IExpr evaluate(final IAST ast, EvalEngine engine) {
VariablesSet eVar = new VariablesSet(ast.arg1());
final VariablesSet eVar;
boolean hasOption = ast.isAST2() ? true : false;
if (ast.isAST2() && ast.arg2().isFree(x -> x.isRuleAST(), false)) {
eVar = new VariablesSet(ast.arg2());
final VariablesSet exprVariables = new VariablesSet(ast.arg1());
if (eVar.size() != exprVariables.size()) {
// `1`
Errors.printMessage(S.SquareFreeQ, "error",
F.List(F.stringx("Currently not supported: number of variables in expression (" //
+ exprVariables.size() //
+ ") unequals number of user variables (" //
+ eVar.size() //
+ ")")),
engine);
return F.NIL;
}
hasOption = false;
} else {
eVar = new VariablesSet(ast.arg1());
}
if (eVar.isSize(0)) {
IExpr arg1 = ast.arg1();
if (arg1.isZero()) {
return S.False;
}
if (arg1.isInteger()) {
return F.booleSymbol(Primality.isSquareFree(((IInteger) arg1).toBigNumerator()));
if (arg1.isExactNumber()) {
if (arg1.isInteger()) {
return F.booleSymbol(Primality.isSquareFree(((IInteger) arg1).toBigNumerator()));
}
if (arg1.isFraction()) {
return F.booleSymbol(Primality.isSquareFree(((IFraction) arg1).toBigNumerator()) //
&& Primality.isSquareFree(((IFraction) arg1).toBigDenominator()));
}
if (arg1.isComplex()) {
IRational re = ((IComplex) arg1).re();
if (re.isInteger()) {
IRational im = ((IComplex) arg1).im();
if (im.isInteger()) {
IAST factors = GaussianInteger.factorize(((IInteger) re).toBigNumerator(),
((IInteger) im).toBigNumerator(), arg1);
if (factors.isListOfLists()) {
for (int i = 1; i < factors.size(); i++) {
IAST subList = factors.getAST(i);
if (!subList.isList2()) {
return S.False;
}
if (subList.second().isInteger()) {
IInteger exponent = (IInteger) subList.second();
if (exponent.isGE(F.C2)) {
return S.False;
}
}
}
return S.True;
}
}
}
}
return S.False;
}
if (arg1.isAtom()) {
return S.False;
}
}
if (!eVar.isSize(1)) {
// `1` currently not supported in `2`.
Errors.printMessage(S.SquareFreeQ, "unsupported", F.List(F.CEmptyList, S.SquareFreeQ),
Errors.printMessage(S.SquareFreeQ, "unsupported", F.List(eVar.getVarList(), S.SquareFreeQ),
engine);
return F.NIL;
}
try {
IExpr expr = F.evalExpandAll(ast.arg1(), engine);
List<IExpr> varList = eVar.getVarList().copyTo();

if (ast.isAST2()) {
if (hasOption) {
return F.booleSymbol(isSquarefreeWithOption(ast, expr, varList, engine));
}
return F.booleSymbol(isSquarefree(expr, varList));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23651,6 +23651,23 @@ public void testSqrt() {

@Test
public void testSquareFreeQ() {
check("SquareFreeQ(-45+28*I)", //
"False");
check("SquareFreeQ(6+7*I)", //
"True");

// message: SquareFreeQ: Currently not supported: number of variables in expression (2) unequals
// number of user variables (1).
check("SquareFreeQ(x*y^2, x)", //
"SquareFreeQ(x*y^2,x)");
check("SquareFreeQ(x*y^2, y)", //
"SquareFreeQ(x*y^2,y)");

check("SquareFreeQ(5/6)", //
"True");
check("SquareFreeQ(3/4)", //
"False");

check("SquareFreeQ(9)", //
"False");

Expand All @@ -23676,6 +23693,8 @@ public void testSquareFreeQ() {
"False");
check("SquareFreeQ(x^2 + 1, Modulus -> 2)", //
"False");
check("SquareFreeQ(6+6*x+x^2)", //
"True");
}

@Test
Expand Down

0 comments on commit 429e811

Please sign in to comment.