Skip to content

Commit df4b55d

Browse files
macromultimodelling:fix_real_data_and_add_ecoWeight_param(diff_from_ecoMult_in_fact)
1 parent 6177c98 commit df4b55d

File tree

17 files changed

+147
-123
lines changed

17 files changed

+147
-123
lines changed

library/src/main/scala/org/openmole/spatialdata/application/multimodelmacro/RealData.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package org.openmole.spatialdata.application.multimodelmacro
22

33
import org.openmole.spatialdata.model.urbandynamics.{Coevolution, EconomicExchanges, Innovation, MacroResultFit, MultiMacroModel}
4-
import org.openmole.spatialdata.model.urbandynamics.MultiMacroModel.MultiMacroResult
4+
import org.openmole.spatialdata.model.urbandynamics.MultiMacroModel.{MultiMacroResult, MultiMacroState}
5+
import org.openmole.spatialdata.utils
56
import org.openmole.spatialdata.utils.io.CSV
67
import org.openmole.spatialdata.utils.math.{DenseMatrix, EmptyMatrix, Matrix, Statistics}
78
import org.openmole.spatialdata.utils.math.Matrix.MatrixImplementation
@@ -21,14 +22,15 @@ object RealData {
2122
result: MultiMacroResult,
2223
fit: MacroResultFit
2324
){
24-
def logmse: Double = 0.0
25-
def mselog: Double = 0.0
25+
def logmse: Double = fit.logmse
26+
def mselog: Double = fit.mselog
2627
}
2728

2829
object Result {
2930
def apply(result: MultiMacroResult): Result = {
30-
val targetPop = result.states.head.populations
31-
val simulatedStates = result.states.toVector
31+
val targetPop = result.realPopulations
32+
val simulatedStates: Vector[MultiMacroState] = result.states.toVector
33+
utils.log(s"Computing real fit: total target pops ${targetPop.colSum.toSeq}; simulated pops: ${simulatedStates.map(_.populations.sum)}")
3234
val fit = MacroResultFit(targetPop, simulatedStates)
3335
Result(result, fit)
3436
}
@@ -48,6 +50,8 @@ object RealData {
4850
val rawdates: Seq[String] = CSV.readCSV(datesFile, withHeader = false).values.toSeq.head
4951
val dates: Array[Double] = rawdates.map(_.toDouble).toArray
5052

53+
utils.log(s"Real data setup : total populations ${populationMatrix.colSum.toSeq} ; average distance ${distancesMatrix.flatValues.sum/(distancesMatrix.nrows*distancesMatrix.nrows)}")
54+
5155
(populationMatrix, distancesMatrix, dates)
5256
}
5357

library/src/main/scala/org/openmole/spatialdata/application/multimodelmacro/RunSDG.scala

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,51 +12,55 @@ object RunSDG extends App {
1212

1313
implicit val rng: Random = new Random
1414

15-
// synthetic setup
16-
/*val initialState = SDG.setupSynthetic(syntheticCities = 30,
17-
syntheticHierarchy = 1.0,
18-
syntheticMaxPop = 100000.0,
19-
finalTime = 20
20-
)
21-
*/
15+
val synthetic = false
2216

23-
// real data setup
24-
val initialState = RealData.setupRealData(
25-
"","","" //TODO
26-
)
17+
val initialState =
18+
if(synthetic) {
19+
// synthetic setup
20+
SDG.setupSynthetic(syntheticCities = 30,
21+
syntheticHierarchy = 1.0,
22+
syntheticMaxPop = 100000.0,
23+
finalTime = 20, // limit to avoid huge values: 50 -> up to larger than 1e9 !
24+
seed = 42L
25+
)
26+
}else {
27+
// real data setup
28+
RealData.setupRealData("data/urbansystems/EU_pops.csv", "data/urbansystems/EU_dist.csv", "data/urbansystems/EU_dates.csv")
29+
}
2730

28-
val result = SDG.runMultiModelMacro(
31+
val result: SDG.Result = SDG.runMultiModelMacro(
2932
SDG.setupMultiModelMacro(
3033
initialState._1, initialState._2, initialState._3,
31-
finalTime = 20, // limit to avoid huge values: 50 -> up to larger than 1e9 !
34+
finalTime = initialState._3.length,
3235
seed = rng.nextInt(),
33-
innovationWeight = 0.005,
34-
innovationGravityDecay = 1.0,//0.5,
35-
innovationInnovationDecay = 0.3,
36+
innovationWeight = 1e-2, // 0.005
37+
innovationGravityDecay = 1000.0,//0.5,
38+
innovationInnovationDecay = 1000.0,
3639
innovationMutationRate = 0.2,
3740
innovationNewInnovationHierarchy = 0.5,
3841
innovationEarlyAdoptersRate = 0.2,
3942
innovationUtilityStd = 1.0,
4043
innovationUtilityDistrib = "log-normal",
41-
ecoWeight = 0.05,
44+
ecoWeight = 1e-2,
45+
ecoMultiplier = 2.0,
4246
ecoSizeEffectOnDemand = 0.1,
4347
ecoSizeEffectOnSupply = 0.2,
44-
ecoGravityDecay = 0.1,//0.5,
45-
ecoWealthToPopulationExponent = 1.5,
46-
ecoPopulationToWealthExponent = 1.5,
47-
coevolWeight = 0.005,
48+
ecoGravityDecay = 1000.0,//0.5,
49+
ecoWealthToPopulationExponent = 1.0,
50+
ecoPopulationToWealthExponent = 1.0,
51+
coevolWeight = 1e-2,
4852
coevolGamma = 1.0,
49-
coevolGravityDecay = 0.5,
50-
coevolNetworkGmax = 0.05,
53+
coevolGravityDecay = 1000.0,
54+
coevolNetworkGmax = 0.0001,
5155
coevolNetworkExponent = 1.0,
5256
coevolNetworkThresholdQuantile = 0.5
5357
)
5458
)
5559

5660
utils.log(s"Indicators: Emissions = ${SDG.cumulatedFlows(result)}; Innovation = ${- SDG.averageUtility(result)}; Infrastructure = ${SDG.averageDistance(result)}; Eco inequality = ${SDG.giniEconomicWealth(result)}; Wealth = ${SDG.averageWealth(result)}")
5761

58-
val realresult: RealData.Result = RealData.Result(result.asInstanceOf[MultiMacroResult])
62+
val realresult: RealData.Result = RealData.Result.apply(result.result)
5963

60-
utils.log(s"Fit on populations : logmse = ${realresult.logmse} ; mselog = ${realresult.mselog}")
64+
utils.log(s"Fit on populations (real setup): logmse = ${realresult.logmse} ; mselog = ${realresult.mselog}")
6165

6266
}

library/src/main/scala/org/openmole/spatialdata/application/multimodelmacro/SDG.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import org.openmole.spatialdata.model.urbandynamics.Coevolution.CoevolutionState
44
import org.openmole.spatialdata.model.urbandynamics.EconomicExchanges.EconomicExchangesState
55
import org.openmole.spatialdata.model.urbandynamics.Innovation.{InnovationState, InnovationUtilityLogNormalDistribution, InnovationUtilityNormalDistribution, mutationInnovation}
66
import org.openmole.spatialdata.model.urbandynamics.MultiMacroModel.MultiMacroResult
7-
import org.openmole.spatialdata.model.urbandynamics.{Coevolution, EconomicExchanges, Innovation, MultiMacroModel}
7+
import org.openmole.spatialdata.model.urbandynamics.{Coevolution, EconomicExchanges, Innovation, MacroResult, MultiMacroModel}
88
import org.openmole.spatialdata.utils.math.Matrix.MatrixImplementation
99
import org.openmole.spatialdata.utils.math.{DenseMatrix, EmptyMatrix, Matrix, Statistics}
1010
import org.openmole.spatialdata.vector.measures.Spatstat
@@ -77,6 +77,7 @@ object SDG {
7777
innovationUtilityStd: Double,
7878
innovationUtilityDistrib: String,
7979
ecoWeight: Double,
80+
ecoMultiplier: Double,
8081
ecoSizeEffectOnDemand: Double,
8182
ecoSizeEffectOnSupply: Double,
8283
ecoGravityDecay: Double,
@@ -102,7 +103,7 @@ object SDG {
102103
// eco exchanges - ! add gravitypotentials in eco state (total emission: cumulated interactions across models)
103104
// ! issue: not same unit for innov / eco (supply - demand gravity potentials) -> should compute something equivalent?
104105
// ! marius weight? - rescale pop updates?
105-
val ecoModel = EconomicExchanges(population, distances, dates, ecoWeight, ecoSizeEffectOnDemand, ecoSizeEffectOnSupply, ecoGravityDecay, ecoWealthToPopulationExponent, ecoPopulationToWealthExponent)
106+
val ecoModel = EconomicExchanges(population, distances, dates, ecoWeight, ecoMultiplier, ecoSizeEffectOnDemand, ecoSizeEffectOnSupply, ecoGravityDecay, ecoWealthToPopulationExponent, ecoPopulationToWealthExponent)
106107
val ecoInitialState = EconomicExchanges.initialState(ecoModel)
107108

108109
// coevolution
@@ -111,10 +112,10 @@ object SDG {
111112
0.0, 1.0, 1.0, coevolNetworkGmax, coevolNetworkExponent, coevolNetworkThresholdQuantile)
112113
val coevolInitialState = Coevolution.initialState(coevolModel)
113114

114-
MultiMacroModel(Seq(innovModel, ecoModel, coevolModel), Seq(innovInitialState, ecoInitialState, coevolInitialState))
115+
MultiMacroModel(population.clone,Seq(innovModel, ecoModel, coevolModel), Seq(innovInitialState, ecoInitialState, coevolInitialState))
115116
}
116117

117-
def runMultiModelMacro(model: MultiMacroModel)(implicit rng: Random): Result = Result(model.run.asInstanceOf[MultiMacroResult])
118+
def runMultiModelMacro(model: MultiMacroModel)(implicit rng: Random): Result = Result(model.run)
118119

119120

120121
/**
@@ -151,7 +152,7 @@ object SDG {
151152
*/
152153
def averageDistance(res: Result): Double = res.result.states.map{s =>
153154
val ptot = s.populations.sum
154-
val diagpop = DenseMatrix.diagonal(s.populations.flatValues.map( _ / ptot))
155+
val diagpop = DenseMatrix.diagonal(s.populations.map( _ / ptot).toArray)
155156
(diagpop %*% s.distanceMatrix %*% diagpop).sum
156157
}.sum / res.result.states.length
157158

library/src/main/scala/org/openmole/spatialdata/model/urbandynamics/Coevolution.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ case class Coevolution(
4949

5050
override def run: MacroResultFit = Coevolution.run(model = this)
5151

52-
override def nextStep(state: MacroState, populations: Matrix, distanceMatrix: Matrix): MacroState = {
52+
override def nextStep(state: MacroState, populations: Seq[Double], distanceMatrix: Matrix): MacroState = {
5353
val updatedState = Coevolution.updateState(state.asInstanceOf[CoevolutionState], populations, distanceMatrix)
5454
Coevolution.nextState(this, updatedState)
5555
}
@@ -71,7 +71,7 @@ object Coevolution {
7171

7272
case class CoevolutionState(
7373
time: Int,
74-
populations: Matrix,
74+
populations: Seq[Double],
7575
distanceMatrix: Matrix,
7676
interactionPotentials: Matrix,
7777
flows: Matrix
@@ -155,7 +155,7 @@ object Coevolution {
155155
)
156156
}
157157

158-
def updateState(state: CoevolutionState, populations: Matrix, distanceMatrix: Matrix): CoevolutionState = {
158+
def updateState(state: CoevolutionState, populations: Seq[Double], distanceMatrix: Matrix): CoevolutionState = {
159159
state.copy(populations = populations, distanceMatrix = distanceMatrix)
160160
}
161161

@@ -168,7 +168,7 @@ object Coevolution {
168168
val interactionPotentials = computeFlows(pops, gravityDistanceWeights, model.gravityGamma, {case (p,g) =>math.pow(p / totalpop,g) })
169169
val flows = computeFlows(pops, gravityDistanceWeights, 1.0, {case (p,_) =>p / totalpop })
170170

171-
CoevolutionState(0, pops, dmat, interactionPotentials, flows)
171+
CoevolutionState(0, pops.flatValues.toSeq, dmat, interactionPotentials, flows)
172172
}
173173

174174
/**
@@ -188,12 +188,12 @@ object Coevolution {
188188
val gravityDistanceWeights = updatedPopulationState.distanceMatrix.map{ d => Math.exp(-d / model.gravityDecay) }
189189

190190
val totalpop = updatedPopulationState.populations.sum
191-
val interactionPotentials = computeFlows(updatedPopulationState.populations, gravityDistanceWeights, model.gravityGamma, {case (p,g) =>math.pow(p / totalpop,g) })
191+
val interactionPotentials = computeFlows(RealMatrix(updatedPopulationState.populations.toArray,row=false), gravityDistanceWeights, model.gravityGamma, {case (p,g) =>math.pow(p / totalpop,g) })
192192

193193
val updatedNetwork = updateNetwork(updatedPopulationState.distanceMatrix, interactionPotentials, networkGmax, networkExponent, networkThresholdQuantile)
194194

195195
val updatedGravityDistanceWeight = updatedNetwork.map{ d => Math.exp(-d / model.gravityDecay) }
196-
val flows = computeFlows(updatedPopulationState.populations, updatedGravityDistanceWeight, 1.0, {case (p,_) => p / totalpop})
196+
val flows = computeFlows(RealMatrix(updatedPopulationState.populations.toArray,row=false), updatedGravityDistanceWeight, 1.0, {case (p,_) => p / totalpop})
197197

198198
utils.log(s"Delta distance = ${updatedPopulationState.distanceMatrix.flatValues.zip(updatedNetwork.flatValues).map{case (d1,d2) =>math.abs(d1-d2)}.sum}")
199199

@@ -244,7 +244,7 @@ object Coevolution {
244244
def step(state: (Vector[MacroStateGen],Vector[Double])): (Vector[MacroStateGen],Vector[Double]) =
245245
(Vector(MacroModel.macroStep(state._1.head,growthRates(model),state._2.head))++state._1,state._2.tail)
246246

247-
val initState = MacroStateGen(0,populationMatrix.getSubmat(0, 0, nrows = n, ncols= 1), distancesMatrices(0))
247+
val initState = MacroStateGen(0,populationMatrix.getSubmat(0, 0, nrows = n, ncols= 1).flatValues.toSeq, distancesMatrices(0))
248248
val deltats = dates.tail.zip(dates.dropRight(1)).map{case (next,prev)=> next-prev}.toVector
249249

250250
val finalState = Iterator.iterate((Vector(initState),deltats))(step).takeWhile(_._2.nonEmpty).toVector.last._1

0 commit comments

Comments
 (0)