Skip to content

Commit

Permalink
Merge pull request #3 from pedro-andrade-inpe/master
Browse files Browse the repository at this point in the history
Updates to TerraME 2.0 (DataFrame).
  • Loading branch information
pedro-andrade-inpe committed Feb 6, 2017
2 parents ec2660e + 5412527 commit 17c0ea3
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 57 deletions.
4 changes: 2 additions & 2 deletions description.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version = "0.3.1"
version = "0.4"
license = "GPL"
package = "sci"
title = "Scientific and Mathematical Functions"
date = "9 May 2016"
date = "6 Feb 2017"
depends = "terrame (>= 2.0)"
authors = "Gilberto Camara"
contact = "gilberto.camara@inpe.br"
Expand Down
64 changes: 64 additions & 0 deletions examples/PredatorPreyFord.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
-- @example Predator-Prey Oscillations on the Kaibab Plateau.
-- Ford, F. A. (1999). Modeling the environment: an introduction to system
-- dynamics models of environmental systems. Island Press.

import("sci")

local deerKilledPerPredatorPerYear = Spline{
points = DataFrame{
x = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100},
y = {0, 15, 25, 30, 35, 40, 45, 50, 55, 60, 60, 60}
}
}

local deerNetBirthRate = Spline{
points = DataFrame{
x = { 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
y = {-0.4, -0.2, 0.0, 0.2, 0.4, 0.45, 0.5, 0.5}
}
}

local predatorsNetBirthRate = Spline{
points = DataFrame{
x = { 0.00, 10.00, 20.00, 30.00, 40.00, 50.00, 60.00, 70.00, 80.00},
y = {-0.60, -0.45, -0.30, -0.15, 0.00, 0.15, 0.30, 0.40, 0.45}
}
}

PredatorPreyFord = Model{
deer = 4000, -- population of deer
predator = 46, -- number of predators,
finalTime = 1932,
init = function(model)
model.prey = function(self)
return self.deer / 80
end

model.chart = Chart{
target = model,
select = {"predator", "prey"},
title = "Predator and Prey Populations"
}

model.timer = Timer{
Event{start = 1901, action = function()
local deer_density = model.deer / 800
local dkpppy = deerKilledPerPredatorPerYear:value(deer_density)

local ffnm = 1 -- fraction forage need met

model.deer = model.deer + model.deer * deerNetBirthRate:value(ffnm) - model.predator * dkpppy

-- the density needs to be recomputed before updating the amount of predators
deer_density = model.deer / 800
dkpppy = deerKilledPerPredatorPerYear:value(deer_density)
model.predator = model.predator + model.predator * predatorsNetBirthRate:value(dkpppy)

end},
Event{start = 1900, action = model.chart}
}
end
}

PredatorPreyFord:run()

24 changes: 11 additions & 13 deletions examples/SimpleSpline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,26 @@

import("sci")

-- relation btw
waterSurface = Spline {
points = { {x = 0, y = 0}, {x = 1000, y = 24.7},
{x = 2000, y = 35.3}, {x = 3000, y = 48.6},
{x = 4000, y = 54.3}, {x = 5000, y = 57.2},
{x = 6000, y = 61.6}, {x = 7000, y = 66.0},
{x = 8000, y = 69.9} },
-- relation btw
waterSurface = Spline {
points = DataFrame{
x = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000},
y = {0, 24.7, 35.3, 48.6, 54.3, 57.2, 61.6, 66.0, 69.9}
},
steps = 1
}
}

spline = Model{
data = 0.0,
surface = 0.0,
finalTime = 80,
data = 0.0,
surface = 0.0,
finalTime = 80,

init = function(model)
model.chart = Chart{
target = model,
select = {"surface", "data"}
}


model.timer = Timer{
Event{action = function(ev)
local time = ev:getTime()
Expand Down
50 changes: 23 additions & 27 deletions lua/Spline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ local function buildSpline(self)
-- build a Catmull-Roll spline
local points = self.points
local steps = self.steps or 10

local values = {}

if #points < 3 then
return points
end
Expand All @@ -27,42 +27,40 @@ local function buildSpline(self)

--prevent duplicate entries
if next(values) == nil then -- table is empty, insert first point
table.insert(values, {x = x , y = y})
elseif values[#values].x ~= x and values[#values].y ~= y then
table.insert(values, {x = x , y = y})
table.insert(values, {x = x , y = y})
elseif values[#values].x ~= x and values[#values].y ~= y then
table.insert(values, {x = x , y = y})
end
end
end

return values
end

Spline_ = {
Spline_ = {
type_ = "Spline",
--- Returns the value of the spline for a given value.
-- @arg t A number value.
-- @usage import("sci")
--
-- waterSurface = Spline{
-- points = {{x = 0, y = 0}, {x = 1000, y = 24.7},
-- {x = 2000, y = 35.3}, {x = 3000, y = 48.6},
-- {x = 4000, y = 54.3}, {x = 5000, y = 57.2},
-- {x = 6000, y = 61.6}, {x = 7000, y = 66.0},
-- {x = 8000, y = 69.9}
-- waterSurface = Spline{
-- points = DataFrame{
-- x = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000},
-- y = {0, 24.7, 35.3, 48.6, 54.3, 57.2, 61.6, 66.0, 69.9}
-- }
-- }
-- }
--
-- print(waterSurface:value(1500))
value = function(self, t)
local iStart, iEnd = 1, #self.values
local iMid

verify(self.values[iEnd].x >= t, " values outside range - last value is smaller that requested")
verify(self.values[iStart].x <= t, " values outside range - first value is bigger than requested")

while true do
iMid = math.floor((iStart + iEnd) / 2)
if self.values[iMid].x == t then
if self.values[iMid].x == t then
return self.values[iMid].y
else if self.values[iMid].x < t then
if self.values[iMid + 1].x < t then
Expand All @@ -71,7 +69,7 @@ Spline_ = {
local w = (t - self.values[iMid].x) / (self.values[iMid + 1].x - self.values[iMid].x)
return (1 - w) * self.values[iMid].y + w * self.values[iMid + 1].y
end
else -- self.values[iMid].x > t
else -- self.values[iMid].x > t
iEnd = iMid
end
end
Expand All @@ -86,22 +84,20 @@ metaTableSpline_ = {__index = Spline_}
-- @arg argv.steps how many points to interpolate btw two data points. Default is 10.
-- @usage import("sci")
--
-- waterSurface = Spline{
-- points = {{x = 0, y = 0}, {x = 1000, y = 24.7},
-- {x = 2000, y = 35.3}, {x = 3000, y = 48.6},
-- {x = 4000, y = 54.3}, {x = 5000, y = 57.2},
-- {x = 6000, y = 61.6}, {x = 7000, y = 66.0},
-- {x = 8000, y = 69.9}
-- waterSurface = Spline{
-- points = DataFrame{
-- x = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000},
-- y = {0, 24.7, 35.3, 48.6, 54.3, 57.2, 61.6, 66.0, 69.9}
-- }
-- }
-- }
function Spline(argv)
mandatoryTableArgument(argv, "points", "table")
mandatoryTableArgument(argv, "points", "DataFrame")
defaultTableValue(argv, "steps", 10)

setmetatable(argv, metaTableSpline_)

argv.values = buildSpline(argv)

return argv
end

28 changes: 13 additions & 15 deletions tests/Spline.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,24 @@

return{
Spline = function(unitTest)
local waterSurface = Spline {
points = { {x = 0, y = 0}, {x = 1000, y = 24.7},
{x = 2000, y = 35.3}, {x = 3000, y = 48.6},
{x = 4000, y = 54.3}, {x = 5000, y = 57.2},
{x = 6000, y = 61.6}, {x = 7000, y = 66.0},
{x = 8000, y = 69.9} }
}
local waterSurface = Spline {
points = DataFrame{
x = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000},
y = {0, 24.7, 35.3, 48.6, 54.3, 57.2, 61.6, 66.0, 69.9}
}
}

unitTest:assertType(waterSurface, "Spline")
end,
value = function(unitTest)
local waterSurface = Spline {
points = { {x = 0, y = 0}, {x = 1000, y = 24.7},
{x = 2000, y = 35.3}, {x = 3000, y = 48.6},
{x = 4000, y = 54.3}, {x = 5000, y = 57.2},
{x = 6000, y = 61.6}, {x = 7000, y = 66.0},
{x = 8000, y = 69.9} }
}
local waterSurface = Spline {
points = DataFrame{
x = {0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000},
y = {0, 24.7, 35.3, 48.6, 54.3, 57.2, 61.6, 66.0, 69.9}
}
}

unitTest:assertEquals(waterSurface:value(1500), 30.7125, 0.0001)
end,
end
}

0 comments on commit 17c0ea3

Please sign in to comment.