I am looking for a robust way to factor an expression (if applicable) to become x^n*(rest) as we do it by hand.

**edit** The input will only be of type `+` and I am looking for a way extract a common factor to convert the input to **term^n*(rest) **where term is the common factor to pull out.

For example, given **x^2*Y+x **and the symbol is given as **x** the result will be **x*(x*Y+1) **and if the input is **Y^2*x^3-x^3 **then the output is **x^3*(Y^2-1) **and if there is no common factor **x** to pull out from all the terms, the output will be the same as the input.

I tried many commands and options, but can't find one method that works all the time for all cases.

For example for ** x^2*Y+x **the command **factor(x^2*Y+x) **gives **(Y - 1)*(Y + 1)*x^3 **which is not what I want. There is no option to **factor **to give the name to factor on. And I did not know how to use the last argument of function to do that.

But here **simplify(x^2*Y+x) **happened to work on this and gives **(Y^2 - 1)*x^3 **but simplify does not work on first example. **simplify(x^2*Y+x) **returns the same expression back. So simplify is not reliable to use.

I tried collect, with options **factor** and **simplify**. Again, they work on one examples but not others.

**collect(x^2*Y+x,x); **does not do it. But **collect(Y^2*x^3-x^3,x); **works and returns **(Y^2 - 1)*x^3** which is what I want.

The problem is that I do not know what the expression looks like. I just know the name **x **and want to find if there is a common **x **to any power that can be pulled out to rewite the expression as **x^n*(rest) **where **n **is an integer or rational number depending.

This seems like a simple problem. But can't find a Maple command for. I could ofcourse program it by brute force. Go over each term in the expression, check if each term has a free **x **to any power in it multiplied by something else, then collect all these **x^n **term in a list. At end find the **x **which is raised to lowest power, and then divide the whole expression by it.

Here is another way I can also try: Use **factor** and also **collect** and also **simplify**. One at a time. Each time I check if the result is of type `*` but not a division! (check that denom is 1). If so, Then check if result has two operands only. If so, check if op(1,result) is for form x^anything. If so, then one of these cases worked. Need to try this now to see if it will work on all cases I have.

Is there a better way to do this in Maple? It has to work on all expresions f(x) without knowing what the expression looks like.

**update**

I've updated the test cases and included all algorithms given to compare. It is hard in Maple to make a nice table to present results and keep math formatting below.

restart;
makegrid := proc(M::Matrix)#https://www.mapleprimes.com/questions/202902-How-To-Create-Table-Like-Output-For
uses DocumentTools:-Layout;
local i,j,m,n,wks;
m,n := op(1,M);
wks := Worksheet(Table(alignment=center,width=20,
seq(Column(),j=1..n),
seq(Row(seq(Cell(Textfield(sprintf("%a",M[i,j]))),
j=1..n)),i=1..m)));
DocumentTools:-InsertContent(wks);
end proc:
acer_V1_common_factor := proc(x::algebraic, ee::algebraic)
local p, d := gcd(ee, x^frontend(degree,[ee,x]),'p');
d * p;
end proc:
acer_V2_common_factor := proc(x, ee) local d, t;
if ee::`+` then
t := max(map(proc(u) local r:=frontend(degree,[u,x]);
`if`(r::numeric,r,0); end proc,[op(ee)]));
d := gcd(numer(ee),x^t);
d*map(u->u/d,ee);
else ee; end if;
end proc:
dharr_common_factor:=proc(x,z)
local xn:=x^ldegree(collect(z,x),x);
if rem(z,xn,x)=0 then xn*quo(z,xn,x) else z end if;
end proc:
me_common_factor:=proc(term,expr)
local tmp;
local T1;
local update_T1:=proc()
T1:= hastype(op(1,tmp),identical(term)^anything) or hastype(op(1,tmp),identical(term));
if not T1 then
T1:= hastype(op(2,tmp),identical(term)^anything) or hastype(op(2,tmp),identical(term));
fi;
end proc;
if type(expr,`*`) or not has(expr,term) then
return expr;
fi;
tmp := collect(expr,term);
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
update_T1();
if T1 then
return tmp;
fi;
fi;
tmp :=factor(expr);
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
update_T1();
if T1 then
return tmp;
fi;
fi;
tmp := simplify(expr);
if type(tmp,`*`) and evalb(denom(tmp)=1) and evalb(nops(tmp)=2) then
update_T1();
if T1 then
return tmp;
fi;
fi;
return expr;
end proc:
############################
test_data:=[[x,x^2*Y+x],
[x,Y^2*x^3-x^3],
[x,x],
[x,x+2*x^2],
[x,x^4*diff(y(x),x)+x^7],
[x,x^4*diff(y(x),x)+x^7-sin(x)],
[y(x),y(x)^4*diff(y(x),x$2)^2*diff(y(x),x)+y(x)^2*diff(y(x),x)+y(x)],
[y(x),y(x)^4*diff(y(x),x$2)^2+y(x)^2*diff(y(x),x)+y(x)^9],
[x,x^4*y^2+x^2*y^2],
[y(x),y(x)^4*diff(y(x),x)^2+y(x)^2*diff(y(x),x)^2],
[diff(y(x),x),y(x)^4*diff(y(x),x)^2+y(x)^2*diff(y(x),x)^2],
[diff(y(x),x),y(x)*diff(y(x),x$2)^2*diff(y(x),x)*sin(x)+diff(y(x),x)^3],
[y(x),diff(y(x),x)-(1+x^(1/2))/(1+y(x)^(1/2))],
[y(x),diff(y(x),x) -(x-1)*y(x)^5/x^2/(-y(x)+2*y(x)^3)],
[y(x),3*y(x)+diff(y(x),x) - 2*x/exp(3*x)],
[x,3*x^2*y^3+7*x/y],
[y,A-(1+x)/(1+y^(1/2))]
]:
RESULT:=Matrix(nops(test_data),6);
for N,item in test_data do
term:=item[1];
expr:=item[2];
RESULT[N,1]:=term; RESULT[N,2]:=expr;
try
result:=acer_V1_common_factor(term,expr);
if type(result,`*`) and denom(result)<>1 then
RESULT[N,3]:=expr;#bypass, not correct output
else
RESULT[N,3]:=result;#accept
fi;
catch:
RESULT[N,3]:=expr;#reject
end try;
try
result:=acer_V2_common_factor(term,expr);
if type(result,`*`) and denom(result)<>1 then
RESULT[N,4]:=expr;#bypass, not correct output
else
RESULT[N,4]:=result;#accept
fi;
catch:
RESULT[N,4]:=expr;#reject
end try;
try
result:=dharr_common_factor(term,expr);
if type(result,`*`) and denom(result)<>1 then
RESULT[N,5]:=expr;#bypass, not correct output
else
RESULT[N,5]:=result;#accept
fi;
catch:
RESULT[N,5]:=expr;#reject
end try;
try
result:=me_common_factor(term,expr);
if type(result,`*`) and denom(result)<>1 then
RESULT[N,6]:=expr;#bypass, not correct output
else
RESULT[N,6]:=result;#accept
fi;
catch:
RESULT[N,6]:=expr;#reject
end try;
od:
RESULT

how_to_do_special_factor.mw

Mapleprime will not let let insert content for some reason. Here is the output as screen shot but it is hard to read. But it is in the above worksheet.