0

I have a code as below:

countpar = 10;
randomA = RandomReal[{1, 10}, {countpar, countpar}];
randomconst = RandomInteger[{0, 1}, {countpar, 1}];

For[i = 1, i < countpar + 1, i++,

If[randomconst[[i, 1]] != 0,

randomA[[All, i]] = 0.; randomA[[i, All]] = 0.; randomA[[i, i]] = 1;

];

];

The problem is when I have changed countpar, lets say, i.e, countpar=1000, then the computational time of the for loop increases dramatically. Is there a way to decrease this time from an expert eye ?

Best Regards,

Ahmet

Michael E2
  • 235,386
  • 17
  • 334
  • 747

2 Answers2

0

I don't know if you've simplified your problem to try to get a targeted answer, but if I take your example at face value, here's an alternate approach that is faster. It looks like what you're producing is just a row-wise and column-wise permutation of a block diagonal matrix.

(*setting up the params*)
(*rather than set up the rows/columns to transform we choose a 
  random size for the "sub-block" of random values*)
sidelength = 10;
blockSize = RandomInteger[sidelength];

(here are the random numbers needed to fill the "sub-blocks") initialMatrix = ArrayPad[ RandomReal[{1, 10}, {blockSize, blockSize}], {sidelength - blockSize, 0}, IdentityMatrix[sidelength]];

(randomonly rearrange the indices) rowColPerm = PermutationReplace[Range@sidelength, RandomPermutation[sidelength]];

(final result) randomA = initialMatrix[[rowColPerm, rowColPerm]];

The padding can actually take significant time here, so if there is already a natural way in your context to set up the initial matrix, then that would save additional time.

Also, this approach does extra work because we should only need to permute with the rows/columns of the "identity block", but I wasn't sure how to do that optimization.

I wouldn't be surprised if there are some built-in matrix-related functions that could do some heavy lifting here, so maybe someone with expertise in manipulating matrices will have a better answer.

lericr
  • 27,668
  • 1
  • 18
  • 64
0

I suppose your problem is to visualize the result? Because to display a matrix of 1000 x 1000, it is very difficult in Mathematica. If so, I suggest you to export randomA in CSV format, to display it on Excel.

countpar = 1000;
randomA = RandomReal[{1, 10}, {countpar, countpar}];
randomconst = RandomInteger[{0, 1}, {countpar, 1}];

For[i = 1, i < countpar + 1, i++,

If[randomconst[[i, 1]] != 0,

randomA[[All, i]] = 0.; randomA[[i, All]] = 0.; randomA[[i, i]] = 1;

];

];

dy2 = ToString["C:\Users\Ahmet\Documents\test1.csv"]; st2 = OpenWrite[dy2]; For[i = 1, i <= countpar, i++, a = ToString[randomA[[i]]]; a = StringReplace[a, "{" -> ""]; a = StringReplace[a, "}" -> ""]; WriteString[st2, a, FromCharacterCode[10]]]; Close[st2]; SystemOpen[dy2]

if your problem is to speed only the code, you can use Parallelize :

countpar = 1000;
randomA = RandomReal[{1, 10}, {countpar, countpar}];
randomconst = RandomInteger[{0, 1}, {countpar, 1}];
ClearSystemCache[];
Parallelize[
Do[If[randomconst[[i, 1]] != 0, randomA[[All, i]] = 0.; 
randomA[[i, All]] = 0.;
randomA[[i, i]] = 1;], {i, 1, countpar}]];
Reda.Kebbaj
  • 674
  • 3
  • 13