# Given $ax^2+bxy+cy^2+dx+ey+f$, what is the best way to get {a,b,c,d,e,f}?

Test cases:

SeedRandom[0]
rand = RandomInteger[{-5, 5}, {5, 6}]
poly = rand.{x^2, x y, y^2, x, y, 1}

res1 = MonomialList[#, {x, y}, "DegreeLexicographic"] /. x | y -> 1 & /@ poly

res2 = CoefficientRules[#, {x, y}, "DegreeLexicographic"][[All, 2]] & /@ poly

res1 == rand
res2 == rand


{{5, 2, -5, 3, -3, -4}, {0, 3, -5, 1, 2, 5}, {-3, -4, -5, 1, -4, -3}, {5, 5, 3, 5, 1, 5}, {0, 0, 3, -1, 0, 4}}

{-4 + 3 x + 5 x^2 - 3 y + 2 x y - 5 y^2, 5 + x + 2 y + 3 x y - 5 y^2, -3 + x - 3 x^2 - 4 y - 4 x y - 5 y^2, 5 + 5 x + 5 x^2 + y + 5 x y + 3 y^2, 4 - x + 3 y^2}

{{5, 2, -5, 3, -3, -4}, {3, -5, 1, 2, 5}, {-3, -4, -5, 1, -4, -3}, {5, 5, 3, 5, 1, 5}, {3, -1, 4}}

{{5, 2, -5, 3, -3, -4}, {3, -5, 1, 2, 5}, {-3, -4, -5, 1, -4, -3}, {5, 5, 3, 5, 1, 5}, {3, -1, 4}}

False

False

When one of the coefficients is zero, I want to get 0, not a missing entry.

• Are you only interested in quadratic polynomials? Jun 4, 2018 at 13:06
• @CarlWoll If it can be generalized would be better. Jun 5, 2018 at 3:49

CoefficientArrays come to mind, but it needs some tweaking. The below solutions work for polynomials of order $2$.

## Demonstration

{m0, m1, m2} = CoefficientArrays[poly[[1]], {x, y}] // Normal


{-4, {3, -3}, {{5, 2}, {0, -5}}}

We want upper-right triangular elements of m2:

Flatten@Table[m2[[i, i ;;]], {i, 1, Length@m2}]


{5, 2, -5}

Make it a function:

RU[m_] := Flatten@Table[m[[i, i ;;]], {i, 1, Length@m}]


and Join it with m1 and m0:

RU[m2]~Join~m1~Join~{m0}


{5, 2, -5, 3, -3, -4}

## Function

Clear@RU

coeff[pol_] :=
Block[{ca = CoefficientArrays[pol, {x, y}] // Normal // Reverse, RU},
RU[m_] := Flatten@Table[m[[i, i ;;]], {i, 1, Length@m}];
RU[First@ca]~Join~Flatten@Rest@ca]

(coeff /@ poly) == rand


True

The function coeff gives the coefficients in the exact same order as the OP requested.

## Three variables

However, a re-arrangement of the terms will make the computations easier:

SeedRandom[0]
rand3 = RandomInteger[{-5, 5}, {3, 10}]
poly3 = rand3.{x^2, y^2, z^2, x y, y z, x z, x, y, z, 1};


{{5, 2, -5, 3, -3, -4, 0, 3, -5, 1}, {2, 5, -3, -4, -5, 1, -4, -3, 5, 5}, {3, 5, 1, 5, 0, 0, 3, -1, 0, 4}}

So here squares come first, then mixed terms, first order terms, and the free term.

{m0, m1, m2} = CoefficientArrays[poly3[[1]], {x, y, z}] // Normal


{1, {0, 3, -5}, {{5, 3, -4}, {0, 2, -3}, {0, 0, -5}}}

Then

Flatten[Table[Diagonal[m2, k], {k, 0, 2}]]~Join~m1~Join~{m0}


{5, 2, -5, 3, -3, -4, 0, 3, -5, 1}

and

% == rand3[[1]]


True

The same line of reasoning should apply to any number of variables, hence

## N variables

coeffN = Module[{ca = CoefficientArrays[#, Variables@#] // Normal},
Flatten[Table[Diagonal[ca[[3]], k], {k, 0, 2}]]~Join~ca[[2]]~Join~{ca[[1]]}
] &;


E.g.

(coeffN /@ poly3) == rand3


True

You can also use CoefficientList as follows:

Flatten[Table[Diagonal[#, -i], {i , 0, Length[#[[1]]] - 1}]] & /@


{{5, 2, -5, 3, -3, -4},
{0, 3, -5, 1, 2, 5},
{-3, -4, -5, 1, -4, -3},
{5, 5, 3, 5, 1, 5},
{0, 0, 3, -1, 0, 4}}

% == rand


True

For arbitrary polynomials in two variables, we can define a function

ClearAll[dlexCL]
dlexCL = Module[{cl = Reverse @ CoefficientList[#, Variables[#]]}, Flatten @
Table[Diagonal[PadLeft[cl, {#, #}&@Length@cl[[1]]], -i], {i, 0, Length@cl[[1]] - 1}]]&;

dlexCL /@ poly == rand


True

dlexCL[1 + x^2 + 3 x^3 y + 2 y^4, {x, y}]


{0, 3, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}

Given ax^2+bxy+cy^2+dx+ey+f, what is the best way to get {a,b,c,d,e,f}?

expr = a x^2 + b x y + c y^2 + d x + e y + f;
r = Flatten[CoefficientList[expr, {x, y}]]
DeleteCases[r, 0]


I find a combination of Series and LogicalExpand useful for this sort of problem:

pattern = a x^2 + b x y + c y^2 + d x + e y + f;

vars = {a, b, c, d, e, f};

res =
vars /. Flatten[
Solve[LogicalExpand[Series[pattern == #, {x, 0, 2}, {y, 0, 2}]],
vars]] & /@ poly;

res == rand
(* True *)