13
$\begingroup$

I have two lists liste = {x, -y, y, -z} and listv = {1, -2, 3, -4}, which represent the inequities obtained evaluating liste - listv <= 0. How do I reassemble or join those two separate lists into a more readable one having the form {x <= 1, 2 <= y <= 3, z >= 4}?

I further require that, when an expression comes with both a lower bound and a upper bound like the y above, it should not be written in two separate equalities y >= 2 and y <= 3, but in the more compact form 2 <= y <= 3.

$\endgroup$
15
$\begingroup$
Thread[liste - listv <= 0] // Reduce
2 <= y <= 3 && z >= 4 && x <= 1
List @@ %
{2 <= y <= 3, z >= 4, x <= 1}

How do I reorder the inequities in an "alphabetic + numeric" order, such as {2 <= x1 <= 3, x2 >= 4, z <= 1}

Assuming there is one variable per inequality and there are no different length variables, e.g. x, x1, x12 at once, then:

#[[Ordering[Cases[#, s_Symbol /; Context[s] =!= "System`", ∞] & /@ #]]] &[
   {2 <= y <= 3, z >= 4, x <= 1}
]
{x <= 1, 2 <= y <= 3, z >= 4}

so at the end

Composition[
  #[[
    Ordering[
      Cases[
        #, s_Symbol /;  Context[s] =!= "System`", ∞
      ] & /@ #
    ]
  ]] &,
  Apply[List],
  Reduce,
  Thread
  ][liste - listv <= 0]
$\endgroup$
  • 6
    $\begingroup$ Can be written directly as List @@ Reduce @ Thread[liste - listv <= 0] $\endgroup$ – m_goldberg Dec 6 '16 at 22:07
  • 1
    $\begingroup$ Great answer. If the three variable names I used change to liste={z, -x1, x1, -x2}, the answer generated would be {x2 >= 4, z <= 1, 2 <= x1 <= 3}. How do I reorder the inequities in an "alphabetic + numeric" order, such as {2 <= x1 <= 3, x2 >= 4, z <= 1}? $\endgroup$ – nanjun Dec 6 '16 at 22:47
  • $\begingroup$ @nanjun done, is that what where you after? $\endgroup$ – Kuba Dec 7 '16 at 7:08
  • $\begingroup$ @Kuba Thank you, exactly. I came up with a follow-up question, though. What if the those inequalities involve some user defined functions? For example, I want something like {2 <= x[1] <= 3, x[2] >= 4, z <= 1}, where z is just a variable, but x[n_] is some function I previously defined. How do I just order the list without evaluating my user function x[n_] here? $\endgroup$ – nanjun Dec 7 '16 at 21:56
  • $\begingroup$ @nanjun you can perform all actions inside Block and use HoldForm to prevent output from evaluation. Here is a minimal example: f[x_] := x^2; Block[{f}, HoldForm[#] &[f[x] < 0]] $\endgroup$ – Kuba Dec 7 '16 at 22:02
5
$\begingroup$
LessEqual @@@ Transpose@{l1, l2} // Reduce

2 <= y <= 3 && z >= 4 && x <= 1

$\endgroup$

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.