3
$\begingroup$

I would like to creat a list of matrices from the following rules:

1- All matrices of the list have diagonal equal to zero.

2- The first matrix have 2x2 dimension, startmatrix={{0,1},{0,0}}

3- The next matrix have 3x3 dimensions and the submatrix have same elements of the matrix write in step 2; the other elements are Random Integers [1,3 -1]; 3 = dimension of the matrix in the step;

4- The next matrix have dimension 4x4; repeat the same elements of the step 3 and other elements is Random Integer [1,4-1]; 4= dimension of the matrix in the step;

For instance: look the figure below

enter image description here

I thought in the code below, but it not repeat the elements of previous matrix

nmax = 15 ;(*number of matrices*)
startMatrix = {{0, 1}, {0, 0}} ;(*The matrix begin*)
d = 2;(*Dimension of the first matrix*)
f[i_, j_] := 
 If[i <= d && j <= d, startMatrix[[i, j]], 
  If[j > i, RandomInteger[{1, j - d}], RandomInteger[{1, i - d}]]](*The rule for to create the matrices*)
m1 = Table[
  SparseArray[{{i_, i_} -> 0, {i_, j_} -> f[i, j]}, {n, n}], {n, d, 
   nmax}](*Obtain the list of matrices*)

Table[MatrixForm[m1[[i]]], {i, nmax - 1}] (*Show the matrix form of the all matrices of the list*)

Please, anybody help me?

$\endgroup$

3 Answers 3

3
$\begingroup$

You may use ArrayFlatten and NestList.

With

SeedRandom[123];
nmax = 4;
startMatrix = {{0, 1}, {0, 0}};

Then

m1 =
  NestList[
   With[{rand = RandomInteger[{1, Length[#] + 1}, {2, Length[#]}]},
     ArrayFlatten[{
       {#, Partition[rand[[1]], 1]},
       {{rand[[2]]}, {{0}}}
       }]
     ] &
   ,
   startMatrix,
   nmax - 1
   ];

MatrixForm /@ m1

Mathematica graphics

This has the added benefit of not generating random variate one at a time which is slower. This quickly becomes noticeable for small nmax.

Hope this helps.


Quick compare

Taking @jjc385 Array[f, {nmax, nmax}] and @KraZug g[mat] with NestList.

GeneralUtilities`BenchmarkPlot[
 {
  Function[{num},
   NestList[
    With[{rand = RandomInteger[{1, Length[#] + 1}, {2, Length[#]}]},
      ArrayFlatten[{
        {#, Partition[rand[[1]], 1]},
        {{rand[[2]]}, {{0}}}
        }]
      ] &
    ,
    startMatrix,
    num - 1
    ]]
  ,
  Array[f, {#, #}] &,
  NestList[g, {{0, 1}, {0, 0}}, #] &
  },
 Identity,
 Range[3, 20],
 PlotLegends -> {"Edmund", "jjc385", "KraZug"}
 ]

Mathematica graphics

$\endgroup$
2
$\begingroup$

Perhaps it would be simpler to generate an nmax by nmax matrix from the start, and replace the initial submatrix.

mat = Table[If[i == j, 0, RandomInteger[{1, Max[i, j]}] ],
   {i, nmax}, {j, nmax}];
mat[[;; d, ;; d]] = startMatrix;
mat

Edit Actually, with OP's function f already created, it's even simpler just to use that:

mat = Array[f, {nmax, nmax}]

Then you could extract the iterative sub-matrices afterward:

Table[mat[[;; i, ;; i]], {i, d, Length@mat}]
MatrixForm /@ %
$\endgroup$
1
$\begingroup$

NestList with an appropriate function for making the next list will work. This looks ugly though, sure it can be improved.

g[mat_] := 
 Transpose[
  FlattenAt[{Transpose[
     FlattenAt[{mat, RandomInteger[{1, Length[mat]}, Length[mat]]}, 
      1]], Flatten[{RandomInteger[{1, Length[mat]}, Length[mat]], 
      0}]}, 1]]

NestList[g, {{0, 1}, {0, 0}}, 15]
$\endgroup$

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.