diff --git a/CAsimulation/AgeManagement.py b/CAsimulation/AgeManagement.py new file mode 100644 index 0000000..e457ef0 --- /dev/null +++ b/CAsimulation/AgeManagement.py @@ -0,0 +1,141 @@ +from typing import Type +import numpy as np +import random +import math +import EpidemiologicalModels.Models as Models +import EpidemiologicalModels.CellManagement as CellManagement +import EpidemiologicalModels.DataManager as DataManager +import EpidemiologicalModels.CellSpaceConfiguration as CellSpaceConfiguration + +class AgesMatrix: + + ranges = [] + + def __init__(self, ranges, cellSpace): + self.ranges = ranges + self.cellSpace = cellSpace + self.agesMatrix = self.__create() + + def __validate(self): + if len(self.ranges) == 0: + print("Debe definir los rangos de edades en el sistema.") + return False + if str(type(self.cellSpace)) != "": + print("Asegurese de pasar un sistema con el tipo ") + return False + else: + for r in self.ranges: + if len(r) != 3: + print("Asegurese de que todos los rangos de edad posean límite inferior, límite superior y la proporción en el sistema.") + return False + elif r[2] > 1: + print("Asegurese de que todas las proporciones sean menores o iguales a 1.") + return False + else: + return True + + def __agesDivisions(self, amoungIndividuals): + agesDivisions = [] + for r in self.ranges: + agesDivisions.append([0] * math.ceil(r[2] * amoungIndividuals)) + return agesDivisions + + def __create(self): + '''Arreglo de edades aleatorias''' + if self.__validate(): + amoungIndividuals = DataManager.SystemMetrics(self.cellSpace, [Models.State.S.value, Models.State.I.value, Models.State.R.value, Models.State.H.value]).numberOfIndividuals() + agesDivisions = self.__agesDivisions(amoungIndividuals) + for divition in range(len(agesDivisions)): + for individualPerGroup in range(len(agesDivisions[divition])): + agesDivisions[divition][individualPerGroup] = random.randint(self.ranges[divition][0], self.ranges[divition][1]) + concatenatedAgeList = agesDivisions[0] + for i in range(1, len(agesDivisions)): + concatenatedAgeList = concatenatedAgeList + agesDivisions[i] + matrixOfAges = -np.ones((self.cellSpace.nRows, self.cellSpace.nColumns)) + for r in range(self.cellSpace.nRows): + for c in range(self.cellSpace.nColumns): + if self.cellSpace.system[r,c] != Models.State.H.value and self.cellSpace.system[r,c] != Models.State.D.value: + randomAge = random.choice(concatenatedAgeList) + matrixOfAges[r,c] = randomAge + elif self.cellSpace.system[r,c] == Models.State.D.value: matrixOfAges[r,c] = 0 + return matrixOfAges + +class AgeMatrixEvolution: + + def __init__(self, systemAges, birthRate, annualUnit = 365, probabilityOfDyingByAgeGroup = [[0, 100, 1]]): + self.birthRate = birthRate # Valor en [0,1) + self.systemAges = systemAges + self.nRows, self.nColumns = systemAges.shape + self.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + self.annualUnit = annualUnit + + def ageGroupPositions(self, inferiorLimit, superiorLimit): + '''Genera las posiciones de los individuos que tienen entre minAge y maxAge años en el sistema''' + groupPositions = [] + for r in range(self.nRows): + for c in range(self.nColumns): + if inferiorLimit < self.systemAges[r][c] and self.systemAges[r][c] < superiorLimit: + groupPositions.append([r,c]) + return groupPositions + + def __birthCell(self): + rate = random.random() + if rate < self.birthRate: return 1 + else: return 0 + + def __birthdaysAndBirths(self, timeUnit): + agesMatrix = CellSpaceConfiguration.CellSpaceConfiguration(self.nRows, self.nColumns) + newYearMatrix = CellManagement.CellManagement(agesMatrix).InsideCopy().system + if timeUnit % self.annualUnit == 0: + for r in range(self.nRows): + for c in range(self.nColumns): + if self.systemAges[r][c] != 0 and self.systemAges[r][c] != -1: + newYearMatrix[r][c] = self.systemAges[r][c] + 1 + elif self.systemAges[r][c] == 0: + newYearMatrix[r][c] = self.__birthCell() + else: + for r in range(self.nRows): + for c in range(self.nColumns): + newYearMatrix[r][c] = self.systemAges[r][c] + return newYearMatrix + + def evolutionRuleForAges(self, timeUnit): + agePositions = [] + mortalityApplicationGroups = [] + for probabilityOfDying in self.probabilityOfDyingByAgeGroup: + ageGroupPosition = self.ageGroupPositions(probabilityOfDying[0], probabilityOfDying[1]) + agePositions.append(ageGroupPosition) + mortalityApplicationGroups.append(math.ceil(len(ageGroupPosition) * probabilityOfDying[2]) - 1) + deadPositions = [] + for g in range(len(mortalityApplicationGroups)): + for age in range(mortalityApplicationGroups[g]): + numberOfDead = random.randint(0, len(agePositions[g]) - 1) + deadPositions.append(agePositions[g][numberOfDead]) + newYearMatrix = self.__birthdaysAndBirths(timeUnit) + for p in range(len(deadPositions)): + newYearMatrix[deadPositions[p][0]][deadPositions[p][1]] = 0 + return newYearMatrix + + def deathByDiseaseRule(self,cellSpace,deathFromDiseaseByAgeRange): + '''Aplica probabilidades de muerte por enfermedad a grupos de edad sobre el sistema''' + deathPositions = [] + infectedIndividualsPerGroup = [] + numberOfInfectedIndividualsDeathPerGroup = [] + systemCopy = CellManagement.CellManagement(cellSpace).InsideCopy() + for group in range(len(deathFromDiseaseByAgeRange)): + groupPositions = self.ageGroupPositions(deathFromDiseaseByAgeRange[group][0], deathFromDiseaseByAgeRange[group][1]) + infectedIndividuals = [] + for individual in range(len(groupPositions)): + if cellSpace.system[groupPositions[individual][0],groupPositions[individual][1]] == Models.State.I.value: + infectedIndividuals.append(groupPositions[individual]) + numberOfInfectedIndividualsDeath = math.ceil(len(infectedIndividuals) * deathFromDiseaseByAgeRange[group][2]) - 1 + infectedIndividualsPerGroup.append(infectedIndividuals) + numberOfInfectedIndividualsDeathPerGroup.append(numberOfInfectedIndividualsDeath) + for group in range(len(numberOfInfectedIndividualsDeathPerGroup)): + for infectedIndividual in range(numberOfInfectedIndividualsDeathPerGroup[group]): + randomIndividual = random.randint(0,len(infectedIndividualsPerGroup[group]) - 1) + deathPositions.append(infectedIndividualsPerGroup[group][randomIndividual]) + for position in range(len(deathPositions)): + self.systemAges[deathPositions[position][0]][deathPositions[position][1]] = 0 + systemCopy.system[deathPositions[position][0]][deathPositions[position][1]] = 3 + return [systemCopy, self.systemAges] \ No newline at end of file diff --git a/CAsimulation/CellManagement.py b/CAsimulation/CellManagement.py new file mode 100644 index 0000000..e877bb5 --- /dev/null +++ b/CAsimulation/CellManagement.py @@ -0,0 +1,60 @@ +import numpy as np +import random +import math +import EpidemiologicalModels.Models as Models +import EpidemiologicalModels.CellSpaceConfiguration as CellSpaceConfiguration + +class CellManagement: + + def __init__(self, cellSpace): + self.cellSpace = cellSpace + + def InsideCopy(self, extraRows = 0, extraColumns = 0): + """Copia del sistema en un entorno extendido + extraRows => Cantidad de filas extra del entorno + extraColumns => Cantidad de columnas extra del entorno""" + copy = -np.ones((self.cellSpace.nRows + (extraRows * 2), self.cellSpace.nColumns + (extraColumns * 2))) + for row in range(self.cellSpace.nRows): + for column in range(self.cellSpace.nColumns): + copy[row + extraRows][column+extraColumns] = self.cellSpace.system[row][column] + nRows, nColumns, unRows, unColumns, xnRows, xnColumns = self.cellSpace.basicParameters() + cellSpaceCopy = CellSpaceConfiguration.CellSpaceConfiguration(nRows, nColumns, unRows, unColumns, xnRows, xnColumns) + cellSpaceCopy.system = copy + return cellSpaceCopy + + def StateCoordinates(self, stateIndicator): + """Enlista los agentes que tengan un estado especifico + stateIndicator : 0 -> Susceptibles; 1 -> Infectados; 2 -> Recuperados; -1 -> Espacios vacios; 3 -> Fallecidos""" + coordinates = [] + for i in range(self.cellSpace.nRows): + for j in range(self.cellSpace.nColumns): + if self.cellSpace.system[i,j] == stateIndicator: + coordinates.append([i,j]) + return coordinates + + def StatePercentageInSpace(self,a,b,state,spatialState=0): + """Porcentaje de individuos con el estado en el espacio (a de cada b tienen el estado) + a,b => Porcentage visto como fracción + state => Estado que van a adquirir los individuos + spatialState => Estado que se considera como base para el cambio al estado state""" + percentageInSpace = [] + space = spatialState*np.ones((1,b)) + for j in range(a): + i = random.randint(1,b-1) + space[0][i] = state + for m in range(1,b): + percentageInSpace.append(int(space[0][m])) + return percentageInSpace + + def InitialCondition(self, initialPercentageInfected): + """Condición inicial aplicada al sistema + initialPercentageInfected => Porcentage inicial de infectados en el sistema""" + susceptibleCoordinates = self.StateCoordinates(Models.State.S.value) + initialInfectedNumber = math.ceil(len(susceptibleCoordinates)*initialPercentageInfected) + # Lista de posiciones de los idividuos que se infectaron y de los que se mantuvieron sanos al aplicar la condicion inicial + percentageInSpace = self.StatePercentageInSpace(initialInfectedNumber,len(susceptibleCoordinates)+1,Models.State.I.value) + cellSpaceCopy = self.InsideCopy() + for i in range(len(percentageInSpace)): + # Los vectores en las posiciones descritas en la lista percentageInSpace adquieren el estado de infección + cellSpaceCopy.system[susceptibleCoordinates[i][0]][susceptibleCoordinates[i][1]] = percentageInSpace[i] + return cellSpaceCopy \ No newline at end of file diff --git a/CAsimulation/CellSpaceConfiguration.py b/CAsimulation/CellSpaceConfiguration.py new file mode 100644 index 0000000..bc18858 --- /dev/null +++ b/CAsimulation/CellSpaceConfiguration.py @@ -0,0 +1,104 @@ +import numpy as np +import EpidemiologicalModels.CellManagement as CellManagement + +class CellSpaceConfiguration: + + def __init__(self, nRows, nColumns, xnRows = -1, xnColumns = -1, unRows = 0, unColumns = 0): + self.__nRows = nRows; self.__nColumns = nColumns # Dimensiones de la región interna inicial + self.__xnRows = xnRows; self.__xnColumns = xnColumns # Ubicación de la región interna inicial + self.__unRows = unRows; self.__unColumns = unColumns # Dimensiones del área externa + self.nRows = max(self.__nRows, self.__xnRows) + self.nColumns = max(self.__nColumns, self.__xnColumns) + self.__createInternalSpace() + + def __validate(self): + if self.__nRows < 0: + print("Debe definir un número de filas mayor a cero.") + return False + elif self.__nColumns < 0: + print("Debe definir un número de columnas mayor a cero.") + return False + else: + return True + + def basicParameters(self): + """Parámetros con los que se definió el sistema inicialmente.""" + return (self.__nRows, self.__nColumns, self.__xnRows, self.__xnColumns, self.__unRows, self.__unColumns) + + # Forma del espacio de células + + def __createInternalSpace(self): + if self.__validate(): + if self.__xnRows == -1 or self.__nColumns == -1: + self.system = np.zeros((self.__nRows, self.__nColumns)) + else: + self.system = -np.ones((self.__xnRows, self.__xnColumns)) + self.system = self.rectangularBoundary(self.__nRows, self.__nColumns, self.__unRows, self.__unColumns) + + def __boundaryDefinition(self, boundaryConditions): + """Definición de la estructura del sistema dadas las condiciones de frontera + boundaryConditions : Lista con las posiciones con individuos dentro del sistema""" + for condition in range(len(boundaryConditions)): + self.system[boundaryConditions[condition][0],boundaryConditions[condition][1]] = 0 + return self.system + + def rectangularBoundary(self, rectangleRows, rectangleColumns, rowPosition, columnPosition): + """Ubica una matriz nula de tamaño rectangleRows*rectangleColumns en la posición a,b del sistema""" + boundaryConditions = [] + for row in range(rectangleRows): + for column in range(rectangleColumns): + boundaryConditions.append((rowPosition + row,columnPosition + column)) + return self.__boundaryDefinition(boundaryConditions) + + # Condición inicial para aplicar el modelo epidemiológico + + def initialLocationOfInfected(self, initialPercentageInfected, position = "random", percentageOfInfectedMisplaced = 0): + """ubicación inicial de infectados + position : random + northwest north northeast + west center east + southwest south southeast""" + if position == "random": + return CellManagement.CellManagement(self).InitialCondition(initialPercentageInfected) + else: + # Se divide la zona rectángular en 9 bloques + a = int(self.nRows/3); b = int(self.nColumns/3) + system = CellManagement.CellManagement(self).InitialCondition(initialPercentageInfected*percentageOfInfectedMisplaced).system + infectedBlock = CellManagement.CellManagement(CellSpaceConfiguration(a,b)).InitialCondition(initialPercentageInfected-percentageOfInfectedMisplaced,).system + if position == "northwest": + for i in range(a): + for j in range(b): + system[i][j] = infectedBlock[i][j] + elif position == "north": + for i in range(a): + for j in range(b,2*b): + system[i][j] = infectedBlock[i][j-b] + elif position == "northeast": + for i in range(a): + for j in range(2*b,3*b): + system[i][j] = infectedBlock[i][j-2*b] + elif position == "west": + for i in range(a,a*2): + for j in range(b): + system[i][j] = infectedBlock[i-a][j] + elif position == "center": + for i in range(a,a*2): + for j in range(b,2*b): + system[i][j] = infectedBlock[i-a][j-b] + elif position == "east": + for i in range(a,a*2): + for j in range(2*b,3*b): + system[i][j]=infectedBlock[i-a][j-2*b] + elif position == "southwest": + for i in range(2*a,3*a): + for j in range(b): + system[i][j] = infectedBlock[i-2*a][j] + elif position == "south": + for i in range(2*a,3*a): + for j in range(b,2*b): + system[i][j] = infectedBlock[i-2*a][j-b] + elif position == "southeast": + for i in range(2*a,3*a): + for j in range(2*b,3*b): + system[i][j] = infectedBlock[i-2*a][j-2*b] + return system \ No newline at end of file diff --git a/CAsimulation/CompartmentalModelsInEDOS.py b/CAsimulation/CompartmentalModelsInEDOS.py new file mode 100644 index 0000000..192decd --- /dev/null +++ b/CAsimulation/CompartmentalModelsInEDOS.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# coding: utf-8 + +# In[ ]: + +import matplotlib.pyplot as plt + +class CompartmentalModelsInEDOS: + __h = 0.1; __n_iterations = 1 + __solutions = []; titlePlot = "Modelo compartimental" + + def __init__(self, listOfDifferentialEquations, initialConditions): + self.listOfDifferentialEquations = listOfDifferentialEquations + self.__initialConditions = initialConditions + self.__wasTheModelApplied = False + self.__validParameters = False + + def __AreTheParametersValid(self): + if not self.__IsThereAnInitialConditionForEachDifferentialEquation(): + print(f"Los parámetros no son validos, tienes {len(self.listOfDifferentialEquations)} ecuaciones diferenciales y {len(self.__initialConditions)} condiciones iniciales.") + elif self.__n_iterations == 1: + print(f"Solo esta considerando una iteración. Intente cambiando la cantidad de iteraciones con 'n_iterations()'.") + else: + self.__validParameters = True + + def __IsThereAnInitialConditionForEachDifferentialEquation(self): + return len(self.listOfDifferentialEquations) == len(self.__initialConditions) + + def __InitialValuesOfTheSolution(self): + self.__discreteSolutions = [] + for value in self.__initialConditions: + self.__discreteSolutions.append([value]) + return self.__discreteSolutions + + def __IsTheFirstIteration(self): + return self.__discreteSolutions == [] + + def __UpdateSolution(self): + lastCalculatedValues = [] + if self.__IsTheFirstIteration(): + self.__InitialValuesOfTheSolution() + for discreteSolution in self.__discreteSolutions: + lastCalculatedValues.append(discreteSolution[-1]) + return lastCalculatedValues + + def __CalculateNewValue(self, diferentialEquationPosition, lastCalculatedValues): + return self.__discreteSolutions[diferentialEquationPosition][-1]+self.__h*self.listOfDifferentialEquations[diferentialEquationPosition](lastCalculatedValues) + + def __TheModelWasApplied(self): + self.__wasTheModelApplied = True + self.__solutions = [self.__discreteSolutions, self.__domainValues] + + def __ApplyEulerMethod(self): + self.__AreTheParametersValid() + if self.__validParameters: + self.__InitialValuesOfTheSolution() + for iteration in range(1, self.__n_iterations): + lastCalculatedValues = self.__UpdateSolution() + for differentialEquation in self.listOfDifferentialEquations: + df = self.listOfDifferentialEquations.index(differentialEquation) + updatedValue = self.__CalculateNewValue(df, lastCalculatedValues) + self.__discreteSolutions[df].append(updatedValue) + self.__TheModelWasApplied() + return self.__solutions + + def n_iterations(self, valueForn_iterations): + self.__n_iterations = valueForn_iterations + self.__domainValues = range(valueForn_iterations) + + def ModelSolutions(self): + if self.__wasTheModelApplied: + return self.__solutions + else: + return self.__ApplyEulerMethod() + + def h(self, valueForh): + self.__h = valueForh + + def plotSolutions(self,nameValues,colors,limit = False,legends = True): + self.ModelSolutions() + if len(nameValues) != len(self.__solutions[0]): + print("Debe asignar la misma cantidad de nombres de variables") + elif len(colors) != len(self.__solutions[0]): + print("Debe asignar la misma cantidad de colores") + else: + for solution in self.__solutions[0]: + index = self.__solutions[0].index(solution) + plt.plot(self.__solutions[1], solution, c = colors[index], label = nameValues[index]) + plt.title(self.titlePlot) + if legends: + plt.legend() + if limit: + plt.plot(self.__solutions[1], [1 for s in range(len(self.__solutions[1]))], "k--") + + def PrintParameters(self): + print(f"""h: {self.__h} \nn_iterations: {self.__n_iterations} \ndifferentialEquations: {self.listOfDifferentialEquations} + """) + + + + \ No newline at end of file diff --git a/CAsimulation/DataManager.py b/CAsimulation/DataManager.py new file mode 100644 index 0000000..746e2df --- /dev/null +++ b/CAsimulation/DataManager.py @@ -0,0 +1,142 @@ +import numpy as np +import EpidemiologicalModels.CellManagement as CellManagement + +class SystemMetrics: + """Metricas que se monitorean por cada modelo: + statusInTheSystem => Cantidad de individuos por estado + numberOfIndividuals => Cantidad de individuos en el sistema + percentagesInTheSystem => Cantidad normalizada de individuos por estado""" + def __init__(self, cellSpace, states, i = None, j = None): + self.cellSpace = cellSpace + self.states = states + self.i, self.j = i, j # Si el sistema es una vecindad + + def statusInTheSystem(self, percentages=True, differentSystem=False, difSystem = None): + """Lista con las cantidades de individuos por cada estado + percentages == True => Valores normalizados + percentages == False => Valores enteros""" + if differentSystem == False: + difSystem = self.cellSpace.system + globalMetrics = [0]*len(self.states) + for row in range(self.cellSpace.nRows): + for column in range(self.cellSpace.nColumns): + if difSystem[row][column] in self.states: + state = self.states.index(difSystem[row][column]) + globalMetrics[state] += 1 + if self.i != None and self.j != None: + if difSystem[self.i][self.j] in self.states: + state = self.states.index(difSystem[self.i][self.j]) + globalMetrics[state] -= 1 + if percentages == False: + return globalMetrics + else: + percentage = [] + for state in globalMetrics: + percentage.append(state/self.numberOfIndividuals()) + return percentage + + def numberOfIndividuals(self): + """Cantidad de individuos en el sistema""" + self.totalIndividuals = sum(self.statusInTheSystem(percentages=False)) + if self.i != None and self.j != None: + if self.cellSpace[self.i][self.j] in self.states: + self.totalIndividuals += 1 + return self.totalIndividuals + +def OrderData(data,states): + """Separa los tipos de datos en 3 grupos: duplas, valores y estados del sistema + data => Lista de evoluciones tras aplicar el modelo epidemiológico + states => Estados que considera el modelo""" + percentages = []; amountsIndividuals = [] + for state in range(len(states)): + percentages.append([]) + for iteration in range(len(data)): + cellSpaceUpdate = data[iteration] + metrics = SystemMetrics(cellSpaceUpdate,states) + percentageData = metrics.statusInTheSystem() + for percentageList in percentages: + percentageList.append(percentageData[percentages.index(percentageList)]) + for state in range(len(states)): + amountsIndividuals.append(np.array((range(len(data)),percentages[state])).transpose()) + return [amountsIndividuals,percentages,data] + +def appliedModel(modelFunction, cellSpace, n_iterations, theSystemHasAges = False, systemAges = None): + """Aplica el modelo 'modelFunction' una cantidad nIterations de veces + modelFunction => Regla de evolución del modelo + n_iterations => Cantidad de veces que va a iterar el modelo + theSystemHasAges => Se usa para los modelos que tienen en cuenta la edad de los individuos + systemAges => Edades que se consideran en el sistema (por defecto no existe)""" + cellSpaceChanges = [cellSpace] + if theSystemHasAges == False: + iteration = 0 + while iteration <= n_iterations: + iteration += 1 + cellSpaceChanges.append(modelFunction(cellSpaceChanges[iteration-1])) + return cellSpaceChanges + else: + systemAgesEvolutions = [systemAges] + iteration = 0 + while iteration <= n_iterations: + iteration = iteration + 1 + updateCellSpace = modelFunction(cellSpaceChanges[iteration-1],systemAgesEvolutions[iteration-1],iteration) + cellSpaceChanges.append(updateCellSpace[0]) + systemAgesEvolutions.append(updateCellSpace[1]) + return cellSpaceChanges + +def mediumData(dataPerSimulation,states,n_iterations,n_simulations): + """Organiza la información de cada simulación + dataPerSimulation => Lista con los datos por estado + states => Estados que se consideran""" + percentages = []; amountsIndividuals = []; percentageAmounts = [] + for state in range(len(states)): + percentages.append([]) + for iteration in range(n_iterations): + for state in states: + rate = 0 + for simulation in range(n_simulations): + rate += dataPerSimulation[states.index(state)][simulation][iteration]/n_simulations + percentages[states.index(state)].append(rate) + for percentage in percentages: + percentageAmounts.append(percentage[1]) + for state in range(len(states)): + amountsIndividuals.append(np.array((range(n_iterations),percentages[state])).transpose()) + return [amountsIndividuals,percentages] + +def appliedMediumData(modelFunction,cellSpace,initialPercentageInfected,states,n_iterations,n_simulations,theSystemHasAges = False, systemAges = None): + """Aplica el modelo epidemiológico en n_simulations + modelFunction => Función basica del modelo epidemiológico + initialPercentageInfected => Porcentaje de infectados en el momento inicial + states => Estados que se consideran""" + mediumStates = [] + for state in states: + mediumStates.append([]) + if theSystemHasAges: + for simulation in range(n_simulations): + infectedCellSpace = CellManagement.CellManagement(cellSpace).InitialCondition(initialPercentageInfected) + systemEvolution = appliedModel(modelFunction, infectedCellSpace, n_iterations, True, systemAges) + evolution = OrderData(systemEvolution, states)[1] + for state in range(len(states)): + mediumStates[state].append(evolution[state]) + else: + for simulation in range(n_simulations): + infectedCellSpace = CellManagement.CellManagement(cellSpace).InitialCondition(initialPercentageInfected) + systemEvolution = appliedModel(modelFunction, infectedCellSpace, n_iterations, False) + evolution = OrderData(systemEvolution, states)[1] + for state in range(len(states)): + mediumStates[state].append(evolution[state]) + return mediumData(mediumStates,states,n_iterations,n_simulations) + +def variationsBetweenScales(scale1,scale2): + '''Genera una lista con las diferencias entre escalas''' + variationsArray = np.zeros((len(scale1),2)) + for data in range(len(scale1)): + variationsArray[data][0] = data + variationsArray[data][1] = abs(scale1[data]-scale2[data]) + return variationsArray + +def scale_differences(L1,L2): + '''variationsBetweenScales''' + L=np.zeros((len(L1),2)) + for i in range(len(L1)): + L[i][0]=i; L[i][1]=abs(L1[i]-L2[i]) + return L \ No newline at end of file diff --git a/CAsimulation/Models.py b/CAsimulation/Models.py new file mode 100644 index 0000000..ddd295b --- /dev/null +++ b/CAsimulation/Models.py @@ -0,0 +1,423 @@ +import enum +import random +import math +from typing_extensions import Annotated +import EpidemiologicalModels.NeighborhoodManager as NeighborhoodManager +import EpidemiologicalModels.CellManagement as CellManagement +import numpy as np +import EpidemiologicalModels.AgeManagement as AgeManagement +import EpidemiologicalModels.DataManager as DataManager +import EpidemiologicalModels.PlotsManager as PlotsManager +import EpidemiologicalModels.SystemVisualization as SystemVisualization + +class State(enum.Enum): + H = -1 # Huecos + S = 0 # Susceptibles + I = 1 # Infectados + R = 2 # Recuperados + D = 3 # Espacio vacío que se puede ocupar por una nueva célula + +class SImodel: + + def __init__(self, alpha, beta, cellSpace, neighborhoodSystems = [], impactRates = []): + """Modelo SI + alpha => Tasa de recuperación + beta => Tasa de infección + system => Espacio de celulas + neighborhoodSystems => Lista con las matrices que describen los sistemas de vecindades en el sistema + """ + self.alpha = alpha + self.beta = beta + self.cellSpace = cellSpace + self.neighborhoodSystems = neighborhoodSystems + self.impactRates = impactRates + + def __validate(self): + if self.alpha <= 0: + print("Debe definir una tasa de recuperación alpha > 0.") + return False + elif self.beta <= 0: + print("Debe definir una tasa de infección beta > 0.") + return False + elif str(type(self.cellSpace)) != "": + print("Asegurese de pasar un sistema con el tipo ") + return False + elif len(self.neighborhoodSystems) == 0: + print("Debe definir un sistema de vecindades.") + return False + elif len(self.impactRates) == 0: + print("Debe definir las tasas de impacto.") + return False + else: + return True + + def __CountNeighborsByState(self, neighbors): + """Cantidad de individuos por estado""" + numberOfSByImpact = 0; numberOfIByImpact = 0; numberOfRByImpact = 0; numberOfDByImpact = 0; numberOfH = 0 + for n in neighbors: + if n[0] == State.S.value: numberOfSByImpact += 1 + elif n[0] == State.I.value: numberOfIByImpact += 1 + elif n[0] == State.R.value: numberOfRByImpact += 1 + elif n[0] == State.D.value: numberOfDByImpact += 1 + elif n[0] == State.H.value: numberOfH += 1 + amountOfCells = numberOfSByImpact + numberOfIByImpact + numberOfRByImpact + numberOfDByImpact + numberOfH + return (numberOfSByImpact, numberOfIByImpact, amountOfCells, numberOfH) + + def __SI_rule(self, cellState, neighborsByImpact): # Grados de impacto 0 y 1 + """Regla totalística que describe el cambio entre los estados S e I de manera local""" + impactRanges = list(neighborsByImpact.keys()) + numberOfS = 0; numberOfI = 0; numberOfH = 0 + numberOfCells = 0 + for ir in impactRanges: + neighbors = neighborsByImpact.get(ir) + numberOfSByImpact, numberOfIByImpact, amountOfCells, amountOfHoles = self.__CountNeighborsByState(neighbors) + numberOfS += numberOfSByImpact * self.impactRates[impactRanges.index(ir)] + numberOfI += numberOfIByImpact * self.impactRates[impactRanges.index(ir)] + numberOfH += amountOfHoles * self.impactRates[impactRanges.index(ir)] + numberOfCells += amountOfCells * self.impactRates[impactRanges.index(ir)] + rho = random.random() + if numberOfI > 0: + localInfectionRate = (self.beta / self.alpha) * (numberOfI / ((numberOfCells - 1) - numberOfH)) + if cellState == State.S.value: + if numberOfI <= numberOfS and rho >= localInfectionRate: return State.S.value + else: return State.I.value + else: return cellState + else: return cellState + + def Apply(self): + """Regla S -> I""" + if self.__validate(): + systemUpdate = CellManagement.CellManagement(self.cellSpace).InsideCopy() + for ns in self.neighborhoodSystems: + neighborsByImpact = NeighborhoodManager.NeigborhoodManager(self.cellSpace, ns[1]).ImpactNeighborClassifier() + if systemUpdate.system[ns[0][0]][ns[0][1]] not in [State.H.value, State.R.value, State.D.value]: + systemUpdate.system[ns[0][0]][ns[0][1]] = self.__SI_rule(self.cellSpace.system[ns[0][0]][ns[0][1]], neighborsByImpact) + return systemUpdate + +class SISmodel(SImodel): + + states = [State.S.value, State.I.value] + colors = ["y", "r"] + labels = ["Susceptibles", "Infectados"] + + def __siRule(self, updatedCellSpace, impactRates): + """Regla S -> I""" + return SImodel(self.alpha, self.beta, updatedCellSpace, self.neighborhoodSystems, impactRates).Apply() + + def __isRule(self, previousCellSpace): + """Regla I -> S""" + PreviousCellSpace = CellManagement.CellManagement(previousCellSpace) + infectedCoordinates = PreviousCellSpace.StateCoordinates(State.I.value) + initialRecoveredNumber = math.ceil(len(infectedCoordinates) * self.alpha) + percentageInSpace = PreviousCellSpace.StatePercentageInSpace(initialRecoveredNumber, len(infectedCoordinates) + 1, State.S.value, State.I.value) + cellSpaceCopy = PreviousCellSpace.InsideCopy() + for i in range(len(percentageInSpace)): + cellSpaceCopy.system[infectedCoordinates[i][0]][infectedCoordinates[i][1]] = percentageInSpace[i] + return cellSpaceCopy + + def basicRule(self, previousCellSpace): + """Aplica la regla de evolución al sistema previousSystem""" + updatedStates_IS = self.__isRule(previousCellSpace) + updatedStates_SI = self.__siRule(updatedStates_IS, self.impactRates) + return updatedStates_SI + +class SIRmodel(SImodel): + + states = [State.S.value, State.I.value, State.R.value] + colors = ["y", "r", "g"] + labels = ["Susceptibles", "Infectados", "Recuperados"] + + def __siRule(self, updatedCellSpace, impactRates): + """Regla S -> I""" + return SImodel(self.alpha, self.beta, updatedCellSpace, self.neighborhoodSystems, impactRates).Apply() + + def __irRule(self,previousCellSpace): + """Regla I -> R""" + PreviousSystem = CellManagement.CellManagement(previousCellSpace) + infectedCoordinates = PreviousSystem.StateCoordinates(State.I.value) + initialRecoveredNumber = math.ceil(len(infectedCoordinates) * self.alpha) + percentageInSpace = PreviousSystem.StatePercentageInSpace(initialRecoveredNumber, len(infectedCoordinates) + 1, State.R.value, State.I.value) + cellSpaceCopy = PreviousSystem.InsideCopy() + + for i in range(len(percentageInSpace)): + cellSpaceCopy.system[infectedCoordinates[i][0]][infectedCoordinates[i][1]] = percentageInSpace[i] + return cellSpaceCopy + + def basicRule(self,previousSystem): + """Aplica la regla de evolución al sistema previousSystem""" + updatedStates_IR = self.__irRule(previousSystem) + updatedStates_SI = self.__siRule(updatedStates_IR, self.impactRates) + return updatedStates_SI + +class birthAndMortavility: + + probabilityOfDyingByAgeGroup = [] + neighborhoodSystems = [] + impactRates = [] + systemAges = np.array(()) + + def __init__(self, model, alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, cellSpace, neighborhoodSystems, impactRates, systemAges): + self.model = model.lower() + self.alpha = alpha + self.beta = beta + self.birthRate = birthRate + self.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + self.annualUnit = annualUnit + self.cellSpace = cellSpace + self.neighborhoodSystems = neighborhoodSystems + self.impactRates = impactRates + self.systemAges = systemAges + self.__modelVariables() + + def __validate(self): + if self.model != "sis" and self.model != "sir": + print("Introduzca un modelo valido. (SIS o SIR)") + return False + elif self.birthRate <= 0: + print("Defina una tasa de natalidad mayor a cero.") + return False + elif len(self.probabilityOfDyingByAgeGroup) == 0: + print("Establezca las probabilidades de muerte por rango.") + return False + elif self.annualUnit <= 0: + print("Defina una unidad anual mayor a cero.") + return False + elif str(type(self.cellSpace)) != "": + print("Asegurese de pasar un sistema con el tipo ") + return False + elif len(self.neighborhoodSystems) == 0: + print("Defina un sistema de vecindades.") + return False + elif len(self.impactRates) == 0: + print("Defina las tasas de impacto.") + return False + elif self.systemAges.shape[0] == 0: + print("Defina una matriz de edades.") + return False + else: + return True + + def __modelVariables(self): + if self.model == "sis": + self.states = [State.S.value, State.I.value, State.D.value] + self.colors = ["y", "r", "b"] + self.labels = ["Susceptibles", "Infectados", "Espacios disponibles"] + elif self.model == "sir": + self.states = [State.S.value, State.I.value, State.R.value, State.D.value] + self.colors = ["y", "r", "g", "b"] + self.labels = ["Susceptibles", "Infectados", "Recuperados", "Espacios disponibles"] + + def basicRule(self,previousCellSpace,previousAgesSystem,timeUnit): + '''Regla de evolución del modelo con natalidad y mortalidad''' + if self.__validate(): + modelWithBirthAndMortavilityCellSpace = CellManagement.CellManagement(self.cellSpace).InsideCopy() + newYearMatrix = AgeManagement.AgeMatrixEvolution(previousAgesSystem, self.birthRate, self.annualUnit, self.probabilityOfDyingByAgeGroup).evolutionRuleForAges(timeUnit) + if self.model == "sis": + modelCellSpace = SISmodel(self.alpha, self.beta, previousCellSpace, self.neighborhoodSystems, self.impactRates).basicRule(previousCellSpace) + elif self.model == "sir": + modelCellSpace = SIRmodel(self.alpha, self.beta, previousCellSpace, self.neighborhoodSystems, self.impactRates).basicRule(previousCellSpace) + for row in range(self.cellSpace.nRows): + for column in range(self.cellSpace.nColumns): + if newYearMatrix[row,column] == 0: modelWithBirthAndMortavilityCellSpace.system[row,column] = State.D.value + elif newYearMatrix[row,column] == 1: modelWithBirthAndMortavilityCellSpace.system[row,column] = State.S.value + else: modelWithBirthAndMortavilityCellSpace.system[row][column] = modelCellSpace.system[row][column] + return [modelWithBirthAndMortavilityCellSpace, newYearMatrix] + +class deathByDisease: + + deathFromDiseaseByAgeRange = [] + + def __init__(self, model, alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, cellSpace, neighborhoodSystems, impactRates, systemAges): + self.model = model.lower() + self.alpha = alpha + self.beta = beta + self.birthRate = birthRate + self.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + self.deathFromDiseaseByAgeRange = deathFromDiseaseByAgeRange + self.annualUnit = annualUnit + self.cellSpace = cellSpace + self.neighborhoodSystems = neighborhoodSystems + self.impactRates = impactRates + self.systemAges = systemAges + self.__modelVariables() + + def __modelVariables(self): + if self.model == "sis": + self.states = [State.S.value, State.I.value, State.D.value] + self.colors = ["y", "r", "b"] + self.labels = ["Susceptibles", "Infectados", "Espacios disponibles"] + elif self.model == "sir": + self.states = [State.S.value, State.I.value, State.R.value, State.D.value] + self.colors = ["y", "r", "g", "b"] + self.labels = ["Susceptibles", "Infectados", "Recuperados", "Espacios disponibles"] + + def __validate(self): + if len(self.deathFromDiseaseByAgeRange) == 0: + print("Defina las probabilidades de muerte por enfermedad.") + return False + else: + return True + + def basicRule(self,cellSpace,systemAges,timeUnit): + if self.__validate(): + evolution = birthAndMortavility(self.model, self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, self.annualUnit, + cellSpace, self.neighborhoodSystems, self.impactRates, systemAges).basicRule(cellSpace,systemAges,timeUnit) + cellSpaceCopy = CellManagement.CellManagement(evolution[0]).InsideCopy() + evolutionsAfterDeaths = AgeManagement.AgeMatrixEvolution(evolution[1],0).deathByDiseaseRule(cellSpaceCopy, self.deathFromDiseaseByAgeRange) + return evolutionsAfterDeaths + +class applyEpidemiologicalModel: + # En las variables data y evolutions se almacenaran los datos luego de aplicar los modelos + data = None # Reporte numperico de los cambios en cada estado + mediumData = None # Reporte numperico promedio de los cambios en cada estado + evolutions = None # Reporte visual de los cambios del sistema + # Datos tomados por defecto + modelHasAges = False + systemAges = None # Edades de los individuos en el sistema + annualUnit = None # Unidad de ciclo temporal (año) + birthRate = None # Tasa de natalidad + probabilityOfDyingByAgeGroup = None # Tasa de mortalidad por grupo de edad + modelHasDeathByDisease = False + deathFromDiseaseByAgeRange = None # Tasa de mortalidad causada por la enfermedad por grupo de edad + + def __init__(self, model, alpha, beta, cellSpace, neighborhoodSystems, impactRates = [1,0]): + """Modelos soportados: sis, sir, sis_bm, sir_bm, sis_dd, sir_dd""" + self.model = model.lower() # Modelo epidemiológico que se va a aplicar + self.alpha = alpha; self.beta = beta # Datos básicos de la enfermedad + self.cellSpace = cellSpace # Sistema sobre el que se va a aplicar el modelo + self.neighborhoodSystems = neighborhoodSystems # Tipo de vecindad que va a considerar para el análisis + self.impactRates = impactRates + self.title = f"Modelo {self.model.upper()}" + + def __validate(self): + if self.model not in ("sis", "sir", "sis_bm", "sir_bm", "sis_dd", "sir_dd"): + print("Asegurese de ingresar un modelo valido. (sis, sir, sis_bm, sir_bm, sis_dd, sir_dd)") + return False + else: + return True + + def __evalConditions(self): + # Definición de las herramientas para aplicar los modelos + if self.model == "sis": + self.epidemiologicalModel = SISmodel(self.alpha,self.beta,self.cellSpace,self.neighborhoodSystems, self.impactRates) + elif self.model == "sir": + self.epidemiologicalModel = SIRmodel(self.alpha,self.beta,self.cellSpace,self.neighborhoodSystems, self.impactRates) + else: + self.modelHasAges = True + if self.model == "sis_bm": + self.epidemiologicalModel = birthAndMortavility("sis", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, self.annualUnit, + self.cellSpace, self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sir_bm": + self.epidemiologicalModel = birthAndMortavility("sir", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, self.annualUnit, + self.cellSpace, self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sis_dd": + self.epidemiologicalModel = deathByDisease("sis", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, + self.deathFromDiseaseByAgeRange, self.annualUnit, self.cellSpace, + self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sir_dd": + self.epidemiologicalModel = deathByDisease("sir", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, + self.deathFromDiseaseByAgeRange, self.annualUnit, self.cellSpace, + self.neighborhoodSystems, self.impactRates, self.systemAges) + + def basicModel(self, n_iterations, modifiedSystem = False, system = None): + """Aplica el modelo n_iterations veces""" + if self.__validate(): + self.__evalConditions() + if modifiedSystem == False: + evolutions = DataManager.appliedModel(self.epidemiologicalModel.basicRule, self.cellSpace, n_iterations, self.modelHasAges, self.systemAges) + else: + evolutions = DataManager.appliedModel(self.epidemiologicalModel.basicRule, system, n_iterations, self.modelHasAges, self.systemAges) + visualization = DataManager.OrderData(evolutions, self.epidemiologicalModel.states) + self.data = visualization[0] + self.evolutions = visualization[2] + + def plotCurvesModel(self, title = "", limit = False): + if title == "": + PlotsManager.plotSolutions(self.data, self.epidemiologicalModel.labels, self.epidemiologicalModel.colors, self.title, limit) + else: + PlotsManager.plotSolutions(self.data, self.epidemiologicalModel.labels, self.epidemiologicalModel.colors, title, limit) + + def plotSpecificIteration(self, iteration): + if iteration <= len(self.evolutions) - 1: + SystemVisualization.SystemVisualization(self.evolutions).evolutionsPlot(iteration) + else: + print(f"La iteración no es valida. Debe ser menor o igual a {len(self.evolutions)-1}") + +class applyEpidemiologicalModel_nIterations: + # En las variables data y evolutions se almacenaran los datos luego de aplicar los modelos + data = None # Reporte numperico de los cambios en cada estado + mediumData = None # Reporte numperico promedio de los cambios en cada estado + evolutions = None # Reporte visual de los cambios del sistema + # Datos tomados por defecto + modelHasAges = False + systemAges = None # Edades de los individuos en el sistema + annualUnit = None # Unidad de ciclo temporal (año) + birthRate = None # Tasa de natalidad + probabilityOfDyingByAgeGroup = None # Tasa de mortalidad por grupo de edad + modelHasDeathByDisease = False + deathFromDiseaseByAgeRange = None # Tasa de mortalidad causada por la enfermedad por grupo de edad + + def __init__(self, model, alpha, beta, cellSpace, neighborhoodSystems, impactRates = [1,0], nSimulations = 1, initialPercentageInfected = 0): + """Modelos soportados: sis, sir, sis_bm, sir_bm, sis_dd, sir_dd""" + self.model = model.lower() # Modelo epidemiológico que se va a aplicar + self.alpha = alpha; self.beta = beta # Datos básicos de la enfermedad + self.cellSpace = cellSpace # Sistema sobre el que se va a aplicar el modelo + self.neighborhoodSystems = neighborhoodSystems # Tipo de vecindad que va a considerar para el análisis + self.impactRates = impactRates + self.title = f"Modelo {self.model.upper()}" + self.nSimulations = nSimulations + self.initialPercentageInfected = initialPercentageInfected + + def __validate(self): + if self.model not in ("sis", "sir", "sis_bm", "sir_bm", "sis_dd", "sir_dd"): + print("Asegurese de ingresar un modelo valido. (sis, sir, sis_bm, sir_bm, sis_dd, sir_dd)") + return False + elif self.nSimulations == 1: + print("Debe generar más de una simulación.") + return False + elif self.initialPercentageInfected < 0: + print("Debe establecer un porcentage de infectados inicial para cada simulación.") + return False + else: + return True + + def __evalConditions(self): + # Definición de las herramientas para aplicar los modelos + if self.model == "sis": + self.epidemiologicalModel = SISmodel(self.alpha,self.beta,self.cellSpace,self.neighborhoodSystems, self.impactRates) + elif self.model == "sir": + self.epidemiologicalModel = SIRmodel(self.alpha,self.beta,self.cellSpace,self.neighborhoodSystems, self.impactRates) + else: + self.modelHasAges = True + if self.model == "sis_bm": + self.epidemiologicalModel = birthAndMortavility("sis", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, self.annualUnit, + self.cellSpace, self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sir_bm": + self.epidemiologicalModel = birthAndMortavility("sir", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, self.annualUnit, + self.cellSpace, self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sis_dd": + self.epidemiologicalModel = deathByDisease("sis", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, + self.deathFromDiseaseByAgeRange, self.annualUnit, self.cellSpace, + self.neighborhoodSystems, self.impactRates, self.systemAges) + if self.model == "sir_dd": + self.epidemiologicalModel = deathByDisease("sir", self.alpha, self.beta, self.birthRate, self.probabilityOfDyingByAgeGroup, + self.deathFromDiseaseByAgeRange, self.annualUnit, self.cellSpace, + self.neighborhoodSystems, self.impactRates, self.systemAges) + + def basicModel(self, n_iterations): + """Aplica el modelo n_iterations veces""" + if self.__validate(): + self.__evalConditions() + if self.model == "sis" or self.model == "sir": + evolutions = DataManager.appliedMediumData(self.epidemiologicalModel.basicRule, self.cellSpace, self.initialPercentageInfected, + self.epidemiologicalModel.states, n_iterations, self.nSimulations) + else: + evolutions = DataManager.appliedMediumData(self.epidemiologicalModel.basicRule, self.cellSpace, self.initialPercentageInfected, + self.epidemiologicalModel.states, n_iterations, self.nSimulations, True, self.systemAges) + self.data = evolutions[0] + + def plotCurvesModel(self, title = "", limit = False): + if title == "": + PlotsManager.plotSolutions(self.data, self.epidemiologicalModel.labels, self.epidemiologicalModel.colors, self.title, limit) + else: + PlotsManager.plotSolutions(self.data, self.epidemiologicalModel.labels, self.epidemiologicalModel.colors, title, limit) \ No newline at end of file diff --git a/CAsimulation/NeighborhoodManager.py b/CAsimulation/NeighborhoodManager.py new file mode 100644 index 0000000..aab4cf7 --- /dev/null +++ b/CAsimulation/NeighborhoodManager.py @@ -0,0 +1,82 @@ +import numpy as np +import random + +class NeigborhoodManager: + def __init__(self, cellSpace, impactMatrix): + self.cellSpace = cellSpace + self.impactMatrix = impactMatrix + + def __Validator(self): + return self.cellSpace.system.shape == self.impactMatrix.shape + + def __ListWithMatrixValues(self): + '''Lista con los valores de la matriz''' + values = [] + for r in range(self.cellSpace.nRows): + for c in range(self.cellSpace.nColumns): + if self.impactMatrix[r][c] not in values: + values.append(self.impactMatrix[r][c]) + values.sort() + return values + + def __Impacts(self): + '''Crea el diccionario que va almacernará los estados de los vecinos por grado de impacto''' + impactValues = self.__ListWithMatrixValues() + keys = []; values = [] + for impact in impactValues: + keys.append(impact); values.append([]) + return dict(zip(keys,values)) + + def ImpactNeighborClassifier(self): + '''Clasifica a los vecinos y sus estados por grado de impacto en un diccionario''' + if self.__Validator(): + impacts = self.__Impacts() + for r in range(self.cellSpace.nRows): + for c in range(self.cellSpace.nColumns): + impact = self.impactMatrix[r][c] + neighborsByImpact = impacts.get(impact) + neighborsByImpact.append([self.cellSpace.system[r,c],[r,c]]) + impacts.update({impact : neighborsByImpact}) + return impacts + else: + print("Las dimensiones del sistema y la matriz de impactos son diferentes.") + +# Sistemas de vecindades básicos + +def randomNeighborhoods(cellSpace): + '''Sistema de vecindades generado aleatoriamente''' + neighborhoodSystems = [] + for r in range(cellSpace.nRows): + for c in range(cellSpace.nColumns): + base = np.ones(cellSpace.system.shape) + p = random.random() + if p <= 0.5: + base[r][c] = 0 + neighborhoodSystems.append([[r,c],base]) + return neighborhoodSystems + +def Von_Neumann(cellSpace): + '''Sistema de vecindades generado por la vecindad de Von Neumann''' + neighborhoodSystems = [] + for r in range(cellSpace.nRows): + for c in range(cellSpace.nColumns): + base = np.ones(cellSpace.system.shape) + for i in range(cellSpace.nRows): + for j in range(cellSpace.nColumns): + if abs(r - i) + abs(c - j) <= 1: + base[i][j] = 0 + neighborhoodSystems.append([[r,c],base]) + return neighborhoodSystems + +def Moore(cellSpace): + '''Sistema de vecindades generado por la vecindad de Moore''' + neighborhoodSystems = [] + for r in range(cellSpace.nRows): + for c in range(cellSpace.nColumns): + base = np.ones(cellSpace.system.shape) + for i in range(cellSpace.nRows): + for j in range(cellSpace.nColumns): + if abs(r - i) <= 1 and abs(c - j) <= 1: + base[i][j] = 0 + neighborhoodSystems.append([[r,c],base]) + return neighborhoodSystems \ No newline at end of file diff --git a/CAsimulation/PlotsManager.py b/CAsimulation/PlotsManager.py new file mode 100644 index 0000000..67e847d --- /dev/null +++ b/CAsimulation/PlotsManager.py @@ -0,0 +1,56 @@ +import numpy as np +import matplotlib.pyplot as plt + +def spline3(A): #spline cubico para la lista de coordenadas A + n = len(A); l = [1]; B = [0] ; g = [0]; gn = 0; C = [0]*n + alpha = []; spline = []; a = []; h = []; x = []; y = []*(n-1) + for i in range(n): + a.append(A[i][1]) + for i in range(n-1): + xh = A[i+1][0]-A[i][0]; h.append(xh) + for i in range(1, n-1): + xa = (3/h[i])*(a[i+1]-a[i])-(3/h[i-1])*(a[i]-a[i-1]); alpha.append(xa) + for i in range(1, n-1): + xl = 2*(A[i+1][0]-A[i-1][0])-h[i-1]*B[i-1]; l.append(xl) + xb = h[i]/l[i]; B.append(xb) + xg = (alpha[i-1]-h[i-1]*g[i-1])/l[i]; g.append(xg) + l.append(1); g.append(0) + for i in range(n-1): + j = (n-1)-(i+1) + xC = g[j]-B[j]*C[j+1]; C[j] = xC + xy = ((a[j+1]-a[j])/h[j])-(h[j]/3)*(C[j+1]+2*C[j]); y.append(xy) + xx = (C[j+1]-C[j])/(3*h[j]); x.append(xx) + for i in range(n-1): + j=(n-1)-(i+1) + S3 = [a[i],y[j],C[i],x[j]]; spline.append(S3) + return np.array(spline) + +def plotSolutions(variables, etiquetas, colores, title, limit=True): + if len(etiquetas) != len(variables): + print("La cantidad de etiquetas debe ser igual a la cantidad de variables") + elif len(colores) != len(variables): + print("La cantidad de colores debe ser igual a la cantidad de variables") + else: + for j in range(len(variables)): + funcion = []; cond = []; x = []; y = [] + A = variables[j] + SP = spline3(A) + for i in range(len(spline3(A))): + xa = np.linspace(A[i,0],A[i+1,0] - 0.0001,11); x = np.concatenate((x,xa)) + ya = SP[i,0] + SP[i,1]*(xa-A[i,0]) + SP[i,2]*(xa-A[i,0])**2 + SP[i,3]*(xa-A[i,0])**3 + y = np.concatenate((y,ya)) + plt.plot(x,y,c = colores[j],label = etiquetas[j]) + if limit == True: + plt.plot(x, x**0, 'k--') + plt.ylim(0,1.05) + plt.title(title) + plt.xlabel("Time") + plt.legend(loc=0) + plt.show() + +def plotMediumCurves(self, initialPercentageInfected, n_iterations, n_simulations, title): + """Gráfica la evolución promedio en n_simulations de los estados en n_iterations""" + if self.mediumData == None: + visualization = self.mediumCurves(initialPercentageInfected, n_iterations, n_simulations) + self.mediumData = visualization[0] + plotSolutions(self.mediumData, self.epidemiologicalModel.labels, self.epidemiologicalModel.colors, title) \ No newline at end of file diff --git a/CAsimulation/README.md b/CAsimulation/README.md new file mode 100644 index 0000000..bd58d8d --- /dev/null +++ b/CAsimulation/README.md @@ -0,0 +1,459 @@ +# CAsimulations + +Para importar la librería, ejecute el siguiente script +~~~ + from EpidemiologicalModels.epidemiologicalModelsInCA import * + ~~~ +## El espacio de células + +### CellSpace(nRows, nColumns, xnRows, xnColumns, unRows, unColumns) + +Genera la configuración básica de un sistema de células +**Parámetros:** +* **nRows(int)** Filas de la región interna inicial del sistema / filas del sistema +* **nColumns(int)** Columnas de la región interna inicial del sistema / Columnas del sistema +* **xnRows(int)** Fila donde se ubica la región interna inicial +* **xnColumns(int)** Columna donde se ubica la región interna inicial +* **unRows(int)** Filas del área externa +* **unColumns(int)** Columnas del área externa + +**Salida:** +* **EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration** Sistema de células + +**Ejemplo 1:** +~~~ +space = CellSpace(10,10) +space.system +--> array([[0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.]]) + +space.initialLocationOfInfected(0.1) +--> array([[0., 0., 0., 0., 0.], + [0., 0., 1., 0., 0.], + [1., 0., 0., 0., 0.], + [0., 1., 0., 0., 0.], + [0., 0., 0., 0., 0.]]) +~~~ +**Ejemplo 2:** +~~~ +space = CellSpace(3,1,5,5) +space.system +--> array([[ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [-1., -1., -1., -1., -1.], + [-1., -1., -1., -1., -1.]]) + +space.rectangularBoundary(2,2,3,1) +--> array([[ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [-1., 0., 0., -1., -1.], + [-1., 0., 0., -1., -1.]]) +~~~ +**Ejemplo 3:** +~~~ +space = CellSpace(3,1,5,5,1,2) +space.system +--> array([[-1., -1., -1., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., -1., -1., -1.]]) +~~~ +### CreateAgeMatrix(ranges, cellSpace) +Crea una matriz con las edades de las células de acuerdon con las probabilidades definidas en ranges. +**Parámetros:** +* **ranges(list(list))** Debe contener los rangos de edad y la proporción de individuos del sistema que tendran una edad en el rango. +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Systema de células a las que se les asignará una edad. + +**Salidas:** +* **numpy.ndarray ** Arreglo con las edades del sistema de células. + +**Ejemplo:** +~~~ +ranges = [[0,10,0.2],[11,100,0.8]] # 20% tienen entre 0 y 10 años, y 80% tienen entre 11 y 100. +space = CellSpace(5,5) +createAgeMatrix(ranges, space) + +--> array([[ 1., 81., 33., 5., 18.], + [90., 19., 18., 36., 50.], + [ 5., 67., 4., 18., 74.], + [45., 36., 4., 36., 4.], + [ 5., 67., 74., 1., 1.]]) +~~~ +### GenerateNeighborhoodSystem(cellSpace, neighborhoodType) +Genera un conjunto de vecindades básico para aplicar los modelos epidemiológicos +**Parámetros:** +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Sistema de células para el cuál se definirá el sistema de vecindades +* **neighborhoodType(string)** Configuración del sistema - Valores permitidos (Moore - Von Neumann), por defecto se genera un sistema con valores aleatorios + +**Salidas:** +* **list** Lista con los arreglos que describen el conjunto de vecindades y las coordenadas de cada célula + +**Ejemplo 1:** +~~~ +GenerateNeighborhoodSystem(CellSpace(3,3)) +--> [[[0, 0],array([[0., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[0, 1],array([[1., 0., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[0, 2],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 0],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 1],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 2],array([[1., 1., 1.], + [1., 1., 0.], + [1., 1., 1.]])], + [[2, 0],array([[1., 1., 1.], + [1., 1., 1.], + [0., 1., 1.]])], + [[2, 1],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[2, 2],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 0.]])]] +~~~ +**Ejemplo 2:** +~~~ +GenerateNeighborhoodSystem(CellSpace(3,3),"Moore") +--> [[[0, 0],array([[0., 0., 1.], + [0., 0., 1.], + [1., 1., 1.]])], + [[0, 1],array([[0., 0., 0.], + [0., 0., 0.], + [1., 1., 1.]])], + [[0, 2],array([[1., 0., 0.], + [1., 0., 0.], + [1., 1., 1.]])], + [[1, 0],array([[0., 0., 1.], + [0., 0., 1.], + [0., 0., 1.]])], + [[1, 1],array([[0., 0., 0.], + [0., 0., 0.], + [0., 0., 0.]])], + [[1, 2],array([[1., 0., 0.], + [1., 0., 0.], + [1., 0., 0.]])], + [[2, 0],array([[1., 1., 1.], + [0., 0., 1.], + [0., 0., 1.]])], + [[2, 1],array([[1., 1., 1.], + [0., 0., 0.], + [0., 0., 0.]])], + [[2, 2],array([[1., 1., 1.], + [1., 0., 0.], + [1., 0., 0.]])]] +~~~ +## Modelos epidemiológicos +### SIS(alpha, beta, n_iterations, cellSpace, neighborhoodSystem, impactRates) +Modelo SIS aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9,9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace,"moore") + +sis = SIS(0.2,0.5,10,cellSpace,neighborhoodSystem,[1,0]) +~~~ + +### SIR(alpha, beta, n_iterations, cellSpace, neighborhoodSystem, impactRates): +Modelo SIR aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9,9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace,"moore") + +sir = SIR(0.2,0.5,10,cellSpace,neighborhoodSystem,[1,0]) +~~~ +### SIS_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Modelo SIS con natalidad y mortalidad aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +sis_bm = SIS_BM(0.2,0.5,0.2,[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### SIR_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Modelo SIR con natalidad y mortalidad aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +sir_bm = SIR_BM(0.2,0.5,0.2,[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### SIS_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Modelo SIS con muerte por enfermedad aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **deathFromDiseaseByAgeRange(list)** Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +sis_dd = SIS_DD(0.2,0.5,0.2,[[0,100,0.0005]],[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### SIR_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Modelo SIR con muerte por enfermedad aplicado sobre el espacio de células +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **deathFromDiseaseByAgeRange(list)** Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +sir_dd = SIR_DD(0.2,0.5,0.2,[[0,100,0.0005]],[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ + +### medium_SIS(alpha, beta, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates) +Aplica el modelo SIS una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sis = medium_SIS(0.2,0.5,0.1,10,3,cellSpace,neighborhoodSystem,[1,0]) +~~~ +### medium_SIR(alpha, beta, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates) +Aplica el modelo SIR una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sir = medium_SIR(0.2,0.5,0.1,10,3,cellSpace,neighborhoodSystem,[1,0]) +~~~ +### medium_SIS_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Aplica el modelo SIS con natalidad y mortalidad una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sis_bm = medium_SIS_BM(0.2,0.5, 0.2, [[0,100,0.0000005]], 365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### medium_SIR_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Aplica el modelo SIR con natalidad y mortalidad una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sir_bm = medium_SIR_BM(0.2,0.5, 0.2, [[0,100,0.0000005]], 365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### medium_SIS_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Aplica el modelo SIS con muerte por enfermead una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **deathFromDiseaseByAgeRange(list)** Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sis_dd = medium_SIS_DD(0.2,0.5, 0.2, [[0,100,0.0000005]], [[0,100,0.0000005]],365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ +### medium_SIR_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges) +Aplica el modelo SIR con muerte por enfermead una cantidad determinada de veces y calcula sus datos promedio +**Parámetros:** +* **alpha(float)** Tasa de recuperación +* **beta(float)** Tasa de infección +* **birthRate(float)** Tasa de natalidad +* **probabilityOfDyingByAgeGroup(list)** Lista con las probabilidades de muerte de una célula por rangos de edad +* **deathFromDiseaseByAgeRange(list)** Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad +* **annualUnit(int)** Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) +* **initialPercentageInfected(float)** Porcentage inicial de individuos infectados +* **n_iterations(int)** Cantidad de iteraciones en las que se aplica en modelo +* **nSimulations(int)** Cantidad de simulaciones que va a considerar +* **cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration)** Espacio de células +* **neighborhoodSystem(list)** Lista con los grados de impacto para cada célula +* **impactRates(list)** Tasas de impacto consideradas +* **systemAges(numpy.ndarray)** Matriz con las edades de cada célula + +**Salidas:** +* **EpidemiologicalModels.Models.applyEpidemiologicalModel** Contiene toda la información generada al aplicar el modelo + +**Ejemplo:** +~~~ +cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) +neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") +ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + +medium_sir_dd = medium_SIR_DD(0.2,0.5, 0.2, [[0,100,0.0000005]], [[0,100,0.0000005]],365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) +~~~ \ No newline at end of file diff --git a/CAsimulation/SystemVisualization.py b/CAsimulation/SystemVisualization.py new file mode 100644 index 0000000..f2066a4 --- /dev/null +++ b/CAsimulation/SystemVisualization.py @@ -0,0 +1,62 @@ +import EpidemiologicalModels.CellManagement as CellManagement +import matplotlib.pyplot as plt +import numpy as np +import seaborn as sns + +class SystemVisualization: + + def __init__(self, evolutionsOfCellSpace): + self.evolutionsOfCellSpace = evolutionsOfCellSpace + + def __color(self,cellSpace): + """Transformación que permite visualizar el sistema a color""" + cellSpaceCopy = CellManagement.CellManagement(cellSpace).InsideCopy() + for i in range(cellSpace.nRows): + for j in range(cellSpace.nColumns): + if cellSpaceCopy.system[i][j] == 0: + cellSpaceCopy.system[i][j] = 190 # Susceptibles => Amarillo + if cellSpaceCopy.system[i][j] == 1: + cellSpaceCopy.system[i][j] = 240 # Infectados => Rojo + if cellSpaceCopy.system[i][j] == 2: + cellSpaceCopy.system[i][j] = 115 # Recuperados => Verde + if cellSpaceCopy.system[i][j] == -1: + cellSpaceCopy.system[i][j] = 0 # Vacíos => Negro + if cellSpaceCopy.system[i][j] == 3: + cellSpaceCopy.system[i][j] = 256 # Muertos => Gris + increasedSystem = CellManagement.CellManagement(cellSpaceCopy).InsideCopy(1,1) + increasedSystem.system[0][0] = 0 + increasedSystem.system[cellSpace.nRows + 1][cellSpace.nColumns + 1] = 256 + return increasedSystem.system + + def evolutionsPlot(self,specificIteration): + """Gráfica una evolución especifica del conjunto de evoluciones generadas tras aplicar el modelo""" + plt.imshow(self.__color(self.evolutionsOfCellSpace[specificIteration]), cmap="nipy_spectral", interpolation='nearest') + + def __orderDefinition(numberOfElements, numberOfCategories): + categories = [(i % numberOfElements) * numberOfCategories for i in range(numberOfElements)] + groups = [[j,i] for i in range(numberOfElements) for j in categories] + return groups + + def showEvolutions(self, categorizer = 5): + numberOfEvolutions = len(self.evolutionsOfCellSpace) + order = self.__orderDefinition(numberOfEvolutions, categorizer) + for i in range(numberOfEvolutions**2): + plt.subplot(numberOfEvolutions,numberOfEvolutions,i+1) + if i in range(numberOfEvolutions): + plt.title(f"t = {i*5}") + self.evolutionsPlot(order[i][0]) + plt.show() + + def heatmap(self, state): + """Mapa de calor para la población infectada (SIR_Model[6])""" + stateHeatMap = [] + n,m = self.evolutionsOfCellSpace[0].shape + for iteration in range(len(self.evolutionsOfCellSpace)): + stateMatrix = np.zeros((n,m)) + for row in range(n): + for column in range(m): + if self.evolutionsOfCellSpace[iteration][row][column] == state: + stateMatrix[row][column] = 1 + stateHeatMap.append(stateMatrix) + average = 1/len(stateHeatMap)*np.sum(stateHeatMap,axis=0) + sns.heatmap(average, center=0, cmap='viridis', fmt='.3f') \ No newline at end of file diff --git a/CAsimulation/camodels.py b/CAsimulation/camodels.py deleted file mode 100644 index 0b82df1..0000000 --- a/CAsimulation/camodels.py +++ /dev/null @@ -1,1387 +0,0 @@ -# -*- coding: utf-8 -*- -"""Funciones del modelo.ipynb - -Automatically generated by Colaboratory. - -Original file is located at - https://colab.research.google.com/drive/1Sj4uPgxzRQTWw142tmkxpXJs98g0drbZ -""" - -import numpy as np -import matplotlib.pyplot as plt -import cv2 -import string -import pandas as pd -import glob -import random -from skimage.color import rgb2gray -import seaborn as sns -import scipy.integrate as spi -import math - -def spline3(A): #spline cubico para la lista de coordenadas A - n = len(A) - a = []; h = []; x = []; y = []*(n-1); C = [0]*n - alpha = [] - l = [1] - B = [0] - g = [0]; gn = 0 - spline = [] - for i in range(n): - a.append(A[i][1]) - for i in range(n-1): - xh = A[i+1][0]-A[i][0] - h.append(xh) - for i in range(1, n-1): - xa = (3/h[i])*(a[i+1]-a[i])-(3/h[i-1])*(a[i]-a[i-1]) - alpha.append(xa) - for i in range(1, n-1): - xl = 2*(A[i+1][0]-A[i-1][0])-h[i-1]*B[i-1] - l.append(xl) - xb = h[i]/l[i] - B.append(xb) - xg = (alpha[i-1]-h[i-1]*g[i-1])/l[i] - g.append(xg) - l.append(1) - g.append(0) - for i in range(n-1): - j = (n-1)-(i+1) - xC = g[j]-B[j]*C[j+1] - C[j] = xC - xy = ((a[j+1]-a[j])/h[j])-(h[j]/3)*(C[j+1]+2*C[j]) - y.append(xy) - xx = (C[j+1]-C[j])/(3*h[j]) - x.append(xx) - for i in range(n-1): - j=(n-1)-(i+1) - S3 = [a[i],y[j],C[i],x[j]] - spline.append(S3) - SC=np.array(spline) - return SC - -def one_function_graph(A,texto): #Grafica del spline cubico para la lista de coordenadas A - cond=[] - funcion=[] - SP=spline3(A) - cond=[] - funcion=[] - x=[] - y=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SP[i,0]+SP[i,1]*(xa-A[i,0])+SP[i,2]*(xa-A[i,0])**2+SP[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - - texto=str(texto) - plt.plot(x, y, c='blue') - plt.title(texto) - plt.xlabel('Tiempo') - plt.show() - -def one_state_graph(A,texto): #Grafica del spline cubico para la lista de coordenadas A - cond=[] - funcion=[] - SP=spline3(A) - cond=[] - funcion=[] - x=[] - y=[]; l=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SP[i,0]+SP[i,1]*(xa-A[i,0])+SP[i,2]*(xa-A[i,0])**2+SP[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - - texto=str(texto) - plt.plot(x, x**0, 'k--') - plt.plot(x, y, c='blue') - plt.title(texto) - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def two_states_graph(A,B,texto1, texto2, titulo): #Grafica del spline cubico para las listas de coordenadas A y B - cond=[] - funcion=[] - SA=spline3(A) - SB=spline3(B) - cond=[] - funcion=[] - x=[] - y=[] - z=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - - texto1=str(texto1); texto2=str(texto2); titulo=str(titulo) - plt.plot(x, x**0, 'k--') - plt.plot(x, y, c='y', label=texto1) - plt.plot(x, z, c='r', label=texto2) - plt.legend(loc=0) - plt.title(titulo) - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def three_states_graph(A,B,C,texto1,texto2,texto3,titulo): #Grafica del spline cubico para las listas de coordenadas A,B y C - cond=[] - funcion=[] - SA=spline3(A) - SB=spline3(B) - SC=spline3(C) - cond=[] - funcion=[] - x=[] - y=[] - z=[] - w=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - - texto1=str(texto1); texto2=str(texto2); texto3=str(texto3); titulo=str(titulo) - plt.plot(x, y, c='y', label=texto1) - plt.plot(x, z, c='g', label=texto2) - plt.plot(x, w, c='r', label=texto3) - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title(titulo) - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def distribution_graph(A,B,C,D,E,F,G,H,I,J): #Grafica de variación presente en la condición inicial - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C); SD=spline3(D); SE=spline3(E) - SF=spline3(F); SG=spline3(G); SH=spline3(H); SI=spline3(I); SJ=spline3(J) - x=[]; y=[]; z=[]; w=[]; t=[]; a=[] - b=[]; c=[]; d=[]; e=[]; f=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - ta=SD[i,0]+SD[i,1]*(xa-D[i,0])+SD[i,2]*(xa-D[i,0])**2+SD[i,3]*(xa-D[i,0])**3 - t=np.concatenate((t,ta)) - aa=SE[i,0]+SE[i,1]*(xa-E[i,0])+SE[i,2]*(xa-E[i,0])**2+SE[i,3]*(xa-E[i,0])**3 - a=np.concatenate((a,aa)) - ba=SF[i,0]+SF[i,1]*(xa-F[i,0])+SF[i,2]*(xa-F[i,0])**2+SF[i,3]*(xa-F[i,0])**3 - b=np.concatenate((b,ba)) - ca=SG[i,0]+SG[i,1]*(xa-G[i,0])+SG[i,2]*(xa-G[i,0])**2+SG[i,3]*(xa-G[i,0])**3 - c=np.concatenate((c,ca)) - da=SH[i,0]+SH[i,1]*(xa-H[i,0])+SH[i,2]*(xa-H[i,0])**2+SH[i,3]*(xa-H[i,0])**3 - d=np.concatenate((d,da)) - ea=SI[i,0]+SI[i,1]*(xa-I[i,0])+SI[i,2]*(xa-I[i,0])**2+SI[i,3]*(xa-I[i,0])**3 - e=np.concatenate((e,ea)) - fa=SJ[i,0]+SJ[i,1]*(xa-J[i,0])+SJ[i,2]*(xa-J[i,0])**2+SJ[i,3]*(xa-J[i,0])**3 - f=np.concatenate((f,fa)) - - plt.plot(x, y, c='g', label="noroeste") - plt.plot(x, z, c='gold', label="norte") - plt.plot(x, w, c='peru', label="noreste") - plt.plot(x, t, c='c', label="oeste") - plt.plot(x, a, c='magenta', label="central") - plt.plot(x, b, c='darkorange', label="este") - plt.plot(x, c, c='royalblue', label="suroeste") - plt.plot(x, d, c='mediumorchid', label="sur") - plt.plot(x, e, c='r', label="sureste") - plt.plot(x, f, c='lime', label="aleatorio") - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title('Condición inicial') - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def scales_graph(A,B,C,D,E): #Gráfica de cambios de escalas - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C); SD=spline3(D); SE=spline3(E) - x=[]; y=[]; z=[]; w=[]; t=[]; l=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - ta=SD[i,0]+SD[i,1]*(xa-D[i,0])+SD[i,2]*(xa-D[i,0])**2+SD[i,3]*(xa-D[i,0])**3 - t=np.concatenate((t,ta)) - la=SE[i,0]+SE[i,1]*(xa-E[i,0])+SE[i,2]*(xa-E[i,0])**2+SE[i,3]*(xa-E[i,0])**3 - l=np.concatenate((l,la)) - - plt.plot(x, y, c='purple', label="escala 1") - plt.plot(x, z, c='steelblue', label="escala 2") - plt.plot(x, w, c='darkorange', label="escala 3") - plt.plot(x, t, c='firebrick', label="escala 4") - plt.plot(x, l, c='seagreen', label="escala 5") - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title('Cambio de escalas') - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def systems_graph(A,B,C,D,E,F,G): #Gráfica de cambios de escalas - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C); SD=spline3(D); SE=spline3(E); SF=spline3(F); SG=spline3(G) - x=[]; y=[]; z=[]; w=[]; t=[]; l=[]; o=[]; p=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - ta=SD[i,0]+SD[i,1]*(xa-D[i,0])+SD[i,2]*(xa-D[i,0])**2+SD[i,3]*(xa-D[i,0])**3 - t=np.concatenate((t,ta)) - la=SE[i,0]+SE[i,1]*(xa-E[i,0])+SE[i,2]*(xa-E[i,0])**2+SE[i,3]*(xa-E[i,0])**3 - l=np.concatenate((l,la)) - oa=SF[i,0]+SF[i,1]*(xa-F[i,0])+SF[i,2]*(xa-F[i,0])**2+SF[i,3]*(xa-F[i,0])**3 - o=np.concatenate((o,oa)) - pa=SG[i,0]+SG[i,1]*(xa-G[i,0])+SG[i,2]*(xa-G[i,0])**2+SG[i,3]*(xa-G[i,0])**3 - p=np.concatenate((p,pa)) - - plt.plot(x, y, c='purple', label="Linea") - plt.plot(x, z, c='steelblue', label="Cuadrado") - plt.plot(x, w, c='darkorange', label="Rectángulo") - plt.plot(x, t, c='firebrick', label="Rombo") - plt.plot(x, l, c='seagreen', label="Triángulo") - plt.plot(x, l, c='cyan', label="Caso #1") - plt.plot(x, l, c='orangered', label="Caso #2") - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title('Comparación entre sistemas') - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def scales_difference_graph(A,B,C,D): #Gráfica de cambios de escalas - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C); SD=spline3(D) - x=[]; y=[]; z=[]; w=[]; t=[]; l=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - ta=SD[i,0]+SD[i,1]*(xa-D[i,0])+SD[i,2]*(xa-D[i,0])**2+SD[i,3]*(xa-D[i,0])**3 - t=np.concatenate((t,ta)) - - plt.plot(x, y, c='purple', label="|E5-E1|") - plt.plot(x, z, c='steelblue', label="|E5-E2|") - plt.plot(x, w, c='darkorange', label="|E5-E3|") - plt.plot(x, t, c='firebrick', label="|E5-E4|") - plt.legend(loc=0) - plt.title('Diferencias') - plt.xlabel('Tiempo') - plt.show() - -def array_generator(K,i,j): #Se genera la veindad para la célula en la posición i,j en el arreglo regular (Ar) - A = np.zeros((3,3)) #La vecindad debe tener 8 agentes y una célula central - A[0][0] = K[i-1][j-1] #Vecino en la possición i-1,j-1 - A[0][1] = K[i-1][j] #Vecino en la possición i-1,j - A[0][2] = K[i-1][j+1] #Vecino en la possición i-1,j+1 - A[1][0] = K[i][j-1] #Vecino en la possición i,j-1 - A[1][1] = K[i][j] #Célula central - A[1][2] = K[i][j+1] #Vecino en la possición i,j+1 - A[2][0] = K[i+1][j-1] #Vecino en la possición i+1,j-1 - A[2][1] = K[i+1][j] #Vecino en la possición i+1,j - A[2][2] = K[i+1][j+1] #Vecino en la possición i+1,j+1 - return A #Vecindad del agente en la posición i,j - -def vector_S(A): #Definición del conjunto de posiciones del estado S en el sistema A - n,m=A.shape #Consideramos la dimensión del sistema A - S=[] #S guardará las posiciones de los individuos susceptibles - for i in range(n): #para i en n filas - for j in range(m): #para j en m columnas - if A[i][j]==0: #Verifique si el individuo en la posición i,j es susceptible - S.append([i,j])#Si es verdadero añanda la posición del individuo a la lista S - return S #Retorne la lista de posiciones de los individuos susceptibles - -def vector_I(A): #Definición del conjunto de posiciones del estado I en el sistema A - n,m=A.shape #Consideramos la dimensión del sistema A - I=[] #I guardará las posiciones de los individuos infectados - for i in range(n): #para i en n filas - for j in range(m): #para j en m columnas - if A[i][j]==1: #Verifique si el individuo en la posición i,j esta infectado - I.append([i,j])#Si es verdadero añanda la posición del individuo a la lista I - return I #Retorne la lista de posiciones de los individuos infectados - -def sumaS(V): #Cantidad de individuos susceptibles en la vecindad V - sumaS=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(3): #Tres filas en la vecindad de Moore - for j in range(3): #Tres columnas en la vecindad de Moore - if V[i][j]==0: #Para cada individuo se verifica si está identificado con el estado S - sumaS=sumaS+1 #Si es verdadero, aumente en uno el contador de susceptibles - if V[1][1]==0: #La célula central no se considera en el conteo - sumaS=sumaS-1 #Si la célula central es susceptible se elimina de la suma - return sumaS #cantidad de suscptibles en la vecindad V - -def sumaI(V): #Cantidad de individuos infectados en la vecindad V - sumaI=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(3): #Tres filas en la vecindad de Moore - for j in range(3): #Tres columnas en la vecindad de Moore - if V[i][j]==1: #Para cada individuo se verifica si está identificado con el estado I - sumaI=sumaI+1 #Si es verdadero, aumente en uno el contador de infectados - if V[1][1]==1: #La célula central no se considera en el conteo - sumaI=sumaI-1 #Si la célula central esta infectada se elimina de la suma - return sumaI #cantidad de infectados en la vecindad V - -def sumaR(V): #Cantidad de individuos recuperados en la vecindad V - sumaR=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(3): #Tres filas en la vecindad de Moore - for j in range(3): #Tres columnas en la vecindad de Moore - if V[i][j]==2: #Para cada individuo se verifica si está identificado con el estado R - sumaR=sumaR+1 #Si es verdadero, aumente en uno el contador de recuperados - if V[1][1]==2: #La célula central no se considera en el conteo - sumaR=sumaR-1 #Si la célula central esta recuperada se elimina de la suma - return sumaR #cantidad de recuperados en la vecindad V - -def sumaV(V): #Cantidad de espacios vacios en la vecindad V - sumaV=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(3): #Tres filas en la vecindad de Moore - for j in range(3): #Tres columnas en la vecindad de Moore - if V[i][j]==-1: #Para cada espacio se verifica si está identificado con el estado V - sumaV=sumaV+1 #Si es verdadero, aumente en uno el contador de recuperados - if V[1][1]==-1: #La célula central no se considera en el conteo - sumaV=sumaV-1 #Si la célula central no está se elimina de la suma - return sumaV #cantidad de espacios vacios en la vecindad V - -def count_S(A): #Cantidad de individuos que poseen el estado S en el arreglo A - n,m=A.shape #Dim(A)=nm - suma=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(n): #n filas del arreglo A - for j in range(m): #m columnas del arreglo A - if A[i][j]==0: #Para cada espacio se verifica si está identificado con el estado S - suma=suma+1 #Si es verdadero, aumente en uno el contador de susceptibles - return int(suma) #cantidad de individuos susceptibles en el arreglo A - -def count_I(A): #Cantidad de individuos que poseen el estado I en el arreglo A - n,m=A.shape #Dim(A)=nm - suma=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(n): #n filas del arreglo A - for j in range(m): #m columnas del arreglo A - if A[i][j]==1: #Para cada espacio se verifica si está identificado con el estado I - suma=suma+1 #Si es verdadero, aumente en uno el contador de infectados - return int(suma) #cantidad de individuos infectados en el arreglo A - -def count_R(A): #Cantidad de individuos que poseen el estado R en el arreglo A - n,m=A.shape #Dim(A)=nm - suma=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(n): #n filas del arreglo A - for j in range(m): #m columnas del arreglo A - if A[i][j]==2: #Para cada espacio se verifica si está identificado con el estado R - suma=suma+1 #Si es verdadero, aumente en uno el contador de recuperados - return int(suma) #cantidad de individuos recuperados en el arreglo A - -def count_D(A): #Cantidad de individuos que poseen el estado D en el arreglo A - n,m=A.shape #Dim(A)=nm - suma=0 #Antes de realizar el conteo se toma un contador igual a cero - for i in range(n): #n filas del arreglo A - for j in range(m): #m columnas del arreglo A - if A[i][j]==3: #Para cada espacio se verifica si está identificado con el estado D - suma=suma+1 #Si es verdadero, aumente en uno el contador de recuperados - return int(suma) #cantidad de individuos muertos en el arreglo A - -def num_individuals(A): #Función contadora de individuos que interactuan en el sistema A - n = count_S(A) #Cantidad de individuos que poseen el estado S - m = count_I(A) #Cantidad de individuos que poseen el estado I - o = count_R(A) #Cantidad de individuos que poseen el estado R - d = count_D(A) #Cantidad de individuos que poseen el estado D - ci = n + m + o + d #Total de individuos que interactuan en el sistema - return ci #Retorna ci - -def count_s(A): #Función de población normalizada para el estado S - return count_S(A)/num_individuals(A) #Promedio de susceptibles con respecto a células que interactuan - -def count_i(A): #Función de población normalizada para el estado I - return count_I(A)/num_individuals(A) #Promedio de infectados con respecto a células que interactuan - -def count_r(A): #Función de población normalizada para el estado R - return count_R(A)/num_individuals(A) #Promedio de recuperados con respecto a células que interactuan - -def count_d(A): #Función de población normalizada para el estado D - return count_D(A)/num_individuals(A) #Promedio de muertos con respecto a células que interactuan - -def base_rule(alpha,beta,V): #Regla base de interacción local - I = sumaI(V); S = sumaS(V); Va = sumaV(V) #Se realiza un conteo de infectados, susceptibles y espacios vacios en la vecindad V - B = np.zeros((3,3)) #Para evitar problemas de apuntadores se realiza la transformación sobre una copia de V - r = random.randint(0,100) #El valor aleatorio rho - for i in range(3): #Copia de las tres filas de la vecindad V - for j in range(3): #Copia de las tres columnas de la vecindad V - B[i][j] = V[i][j] #Copia de los indiviuos en la vecindad V - if V[1][1] != -1: #Se consideran unicamente los espacios no vacios ya que la tranformación de un espacio vacio es vacio - if I > 0: #Si no hay infectados en la vecindad, no hay propagacióón de la enfermedad en la vecindad - if I <= S and r >= (I/(8 - Va))*(beta/alpha) * 100: #Condición para transición al estado S - B[1][1] = 0 - else: #Condición para transición al estado I - B[1][1] = 1 - else: - B[1][1] = V[1][1] - else: #Si la célula es vacia se mantiene vacia - B[1][1] = -1 - return B[1][1] #Al ser una regla totalíística, se retorna el valor central - -def evolution_sis(alpha,beta,U): #Regla base de evolucion en U de parametros alpha y beta - n,m=U.shape #dim(U)=nm - B=np.zeros((n+2,m+2)) #B será un arreglo nulo sobre el cual se sobreescribiran los datos de U - C=np.zeros((n,m)) #C será el arreglo que guardará los datos luego de aplicar la regla base de evolución - I=count_I(U) #Se aplicará la regla siempre y cuando existan individuos infectados - for i in range(n): - for j in range(m): - B[i+1][j+1]=U[i][j] #Se sobreescriben los datos de U sobre B - for i in range(n): - for j in range(m): - if I > 0: #Si hay individuos infectados en el sistema - C[i][j]=base_rule(alpha,beta,array_generator(B,i+1,j+1)) #Aplique la regla base de evolución local a U y guarde los valores en C - else: #Si no hay individuos infectados - C[i][j] = U[i][j] #La regla base de evolución actua como la función identica sobre el sistema - return C #Retorne la evolución del sistema - -def evolution_SIS(alpha,beta,tf,A): #Definición del conjunto de evoluciones - L = [A] #El primer elemento del conjunto es la configuracióón inicial - i = 0 #Se define el contador de composiciones - while i <= tf: #Se realizarán composiciones hasta el tiempo tf - i = i + 1 #El contador crece en una unidad - L.append(evolution_sis(alpha,beta,L[i-1])) #Se añade la composición i del arreglo en la posición i-1 - return L - -def SIS_model(alpha,beta,tf,A): #Modelo SIS - S = []; I = [] #S e I guardan la cantidad de individuos pertenecientes a los estados S e I por cada iteración - CI = np.zeros((tf,2)); CS = np.zeros((tf,2)) #CS y CI nos permitiran graficar los datos de S e I - B = evolution_SIS(alpha,beta,tf,A) #Calculamos la evolución inicial del sistema A hasta el tiempo tf - for j in range(tf): #Para cada iteración defina - M = B[j] #M será la evolución en el instante t=i - S.append(count_s(M)) #Añadimos el promedio de susceptibles en M a S - I.append(count_i(M)) #Añadimos el promedio de infectados en M a I - for i in range(tf): #Para cada instante i hasta tf defina - CS[i][0] = i; CS[i][1] = S[i] #CS[i]=(i,S[i]) -> (tiempo i, cantidad de susceptibles en el tiempo i) - CI[i][0] = i; CI[i][1] = I[i] #CI[i]=(i,I[i]) -> (tiempo i, cantidad de infectados en el tiempo i) - return [CS,CI,S,I,B] #Lista con las parejas ordenadas CS, CI, cantidad de individuos susceptibles, infectados y las evoluciones del sistema - -def num_I(a,b): #Porcentaje de infectados en el espacio (a de cada b están infectados) - A=np.zeros((1,b)) #Generamos una b-tupla, la vemos como un arreglo para facilitar la manipulación - L=[] #L sera la lista cuyos elelementos son a de b infectados - for j in range(a): #a individuos recibirán la cualidad de infectados - i=random.randint(1,b-1) #La posición de los individuos infectados será aleatoria en el arreglo A - A[0][i]=1 #El individuo en la posición aleatoria 0,i adquiere el estado de infección - for m in range(1,b): #Se añadirán los elementos del arreglo A en la lista L - L.append(int(A[0][m])) - return L #Retorne la lista porcentaje de indiviuos infectados - -def initial_condition(I0,A): #Condición inicial aplicada al sistema A - L=vector_S(A) #Defina L como el vector de posiciones del estado S en el sistema A - n,m=A.shape #dim(A)=nm - k=math.ceil(len(L)*I0) #El I0% de los individuos susceptibles adquieren la enfermedad, se toma la función techo para redondear a un entero esta cantidad - R=num_I(k,len(L)+1) #R es la lista de posiciones de los idividuos que se infectaron y de los que se mantuvieron sanos al aplicar la condicion inicial - C=np.zeros((n,m)) #Se define C para evitar problemas de apuntadores - for i in range(n): #Para i en las n filas de A - for j in range(m): #Para j en las m columnas de A - C[i][j]=A[i][j] #C será una copia de A, esto permite que la información de A no se modifique - for i in range(len(R)): #Para i en un rango de 0 a la longitud de la lista R - C[L[i][0]][L[i][1]]=R[i] #Los vectores en las posiciones descritas en la lista R adquieren el estado de infección - return C #Se retorna el arreglo con la condición inicial - -def graph_sis_S(alpha,beta,tf,A): #Grafica que describe la evolución de la población susceptible en el modelo SIS - SIS=SIS_model(alpha,beta,tf,A) #Se aplica el modelo al sistema A, con tasas de recuperación e infección hasta un tiempo tf - one_state_graph(SIS[0],"Susceptibles") #Graficamos los datos mediante un spline cubico de la lista S generada por la función sis - -def graph_sis_I(alpha,beta,tf,A): #Grafica que describe la evolución de la población infectados en el modelo SIS - SIS=SIS_model(alpha,beta,tf,A) #Se aplica el modelo al sistema A, con tasas de recuperación e infección hasta un tiempo tf - one_state_graph(SIS[1], "Infectados") #Graficamos los datos mediante un spline cubico de la lista I generada por la función sis - -def graph_sis(alpha,beta,tf,A): #Grafica del modelo SIS - SIS=SIS_model(alpha,beta,tf,A) #Se aplica el modelo al sistema A, con tasas de recuperación e infección hasta un tiempo tf - two_states_graph(SIS[0],SIS[1],"Susceptibles", "Infectados", "Modelo SIS") #Graficamos los datos mediante un spline cubico de las listas S e I generadas por la función sis - -def interaction_SI(alpha,beta,A): #Regla de interacción del estado S - n,m=A.shape #dim(A)=nm - B=np.zeros((n+2,m+2)) #Se aplica la condición para las células en la frontera - C=np.zeros((n,m)) #Se define la matriz C para evitar problemas de apuntadores - for i in range(n): - for j in range(m): - B[i+1][j+1]=A[i][j] - for i in range(n): - for j in range(m): - if A[i][j]==0: #Si el estado de la célula es susceptible aplique la regla base de interaccion local - C[i][j]=base_rule(alpha,beta,array_generator(B,i+1,j+1)) - elif A[i][j]==2: #Para el estado R funciona como la identidad - C[i][j]=2 - elif A[i][j]==-1: #La regla no se aplica en espacios vacios - C[i][j]=-1 - elif A[i,j]==3: #opcional - C[i,j]=3 - else: #La regla actua como la identica en el estado I - C[i][j]=1 - return C #Retorna la evolución del sistema A bajo la regla de S - -def num_R(a,b): #Porcentaje de recuperados en el espacio (a de cada b están curados) - A=np.ones((1,b)) #Generamos una b-tupla, la vemos como un arreglo para facilitar la manipulación - L=[] #L sera la lista cuyos elelementos son a de b recuperados - for j in range(a): #a individuos recibirán la cualidad de recuperados - i=random.randint(1,b-1) #La posición de los individuos recuperados será aleatoria en el arreglo A - A[0][i]=2 #El individuo en la posición aleatoria 0,i adquiere el estado de recuperado - for m in range(1,b): #Se añadirán los elementos del arreglo A en la lista L - L.append(int(A[0][m])) - return L #Retorne la lista porcentaje de indiviuos recuperados - -def interaction_IR(alpha,A): #Regla de interacción del estado I - L=vector_I(A) #Generamos el conjunto de posiciones de infectados del sistema A - n,m=A.shape #dim(A)=nm - k=math.ceil(len(L)*alpha) #alpha% de los infectados se curará - R=num_R(k,len(L)+1) #Generamos la lista en la cual de manera explicita tenemos alpha recuperados de una poblacióón infectada - C=np.zeros((n,m)) #Se creará una copia de A para evitar problemas de apuntadores - for i in range(n): - for j in range(m): - C[i][j]=A[i][j] - for i in range(len(R)): #Los individuos que se recuperarón se envian a la posición que tenian en el estado I - C[L[i][0]][L[i][1]]=R[i] - return C #Retorna la evolución del sistema A bajo la regla de I - -def evolution_sir(alpha,beta,A): #Regla de comportamiento SIR - B=interaction_IR(alpha,A) #Primero se evalua cuales individuos se curarán el el siguiente tic - C=interaction_SI(alpha,beta,B) #Los que no se curaróón siguen infectando la población susceptible - return C #Sistema al aplicar la regla de comportamiento SIR - -def evolution_SIR(alpha,beta,tf,A): #Lista de evoluciones al aplicar SIR hasta un tiempo tf - L=[A] #El primer elemento de la lista es la configuración inicial - i=0 #Aplique SIR hasta el tiempo tf - while i<=tf: - i=i+1 - L.append(evolution_sir(alpha,beta,L[i-1])) #Se aplica SIR al arreglo en la posición anterior del contador - return L #Lista de evoluciones en un sistema bajo la aplicación SIR - -def SIR_model(alpha,beta,tf,A): #Modelo SIR - S=[]; I=[]; R=[] #Listas que guardarán la cantidad de individuos por estado normalizada - CI=np.zeros((tf,2)) #Arreglo que permitirá graficar la población infectada - CS=np.zeros((tf,2)) #Arreglo que permitirá graficar la población susceptible - CR=np.zeros((tf,2)) #Arreglo que permitirá graficar la población recuperada - B=evolution_SIR(alpha,beta,tf,A) #Lista de evoluciones del sistema A hasta el tiemp tf - for j in range(tf): #Para cada elemento en la lista - M=B[j] #M es la evolución en el tiempo j - S.append(count_s(M)) #Población susceptible normalizada - I.append(count_i(M)) #Población infectada normalizada - R.append(count_r(M)) #Población recuperada normalizada - for i in range(tf): #Se generan las listas de coordenadas que permitirán graficar la evolución - CS[i][0]=i; CS[i][1]=S[i] #Coordenadas de cantidad de susceptibles - CI[i][0]=i; CI[i][1]=I[i] #Coordenadas de cantidad de infectados - CR[i][0]=i; CR[i][1]=R[i] #Coordenadas de cantidad de recuperados - return [CS,CR,CI,S,I,R,B] #Lista con las coordenadas de los tres estados, cantidades normalizadas y las evoluciones - -def graph_sir_S(alpha,beta,tf,A): #Gráfica de la población susceptible - SIR=SIR_model(alpha,beta,tf,A) #Se aplica el modelo bajo las condiciones de la función - one_state_graph(SIR[0], "Susceptibles") #Gráfica de la población susceptible - -def graph_sir_I(alpha,beta,tf,A): #Gráfica de la población infectada - SIR=SIR_model(alpha,beta,tf,A) #Se aplica el modelo bajo las condiciones de la función - one_state_graph(SIR[2], "Infectados") #Gráfica de la población infectada - -def graph_sir_R(alpha,beta,tf,A): #Gráfica de la población recuperada - SIR=SIR_model(alpha,beta,tf,A) #Se aplica el modelo bajo las condiciones de la función - one_state_graph(SIR[1], "Recuperados") #Gráfica de la población recuperada - -def graph_sir(alpha,beta,tf,A): #Gráfica del modelo SIR - SIR=SIR_model(alpha,beta,tf,A) #Se aplica el modelo bajo las condiciones de la función - three_states_graph(SIR[0],SIR[1],SIR[2],"Susceptibles","recuperados","infectados","Modelo SIR") - -def color(A): #Transformación que permite visualizar el sistema en escala nipy_spectral - n,m=A.shape #dim(A)=nm - C=np.zeros((n,m)) #Se realizará una copia de A para evitar problemas de apuntadores - for i in range(n): - for j in range(m): - C[i][j]=A[i][j] - for i in range(n): - for j in range(m): - if C[i][j]==0: #A los individuos susceptibles se les asigna el color amarillo - C[i][j]=190 - if C[i][j]==1: #A los individuos infectados se les asigna el color rojo - C[i][j]=240 - if C[i][j]==2: #A los individuos recuperados se les asigna el color verde - C[i][j]=115 - if C[i][j]==-1: #A los espacios vacios se les asigna el color negro - C[i][j]=0 - if C[i][j]==3: - C[i][j]=256 - D=np.zeros((n+2,m+2)) - for i in range(n): - for j in range(m): - D[i+1][j+1]=C[i][j] - D[0][0]=0; D[n+1][m+1]=256 #Polos de color para poder ajustar la escala de manera adecuada - return D - -def heatmap_sis(alpha,beta,tf,A): #Mapa de calor de la enfermedad hasta el tiempo tf - a,b=A.shape - B=SIS_model(alpha,beta,tf,A)[4] - C=[] - for i in range(len(B)): - D=np.zeros((a,b)); F=np.zeros((a,b)) - for j in range(a): - for k in range(b): - if B[i][j][k]==1: - D[j][k]=1 - C.append(D) - suma1=1/tf*np.sum(C,axis=0) - sns.heatmap(suma1, center=0, cmap='viridis', fmt='.3f') - -def heatmap_sir_I(alpha,beta,tf,A): - a,b=A.shape - B=SIR_model(alpha,beta,tf,A)[6] - C=[] - for i in range(len(B)): - D=np.zeros((a,b)); F=np.zeros((a,b)) - for j in range(a): - for k in range(b): - if B[i][j][k]==1: - D[j][k]=1 - C.append(D) - suma1=1/tf*np.sum(C,axis=0) - sns.heatmap(suma1, center=0, cmap='viridis', fmt='.3f') - -def heatmap_sir_R(alpha,beta,tf,A): - a,b=A.shape - B=SIR_model(alpha,beta,tf,A)[6] - C=[] - for i in range(len(B)): - D=np.zeros((a,b)); F=np.zeros((a,b)) - for j in range(a): - for k in range(b): - if B[i][j][k]==2: - D[j][k]=1 - C.append(D) - suma1=1/tf*np.sum(C,axis=0) - sns.heatmap(suma1, center=0, cmap='viridis', fmt='.3f') - -def northwest(n,m,I0): #Bloque noroeste - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*0.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque noroeste - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(0.995-I0,A) - for i in range(a): - for j in range(b): - D[i][j]=D1[i][j] #Se reemplazan los valores del bloque noroeste por el bloque de infectados - return D - -def north(n,m,I0): #Bloque norte - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque norte - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(0.995-I0,A) - for i in range(a): - for j in range(b,2*b): - D[i][j]=D1[i][j-b] #Se reemplazan los valores del bloque norte por el bloque de infectados - return D - -def northeast(n,m,I0): #Bloque noreste - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque noreste - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(a): - for j in range(2*b,3*b): - D[i][j]=D1[i][j-2*b] #Se reemplazan los valores del bloque noreste por el bloque de infectados - return D - -def west(n,m,I0): #Bloque oeste - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque oeste - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(a,a*2): - for j in range(b): - D[i][j]=D1[i-a][j] #Se reemplazan los valores del bloque oeste por el bloque de infectados - return D - -def center(n,m,I0): #Bloque central - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque central - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(a,a*2): - for j in range(b,2*b): - D[i][j]=D1[i-a][j-b] #Se reemplazan los valores del bloque central por el bloque de infectados - return D - -def east(n,m,I0): #Bloque este - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque este - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(a,a*2): - for j in range(2*b,3*b): - D[i][j]=D1[i-a][j-2*b] #Se reemplazan los valores del bloque este por el bloque de infectados - return D - -def southwest(n,m,I0): #Bloque suroeste - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque suroeste - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(2*a,3*a): - for j in range(b): - D[i][j]=D1[i-2*a][j] #Se reemplazan los valores del bloque suroeste por el bloque de infectados - return D - -def south(n,m,I0): #Bloque sur - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque sur - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(2*a,3*a): - for j in range(b,2*b): - D[i][j]=D1[i-2*a][j-b] #Se reemplazan los valores del bloque sur por el bloque de infectados - return D - -def southeast(n,m,I0): #Bloque sureste - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0*.005,D) #Un porcentaje muy pequeño de los individuos infectados no se encontrará en el bloque sureste - a=int(n/3); b=int(m/3) #Se divide la zona rectángular en 9 bloques - A=np.zeros((a,b)) #Bloque sobre el cual estarán ubicados la mayoria de los enfermos - D1=initial_condition(.995-I0,A) - for i in range(2*a,3*a): - for j in range(2*b,3*b): - D[i][j]=D1[i-2*a][j-2*b] #Se reemplazan los valores del bloque sureste por el bloque de infectados - return D - -def aleatorio(n,m,I0): #Distribución aleatoria en el espacio - D=np.zeros((n,m)) #Creamos el arreglo rectángular sobre el cual se realizará el analisis - D=initial_condition(I0,D) #Se aplica la condición inicial - return D - -def medium_curves_sis(alpha,beta,tf,csim,I0,A): #Promedio de csim simulaciones para el modelo SIS - S=[]; I=[] #S e I guardarán el promedio de las cantidades normalizadas por estados respectivos - cs=[]; ci=[] #cs y ci serán las listas que permiten promediar la cantidad de individuos para csim simulaciones - CI=np.zeros((tf,2)); CS=np.zeros((tf,2)) #Hay tf coordenadas - for i in range(csim): #Para csim simulaciones - promsis=SIS_model(alpha,beta,tf,initial_condition(I0,A)) #Aplique un condición inicial de distribución uniforme de infectados - cs.append(promsis[2]); ci.append(promsis[3]) #Las listas S e I generadas por cada iteración son enviadas a las listas cs y ci - for i in range(tf): #Se promedian las cantidades - k=0; l=0 - for j in range(csim): - k=k+cs[j][i]/csim; l=l+ci[j][i]/csim - S.append(k); I.append(l) #Las cantidades promedio son enviadas a las listas S e I - for i in range(tf): #Se crean las listas de coordenadas - CS[i][0]=i; CS[i][1]=S[i] - CI[i][0]=i; CI[i][1]=I[i] - return [CS,CI,S,I] #Datos promedio del modelo SIS para csim simulaciones - -def graph_medium_curves_sis(alpha,beta,tf,csim,I0,A): #Grafica del promedio de simulaciones para el modelo SIS - SIS=medium_curves_sis(alpha,beta,tf,csim,I0,A) - two_states_graph(SIS[0],SIS[1],"susceptibles","infectados","Curva promedio - Modelo SIS") - -def medium_curves_sir(alpha,beta,tf,csim,I0,A): #Promedio de csim simulaciones para el modelo SIR - S=[]; I=[]; R=[] #S,I y R guardarán el promedio de las cantidades normalizadas por estados respectivos - cs=[]; ci=[]; cr=[] #cs,ci y cr serán las listas que permiten promediar la cantidad de individuos para csim simulaciones - CI=np.zeros((tf,2)); CS=np.zeros((tf,2)); CR=np.zeros((tf,2)) #Hay tf coordenadas - for i in range(csim): #Para csim simulaciones - promsir=SIR_model(alpha,beta,tf,initial_condition(I0,A)) #Aplique un condición inicial de distribución uniforme de infectados - cs.append(promsir[3]); ci.append(promsir[4]); cr.append(promsir[5]) #Las listas S, I y R generadas por cada iteración son enviadas a las listas cs, ci y cr - for i in range(tf): #Se promedian las cantidades - k=0; l=0; p=0 - for j in range(csim): - k=k+cs[j][i]; l=l+ci[j][i]; p=p+cr[j][i] - k=k/csim; l=l/csim; p=p/csim - S.append(k); I.append(l); R.append(p) #Las cantidades promedio son enviadas a las listas S, I y R - for i in range(tf): #Se crean las listas de coordenadas - CS[i][0]=i; CS[i][1]=S[i] - CI[i][0]=i; CI[i][1]=I[i] - CR[i][0]=i; CR[i][1]=R[i] - return [CS,CR,CI,S,I,R] #Datos promedio del modelo SIR para csim simulaciones - -def graph_medium_curves_sir(alpha,beta,tf,csim,I0,A): #Grafica del promedio de simulaciones para el modelo SIR - SIR=medium_curves_sir(alpha,beta,tf,csim,I0,A) - three_states_graph(SIR[0],SIR[1],SIR[2],"Susceptibles","Recuperados","Infectados","Curva promedio - Modelo SIR") - -def boundary(L,M): #La lista L posee las coordenadas que definen las posiciones nulas en el sistema M - n,m=M.shape - K=np.ones((n,m)) - for i in range(n): - for j in range(m): - K[i][j]=M[i][j] - for i in range(len(L)): #Para cada coordenada - K[L[i][0],L[i][1]]=0 #Cambie la posición respectiva de la matriz M por cero - return K #Retorne el sistema M - -def domain_definition(n,m,a,b,M): #Ubica una matriz nula de tamaño nxm en la posición a,b de M - L=[] #Lista de coordenadas que se anularán - for i in range(n): - for j in range(m): - L.append((a+i,b+j)) #Ingrese a la lista L las coordenadas de las posiciones de la submatriz nula - return boundary(L,M) #Reemplace las nxm posiciones de M por ceros en las posiciones a,b - -def rombo(a,b,c,d,B): #Rombo de diagonal mayor igual al doble de diagonal menor - L=[B] - i=0 - while c>1: - a=a+2; b=b-4; c=c-1; d=d+2; i=i+1 - L.append(domain_definition(a,b,c,d,L[i-1])) - return L[i] - -def triangulo(n,m,a,b,M): - L=[M] - i=0 - while m>=1: - i=i+1 - L.append(domain_definition(n,m,a,b,L[i-1])) - m=m-2; a=a-1; b=b+1 - return L[i] - -def scale_differences(L1,L2): #Calcula las diferencias entre dos escalas L1 y L2 - L=np.zeros((len(L1),2)) - for i in range(len(L1)): - L[i][0]=i; L[i][1]=abs(L1[i]-L2[i]) - return L - -def three_states_graph_2(A,B,C,titulo): #Gráfica el modelo SIS tomando además la población muerta - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C) - x=[]; y=[]; z=[]; w=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - - plt.plot(x, y, c='y', label="Susceptibles") - plt.plot(x, z, c='r', label="Infectados") - plt.plot(x, w, 'b--', label="Muertos") - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title(str(titulo)) - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def four_states_graph(A,B,C,D,titulo): #Gráfica el modelo SIR tomando además la población muerta - cond=[] - funcion=[] - SA=spline3(A); SB=spline3(B); SC=spline3(C); SD=spline3(D) - x=[]; y=[]; z=[]; w=[]; t=[]; l=[] - for i in range(len(spline3(A))): - xa=np.linspace(A[i,0],A[i+1,0]-0.0001,11) - x=np.concatenate((x,xa)) - ya=SA[i,0]+SA[i,1]*(xa-A[i,0])+SA[i,2]*(xa-A[i,0])**2+SA[i,3]*(xa-A[i,0])**3 - y=np.concatenate((y,ya)) - za=SB[i,0]+SB[i,1]*(xa-B[i,0])+SB[i,2]*(xa-B[i,0])**2+SB[i,3]*(xa-B[i,0])**3 - z=np.concatenate((z,za)) - wa=SC[i,0]+SC[i,1]*(xa-C[i,0])+SC[i,2]*(xa-C[i,0])**2+SC[i,3]*(xa-C[i,0])**3 - w=np.concatenate((w,wa)) - ta=SD[i,0]+SD[i,1]*(xa-D[i,0])+SD[i,2]*(xa-D[i,0])**2+SD[i,3]*(xa-D[i,0])**3 - t=np.concatenate((t,ta)) - - plt.plot(x, y, c='y', label="Susceptibles") - plt.plot(x, z, c='r', label="Infectados") - plt.plot(x, w, c='g', label="Recuperados") - plt.plot(x, t, 'b--', label="Muertos") - plt.plot(x, x**0, 'k--') - plt.legend(loc=0) - plt.title(str(titulo)) - plt.xlabel('Tiempo') - plt.ylim(0,1.05) - plt.show() - -def ages(ranges, A): #Genera la matriz de edades para A basada en los datos de rangos - n,m=A.shape #dimensión de A - Ci=num_individuals(A) - L=[] - for i in range(len(ranges)): #Cantidad de rangos de edad - L.append([0]*math.ceil(ranges[i][2]*Ci)) #Lista nula tomando el porcentaje de cada rango de edad en la cantidad de individuos - for i in range(len(L)): #Cantidad de divisiones del espacio por grupos de edad - for j in range(len(L[i])): #Cantidad de individuos por cada grupo de edad - L[i][j]=random.randint(ranges[i][0],ranges[i][1]) #A cada individuo se le asigna una edad en el rango definido por las dos primeras componentes de rangos - Ed=L[0] - for i in range(1,len(L)): - Ed=Ed+L[i] #Se unen todas las listas con las edades - E=-np.ones((n,m)) #Se crea el arreglo sobre el cual se distribuiran las edades de manera aleatoria - for i in range(n): - for j in range(m): - if A[i,j]!=-1 and A[i,j]!=3: #Si el píxel no es un espacio vacío o un agente muerto se le asigna una edad - p=random.choice(Ed) - E[i,j]=p - elif A[i,j]==3: - E[i,j]=0 - return E - -def age_group(a,b,A): #Genera las posiciones de los individuos que tienen entre a y b años en A - n,m=A.shape - E=[] - for i in range(n): - for j in range(m): - if a array([[0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.], + [0., 0., 0., 0., 0.]]) + + space.initialLocationOfInfected(0.1) + --> array([[0., 0., 0., 0., 0.], + [0., 0., 1., 0., 0.], + [1., 0., 0., 0., 0.], + [0., 1., 0., 0., 0.], + [0., 0., 0., 0., 0.]]) + + Ejemplo 2: + space = CellSpace(3,1,5,5) + space.system + --> array([[ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [-1., -1., -1., -1., -1.], + [-1., -1., -1., -1., -1.]]) + + space.rectangularBoundary(2,2,3,1) + --> array([[ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [ 0., -1., -1., -1., -1.], + [-1., 0., 0., -1., -1.], + [-1., 0., 0., -1., -1.]]) + + Ejemplo 3: + space = CellSpace(3,1,5,5,1,2) + space.system + --> array([[-1., -1., -1., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., 0., -1., -1.], + [-1., -1., -1., -1., -1.]]) + """ + return CellSpaceConfiguration.CellSpaceConfiguration(nRows, nColumns, xnRows, xnColumns, unRows, unColumns) + +def CreateAgeMatrix(ranges, cellSpace): + """ + Crea una matriz con las edades de las células de acuerdon con las probabilidades definidas en ranges. + Parámetros: + ranges(list(list)) Debe contener los rangos de edad y la proporción de individuos del sistema que tendran una edad en el rango. + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Systema de células a las que se les asignará una edad. + Salidas: + numpy.ndarray Arreglo con las edades del sistema de células. + + Ejemplo: + ranges = [[0,10,0.2],[11,100,0.8]] # 20% tienen entre 0 y 10 años, y 80% tienen entre 11 y 100. + space = CellSpace(5,5) + createAgeMatrix(ranges, space) + + --> array([[ 1., 81., 33., 5., 18.], + [90., 19., 18., 36., 50.], + [ 5., 67., 4., 18., 74.], + [45., 36., 4., 36., 4.], + [ 5., 67., 74., 1., 1.]]) + """ + return AgeManagement.AgesMatrix(ranges, cellSpace).agesMatrix + +def GenerateNeighborhoodSystem(cellSpace, neighborhoodType = "random"): + """ + Genera un conjunto de vecindades básico para aplicar los modelos epidemiológicos + Parámetros: + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Sistema de células para el cuál se definirá el sistema de vecindades + neighborhoodType(string) Configuración del sistema - Valores permitidos (Moore - Von Neumann), por defecto se genera un sistema con valores aleatorios + Salidas: + list Lista con los arreglos que describen el conjunto de vecindades y las coordenadas de cada célula + + Ejemplo 1: + GenerateNeighborhoodSystem(CellSpace(3,3)) + --> [[[0, 0],array([[0., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[0, 1],array([[1., 0., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[0, 2],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 0],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 1],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[1, 2],array([[1., 1., 1.], + [1., 1., 0.], + [1., 1., 1.]])], + [[2, 0],array([[1., 1., 1.], + [1., 1., 1.], + [0., 1., 1.]])], + [[2, 1],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 1.]])], + [[2, 2],array([[1., 1., 1.], + [1., 1., 1.], + [1., 1., 0.]])]] + + Ejemplo 2: + GenerateNeighborhoodSystem(CellSpace(3,3),"Moore") + --> [[[0, 0],array([[0., 0., 1.], + [0., 0., 1.], + [1., 1., 1.]])], + [[0, 1],array([[0., 0., 0.], + [0., 0., 0.], + [1., 1., 1.]])], + [[0, 2],array([[1., 0., 0.], + [1., 0., 0.], + [1., 1., 1.]])], + [[1, 0],array([[0., 0., 1.], + [0., 0., 1.], + [0., 0., 1.]])], + [[1, 1],array([[0., 0., 0.], + [0., 0., 0.], + [0., 0., 0.]])], + [[1, 2],array([[1., 0., 0.], + [1., 0., 0.], + [1., 0., 0.]])], + [[2, 0],array([[1., 1., 1.], + [0., 0., 1.], + [0., 0., 1.]])], + [[2, 1],array([[1., 1., 1.], + [0., 0., 0.], + [0., 0., 0.]])], + [[2, 2],array([[1., 1., 1.], + [1., 0., 0.], + [1., 0., 0.]])]] + """ + if neighborhoodType.lower() == 'moore': + return NeighborhoodManager.Moore(cellSpace) + elif neighborhoodType.lower() == 'von neumann': + return NeighborhoodManager.Von_Neumann(cellSpace) + else: + return NeighborhoodManager.randomNeighborhoods(cellSpace) + +def SIS(alpha, beta, n_iterations, cellSpace, neighborhoodSystem, impactRates): + """ + Modelo SIS aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9,9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace,"moore") + sis = SIS(0.2,0.5,10,cellSpace,neighborhoodSystem,[1,0]) + sis.data + --> [array([[ 0. , 0.88888889], + [ 1. , 0.67901235], + [ 2. , 0.38271605], + [ 3. , 0.19753086], + [ 4. , 0.09876543], + [ 5. , 0.03703704], + [ 6. , 0. ], + [ 7. , 0. ], + [ 8. , 0. ], + [ 9. , 0. ], + [10. , 0. ], + [11. , 0. ]]), + array([[ 0. , 0.11111111], + [ 1. , 0.32098765], + [ 2. , 0.61728395], + [ 3. , 0.80246914], + [ 4. , 0.90123457], + [ 5. , 0.96296296], + [ 6. , 1. ], + [ 7. , 1. ], + [ 8. , 1. ], + [ 9. , 1. ], + [10. , 1. ], + [11. , 1. ]])] + + sis.evolutions[1].system + --> array([[1., 1., 0., 0., 0., 0., 0., 0., 0.], + [1., 1., 0., 0., 0., 1., 0., 0., 0.], + [1., 1., 0., 0., 0., 1., 1., 0., 0.], + [1., 1., 0., 0., 0., 1., 0., 0., 0.], + [1., 0., 0., 0., 0., 0., 0., 0., 0.], + [0., 1., 1., 1., 0., 0., 0., 0., 0.], + [1., 0., 1., 1., 1., 0., 0., 0., 0.], + [0., 0., 1., 1., 1., 0., 0., 0., 1.], + [0., 0., 1., 0., 0., 0., 0., 0., 1.]]) + """ + modelApply = Models.applyEpidemiologicalModel("sis", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.basicModel(n_iterations) + return modelApply + +def SIR(alpha, beta, n_iterations, cellSpace, neighborhoodSystem, impactRates): + """ + Modelo SIR aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9,9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace,"moore") + sir = SIR(0.2,0.5,10,cellSpace,neighborhoodSystem,[1,0]) + sir.data + [array([[ 0. , 0.90123457], + [ 1. , 0.75308642], + [ 2. , 0.50617284], + [ 3. , 0.2345679 ], + [ 4. , 0.12345679], + [ 5. , 0.08641975], + [ 6. , 0.04938272], + [ 7. , 0.02469136], + [ 8. , 0. ], + [ 9. , 0. ], + [10. , 0. ], + [11. , 0. ]]), + array([[ 0. , 0.09876543], + [ 1. , 0.22222222], + [ 2. , 0.43209877], + [ 3. , 0.61728395], + [ 4. , 0.62962963], + [ 5. , 0.54320988], + [ 6. , 0.4691358 ], + [ 7. , 0.39506173], + [ 8. , 0.35802469], + [ 9. , 0.28395062], + [10. , 0.2345679 ], + [11. , 0.18518519]]), + array([[ 0. , 0. ], + [ 1. , 0.02469136], + [ 2. , 0.0617284 ], + [ 3. , 0.14814815], + [ 4. , 0.24691358], + [ 5. , 0.37037037], + [ 6. , 0.48148148], + [ 7. , 0.58024691], + [ 8. , 0.64197531], + [ 9. , 0.71604938], + [10. , 0.7654321 ], + [11. , 0.81481481]])] + + sir.evolutions[4].system + --> array([[0., 0., 2., 1., 2., 1., 2., 1., 2.], + [0., 0., 0., 1., 1., 1., 1., 1., 1.], + [0., 0., 0., 1., 2., 2., 1., 1., 1.], + [0., 0., 2., 2., 1., 1., 1., 1., 1.], + [1., 1., 1., 2., 2., 1., 1., 1., 1.], + [2., 1., 1., 2., 2., 2., 1., 1., 1.], + [2., 1., 2., 1., 1., 1., 1., 2., 2.], + [1., 1., 1., 1., 1., 2., 1., 1., 1.], + [1., 1., 1., 1., 1., 1., 1., 2., 1.]]) + """ + modelApply = Models.applyEpidemiologicalModel("sir", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.basicModel(n_iterations) + return modelApply + +def SIS_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Modelo SIS con natalidad y mortalidad aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + sis_bm = SIS_BM(0.2,0.5,0.2,[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel("sis_bm", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def SIR_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Modelo SIR con natalidad y mortalidad aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + sir_bm = SIR_BM(0.2,0.5,0.2,[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel("sir_bm", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def SIS_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Modelo SIS con muerte por enfermedad aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + deathFromDiseaseByAgeRange(list) Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + sis_dd = SIS_DD(0.2,0.5,0.2,[[0,100,0.0005]],[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel("sis_dd", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.deathFromDiseaseByAgeRange = deathFromDiseaseByAgeRange + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def SIR_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, n_iterations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Modelo SIR con muerte por enfermedad aplicado sobre el espacio de células + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + deathFromDiseaseByAgeRange(list) Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + sir_dd = SIR_DD(0.2,0.5,0.2,[[0,100,0.0005]],[[0,100,0.0005]],365,20,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel("sir_dd", alpha, beta, cellSpace, neighborhoodSystem, impactRates) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.deathFromDiseaseByAgeRange = deathFromDiseaseByAgeRange + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIS(alpha, beta, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates): + """ + Aplica el modelo SIS una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sis = medium_SIS(0.2,0.5,0.1,10,3,cellSpace,neighborhoodSystem,[1,0]) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sis", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIR(alpha, beta, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates): + """ + Aplica el modelo SIR una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sir = medium_SIR(0.2,0.5,0.1,10,3,cellSpace,neighborhoodSystem,[1,0]) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sir", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIS_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Aplica el modelo SIS con natalidad y mortalidad una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sis_bm = medium_SIS_BM(0.2,0.5, 0.2, [[0,100,0.0000005]], 365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sis_bm", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIR_BM(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Aplica el modelo SIR con natalidad y mortalidad una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sir_bm = medium_SIR_BM(0.2,0.5, 0.2, [[0,100,0.0000005]], 365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sir_bm", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIS_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Aplica el modelo SIS con muerte por enfermead una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + deathFromDiseaseByAgeRange(list) Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sis_dd = medium_SIS_DD(0.2,0.5, 0.2, [[0,100,0.0000005]], [[0,100,0.0000005]],365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sis_dd", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.deathFromDiseaseByAgeRange = deathFromDiseaseByAgeRange + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply + +def medium_SIR_DD(alpha, beta, birthRate, probabilityOfDyingByAgeGroup, deathFromDiseaseByAgeRange, annualUnit, initialPercentageInfected, n_iterations, nSimulations, cellSpace, neighborhoodSystem, impactRates, systemAges): + """ + Aplica el modelo SIR con muerte por enfermead una cantidad determinada de veces y calcula sus datos promedio + Parámetros: + alpha(float) Tasa de recuperación + beta(float) Tasa de infección + birthRate(float) Tasa de natalidad + probabilityOfDyingByAgeGroup(list) Lista con las probabilidades de muerte de una célula por rangos de edad + deathFromDiseaseByAgeRange(list) Lista con las probabilidades de muerte ocasionada por la enfermedad por rango de edad + annualUnit(int) Unidad que se toma como base para un ciclo (se puede entender como un año de 365 días) + initialPercentageInfected(float) Porcentage inicial de individuos infectados + n_iterations(int) Cantidad de iteraciones en las que se aplica en modelo + nSimulations(int) Cantidad de simulaciones que va a considerar + cellSpace(EpidemiologicalModels.CellSpaceConfiguration.CellSpaceConfiguration) Espacio de células + neighborhoodSystem(list) Lista con los grados de impacto para cada célula + impactRates(list) Tasas de impacto consideradas + systemAges(numpy.ndarray) Matriz con las edades de cada célula + Salidas: + EpidemiologicalModels.Models.applyEpidemiologicalModel Contiene toda la información generada al aplicar el modelo + + Ejemplo: + cellSpace = CellSpace(9, 9).initialLocationOfInfected(0.1) + neighborhoodSystem = GenerateNeighborhoodSystem(cellSpace, "moore") + ageMatrix = CreateAgeMatrix([[0,100,1]], cellSpace) + + medium_sir_dd = medium_SIR_DD(0.2,0.5, 0.2, [[0,100,0.0000005]], [[0,100,0.0000005]],365, 0.1,10,3,cellSpace,neighborhoodSystem,[1,0],ageMatrix) + """ + modelApply = Models.applyEpidemiologicalModel_nIterations("sir_dd", alpha, beta, cellSpace, neighborhoodSystem, impactRates, nSimulations, initialPercentageInfected) + modelApply.birthRate = birthRate + modelApply.probabilityOfDyingByAgeGroup = probabilityOfDyingByAgeGroup + modelApply.deathFromDiseaseByAgeRange = deathFromDiseaseByAgeRange + modelApply.annualUnit = annualUnit + modelApply.systemAges = systemAges + modelApply.basicModel(n_iterations) + return modelApply \ No newline at end of file diff --git a/LICENSE b/LICENSE index 048c205..0b1c0b5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Grupo-de-simulacion-con-automatas +Copyright (c) 20222 Grupo-de-simulacion-con-automatas Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal