# Hyperplane equation coefficients

I am stuck to this very simple problem, on paper, but I cannot see a way of having Mathematica giving me the coefficients of a hyperplane equation given n+1 points in n dimensions.

Let's simplify this and move to 2D, where I have equations as ax + by + c = 0. I have tried to use Solve to get a, b, and c, but the answer wasn't what I expected:

p1 = {0, 0}
p2 = {1, 0}

Solve[
(a*x + b*y + c == 0 /. x -> p1[[1]] /. y -> p1[[2]])
&&
(a*x + b*y + c == 0 /. x -> p2[[1]] /. y -> p2[[2]]),
{a, b, c}
]

{{a -> 0., c -> 0.}} (* answer *)


Well, yes, the answer is obviously correct as y = 0 is the solution. But I'd like it to give me only one choice of coefficients, with the free one of its choice (maybe 1?).

Is there a way of having Solve choose a particular free parameter as solution?

Perhaps Solve isn't a great choice in this case?

• This is the situation where I like representing hyperplanes as determinants: With[{p1 = {0, 0}, p2 = {1, 0}}, Det[{{x, y, 1}, Append[p1, 1], Append[p2, 1]}] == 0]. Jan 29, 2021 at 15:58
• @J.M. thanks, that is an interesting way! Solve then is not suited to the task? Jan 29, 2021 at 16:01
• "not suited" is a strong phrase, but I would say that Solve[] does too much work here. Jan 29, 2021 at 16:02
• If {a,b,c}is one solution, then ALL the solutions are of the form {k*a,k*b,k*c} with k any non-zero. So (this is a standard trick with homogeneous coordinates) we can scale any coefficient to $1$ (as long as that coefficient does not vanish for all choices of $k$). So one way is to simply set a=1. Then let Solve do its magic to get unique b,c. And then scale all three as above. That way you have b,c, in terms of a. If you want them in terms of b then set b=1 and proceed as above. Jan 29, 2021 at 16:19
• Of course, then you need to be prepared for the exceptional case when the hyperplane is in some specific position. Like in your example, when the line was vertical and a=0=c for all the solutions. Jan 29, 2021 at 16:22

The list of points:

pts = {{0, 0}, {1, 0}};


Add a $$1$$ at the end of each number and look for the null-space:

NullSpace[Append[#, 1] & /@ pts]
(*    {{0, 1, 0}}    *)


In this case, there is only one null-vector, and it's {0,1,0}, meaning that $$\{x,y,1\}\cdot\{0,1,0\}=0$$ is the only hyperplane passing through all (both) points.

3D example: 3 points in 3D define a plane,

pts = {{2, -9, -5}, {-2, 4, -4}, {6, -8, -3}};
NullSpace[Append[#, 1] & /@ pts]
(*    {{-25, -12, 56, 222}}    *)


meaning that the plane $$\{x,y,z,1\}\cdot\{-25, -12, 56, 222\}=0$$ describes the plane passing through three points.

The advantage of this method is that degenerate cases are flagged as such: consider, for example, three collinear points in 3D,

pts = {{1, 0, 0}, {2, 0, 0}, {3, 0, 0}};
ns = NullSpace[Append[#, 1] & /@ pts]
(*    {{0, 0, 1, 0}, {0, 1, 0, 0}}    *)


The resulting null-space is two-dimensional, meaning that there are two constraints on the points, which together define a line in 3D (not a plane): $$\{x,y,z,1\}\cdot\{0,0,1,0\}=0\land\{x,y,z,1\}\cdot\{0,1,0,0\}=0$$, which simplifies to $$y=0\land z=0$$:

And @@ Thread[ns . {x, y, z, 1} == 0]
(*    z == 0 && y == 0    *)

• Thanks, Roman. This is nice, I would have liked to avoid computing the null space and using Solve to avoid degenerate cases by hand. I guess I'll have to do it by hand as you suggest. Feb 1, 2021 at 16:29
n = 4;
pts = RandomReal[{-1, 1}, {n, n}]
vars = Table[c[k], {k, 0, n}]
equs = Join[Thread[pts.Take[vars, {2, n + 1}] + vars[[1]] Table[1, n] == 0], {c[0] > 1}]
FindInstance[equs, vars, Reals]


To avoid the trivial solution we should introduce a nonhomogeneous condition like c[0] > 1