1. a simple fuzzy.e
- Posted by jbrown105 at speedymail.org Apr 11, 2002
- 333 views
Here's a simple fuzzy.e which may be useful. You can make fuzzy() act as =, <, >, !=, >=, or <=, depending on the operation you tell it to do. fuzzy_compare() acts just like compare(), except that it will do fuzzy comparisons. jbrown --CUT HERE-- with trace -- fuzzy.e -- function for fuzzy comparisions -- sorry, very little testing --define the ops global constant OP_EQ = 1, OP_NEQ = 2, OP_GR = 3, OP_LS = 4, OP_GE = 5, OP_LE = 6 --heres the range which numbers are considered equal - must be a pos value global atom fuzzy_diff fuzzy_diff = 0.0000001 --fuzzy for atoms global function fuzzy_atom(atom a1, integer op, atom a2) atom diff diff = fuzzy_diff if 0 then elsif op = OP_EQ then --original algorithem --if the difference in the numbers is between diff and -diff --(with 0 being the most ideal) they can be conidered equal return ((a1-a2) < diff) and ((a1-a2) > -diff) elsif op = OP_NEQ then --simply perform logical not on equal test return not fuzzy_atom(a1, OP_EQ, a2) elsif op = OP_GR then if fuzzy_atom(a1, OP_EQ, a2) then --make sure that they're not equal first! return 0 end if --if a1 is more, diff is positive return (a1-a2) > 0 elsif op = OP_LS then if fuzzy_atom(a1, OP_EQ, a2) then --make sure that they're not equal first! return 0 end if --if a1 is less, diff is negative return (a1-a2) < 0 elsif op = OP_GE then if fuzzy_atom(a1, OP_EQ, a2) then --test for equalness first return 1 end if --test a1 > a2 return fuzzy_atom(a1, OP_GR, a2) elsif op = OP_LE then if fuzzy_atom(a1, OP_EQ, a2) then --test for equalness first return 1 end if --test a1 < a2 return fuzzy_atom(a1, OP_LS, a2) end if end function --main fuzzy function global function fuzzy(object a1, integer op, object a2) if atom(a1) and atom(a2) then return fuzzy_atom(a1, op, a2) elsif atom(a1) or atom(a2) then --abort ? a1 = a2 end if if length(a1) != length(a2) then --abort ? a1 = a2 end if for i = 1 to length(a1) do a1[i] = fuzzy(a1[i], op, a2[i]) end for return a1 end function --fuzzy version of compare global function fuzzy_compare(object a1, object a2) integer r integer l, g sequence a if atom(a1) and atom(a2) then if fuzzy_atom(a1, OP_EQ, a2) then return 0 elsif fuzzy_atom(a1, OP_GR, a2) then return 1 else --fuzzy_atom(a1, OP_LS, a2) - must be this, no need to check return -1 end if elsif atom(a1) or atom(a2) then --sequence always larger than atom --its safe to use compare here return compare(a1, a2) end if --get the size of the smaller sequence - can't compare beyond there if length(a1) > length(a2) then r = length(a2) else r = length(a1) end if a = repeat(0, r) for i = 1 to r do a[i] = fuzzy_compare(a1[i], a2[i]) end for g = find(1, a) l = find(-1, a) if g = 0 and l = 0 then if length(a1) = length(a2) then return 0 elsif length(a1) > length(a2) then return 1 else --length(a1) < length(a2) - no need to check return -1 end if elsif g = 0 then return 1 elsif l = 0 then return -1 else if g > l then --greater comparision was first return 1 else --greater comparision was not first return 0 end if end if end function --a simple test atom az az = 0 for i = 1 to 10 do az += .1 --az ~= 1 end for --compare eu compare op with fuzzy() ? {az} = {1} ? fuzzy({az}, OP_EQ, {1}) --compare eu compare() with fuzzy_compare() ? compare({az}, {1}) = 0 ? fuzzy_compare({az}, {1}) = 0 --CUT HERE--