diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/GeneralizedLotkaVolterra.gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/Generalized Lotka-Volterra (Toy model).gaml similarity index 85% rename from ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/GeneralizedLotkaVolterra.gaml rename to ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/Generalized Lotka-Volterra (Toy model).gaml index af30918018..1cbec882c7 100644 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/GeneralizedLotkaVolterra.gaml +++ b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/Generalized Lotka-Volterra (Toy model).gaml @@ -18,9 +18,22 @@ model GeneralizedLotkaVolterra global { int max_species <- 8; - list> animal_names <- [["Goé","land"],["Ga","zelle"],["Tama","noir"],["La","pin"],["Cou","cou"],["Ca","nard"],["Cha","mois"],["Ecu","reuil"],["Elé","phant"], + string dummy <- ''; + + string language <- "english" among: ["french","english"]; + + map>> animal_names <- map( + "french"::[["Goé","land"],["Ga","zelle"],["Tama","noir"],["La","pin"],["Cou","cou"],["Ca","nard"],["Cha","mois"],["Ecu","reuil"],["Elé","phant"], ["Droma","daire"],["Pé","lican"],["Sou","ris"],["Pou","let"],["Perro","quet"],["Rossi","gnol"],["Gre","nouille"],["Phaco","chère"],["Maque","reau"], - ["Sar","dine"],["Mou","ton"],["Ser","pent"],["Tor","tue"],["Pu","tois"]]; + ["Sar","dine"],["Mou","ton"],["Ser","pent"],["Tor","tue"],["Pu","tois"]], + "english"::[["Chee","tah"],["Gi","raffe"],["Ele","phant"],["Ra","bbit"],["Squi","rrel"], + ["Chame","leon"],["Bumble","bee"],["Bu","ffalo"],["Ze","bra"], + ["Rattle","snake"],["Bea","ver"],["Sala","mander"],["Hippo","potamus"],["Pa","rrot"], + ["Rhino","ceros"],["Kanga","roo"],["Leo","pard"],["Alli","gator"], + ["Go","rilla"],["Croco","dile"],["Platy","pus"],["Octo","pus"],["Porcu","pine"]] + ); + + list possible_type <-["neutral","positive","negative"]; map type_color <- ["neutral"::rgb(240,240,240),"negative"::rgb(250,65,65),"positive"::rgb(150,217,100)]; @@ -35,7 +48,7 @@ global { float hKR4 <- 0.01; init{ - create population_count; + // create population_count; loop i from: 0 to: max_species-1{ color_list[i] <- rgb(int(240/max_species*i),int(240/max_species*i),255); } @@ -56,15 +69,6 @@ global { } } -species population_count{ - list pop <- list_with(max_species,0.0); - - reflex update_count{ - loop i from: 0 to: max_species-1{ - pop[i] <- (species_list[i] != nil)?species_list[i].pop:0; - } - } -} species animal{ float t; @@ -130,7 +134,7 @@ species solver_and_scheduler{ }else{ // add a new animal species create animal{ - name <- animal_names[rnd(length(animal_names)-1)][0]+animal_names[rnd(length(animal_names)-1)][1]; + name <- animal_names[language][rnd(length(animal_names[language])-1)][0]+animal_names[language][rnd(length(animal_names[language])-1)][1]; species_list[selected_button.grid_y - 1] <- self; r <- rnd(100)/100; k <- 30.0+rnd(50); @@ -229,23 +233,26 @@ grid button width:max_species+1 height:max_species+1 -experiment simulation type: gui autorun: true { +experiment simulation type: gui autorun: true { float minimum_cycle_duration <- 0.1; + parameter "Language for animal names" var: language category: "language"; + parameter "Click on '?'s to add animal species, then click on grey squares to change types of interactions.\n'+' means that the upper species has a positive impact on the left species (e.g. the left one eats the top one). '-' is for negative impact and grey for neutral. The interaction graph is shown in the lower-right corner." + var: dummy category: "Help"; + output { layout value: horizontal([0::50,vertical([1::50,2::50])::50]) tabs:true; display action_button name:"Interaction matrix" { species button aspect:modern ; event mouse_down action:activate_act; } - display LV name: "Time series" refresh: every(1#cycle) { - chart "Population" type: series background: rgb('white') x_range: 200 { + display LV name: "Time series" refresh: every(1#cycle) type: java2D { + chart "Population size" type: series background: rgb('white') x_range: 200 x_tick_line_visible: false{ loop i from: 0 to: max_species-1{ - data "espèce "+i value: first(population_count).pop[i] color: (species_list[i] != nil)?color_list[i]:rgb(0,0,0,0) marker: false; - data "espèce "+i value: first(solver_and_scheduler).pop[i] color: (species_list[i] != nil)?color_list[i]:rgb(0,0,0,0) marker: false; + data "Species "+i value: first(solver_and_scheduler).pop[i] color: (species_list[i] != nil)?color_list[i]:rgb(0,0,0,0) marker: false; } } } - display "Interaction graph" { + display "Interaction graph" type: java2D { graphics "edges" { loop edge over: the_graph.edges { float angle <- (pair(edge)).key towards (pair(edge)).value; diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/SIR (Simple).gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/SIR (Simple).gaml similarity index 54% rename from ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/SIR (Simple).gaml rename to ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/SIR (Simple).gaml index c0d6b8efa5..c4234fd955 100644 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/SIR (Simple).gaml +++ b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Examples/SIR (Simple).gaml @@ -40,13 +40,20 @@ species agent_with_SIR_dynamic { } -experiment maths type: gui { +experiment Simulation type: gui { + float minimum_cycle_duration <- 0.1#s; output { + layout #vertical; display display_charts { - chart "SIR_agent" type: series background: #white { - data 'S' value: first(agent_with_SIR_dynamic).S color: #green ; - data 'I' value: first(agent_with_SIR_dynamic).I color: #red ; - data 'R' value: first(agent_with_SIR_dynamic).R color: #blue ; + chart "Time series" type: series background: #white { + data 'S' value: first(agent_with_SIR_dynamic).S color: rgb(46,204,113) ; + data 'I' value: first(agent_with_SIR_dynamic).I color: rgb(231,76,60) ; + data 'R' value: first(agent_with_SIR_dynamic).R color: rgb(52,152,219) ; + } + } + display display_phase_portrait { + chart "Phase portrait" type: xy background: #white x_label:"S" y_label:"Y" x_range: {0,1600} y_range: {0,700}{ + data 'I vs S' value: [first(agent_with_SIR_dynamic).S,first(agent_with_SIR_dynamic).I] color: rgb(243,156,18) ; } } } diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/ContinuousCurves.gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/ContinuousCurves.gaml deleted file mode 100644 index 1428813d91..0000000000 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/ContinuousCurves.gaml +++ /dev/null @@ -1,58 +0,0 @@ -/** - * continuous curves - * Author: tri and nghi - * Description: - */ -model ContinuousCurves - - -global { - float step <- 1 # s; - - init { - create my_SEIR_maths; - } -} - -species my_SEIR_maths { - float ttt; - float Sm <- 0.0658; - float Em <- 0.007; - float Im <- 0.002; - float mu <- 0.02; - float alpha <- 35.842; - float gamma <- 100.0; - float beta0 <- 1884.95; - float beta1 <- 0.255; - - equation SEIR { - diff(Sm, ttt) = (mu - beta0 * (1 + beta1 * cos(2 * 3.14 * ttt)) * self.Sm * self.Im - mu * self.Sm); - diff(Em, ttt) = (beta0 * (1 + beta1 * cos(2 * 3.14 * ttt)) * self.Sm * self.Im - (mu + alpha) * self.Em); - diff(Im, ttt) = (alpha * self.Em - (mu + gamma) * self.Im); - } - - reflex solving { - solve SEIR method: #rk4 step_size: 0.01; - } -} - -experiment mysimulation type: gui { - output { - display chartcontinuous { - chart 'chartcontinuous' type: series background: rgb('lightGray') - x_serie: (my_SEIR_maths[0]).ttt[] - size: { 1.0, 0.5 } position: { 0.0, 0.0 } - { - data "s_mathsc" value: (my_SEIR_maths[0]).Sm[] color: # red marker: false; - data "e_mathsc" value: (my_SEIR_maths[0]).Em[] color: # yellow marker: false; - data "i_mathsc" value: (my_SEIR_maths[0]).Im[] color: # blue marker: false; - } - - chart 'chartdiscret' type: series background: rgb('white') size: { 1.0, 0.5 } position: { 0.0, 0.5 } { - data "s_mathsd" value: first(my_SEIR_maths).Sm color: rgb('red') marker: false; - data "e_mathsd" value: first(my_SEIR_maths).Em color: rgb('yellow') marker: false; - data "i_mathsd" value: first(my_SEIR_maths).Im color: rgb('blue') marker: false; - } - } - } -} diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/Displays (Continuous, Phase Portrait).gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/Displays (Continuous, Phase Portrait).gaml new file mode 100644 index 0000000000..d34ef1b444 --- /dev/null +++ b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/Displays (Continuous, Phase Portrait).gaml @@ -0,0 +1,75 @@ +/** + * continuous curves + * Author: Tri and Nghi + * Description: + * + * This model illustrates different displays for a Lotka-Volterra model. ABMs usually only require a discrete + * visualization of the results (one value per cycle). EBMs compute a continuous solution, and thus require + * a continuous display. The syntax is shown below. + * + * Phase portraits are very common in mathematics, and can be displayed with the 'type: xy' facet. + */ + + +model Displays + + +global { + init { + create LV_model with: [x::2.0, y::2.0]; + } +} + +species LV_model { + float t; + float x; + float y; + float h <- 0.1; + float alpha <- 0.8; + float beta <- 0.3; + float gamma <- 0.2; + float delta <- 0.85; + + equation eqLV { + diff(x, t) = x * (alpha - beta * y); + diff(y, t) = -y * (delta - gamma * x); + } + + reflex solving { + solve eqLV method: #rk4 step_size: h; + } +} + +experiment Displays type: gui { + float minimum_cycle_duration <- 0.1#s; + output { + layout #split; + display D1 synchronized:false { + chart 'Time series' type: series background: #white y_label:"pop" x_tick_line_visible: false{ + data "x" value: first(LV_model).x color: rgb(52,152,219); + data "y" value: first(LV_model).y color: rgb(41,128,185); + } + } + display D2 synchronized:false { + chart 'Time series - continuous display' type: series background: #white y_label:"pop" x_tick_line_visible: false{ + // chart 'Time series - continuous display' type: series x_serie: first(LV_model).t[] background: #white y_label:"pop"{ + data "x" value: first(LV_model).x[] color: rgb(52,152,219) marker: false; + data "y" value: first(LV_model).y[] color: rgb(41,128,185) marker: false; + } + } + display D3 name: "Phase Portrait " synchronized:false { + chart 'Phase Portrait' type: xy background: #white x_label: "x" y_label:"y"{ + // Continuous display requires to pass a list of two values x and y + data "y(x(t))" value: [first(LV_model).x,first(LV_model).y] color: rgb(243,156,18); + } + } + display D4 name: "Phase Portrait - continuous display" synchronized:false { + chart 'Phase Portrait - continuous display' type: xy background: #white x_label: "x" y_label:"y"{ + // Continuous display requires to pass a list of two values x and y + data "y(x(t))" value: rows_list(matrix(first(LV_model).x[],first(LV_model).y[])) color: rgb(243,156,18) marker: false; + } + } + + } + +} \ No newline at end of file diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Simple with advanced charts).gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Simple with advanced charts).gaml deleted file mode 100644 index 154af71c33..0000000000 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Simple with advanced charts).gaml +++ /dev/null @@ -1,94 +0,0 @@ -/** -* Name: SIR (Simple) -* Author: hqnghi -* Description: A simple example of ODE use into agents with the example of the SIR equation system. -* Tags: equation, math -*/ - -model simple_ODE_SIR - -global { - - string mm <- "rk4"; - - list S_3d -> aSIR collect each.S; - list I_3d -> aSIR collect each.I; - list R_3d -> aSIR collect each.R; - - init { - create aSIR number: 10 { - S<-S-(int(self)*10000); - } - } - - reflex ss when: cycle>=40 { - do pause; - } -} - - -species aSIR { - int N <- 150000 ; - int iInit <- 1000; - - float t; - float S <- N - float(iInit); - float I <- float(iInit); - float R <- 0.0; - - float alpha <- 0.2 min: 0.0 max: 1.0; - float beta <- 0.8 min: 0.0 max: 1.0; - - float h <- 0.1; - - equation SIR { - diff(S,t) = (- beta * S * I / N); - diff(I,t) = (beta * S * I / N) - (alpha * I); - diff(R,t) = (alpha * I); - } - - reflex solving { - solve SIR method: #rk4 step_size: h ; - } -} - - -experiment maths type: gui { - float minimum_cycle_duration<-0.2; - - output { - display display_charts { - chart "SIR_agent" type: series background: #white { - loop i from: 0 to: length(aSIR) - 1 { - data 'S'+i value: (aSIR[i]).S color: #green ; - } - - loop i from: 0 to: length(aSIR) - 1 { - data 'I'+i value: (aSIR[i]).I color: #red ; - } - - loop i from: 0 to: length(aSIR) - 1 { - data 'R'+i value: (aSIR[i]).R color: #blue ; - } - } - } - - display display_charts_radar { - chart "SIR_agent" type: radar background: #white axes:#white { - data 'S0' value: (aSIR[0]).S[] color: #green ; - data 'I0' value: (aSIR[0]).I[] color: #red ; - data 'R0' value: (aSIR[0]).R[] color: #blue ; - } - } - -// display display_chartsH { -// chart "SIR_agent" type: heatmap background: #white -// reverse_axes: true -// { -// data 'S0' value: S_3d color: #green ; -// data 'I0' value: I_3d color: #red ; -// data 'R0' value: R_3d color: #blue ; -// } -// } - } -} diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Split in Agents, Multiple Strains).gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Split in Agents, Multiple Strains).gaml index 0b843f8131..d8a707e1e8 100644 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Split in Agents, Multiple Strains).gaml +++ b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/For Advanced Users/SIR (Split in Agents, Multiple Strains).gaml @@ -13,8 +13,8 @@ global { int number_I <- 5 ; // The number of infected int number_R <- 0 ; // The number of removed - float _beta <- 1.0 ; // The parameter Beta - float _delta <- 0.01 ; // The parameter Delta + float _beta <- 0.8 ; // The parameter Beta + float _delta <- 0.2 ; // The parameter Delta // Global variables int strain_number <- 2; @@ -28,7 +28,8 @@ global { create I_agt number: strain_number { Isize <- float(number_I); - self.beta <- _beta; + self.beta <- _beta*(0.8+rnd(0.4)); + write self.beta; self.delta <- _delta; } @@ -102,30 +103,32 @@ species my_SIR_maths { experiment Simulation type: gui { + float minimum_cycle_duration <- 0.1#s; parameter 'Number of Susceptible' type: int var: number_S <- 495 category: "Initial population"; parameter 'Number of Infected' type: int var: number_I <- 5 category: "Initial population"; parameter 'Number of Removed' type: int var: number_R <- 0 category: "Initial population"; - parameter 'Beta (S->I)' type: float var: _beta <- 1.0 category: "Parameters"; - parameter 'Delta (I->R)' type: float var: _delta <- 0.01 category: "Parameters"; + parameter 'Beta (S->I)' type: float var: _beta <- 0.8 category: "Parameters"; + parameter 'Delta (I->R)' type: float var: _delta <- 0.2 category: "Parameters"; - output { + output { + layout #split; display chart_3system_eq { - chart 'Split system' type: series background: #lightgray { - data 'susceptible' value: first(S_agt).Ssize color: #green; - data 'infected0' value: first(I_agt).beta * first(I_agt).Isize color: #white; - data 'infected1' value: last(I_agt).beta * last(I_agt).Isize color: #yellow; - data 'i1+i2' value: sum(I_agt accumulate (each.beta * each. Isize)) color: rgb ( 'red' ) ; - data 'recovered' value: first(R_agt).Rsize color: #blue; + chart 'Split system' type: series background: #white x_tick_line_visible: false{ + data 'susceptible' value: first(S_agt).Ssize color: rgb(46,204,113) marker_shape: marker_circle; + data 'infected 1' value: first(I_agt).beta * first(I_agt).Isize color: rgb(231,76,60)+120 marker_shape: marker_diamond; + data 'infected 2' value: last(I_agt).beta * last(I_agt).Isize color: rgb(231,76,60)+100 marker_shape: marker_diamond; + data 'infected 1+2' value: sum(I_agt accumulate (each.beta * each. Isize)) color: rgb(231,76,60) marker_shape: marker_circle; + data 'recovered' value: first(R_agt).Rsize color: rgb(52,152,219) marker_shape: marker_circle; } } display chart_1system_eq { - chart 'unified system' type: series background: #lightgray { - data 'susceptible_maths' value: first(my_SIR_maths).Sm color: #green; - data 'infected_maths' value: first(my_SIR_maths).Im color: #red; - data 'recovered_maths' value: first(my_SIR_maths).Rm color: #blue; + chart 'unified system' type: series background: #white x_tick_line_visible: false{ + data 'susceptible (maths)' value: first(my_SIR_maths).Sm color: rgb(46,204,113) marker_shape: marker_circle; + data 'infected (maths)' value: first(my_SIR_maths).Im color: rgb(231,76,60) marker_shape: marker_circle; + data 'recovered (maths)' value: first(my_SIR_maths).Rm color: rgb(52,152,219) marker_shape: marker_circle; } } } diff --git a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Technical Details/Influence of the integration method (LV).gaml b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Technical Details/Influence of the integration method (LV).gaml index b51ce379ac..cddd30e582 100644 --- a/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Technical Details/Influence of the integration method (LV).gaml +++ b/ummisco.gaml.extensions.maths/models/Ordinary Differential Equations/models/Technical Details/Influence of the integration method (LV).gaml @@ -2,13 +2,12 @@ * Name: Influence of the integration step * Author: Tri, Nghi, Benoit * Description: The aim is to show the influence of the integration method on the result precision. -* Note: an integration step of 0.1 is considered as not precise enough. It is used here to highlight clearly the impact of the integration method. +* Note: an integration step of 0.1 is considered as not accurate enough. It is used here to highlight clearly the impact of the integration method. * Tags: equation, math ***/ -model LVInfluenceoftheIntegrationstep +model LVInfluenceoftheIntegrationMethod global { - init { create LVRK4 with: [x::2.0, y::2.0]; create LVEuler with: [x::2.0, y::2.0]; @@ -37,6 +36,7 @@ species LVRK4 { } + species LVEuler { float t; float x; @@ -52,26 +52,23 @@ species LVEuler { diff(y, t) = -y * (delta - gamma * x); } - reflex solving { - try{ - solve eqLV method: #Euler step_size: h; - if(!is_finite(x)){ - ask world{do pause;} - } - } - + reflex solving { + solve eqLV method: #Euler step_size: h; + } + + reflex end_simulation when: cycle > 126{ + ask world{do pause;} } } experiment examples type: gui { + float minimum_cycle_duration <- 0.1#s; output { display LV synchronized:false { - chart 'Comparison Euler - RK4 (RK4 is more precise)' type: series background: #lightgray { - data "xRK4" value: first(LVRK4).x color: #yellow; - data "yRK4" value: first(LVRK4).y color: #blue; - data "xEuler" value: last(LVEuler).x color: #red; - data "yEuler" value: last(LVEuler).y color: #green; + chart 'Comparison Euler - RK4 (RK4 is more accurate)' type: xy x_serie:first(LVRK4).t[] background: #white { + data "RK4" value: [first(LVRK4).x,first(LVRK4).y] color: #blue marker: false; + data "Euler" value: [first(LVEuler).x,first(LVEuler).y] color: #red marker: false; } } diff --git a/ummisco.gaml.extensions.maths/src/ummisco/gaml/extensions/maths/ode/utils/solver/Solver.java b/ummisco.gaml.extensions.maths/src/ummisco/gaml/extensions/maths/ode/utils/solver/Solver.java index 7981f7ad00..b41aa0504f 100644 --- a/ummisco.gaml.extensions.maths/src/ummisco/gaml/extensions/maths/ode/utils/solver/Solver.java +++ b/ummisco.gaml.extensions.maths/src/ummisco/gaml/extensions/maths/ode/utils/solver/Solver.java @@ -67,7 +67,7 @@ public void handleStep(final StepInterpolator interpolator, final boolean isLast if (lastT < 0) { storeIntegratedValues(time, y, integrated_val); } else { - if (Maths.abs(lastT - time) > 0.01) { + if (Maths.abs(lastT - time) > 10E-12) { storeIntegratedValues(time, y, integrated_val); } }