1
$\begingroup$

I have this code to replace the data of each row in a specific function and display a new column showing the values ​​of the function

RS = 1 - (1 - Subscript[x, 1] Subscript[x, 2]) (1 - 
      Subscript[x, 1] Subscript[x, 3]);
(data = Tuples[{0, 1}, 3]) // MatrixForm; LLR = {Block[{Subscript}, 
   Do[Subscript[x, j] = Transpose[data][[j]], {j, 3}]; RS]};
(table = Prepend[
    Transpose@Join[{Range@Length@data}, Transpose@data, LLR], 
    Flatten[{"order", Subscript["x", #] & /@ Range[3], "H"}]]) // 
 Grid[#, Frame -> All] &

enter image description here

I am looking for taking the complement of each column separately ($1-x_1$,$1-x_2$,$1-x_3$) and substituting the complement with the rest of the columns and displaying the result of the function in another columns ($H1,H2,H3$).

In other words, the complement of the first column ($1-x_1$) with the second ($x_2$ and third ($x_3$) columns gives $H1$, ($1-x_2$) with ($x_1$ and ($x_3$) gives $H2$, ($1-x_3$) with ($x_1$ and ($x_2$) gives $H3$

My attempts gave accurate results but the code seems to be useless in more general cases. When the number of variables increases.

RS = 1 - (1 - Subscript[x, 1] Subscript[x, 2]) (1 - 
      Subscript[x, 1] Subscript[x, 3]);
RS1 = 1 - (1 - Subscript[x, 1] Subscript[x, 2]) (1 - 
       Subscript[x, 1] Subscript[x, 3]) /. 
   Subscript[x, 1] -> (1 - Subscript[x, 1]) ;
RS2 = 1 - (1 - Subscript[x, 1] Subscript[x, 2]) (1 - 
       Subscript[x, 1] Subscript[x, 3]) /. 
   Subscript[x, 2] -> (1 - Subscript[x, 2]) ;
RS3 = 1 - (1 - Subscript[x, 1] Subscript[x, 2]) (1 - 
       Subscript[x, 1] Subscript[x, 3]) /. 
   Subscript[x, 3] -> (1 - Subscript[x, 3]) ;
(data = Tuples[{0, 1}, 3]) // MatrixForm; LLR = {Block[{Subscript}, 
   Do[Subscript[x, j] = Transpose[data][[j]], {j, 3}]; RS]};
LLR1 = {Block[{Subscript}, 
    Do[Subscript[x, j] = Transpose[data][[j]], {j, 3}]; RS1]};
LLR2 = {Block[{Subscript}, 
    Do[Subscript[x, j] = Transpose[data][[j]], {j, 3}]; RS2]};
LLR3 = {Block[{Subscript}, 
    Do[Subscript[x, j] = Transpose[data][[j]], {j, 3}]; RS3]};
(table = Prepend[
    Transpose@
     Join[{Range@Length@data}, Transpose@data, LLR, LLR1, LLR2, LLR3],
     Flatten[{"order", Subscript["x", #] & /@ Range[3], "H", "H1", 
      "H2", "H3"}]]) // Grid[#, Frame -> All] &

enter image description here

I have put a condition on the function and duplicated the code... but this seems to be useless in general.

I am looking for better dynamics for the code in more general cases.

Thanks a lot for the help

$\endgroup$
9
  • 1
    $\begingroup$ So, you want something that generalizes when you add an x4 (and then x5, etc)? So your core data structure would be Tuples[{0, 1}, n] where you started with n = 3 and you want to expand to n > 3, is that right? $\endgroup$
    – lericr
    Commented Aug 16 at 19:03
  • $\begingroup$ @lericr Yes exactly. For example: in the case I am working on, the table is in the form: Tuples[{0, 1}, 10] and the variables are $x_1,x_2,...,x_{10}$ $\endgroup$ Commented Aug 16 at 19:10
  • $\begingroup$ Okay, help me understand how the RS should be generated. For the n = 3 case, we took all pairs that included x1 (so we excluded the term that would have used x2 x3). So, for n = 4 will we take the terms built from x1 x2, x1 x3, and x1 x4? That's half of the possible 6 ways to pair up the terms. Or is it a more complicated rule? $\endgroup$
    – lericr
    Commented Aug 16 at 19:19
  • $\begingroup$ @lericr Of course, the function changes as the number of variables increases. The function is an input. There is no basic formula for it. For example, n=4, RS=1-(1-x1 x2)(1-x3 x4) and for n=5, RS=1-(1-x1)(1-x2)(1-x4)(1-x3 x5). Can the function be considered an input and may change? $\endgroup$ Commented Aug 16 at 19:31
  • $\begingroup$ Sure. That actually makes it kind of easier. $\endgroup$
    – lericr
    Commented Aug 16 at 19:32

1 Answer 1

1
$\begingroup$

Let's build this up bit by bit. At each step, there are probably several alternate ways to do it, so you might want to experiment to figure out exactly what you want.

First, we need a representation for each "function template". I'm assuming that there's one for each "dimension", but you may need to expand this if you want to play around with different functions for each "dimension".

RS[3] = Function[, 1 - (1 - #1 #2) (1 - #1 #3)];
RS[4] = Function[, 1 - (1 - #1 #2) (1 - #3 #4)];
RS[5] = Function[, 1 - (1 - #1) (1 - #2) (1 - #4) (1 - #3 #5)];

Now let's come up with a general way to make the variable names. This is mostly for the header in the display, but it'll also be nice to demonstrate things.

MakeVariables[n_] := Indexed[\[FormalX], {#}] & /@ Range[n]

So,

MakeVariables[3]
(* {Indexed[\[FormalX], {1}], Indexed[\[FormalX], {2}], Indexed[\[FormalX], {3}]} *)

I'm using FormalX to avoid collisions and also just to be clear that these are just dummy variables for now. I'm also using Indexed instead of Subscript because it will give us nice behavior if we want to replace FormalX with an array. But of course, you could substitute Subscript if you really want.

Just to demonstrate what we have so far:

RS[3] @@ MakeVariables[3]
(* 1 - (1 - Indexed[\[FormalX], {1}] Indexed[\[FormalX], {2}]) (1 - Indexed[\[FormalX], {1}] Indexed[\[FormalX], {3}]) *)

Now let's create a helper function to take the complement of a variable.

ComplementFn = Function[, 1 - #]

This is kind of overkill, but it'll keep things tidy.

Now, we want to apply our template function (RS[3] for now) to a list of inputs, but we'll go ahead and do all of the complements first. This will create all the argument lists that you want.

argLists = Through[(MapAt[ComplementFn, {{#}}] & /@ Subsets[Range[3], 1])[MakeVariables[3]]]

(*
    {{Indexed[\[FormalX], {1}], Indexed[\[FormalX], {2}], Indexed[\[FormalX], {3}]}, 
     {1 - Indexed[\[FormalX], {1}], Indexed[\[FormalX], {2}], Indexed[\[FormalX], {3}]}, 
     {Indexed[\[FormalX], {1}], 1 - Indexed[\[FormalX], {2}], Indexed[\[FormalX], {3}]}, 
     {Indexed[\[FormalX], {1}], Indexed[\[FormalX], {2}], 1 - Indexed[\[FormalX], {3}]}}
*)

That's using some abstract functionality, so if it's not clear how it works, break it apart into sub-expressions and play with it. Anyway, now we have 4 argument lists that we can apply our function to.

RS[3] @@@ argLists

formal argument lists

Okay, but we actually want to apply it to the binary tuples. So let's use our functions on the tuples.

concreteArgLists = Through[(MapAt[ComplementFn, {{#}}] & /@ Subsets[Range[3], 1])[Transpose[Tuples[{0, 1}, 3]]]]

binary argument lists

And now let's apply our template function:

RS[3] @@@ concreteArgLists
(* {{0, 0, 0, 0, 0, 1, 1, 1}, {0, 1, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 0, 1}, {0, 0, 0, 0, 1, 0, 1, 1}} *)

That's your 4 columns H, H1, H2, H3.

To get the five columns for the 4 dimensional case:

RS[4] @@@ Through[(MapAt[ComplementFn, {{#}}] & /@ Subsets[Range[4], 1])[Transpose[Tuples[{0, 1}, 4]]]]

results for 4 dimensions

For display, you could do something like this:

TableForm[
  Transpose[Join[Transpose[Tuples[{0, 1}, 3]], RS[3] @@@ concreteArgLists]],
  TableHeadings -> {Range[8], Flatten[{MakeVariables[3], "H", "H1", "H2", "H3"}]}]

pretty form

That could be wrapped up in its own function, and you could use Grid if you want.

$\endgroup$
1
  • $\begingroup$ Accurate answer. Thank you very much. It helped me a lot. $\endgroup$ Commented Aug 16 at 20:52

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.