Allow for multiplication and division of conditions that return numbers.
Johnny C. Lam [10-15-13 - 01:26]
Allow for multiplication and division of conditions that return numbers.
All "numbers" are actually linear functions of the form:
f(t) = a + (t - b)*c.
Multiplication and division of linear functions does not yield a linear
function in the general case, but the resulting function can be
approximated with a first order Taylor series expansion around the current
time point.
git-svn-id: svn://svn.curseforge.net/wow/ovale/mainline/trunk@1058 d5049fe3-3747-40f7-a4b5-f36d6801af5f
diff --git a/OvaleBestAction.lua b/OvaleBestAction.lua
index a21fa68..c6cbc09 100644
--- a/OvaleBestAction.lua
+++ b/OvaleBestAction.lua
@@ -24,6 +24,7 @@ local OvaleStance = Ovale.OvaleStance
local OvaleState = Ovale.OvaleState
local OvaleTimeSpan = Ovale.OvaleTimeSpan
+local abs = math.abs
local floor = math.floor
local ipairs = ipairs
local loadstring = loadstring
@@ -208,51 +209,50 @@ local function ComputeArithmetic(element, atTime)
if element.operator == "+" then
--[[
- A(t) = A(t0) + (t - t0)*c
- B(t) = B(t0) + (t - t0)*z
+ A(t) = A(t0) + (t - t0)*c = A + (t - t0)*c
+ B(t) = B(t0) + (t - t0)*z = B + (t - t0)*z
- A(t) + B(t) = [A(t0) + B(t0)] + (t - t0)*(c + z)
+ A(t) + B(t) = (A + B) + (t - t0)*(c + z)
--]]
l = A + B
m = atTime
n = c + z
elseif element.operator == "-" then
--[[
- A(t) = A(t0) + (t - t0)*c
- B(t) = B(t0) + (t - t0)*z
+ A(t) = A(t0) + (t - t0)*c = A + (t - t0)*c
+ B(t) = B(t0) + (t - t0)*z = B + (t - t0)*z
- A(t) - B(t) = [A(t0) - B(t0)] + (t - t0)*(c - z)
+ A(t) - B(t) = (A - B) + (t - t0)*(c - z)
--]]
l = A - B
m = atTime
n = c - z
elseif element.operator == "*" then
--[[
- A(t) = A(t0) + (t - t0)*c
- B(t) = B(t0) + (t - t0)*z
+ A(t) = A(t0) + (t - t0)*c = A + (t - t0)*c
+ B(t) = B(t0) + (t - t0)*z = B + (t - t0)*z
+ A(t)*B(t) = A*B + (t - t0)*[A*z + B*c] + [(t - t0)^2]*(c*z)
+ = A*B + (t - t0)*[A*z + B*c] + O(t^2) converges everywhere.
--]]
- if c == 0 then
- l = A * B
+ l = A*B
m = atTime
- n = A * z
- elseif z == 0 then
- l = A * B
- m = atTime
- n = c * B
- else
- Ovale:Error("at least one value must be constant when multiplying")
- return nil
- end
+ n = A*z + B*c
elseif element.operator == "/" then
--[[
- A(t) = A(t0) + (t - t0)*c
- A(t)/B(t0) = [A(t0)/B(t0)] + (t - t0)*[c / B(t0)]
-
- Divide by B(t0) instead of B(t) to allow constructs like {target.Health() / target.TimeToDie()}.
+ A(t) = A(t0) + (t - t0)*c = A + (t - t0)*c
+ B(t) = B(t0) + (t - t0)*z = B + (t - t0)*z
+ A(t)/B(t) = A/B + (t - t0)*[(B*c - A*z)/B^2] + O(t^2) converges when |t - t0| < |B/z|.
--]]
- l = A / B
+ l = A/B
m = atTime
- n = c / B
+ n = (B*c - A*z)/(B^2)
+ local bound
+ if z == 0 then
+ bound = math.huge
+ else
+ bound = abs(B/z)
+ end
+ startA, endA = Intersect(startA, endA, atTime - bound, atTime + bound)
elseif element.operator == "%" then
if c == 0 and z == 0 then
l = A % B