0
$\begingroup$

I’ve got this simple loop that prints out the solutions to 2 simple equations for various values of parameters $a$ and $b$.

I need to add a command that would display the parameter values that lead to the solution which is closest (in absolute way) to $x = 0.21$, $y = 0.34$. In my particular case it happens when $a=3$ and $b=2$ (which leads to $x=2/9$, $y=1/3$ exactly), but how to get this {a=3,b=2} answer? Thank you.

q := Do[sol = Solve[{a*x + y == 1, -3*x + b*y == 0}, {x, y}]; 
Print[{x /.sol[[1]], y /.sol[[1]]}], {a, 2, 3, 1}, {b, 2, 3, 1}]
q
$\endgroup$
1
$\begingroup$

NMinimizesolves it directly in one step, assuming (a | b) \[Element] Integers:

NMinimize[{1, {x == .21, y == 0.34, a*x + y == 1, -3*x + b*y == 0,Element[{a, b}, Integers]}}, {x, y, a, b}]
(*{1., {x -> 0.21, y -> 0.34, a -> 3, b -> 2}}*)
$\endgroup$
  • $\begingroup$ Thank you, this seems to work fine. Just a question, in NMinimize you wrote "1" at the beginning. Why is it needed? Shouldn't be the function to be minimized subject to constraints? $\endgroup$ – Alex Aug 18 at 13:08
  • $\begingroup$ That means a pseudo minimization of "1" with several constraints. Often the solver of NMinimize ist very robust. $\endgroup$ – Ulrich Neumann Aug 18 at 17:59
1
$\begingroup$

Not sure this is what you are looking for, but this is how I would approach the problem:

sol = Solve[{a*x + y == 1, -3*x + b*y == 0}, {x, y}]

NMinimize[Total@Abs[{0.21, 0.34} - sol[[1, ;; , 2]]], {a, b}]

{5.86753*10^-11, {a -> 3.14286, b -> 1.85294}}

These are the coefficients {a,b} that lead to the closest values of x,y under the metric I'm using, that is just a minimisation of the total of the distances between {x,y} and the target values.

If you instead want integer values, you could try:

sol = Solve[{a*x + y == 1, -3*x + b*y == 0}, {x, y}];
solfun[{a_, b_}] = sol[[1, ;; , 2]];
coeff = Tuples[{2, 3}, 2];
list = solfun /@ coeff;
min = MinDetect[Total /@ Abs[# - {0.21, 0.34} & /@ list]];

{{3, 2}}

$\endgroup$
1
$\begingroup$

You can try this :

sol := Solve[{a*x + y == 1, -3*x + b*y == 0}, {x, y}];
Minimize[
 {Abs[.21 - x /. sol[[1]]] + Abs[.34 - y /. sol[[1]]], 
  1 <= a <= 3 && 1 <= b <= 3}, {a, b}, Integers]

with output

{0.0188889, {a -> 3, b -> 2}}.

Or, better, optimize simultaneously over all 4 variables :

Minimize[
 {Abs[.21 - x] + Abs[.34 - y],
  a*x + y == 1 
   && -3*x + b*y == 0 
   && 1 <= a <= 3 
   && 1 <= b <= 3
   && {x, y} \[Element] Reals
   && {a, b} \[Element] Integers},
 {x, y, a, b}]

{0.0188889, {x -> 0.222222, y -> 0.333333, a -> 3, b -> 2}}

$\endgroup$
  • $\begingroup$ Thank you. But I would like to rather not rely on Minimize, but be able to "manually" vary a and b. This can be done by altering the step size in a command {a, 2, 3, 1}, {b, 2, 3, 1}. I should also apologize and correct myself because I said earlier "lead to the solution which is closest (in absolute way) to x=0.21, y=0.34". The abs diff should satisfy a predetermined tolerance level, say absolute difference should be less and equal to 0.01. Minimize is great b/c it can help to narrow down where a and b lie; then I could try to change the step size in varying a/b, to satisfy the tolerance. $\endgroup$ – Alex Aug 18 at 12:34
  • $\begingroup$ @Alex If what you want is a tolerance, why not make it a constraint? $\endgroup$ – A.G. Aug 18 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.