0
$\begingroup$

This is an outgrowth of this question.

Suppose I have the following definitions:

eqexp = {a, b, c, d};
eqval = {e, f, g, h};
signval = {{}, {1}, {-1}, {1, -1}};
criteria = {{}, {i}, {j}, {k, l}};

As before, I want signval to determine whether the eqexp component is greater than or less than the eqval component. But now I have an extra list (criteria) which has the same structure as signval. I want the corresponding criteria value to be equal to zero as well, and then the resulting inequalities combined with an Or. So the desired output would be:

{False, b > f && i == 0, c < g && j == 0, 
 (d > h && k == 0) || (d < h && l == 0)}

The previous answers (without the criteria component) cleverly used a replacement rule on signval. I don't see how to do the same thing here. Any suggestions?

$\endgroup$

3 Answers 3

2
$\begingroup$
Or @@@ MapThread[
  And @@@ Transpose[{#3 /. {1 -> #1 > #2, -1 -> #1 < #2}, Thread[#4 == 0]}] &,
    {eqexp, eqval, signval, criteria}]

On further thought, another Thread feels better than the Transpose:

Or @@@ MapThread[
  Thread[(#3 /. {1 -> #1 > #2, -1 -> #1 < #2}) && Thread[#4 == 0]] &,
  {eqexp, eqval, signval, criteria}]
$\endgroup$
3
$\begingroup$
f0 = Function[, Construct @ ##, Listable];
Or @@@ f0[And, 
         f0[signval /. {1 -> Greater, -1 -> Less}, eqexp, eqval], 
         f0[EqualTo[0], criteria]]

{False, b > f && i == 0, c < g && j == 0, (d > h && k == 0) || (d < h && l == 0)}

$\endgroup$
4
  • 1
    $\begingroup$ Why does your method not work if I define f0 = Construct@## &; SetAttributes[f0, Listable];? (Maybe this should be a full question by itself) $\endgroup$
    – Roman
    Jul 6, 2019 at 12:47
  • $\begingroup$ @Roman, great question; really puzzling. $\endgroup$
    – kglr
    Jul 6, 2019 at 13:02
  • 1
    $\begingroup$ I conclude that there are two ways of using attributes: (i) anonymous functions need the attributes assigned as the third argument of Function (not assigned to the variable holding the anonymous function, f0 in your case), and (ii) regular functions (with patterns on the LHS) need the attributes assigned with SetAttribute to the function head. Mixing these two different ways of using attributes gives poor results. $\endgroup$
    – Roman
    Jul 6, 2019 at 13:57
  • 1
    $\begingroup$ Roman, that brings out an important difference between specifying a pure function foo as foo = something& versus foo = Function[, something]. The latter seems to be the only way to assign Attributes to foo. $\endgroup$
    – kglr
    Jul 6, 2019 at 14:45
1
$\begingroup$

And once again, I post a question and right away figure out an answer. Here it is (although I would absolutely welcome more efficient ways to do it):

Or @@ MapThread[And, #] & /@ MapThread[{#3 /. {1 -> #1 > #2, -1 -> #1 < #2}, 
                    Map[# == 0 &, #4]} &, {eqexp, eqval, signval, criteria}]
$\endgroup$

Your Answer

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

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