Is there a general solution method for one unknown if the unknown variable changes?

I have a simple algebraic relationship that uses three variables. I can guarantee that I know two of the three and the third must decide, but I do not necessarily know which of the two variables I will know. I am looking for one method or algorithm that can handle any cases without a huge batch of conventions. This may not be possible, but I would like to implement it in a more general sense, and not in the code in all respects from the point of view of other variables. For example, if it was a link:

3x - 5y + z = 5 

I do not want to code this:

 function(int x, int y) { return 5 - 3x + 5y; } function(int x, int z) { return (5 - z - 3x)/(-5); } 

And so on. Is there a standard way to solve such programming problems? Maybe using matrices, parameterization, etc.?

+7
c # algorithm symbolic-math
source share
4 answers

If you restrict yourself to the linear functions shown above, you can generalize this function as

 3x - 5y + z = 5 

will become

 a[0]*x[0] + a[1]*x[1] + a[2]*x[2] = c 

with a = { 3, -5, 1 } and c = 5 .

Ie you need a list (or array) of constant factors List<double> a; and the variable list List<double?> x; plus a constant on the right side of double c;

 public double Solve(IList<double> a, IList<double?> x, double c) { int unknowns = 0; int unkonwnIndex = 0; // Initialization required because the compiler is not smart // enough to infer that unknownIndex will be initialized when // our code reaches the return statement. double sum = 0.0; if (a.Count != x.Count) { throw new ArgumentException("a[] and x[] must have same length"); } for (int i = 0; i < a.Count; i++) { if (x[i].HasValue) { sum += a[i] * x[i].Value; } else { unknowns++; unknownIndex = i; } } if (unknowns != 1) { throw new ArgumentException("Exactly one unknown expected"); } return (c - sum) / a[unknownIndex]; } 

Example:

 3x - 5y + z = 5 5 - (- 5y + z) x = -------------- 3 

As you can see from the example, the solution consists of subtracting the sum of all members except the unknown member from the constant, and then dividing by the coefficient of the unknown. Therefore, my decision remembers the index of the unknown.


You can generalize with such powers, considering that you have an equation

 a[0]*x[0]^p[0] + a[1]*x[1]^p[1] + a[2]*x[2]^p[2] = c 

you need an additional parameter IList<int> p , and the result will be

 return Math.Pow((c - sum) / a[unknownIndex], 1.0 / p[unknownIndex]); 

as x ^ (1/n) equals nth-root(x) .


If you use doubling for authority, you can even represent functions such as

  5 7*x^3 + --- + 4*sqrt(z) = 11 y^2 a = { 7, 5, 4 }, p = { 3, -2, 0.5 }, c = 11 

because

  1 x^(-n) = --- x^n 

and

 nth-root(x) = x^(1/n) 

However, you cannot find the roots of true nonlinear polynomials of type x^2 - 5x = 7 . The algorithm shown above only works if the unknown appears exactly once in the equation.

+6
source share

There is no standard way to solve this problem.

In the general case, symbolic math is a problem solved by target built-in libraries, Math.NET has a symbolic library that may interest you: http://symbolics.mathdotnet.com/

Ironically, a much more complex task - a system of linear equations - can easily be solved by a computer by computing the inverse matrix. You can customize the provided equation this way, but there are no general-purpose Matrix built-in classes in .NET.

In your specific case, you can use something like this:

 public int SolveForVar(int? x, int? y, int? z) { int unknownCount = 0; int currentSum = 0; if (x.HasValue) currentSum += 3 * x.Value; else unknownCount++; if (y.HasValue) currentSum += -5 * y.Value; else unknownCount++; if (z.HasValue) currentSum += z.Value; else unknownCount++; if (unknownCount > 1) throw new ArgumentException("Too Many Unknowns"); return 5 - currentSum; } int correctY = SolveForVar(10, null, 3); 

Obviously, this approach becomes cumbersome for a large number of variables and does not work if you need a lot of dynamic numbers or complex operations, but it can be generalized to a certain extent.

+2
source share

Yes, there is one function:

 private double? ValueSolved (int? x, int? y, int? z) { if (y.HasValue && z.HasValue && !x.HasValue return (5 + (5 * y.Value) - z.Value) / 3; if (x.HasValue && z.HasValue && !y.HasValue return (5 - z.Value - (3 * x.Value)) / -5; if (x.HasValue && y.HasValue && !z.HasValue return 5 - (3 * x.Value) + (5 * y.Value); return null; } 
+2
source share

I'm not sure what you are looking for since the question is marked with symbolic-math , but the code sample that you have is a numerical solution, not a symbolic one.

If you want to find a numerical solution for a more general case, then define a function

 f(x, y, z) = 3x - 5y + z - 5 

and pass it to the general root search algorithm to find the value of the unknown parameters that will generate the root. Most root search implementations allow you to block certain function parameters to fixed values ​​before searching for a root from an unlocked dimension of a problem.

+1
source share

All Articles