123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- import numpy as np
- from scipy.stats import multivariate_normal
- import matplotlib.pyplot as plt
- class dataCreator:
- '''
- Generates a pollution scenario
- '''
- def __init__(self, sceneWidth, sceneLength, numSensor, numRef, rdvR, mvR, phenLowerBound, phenUpperBound, Mu_beta,
- Mu_alpha, Bound_beta, Bound_alpha):
- self.sceneWidth = sceneWidth # Width of the scene
- self.sceneLength = sceneLength # Length of the scene
- self.numArea = self.sceneWidth * self.sceneLength # Number of sampled area in the scene
- self.numSensor = numSensor # Number of sensors in the scene
- self.numRef = numRef # Number of references in the scene
- self.rdvR = rdvR # Rendez-vous rate : number of rendez-vous/number of sensors
- self.mvR = mvR # missing value rate
- self.phenLowerBound = phenLowerBound # lower bound on the phenomena (air pollution concentrations) standard deviation (normal distribution)
- self.phenUpperBound = phenUpperBound # upper bound "
- self.Mu_beta = Mu_beta # Mean sensors offset
- self.Mu_alpha = Mu_alpha # Mean sensors gain
- self.Bound_beta = Bound_beta # Offset boundaries
- self.Bound_alpha = Bound_alpha # Gain boundaries
- self.numRdv = round(self.numSensor * self.rdvR) # Number of sensors having a rendez-vous in the scene
- # self.numAreaVisited = self.numSensor+self.numRef-self.numRdv # Number of not empty areas
- def create_scene(self, randSeed):
- np.random.seed(randSeed) # Random seed
- # Creation of the map
- self.S = np.zeros(shape=self.numArea)
- x = np.linspace(-1, 1, num=self.sceneLength)
- y = np.linspace(-1, 1, num=self.sceneWidth)
- # Create meshgrid
- xx, yy = np.meshgrid(x, y)
- coord = np.vstack((xx.ravel(), yy.ravel())).T
- # number of pollution pics fixed to 10
- # MUTED FOR DEBUGGIN
- # for _ in range(10):
- # mean = np.squeeze(np.array([2 * (np.random.rand(1) - 0.5), 2 * (np.random.rand(1) - 0.5)]))
- # cxy = 0
- # cov = np.squeeze(np.array([[self.phenLowerBound + (self.phenUpperBound - self.phenLowerBound) * np.absolute(
- # np.random.randn(1) + 0.5), cxy],
- # [cxy,
- # self.phenLowerBound + (self.phenUpperBound - self.phenLowerBound) * np.absolute(
- # np.random.randn(1) + 0.5)]]))
- # z = multivariate_normal.pdf(coord, mean=mean, cov=cov)
- # self.S = self.S + z
- # REMOVE THIS BLOCK AFTER DEBUG
- z = multivariate_normal.pdf(coord, mean=[0, 0], cov=[[1, 0], [0, 1]])
- z = z - np.min(z)
- z = 0.5 * (z / np.max(z)) + 1e-5
- self.S = z
- # Random locations for the mobile sensors and the references
- posRef = np.random.permutation(self.numArea)[0:self.numRef] # Selection of the references
- idxSenRdv = np.random.permutation(self.numSensor)[
- 0:self.numRdv] # Selection of the sensors having a rendez-vous
- idxRefRdv = np.random.randint(self.numRef,
- size=self.numRdv) # Selection of the references corresponding to idxSenRdv
- # idxSen = np.arange(self.numSensor)
- # idxSen = np.delete(idxSen,idxSenRdv) # Still available sensors
- # freePos = np.arange(self.numArea)
- # freePos = np.delete(freePos,posRef) # Still available positions
- # posSen = np.random.choice(freePos,size=(self.numSensor-self.numRdv)) # Selection of the positions
- # self.posAll = np.unique(np.concatenate((posRef,posSen))) # All unique positions of sensors and references
- # self.posEmpty = np.arange(self.numArea)
- # self.posEmpty = np.delete(self.posEmpty,self.posAll)
- # Computation of W,G,F and X
- self.W = np.zeros(shape=[self.numArea, self.numSensor + 1])
- # The references
- self.W[posRef, -1] = 1
- # The sensors having a rendez-vous
- self.W[posRef[idxRefRdv], idxSenRdv] = 1 # np.put(self.W,(self.numSensor+1)*posRef[idxRefRdv]+idxSenRdv,1)
- # The other sensors
- Ndata = round((1 - self.mvR) * self.numSensor * (self.numArea - self.numRef))
- posSen = np.delete(np.arange(self.numArea), posRef)
- xx, yy = np.meshgrid(posSen, np.arange(self.numSensor))
- idx_mesh_sensor = np.random.permutation((self.numArea - self.numRef) * self.numSensor)[0:Ndata]
- self.W[xx.flat[idx_mesh_sensor], yy.flat[idx_mesh_sensor]] = 1
- # The areas that are not measured
- self.nW = 1 - self.W
- self.G = np.ones([self.numArea, 2]) # The last column of G is only composed of ones
- self.G[:, 0] = self.S.flat # The first column of G is composed of the true concentration for each area
- self.F = np.squeeze([np.maximum(self.Bound_alpha[0], np.minimum(self.Bound_alpha[1],
- self.Mu_alpha + 0.5 * np.random.randn(1,
- self.numSensor + 1))),
- np.maximum(self.Bound_beta[0], np.minimum(self.Bound_beta[1],
- self.Mu_beta + 0.5 * np.random.randn(1,
- self.numSensor + 1)))])
- self.F[:, -1] = [1, 0]
- self.Xtheo = np.dot(self.G, self.F)
- self.X = np.multiply(self.Xtheo, self.W)
- # Computation of omega and phi
- self.Omega_G = np.vstack((self.W[:, -1], np.ones(shape=self.numArea))).T
- self.Omega_F = np.hstack((np.zeros(shape=(2, self.numSensor)), np.ones(shape=(2, 1))))
- self.Phi_G = np.vstack((self.X[:, -1], np.ones(shape=self.numArea))).T
- self.Phi_F = np.zeros(shape=(2, self.numSensor + 1))
- self.Phi_F[0, -1] = 1
- # Faster access to the fixed values, done to avoid time consuming Hadamard product
- self.idxOG = np.argwhere(self.Omega_G.flat)
- self.sparsePhi_G = self.Phi_G.flat[self.idxOG]
- self.idxOF = np.argwhere(self.Omega_F.flat)
- self.sparsePhi_F = self.Phi_F.flat[self.idxOF]
- # Initial F and G
- self.Finit = np.squeeze([np.maximum(self.Bound_alpha[0], np.minimum(self.Bound_alpha[1],
- self.Mu_alpha + 0.5 * np.random.randn(1,
- self.numSensor + 1))),
- np.maximum(self.Bound_beta[0], np.minimum(self.Bound_beta[1],
- self.Mu_beta + 0.5 * np.random.randn(1,
- self.numSensor + 1)))])
- self.Finit[:, -1] = [1, 0]
- self.Ginit = np.absolute(np.mean(self.Phi_G[posRef, 0]) + np.random.randn(self.numArea, 2))
- np.put(self.Ginit, self.idxOG, self.sparsePhi_G)
- def show_scene(self):
- plt.imshow(self.S.reshape((self.sceneWidth, self.sceneLength)))
- plt.show()
- # def show_measured_scene(self):
- # obs = np.zeros(shape=(self.sceneWidth,self.sceneLength))
- # np.put(obs,self.posAll,1)
- # plt.imshow(np.multiply(obs,self.S.reshape((self.sceneWidth,self.sceneLength))))
- # plt.show()
|