I would like to make a rectangular array of 1
and 0
with continuous columns of 1
.
We are given the total rows of the array and the starting points of the 1
.
For example:
totalRows = 5;
startRows = {1, 3, 10};
desiredArray = {{1, 0, 0}, {1, 0, 0}, {1, 1, 0}, {1, 1, 0}, {1, 1, 0}};
TableForm[desiredArray]
I need to make about 10,000 of such arrays of 10,000x1000 size. How can I do this quickly?
My current implementation is
foo[startRows_List, totalRows_Integer] :=
With[
{
cols = Length[startRows],
lengthOfOnes = Min[Max[#, 0], totalRows] & /@ (totalRows - startRows + 1)
},
Module[
{
raggedOnesArray = ConstantArray[1, #] & /@ lengthOfOnes
},
Transpose@PadLeft[raggedOnesArray, {cols, totalRows}]
]
];
foo[startRows, totalRows] == desiredArray (* True *)
For my use case this takes about 0.50s per array
SeedRandom[1];
startRowsBig = RandomInteger[{1, 11000}, 1000];
totalRowsBig = 10000;
foo[startRowsBig, totalRowsBig]; // RepeatedTiming (* {0.496737, Null} *)
How can I make this faster?
D
, that I multiply with this 1and0s matrix,B
. I then work on the cleanM
matrix. I guess I could encode the process of checkingstartRow
in the creation ofD
so it comes out clean (asM
) but I thought this way could be quicker than having someIf[row>stratRow, d, 0]
. $\endgroup$