Thread Tools Display Modes
11-24-13, 12:47 PM   #1
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Need help with a math function

Hi,

I need to compare a number with a list of numbers and work out which one of the numbers in the list is closest to the one I want to compare. If there are two numbers that have the same amount of difference then pick the higher number. All numbers in this list will be unique.

Is there a function that can help me? I need recommendations on what to use or some help as I'm not brilliant with programming.

Basically I have this:
currentIndex = GetCurrentResolution()

and I need to compare the currentIndex with a list of numbers {7, 11, 12, 13, 15, 16}

Thank you for reading!
  Reply With Quote
11-24-13, 01:24 PM   #2
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Why do you exactly need this?
  Reply With Quote
11-24-13, 01:30 PM   #3
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Looks pretty straightforward algorithm to me... go over the list, compare the numbers, save the best fit
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
11-24-13, 01:31 PM   #4
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Originally Posted by Resike View Post
Why do you exactly need this?
So that it finds your current resolution and sees whether it is in the list of resolutions that the UI supports and if not then it picks the closest resolution to yours and sets the UI up accordingly. So that it may only need slightly adjusting.
  Reply With Quote
11-24-13, 01:32 PM   #5
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Lua Code:
  1. local math = math
  2.  
  3. local x = 14
  4. local y = {7, 11, 12, 13, 15, 16}
  5.  
  6. function ReturnStuff(n, t)
  7.     local closest = t[#t]
  8.     local closestId
  9.     for i = 1, #t do
  10.         if closest >= math.abs(t[i] - n) then
  11.             closest = math.abs(t[i] - n)
  12.             closestId = i
  13.         end
  14.     end
  15.     return t[closestId]
  16. end
  17.  
  18. print(ReturnStuff(x, y))

Edit: Try this.

Last edited by Resike : 11-25-13 at 07:47 AM.
  Reply With Quote
11-24-13, 01:33 PM   #6
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Originally Posted by Malsomnus View Post
Looks pretty straightforward algorithm to me... go over the list, compare the numbers, save the best fit
Is there some sort of function I could use to see if one number is closer to a number than another number?
Probably does not help that I have a massive head ache at the moment lol

EDIT: Thank you Resike! I will try using that

EDIT2: No that does not work Resike. Will look into another solution

Last edited by Mayron : 11-24-13 at 01:50 PM.
  Reply With Quote
11-24-13, 01:57 PM   #7
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
If this were me, I would just put the resolutions in a dropdown menu.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
11-24-13, 02:08 PM   #8
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Originally Posted by Seerah View Post
If this were me, I would just put the resolutions in a dropdown menu.
Well sadly I'm not you. I'm not that advanced with Lua yet haha. Otherwise yes that would solve everything but the way my addon works. Not sure how I would add a drop down box onto the artwork.
  Reply With Quote
11-24-13, 02:22 PM   #9
Mayron
A Frostmaul Preserver
 
Mayron's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2010
Posts: 275
Originally Posted by Resike View Post
Lua Code:
  1. --Code

Edit: Try this.
Thank you very much for your work! That works perfectly Really appreciate your help!
  Reply With Quote
11-24-13, 05:40 PM   #10
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Mayron View Post
Thank you very much for your work! That works perfectly Really appreciate your help!
Actually that code has errors in it. Other than the obvious, it assumes that the array you are passing in is sorted which was never a stated condition. This will fix the errors as well as that assumption:
Code:
local math_abs = math.abs

local resArray = { 7, 11, 12, 13, 15, 16 }
local resIndex = GetCurrentResolution()

local function GetClosestNumber(num, array)
    local id = 1
    local closest = math_abs(array[id] - num)
    for index = 2, #array do
        local delta = math_abs(array[index] - num)
        if delta < closest or (closest == delta and array[index] > array[id]) then
            closest, id = delta, index
        end
    end
    return array[id]
end

print(GetClosestNumber(resIndex, resArray))
If the array will always be pre-sorted then this is what you want:
Code:
local function GetClosestMatch(num, array)
    local id = 1
    local closest = math_abs(array[id] - num)
    for index = 2, #array do
        local delta = math_abs(array[index] - num)
        if delta < closest then
            closest, id = delta, index
        elseif delta == 0 or closest == delta then
            id = index
            break
        else
            break
        end
    end
    return array[id]
end

Last edited by Vrul : 11-25-13 at 09:05 AM. Reason: Fixed an error
  Reply With Quote
11-24-13, 08:12 PM   #11
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Originally Posted by Vrul View Post
Actually that code has errors in it. Other than the obvious, it assumes that the array you are passing in is sorted which was never a stated condition.
Can you explain this? Because I don't see it. All I see is some references to table which should be t.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
11-24-13, 10:27 PM   #12
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Lombra View Post
Can you explain this? Because I don't see it. All I see is some references to table which should be t.
As you pointed out there are a few references to table that should be t. The references to x in the function should be resolutionId, or resolutionId in the function definition should be changed to x. And like I stated it makes an assumption that was not stated as a known fact about the input. Going on that assumption though, the code makes an unnecessary extra for iteration (worst case) and has no early out (not worst case). It also makes a local reference to math while only using it to call math.abs instead of just making math.abs the local reference. The last two aren't errors, just pointing it out for those trying to learn.
  Reply With Quote
11-25-13, 04:22 AM   #13
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
As you pointed out there are a few references to table that should be t. The references to x in the function should be resolutionId, or resolutionId in the function definition should be changed to x. And like I stated it makes an assumption that was not stated as a known fact about the input. Going on that assumption though, the code makes an unnecessary extra for iteration (worst case) and has no early out (not worst case). It also makes a local reference to math while only using it to call math.abs instead of just making math.abs the local reference. The last two aren't errors, just pointing it out for those trying to learn.
Well i assumed it's sorted, since the resoultion dropdown seems sorted, but yeah presorting the table, or your method would be better. However i still think my code is faster, despite the math calls and the extra for iterate, since you store an unneseccary delta variable inside the for loop which is more expensive.

Anyway something seems to be wrong with your functions because none of them is returning the right values.

Last edited by Resike : 11-25-13 at 07:16 AM.
  Reply With Quote
11-25-13, 04:43 AM   #14
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Resike View Post
... i still think my code is faster, despite the math calls and the extra for iterate, since you store an unneseccary delta variable inside the for loop which is more expensive.
wat?

Assigning a value to a variable N times is not more expensive than calling a function N extra times. The value is already taking up space in memory just by existing. Assigning it to a variable there costs basically nothing, whereas calling the same function to get the same value again is a complete waste of CPU time...
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
11-25-13, 07:20 AM   #15
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Mayron View Post
Well sadly I'm not you. I'm not that advanced with Lua yet haha. Otherwise yes that would solve everything but the way my addon works. Not sure how I would add a drop down box onto the artwork.
If you want to use that version then:

Lua Code:
  1. print(UIDropDownMenu_GetSelectedID(Graphics_ResolutionDropDown))
  Reply With Quote
11-25-13, 09:22 AM   #16
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Resike View Post
Anyway something seems to be wrong with your functions because none of them is returning the right values.
Yep, I forgot to change id to index when I copy-pasted math_abs(array[id] - num) from a couple lines up, it is fixed now.

Luckily Phanx already corrected you on the latest misinformation, but please quit making stuff up and posting it as fact. I'm not trying to be a bad guy here, you posting that stuff could really mislead someone trying to learn this stuff.
  Reply With Quote
11-25-13, 09:59 AM   #17
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
Originally Posted by Vrul View Post
Yep, I forgot to change id to index when I copy-pasted math_abs(array[id] - num) from a couple lines up, it is fixed now.

Luckily Phanx already corrected you on the latest misinformation, but please quit making stuff up and posting it as fact. I'm not trying to be a bad guy here, you posting that stuff could really mislead someone trying to learn this stuff.
Sorry, my bad.
  Reply With Quote
11-25-13, 08:29 PM   #18
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
I meant the bit about the assumption that the array is sorted. I don't see anything here that the sorting of the array would have any impact on:
Lua Code:
  1. local math = math
  2.  
  3. local x = 14
  4. local y = {7, 11, 12, 13, 15, 16}
  5.  
  6. function ReturnStuff(n, t)
  7.     local closest = t[#t]
  8.     local closestId
  9.     for i = 1, #t do
  10.         if closest >= math.abs(t[i] - n) then
  11.             closest = math.abs(t[i] - n)
  12.             closestId = i
  13.         end
  14.     end
  15.     return t[closestId]
  16. end
  17.  
  18. print(ReturnStuff(x, y))
This is the snippet you were commenting, yes? Pretty sure that's how it looked when I first posted bar the table -> t.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
11-25-13, 08:58 PM   #19
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
Originally Posted by Lombra View Post
I meant the bit about the assumption that the array is sorted. I don't see anything here that the sorting of the array would have any impact on:
Reverse the sample array and you will get 13 instead of 15, which is not the desired stated behavior.

Originally Posted by Lombra View Post
This is the snippet you were commenting, yes? Pretty sure that's how it looked when I first posted bar the table -> t.
The n was instead the variable x from outside the function, making the passed value to search for be ignored. Sure the code as posted worked but taking the function, the whole point of this thread, and pasting it into another addon would not work as intended.
  Reply With Quote
11-26-13, 07:58 AM   #20
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
Ok, I missed the bit about needing to default to the higher value if equal.
__________________
Grab your sword and fight the Horde!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Need help with a math function


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off