6

There is list containing some $(i,j)$ values of indices. Now i want to create a matrix of dimension n $\times$ m whose entries are 1 for the indices corresponding to the given list otherwise its zero.

For e.g if the list is as given below

list = {{1, 1}, {1, 2}, {2, 1}, {3, 3}};

And if $n=m=3$ then the output should be

 {{1, 1, 0}, {1, 0, 0}, {0, 0, 1}}

I was able to do this as shown below but i believe this could be achieved with a shorter and a more elegant code. Maybe a one liner.

      cHeck[n1_, n2_] := Module[{flag = 0, list, i},
                         list = {{1, 1}, {1, 2}, {2, 1}, {3, 3}};
                         For[i = 1, i <= Length[list], i++,
                           Which[{n1, n2} === list[[i]], flag = 1]
                             ];
                        flag
                            ]
 A[n_, m_] := Table[cHeck[i, j], {i, 1, n}, {j, 1, m}]

 A[3, 3] 
 (*{{1, 1, 0}, {1, 0, 0}, {0, 0, 1}}*)
Hubble07
  • 3,614
  • 13
  • 23
  • 5
    Try SparseArray[# -> 1 & /@ list, {n, m}, 0]. – b.gates.you.know.what Feb 07 '14 at 14:49
  • wow that worked. i knew there would be a one liner. Thanks. – Hubble07 Feb 07 '14 at 15:05
  • @rm-rf I disagree with closing this question as a duplicate of the one you chose. That one is considerably more complex and obscures the simplicity if what is needed here. I searched for a duplicate myself and found many examples with Band, as well as many uses of SparseArray as part of a larger answer, but I did not fine one that I felt was a duplicate. – Mr.Wizard Feb 07 '14 at 15:59
  • @Mr.Wizard Isn't the solution the same as your f1? Just with list -> 1 instead of individually setting them? Feel free to reopen it if you feel it isn't addressed by the other one. – rm -rf Feb 07 '14 at 16:34
  • @rm-rf The syntax is different; the answers to this question show that both ReplacePart and SparseArray can accept the form positionlist -> value without the need for mapping or threading. The first comment above shows that people are not all aware of this. Closer are some of the answers I found using Band. I am going to reopen this for now; if you come across another Q&A that is not overly involved that clearly shows the syntax I describe please close it again. – Mr.Wizard Feb 07 '14 at 16:42

3 Answers3

8

You can use SparseArray:

list = {{1, 1}, {1, 2}, {2, 1}, {3, 3}};

n = m = 3;

SparseArray[list -> 1, {n, m}] // MatrixForm
1 1 0
1 0 0
0 0 1

Timing compared to ReplacePart as proposed by bill s:

list = DeleteDuplicates @ RandomInteger[{1, 1000}, {75000, 2}];
n = m = 1000;

ReplacePart[ConstantArray[0, {n, m}], list -> 1] // AbsoluteTiming // First
SparseArray[list -> 1, {n, m}]                   // AbsoluteTiming // First
0.170

0.018

The SparseArray object can be converted to a standard array using Normal in negligible time.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
4

If the matrix is already defined, you can use ReplacePart:

list = {{1, 1}, {1, 2}, {2, 1}, {3, 3}};
q = ConstantArray[0, {3, 3}];

ReplacePart[q, list -> 1]
{{1, 1, 0}, {1, 0, 0}, {0, 0, 1}}

Of course, this is more lines than the SparseArray solution.

bill s
  • 68,936
  • 4
  • 101
  • 191
  • This is faster than I remembered it being. +1. However it's still not nearly as fast as SparseArray, at least in v7. – Mr.Wizard Feb 07 '14 at 15:37
0

Also: MapAt

list = {{1, 1}, {1, 2}, {2, 1}, {3, 3}};
q = ConstantArray[0, {3, 3}];

MapAt[1 &, q, list]

{{1, 1, 0}, {1, 0, 0}, {0, 0, 1}}

Note: this is much slower than both SparseArray and ReplacePart.

kglr
  • 394,356
  • 18
  • 477
  • 896