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$

2 Answers 2

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$
5
  • 6
    $\begingroup$ Can be written directly as List @@ Reduce @ Thread[liste - listv <= 0] $\endgroup$
    – m_goldberg
    Dec 6, 2016 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, 2016 at 22:47
  • $\begingroup$ @nanjun done, is that what where you after? $\endgroup$
    – Kuba
    Dec 7, 2016 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, 2016 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, 2016 at 22:02
5
$\begingroup$
LessEqual @@@ Transpose@{l1, l2} // Reduce

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

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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