TheBigDig
TheBigDig

Reputation: 49

Create a matrix of alternating zeroes and random numbers?

I'm trying to write some code that will create a matrix of alternating 1/-1 and 0 i.e:

[-1  0 -1  0  1  0  1  0 -1  0]
[ 0  1  0 -1  0  1  0 -1  0  1]
[ 1  0  1  0 -1  0 -1  0 -1  0]
[ 0  1  0 -1  0 -1  0 -1  0  1]
[ 1  0  1  0  1  0  1  0  1  0]

I've created a class that generates a matrix of zeroes and appends it with 1 or -1 and I have tried messing with my for loop and slicing my matrix but I can't seem to generate the matrix I'd like above. I have an intermediate level of python knowledge so I appreciate that a solution to my problem using the code I've created might not be particularly elegant but any help would be greatly appreciated.

import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
import random


#constants
N = 10 #dimensions of matrix


class initial_lattice: 
    def __init__(self,N):   #create initial matrix of size NxN
        self.N=N
        self.matrix_lattice()

    def matrix_lattice(self):
        self.lattice = np.zeros((N,N), dtype=int) #creates initial matrix of zeroes
        for x in range(0,N):    
            for y in range(0,N):
                self.lattice[x,y]=random.choice([1,-1]) #randomly chooses values of 1 and -1 and appends matrix

lattice1=initial_lattice(N) 


print lattice1.lattice

Upvotes: 3

Views: 444

Answers (5)

Daniel F
Daniel F

Reputation: 14399

Intead of filling with random and zeroing, I'd fill with zeros and input the random values

def matrix_lattice(self):
    self.lattice = np.zeros((N, N))
    self.lattice[::2,   ::2] = np.random.choice([-1, 1], (-(-N // 2), -(-N // 2)))
    self.lattice[1::2, 1::2] = np.random.choice([-1, 1], (N // 2,     N // 2)))

Upvotes: 0

mjkrause
mjkrause

Reputation: 424

#!/usr/bin/env python

import numpy as np 
import random

class SpecialMat:
    def __init__(self, m, n):
        self.dim = (m, n)  # matrix dimension
        self.members = (-1, 1)
        self.data = self.__matrix_lattice(self)

    def display(self):
        print(self.data)

    @staticmethod
    def __matrix_lattice(self):
        m = self.dim[0]
        n = self.dim[1]
        L = self.members
        a = np.zeros((m, n), dtype=int)
        for i in range(m):
            for j in range(n):
                if self._is_odd(j + i):
                    a[i, j] = random.choice(L)
        return a

    def _is_odd(self, num):
        return num % 2 is not 0

then in Python (3.6):

from <yourPythonFileName> import SpecialMat
M = SpecialMat(10, 5)  # should work with any integers
M.display()
[[ 0  1  0  1  0  1  0 -1  0 -1]
 [-1  0  1  0 -1  0  1  0  1  0]
 [ 0 -1  0  1  0 -1  0 -1  0  1]
 [-1  0  1  0 -1  0  1  0  1  0]
 [ 0  1  0  1  0  1  0 -1  0 -1]]

def _is_odd is from here

Upvotes: -3

anon01
anon01

Reputation: 11181

I prefer making a filter based on the mod of the indices, multiplied by a random +-1 matrix. E.g:

def my_matrix(N=10, toggle=0):

    m       = np.random.choice([-1, 1], (N, N))
    [j,k]   = np.indices([N,N])
    filter  = (j + k + toggle)%2

    return filter*m

Upvotes: 0

f5r5e5d
f5r5e5d

Reputation: 3741

the even/odd rows idea seems fine, a variation:

def matrix_lattice(self):
    self.lattice = np.random.choice([-1, 1], (N, N))
    self.lattice[::2, ::2] = 0
    self.lattice[1::2, 1::2] = 0

Upvotes: 7

DYZ
DYZ

Reputation: 57135

There may be a better solution, but this one definitely works:

def matrix_lattice(m,n):
  mask = np.ones((m,n), dtype=int) # All 1s
  mask[1::2, ::2] = 0 # Clean even fields in odd rows
  mask[::2, 1::2] = 0 # Clean odd fields in even rows
  u = np.random.randint(2, size=(m,n)) * 2 - 1 # 1s and -1s      
  return u * mask # Superimpose the matrices

print(matrix_lattice(5,5))
#array([[-1,  0,  1,  0,  1],
#       [ 0, -1,  0,  1,  0],
#       [ 1,  0,  1,  0, -1],
#       [ 0,  1,  0, -1,  0],
#       [ 1,  0, -1,  0, -1]])

Upvotes: 5

Related Questions