2

Given the equation: 10 = 2x + 3y + 2z, I want to find all the combination of x, y and z between 2 thresholds (e.g. -100 and 100) that make the equation hold true.

So far, I have tried the following with no success (please see the comments):

set.seed(333)

result = 10

# sample random values from uniform distribution
x = runif(100, -100, 100)
y = runif(100, -100, 100)
z = runif(100, -100, 100)

# store the vectors in a single dataframe
df = data.frame(x, y, z)

# find all the combinations of x, y and z
expanded = expand.grid(df)

# calculation with all the combinations
expanded$result = ((expanded$x * 2) + (expanded$y * 3) + (expanded$z * 2)) == result

# show the data where result is 10
expanded[expanded$result, ]

[1] x      y      z      result
<0 rows> (or 0-length row.names)

How would I achieve this?

bird
  • 2,938
  • 1
  • 6
  • 27
  • 4
    I'm not much of a mathematician, but there should be infinite values of `x`, `y`, and `z` that fulfill the equation `10 = 2x + 3y + 2z`. Good luck computing all of them. – Ian Campbell Sep 29 '22 at 19:40
  • 3
    There would be infinitely many in such an underspecified system -- though it's very unlikely you'll find one by random chance. Is there some other constraint you are trying to enforce? It's not clear what you are trying to do exactly. – MrFlick Sep 29 '22 at 19:41
  • Of course, please see the edits :). I agree that doing this by random sampling is a wrong choice - in fact I need the recommendation there (e.g. what method should I use to achieve this as opposed to random sampling). – bird Sep 29 '22 at 19:41
  • 3
    Ignoring for now the uncountable issues raised above, your test for equality is likely going to hit another snag in computing: floating-point equality. Long-story-short: especially with high-precision numbers, finding true equality is never assured. See https://stackoverflow.com/q/9508518/3358272, https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f. In your sampling, you might change your `((expanded$x*2)+...) == result` to `((expanded$x*2)+...) - result < 1e-9` (where `1e-9` is a reasonable start to determine that a number is really close to 10). – r2evans Sep 29 '22 at 19:43
  • 1
    (Note, that should be the *absolute* difference, using `abs(...)`, missed that in the comment. We find none in this 1Mi row sample, the closest being `0.0434` away from 10.) – r2evans Sep 29 '22 at 19:53
  • 2
    Even if you limit to between just two threshold numbers, there are infinitely many such solutions. If you have `10 = 2x + 3y + 2z`. Consider the case where `y` is 10/3. Then you can choose any `x` and then choose `z=-x` so they cancel out. And since there are infinitely many real numbers between any two real numbers, then there are infinitely many solutions. But to be fair, computers do have limits to their precision do they cannot represent any number, – MrFlick Sep 29 '22 at 19:55

2 Answers2

4

A linear equation of three variables can be thought of as a plane in 3D space. Solving your equation for z we have:

z = 5 - x - 1.5 * y

So we can at least see what the solution looks like. Let's examine all the valid integer values of x and y:

df <- expand.grid(x = seq(-100, 100), y = seq(-100, 100))

We can then get the corresponding values of z:

df$z <- 5 - df$x - 1.5 * df$y

But we need to disallow any values of z below -100 or above 100:

df$z[abs(df$z) > 100]  <- NA

And we can plot the resultant plane with the z value shown as a fill color:

ggplot(df, aes(x, y, fill = z)) +
  geom_raster() +
  scale_fill_viridis_c() +
  coord_equal()

enter image description here

These at a glance, are all 25,184 integer solutions of your equation with the given constraints (as others have pointed out, there are of course an infinite number of non-integer solutions), and it's a reasonable approximation of the whole system. You can see all these combinations with

df[!is.na(df$z),]
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Does this mean that finding all the **integer** combinations of these 3 variables (between the mentioned thresholds) is actually possible with this approach? – bird Sep 29 '22 at 20:39
  • 1
    Yes, there are 25,184 integer solutions that obey the constraint of all 3 variables being limited to fall in the range [-100, 100]`, which the last line of code will show you. – Allan Cameron Sep 29 '22 at 20:41
  • This is amazing! I love how both answers very elegantly answer the question. I will accept this answer since it is easier to understand the implementation and math behind it. – bird Oct 01 '22 at 09:32
3

As multiple commenters have noted, your equation 10 = 2x + 3y + 2z forms a plane of possible values.

Consider this:

library(plotly)
myfunc <- \(x,y)5-x-(3/2 * y)
y <- x <- seq(-100,100,1)
z <- outer(x, y, myfunc)
plot_ly(x = x, y = y, z = z) %>%
   add_surface()

Graph of plane

As you can see, given unlimited precision, there are an infinite number of points on that plane.

Ian Campbell
  • 23,484
  • 14
  • 36
  • 57