1 | initial version |

I have adapted an idea I have found in Stackexchange. It is based in the following facts:

Let $J_k$ be the identity matrix of order $n$ with the null elements in the $k$-th row replaced by random integers. Then $J_k$ is unimodular, i.e. $\lvert J_k\rvert=1$.

If $A$ is an unimodular symmetric matrix, so it is $J_k^T A J_k$.

Thus, one can start with $A=I_n$, choose a row $k$ at random, construct $J_k$, compute $J_k^T A J_k$ and replace $A$ by that matrix. This process can be repeated as many times as wanted. The result is an unimodular symmetric matrix. The following code implements this idea:

```
def unimod_sym_matrix(n, niter=1, min_int=-1, max_int=1):
A = identity_matrix(n)
rows = random_vector(niter, x=0, y=n)
for k in rows:
J = identity_matrix(n)
J[k,:] = random_vector(n, x=min_int, y=max_int+1)
J[k,k] = 1
A = J.transpose()*A*J
return A
```

Observe that, to get $J_k$ , random integers are taken from `min_int`

to `max_int`

, both included. Likewise, `niter`

is the number of matrices $J_k$ that are constructed.

For example, the following code

```
set_random_seed(1000)
A = unimod_sym_matrix(6,3); show(A)
A = unimod_sym_matrix(6); show(A)
```

yields

$\begin{pmatrix} 2 & -2 & -1 & 0 & 1 & 0 \\ -2 & 9 & 4 & 1 & -3 & 3 \\ -1 & 4 & 2 & 0 & -1 & 2 \\ 0 & 1 & 0 & 2 & -1 & -1 \\ 1 & -3 & -1 & -1 & 2 & 1 \\ 0 & 3 & 2 & -1 & 1 & 6 \end{pmatrix}$

$\begin{pmatrix} 2 & 0 & 1 & -1 & -1 & -1 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 2 & -1 & -1 & -1 \\ -1 & 0 & -1 & 1 & 1 & 1 \\ -1 & 0 & -1 & 1 & 2 & 1 \\ -1 & 0 & -1 & 1 & 1 & 2 \end{pmatrix}$

I have included `set_random_seed`

just for the sake of reproducibility of the above output.

Since you want matrix entries between $-2$ and $2$, you have better to use the default values for `niter`

, `min_int`

and `max_int`

.

2 | No.2 Revision |

I have adapted an idea I have found in Stackexchange. It is based ~~in ~~on the following facts:

Let $J_k$ be the identity matrix of order $n$ with the null elements in the $k$-th row replaced by random integers. Then $J_k$ is unimodular, i.e. $\lvert J_k\rvert=1$.

If $A$ is an unimodular symmetric matrix, so it is $J_k^T A J_k$.

Thus, one can start with $A=I_n$, choose a row $k$ at random, construct $J_k$, compute $J_k^T A J_k$ and replace $A$ by that matrix. This process can be repeated as many times as wanted. The result is an unimodular symmetric matrix. The following code implements this idea:

```
def unimod_sym_matrix(n, niter=1, min_int=-1, max_int=1):
A = identity_matrix(n)
rows = random_vector(niter, x=0, y=n)
for k in rows:
J = identity_matrix(n)
J[k,:] = random_vector(n, x=min_int, y=max_int+1)
J[k,k] = 1
A = J.transpose()*A*J
return A
```

Observe that, to get $J_k$ , random integers are taken from `min_int`

to `max_int`

, both included. Likewise, `niter`

is the number of matrices $J_k$ that are constructed.

For example, the following code

```
set_random_seed(1000)
A = unimod_sym_matrix(6,3); show(A)
A = unimod_sym_matrix(6); show(A)
```

yields

$\begin{pmatrix} 2 & -2 & -1 & 0 & 1 & 0 \\ -2 & 9 & 4 & 1 & -3 & 3 \\ -1 & 4 & 2 & 0 & -1 & 2 \\ 0 & 1 & 0 & 2 & -1 & -1 \\ 1 & -3 & -1 & -1 & 2 & 1 \\ 0 & 3 & 2 & -1 & 1 & 6 \end{pmatrix}$

$\begin{pmatrix} 2 & 0 & 1 & -1 & -1 & -1 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 2 & -1 & -1 & -1 \\ -1 & 0 & -1 & 1 & 1 & 1 \\ -1 & 0 & -1 & 1 & 2 & 1 \\ -1 & 0 & -1 & 1 & 1 & 2 \end{pmatrix}$

I have included `set_random_seed`

just for the sake of reproducibility of the above output.

Since you want matrix entries between $-2$ and $2$, you have better to use the default values for `niter`

, `min_int`

and `max_int`

.

3 | No.3 Revision |

I have adapted an idea I have found in Stackexchange. It is based on the following facts:

Let $J_k$ be the identity matrix of order $n$ with the null elements in the $k$-th row replaced by random integers. Then $J_k$ is unimodular, i.e. $\lvert J_k\rvert=1$.

If $A$ is an unimodular symmetric matrix, so it is $J_k^T A J_k$.

Thus, one can start with $A=I_n$, choose a row $k$ at random, construct $J_k$, compute $J_k^T A J_k$ and replace $A$ by that matrix. This process can be repeated as many times as wanted. The result is an unimodular symmetric matrix. The following code implements this idea:

```
def unimod_sym_matrix(n, niter=1, min_int=-1, max_int=1):
A = identity_matrix(n)
rows = random_vector(niter, x=0, y=n)
for k in rows:
J = identity_matrix(n)
J[k,:] = random_vector(n, x=min_int, y=max_int+1)
J[k,k] = 1
A = J.transpose()*A*J
return A
```

Observe that, to get $J_k$ , random integers are taken from `min_int`

to `max_int`

, both included. Likewise, `niter`

is the number of matrices $J_k$ that are constructed.

For example, the following code

```
set_random_seed(1000)
A = unimod_sym_matrix(6,3); show(A)
A = unimod_sym_matrix(6); show(A)
```

yields

$\begin{pmatrix} 2 & -2 & -1 & 0 & 1 & 0 \\ -2 & 9 & 4 & 1 & -3 & 3 \\ -1 & 4 & 2 & 0 & -1 & 2 \\ 0 & 1 & 0 & 2 & -1 & -1 \\ 1 & -3 & -1 & -1 & 2 & 1 \\ 0 & 3 & 2 & -1 & 1 & 6 \end{pmatrix}$

$\begin{pmatrix} 2 & 0 & 1 & -1 & -1 & -1 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 1 & 0 & 2 & -1 & -1 & -1 \\ -1 & 0 & -1 & 1 & 1 & 1 \\ -1 & 0 & -1 & 1 & 2 & 1 \\ -1 & 0 & -1 & 1 & 1 & 2 \end{pmatrix}$

I have included `set_random_seed`

just for the sake of reproducibility of the above output.

Since you want matrix entries between $-2$ and $2$, you ~~have ~~had better to use the default values for `niter`

, `min_int`

and `max_int`

.

4 | No.4 Revision |

I have adapted an idea I have found in Stackexchange. It is based on the following facts:

If $A$ is an unimodular symmetric matrix, so it is $J_k^T A J_k$.

```
def unimod_sym_matrix(n, niter=1, min_int=-1, max_int=1):
A = identity_matrix(n)
rows = random_vector(niter, x=0, y=n)
for k in rows:
J = identity_matrix(n)
J[k,:] = random_vector(n, x=min_int, y=max_int+1)
J[k,k] = 1
A = J.transpose()*A*J
return A
```

`min_int`

to `max_int`

, both included. Likewise, `niter`

is the number of matrices $J_k$ that are constructed.

For example, the following code

```
set_random_seed(1000)
A = unimod_sym_matrix(6,3); show(A)
A = unimod_sym_matrix(6); show(A)
```

yields

I have included `set_random_seed`

just for the sake of reproducibility of the above output.

Since you want matrix entries between $-2$ and $2$, you had better to use the default values for `niter`

, `min_int`

and `max_int`

.

5 | No.5 Revision |

I have adapted an idea I have found in Stackexchange. It is based on the following facts:

If $A$ is an unimodular symmetric matrix, so it is $J_k^T A J_k$.

```
def unimod_sym_matrix(n, niter=1, min_int=-1, max_int=1):
A = identity_matrix(n)
rows = random_vector(niter, x=0, y=n)
for k in rows:
J = identity_matrix(n)
J[k,:] = random_vector(n, x=min_int, y=max_int+1)
J[k,k] = 1
A = J.transpose()*A*J
return A
```

`min_int`

to `max_int`

, both included. Likewise, `niter`

is the number of matrices $J_k$ that are constructed.

For example, the following code

```
set_random_seed(1000)
A = unimod_sym_matrix(6,3); show(A)
A = unimod_sym_matrix(6); show(A)
```

yields

I have included `set_random_seed`

just for the sake of reproducibility of the above output.

Since you want matrix entries between $-2$ and $2$, you had better ~~to ~~use the default values for `niter`

, `min_int`

and `max_int`

.

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.