-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix GeoPatch algorithm #264
Conversation
Requested review form @samuel-uniris @I-Archer-Zero |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good and precision is improved
lat_sign = sign(lat) | ||
lon_sign = sign(lon) | ||
lat_pos = (lat + 90) / 11.25 | ||
lon_pos = (lon + 180) / 22.5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@I-Archer-Zero
Looks like added 90,180 to avoid negative sign but look at
lat_pos
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It must be
lat_pos = (lat + 90) / 22.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi !
Dividing lat by 22.5 will have a result between 0 and 8. But we are looking for a range between 0 and 16 to get all hexadecimal possibilities (0 to F).
So we have to divide by 11.25 to get it.
I think on issue's example there is a mismatch. On the graph, latitude only have 8 parts, but on explication bellow it says that first 2 digits are on range of 0 to F so 16 parts...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@I-Archer-Zero
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Neylix (Cc @samuel-uniris)
Good observation!
lat should be divided by 22.5 and not 11.25 because we need square patches (not rectangle)
This also means that the lat/22.5 will have a result between 0 to 8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi ! Thanks for your return.
I didn't know it had to be a square, I'll update it as you requested. Also need to add 4 to result to get index from C to 3 as in your graph.
I also noticed that in issue you say that first digit is for longitude index, but I did latitude first, should I update it too ?
I'm actually out of my PC until sunday, I'll update it at this time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello !
I fixed calculation in lastest commits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest you can you >=
and <=
condition checks and fix the edge cases and also implement the algo as mentioned in #253. So, first digit and third digt can be [8,9,A,B,C,D,E,F,0,1,2,3,4,5,6,7] And second digit can be [C,D,E,F,0,1,2,3]
As precision digit being computed as per previous implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Edge case problem is till in the new Algo but I avoided it by taking that also in the range
so, earlier
defp index_patch([f_i, s_i]) when f_i > 0.5 and f_i <= 1 and s_i < -0.5 and s_i >= -1, do: '0'
and when we input (-45, x) it crashed and it shall be avoided
by using just >=
while condition check
Now
defp precision_patch(lat, lon) when lat >= 0 and lat <= 0.25 and lon >= 0 and lon <= 0.25, do: '0'
@imnik11 |
|> resolve_with_sign([lat, lon]) | ||
lon_pos = (lon + 180) / 22.5 | ||
# Adding 4 to have second digit hex value from C to 3 | ||
lat_pos = (lat + 90) / 22.5 + 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid adding 4 and adding 90, 180 was in earlier implementation so, avoid it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello !
I don't really understand your suggestion. Here is why I choose this implementation instead of the one did before :
The first calculations with adding 90 / 180 / 4 result in an index between 0 and 15 for lon_pos
one and between 4 and 11 for lat_pos
.
With these index, we can easily find the good hexadecimal value in the array of the function main_index_patch
.
The advantage of this implementation is that it takes less ressources and less execution times than the previous implementation, i.e guetting a value from an array by his index is faster than doing multiple if condition to find the good hexadecimal value.
An other advantage is that it takes less lines of code.
To be easier to read, instead of adding 4 to lat_pos
we can create a new array [C,D,E,F,0,1,2,3] and get hexadecimal value from it, but I think that using same array as for lon_pos
is better to reduce memory usage.
@samuel-uniris What is your advice about it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in term of performance pattern matching (multiple function clause) is like if/else block under the good bu is quite fast and optimized during compilation.
Accessing a random element in a list is not the same in Erlang. List are not arrays but linked list , which means to access nth element, need to scan nth before . When the list is big is not efficient.
However if the list is bounded, know and static, you can leverage tuple where access a specific element is fast.
There is different strategy for this problem.
In term of readability the pattern matching is better when you have a several if/else/case blocks.
For reusability, sure it's better to keep a main indexing/reference, but keep in mind it's function programming, so variables a immutable. So you get a new memory reference after each mutation or assignment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi ! Updated in last commit to use tuple. Using pattern matching function was not as easy to read because it needs to much function to catch all conditions.
Seems more clear now. |
Added some tests with near location cities |
@@ -40,5 +56,9 @@ defmodule ArchEthic.P2P.GeoPatchTest do | |||
assert "A1A" == GeoPatch.from_ip({15, 62, 246, 57}) | |||
assert "021" == GeoPatch.from_ip({109, 164, 214, 168}) | |||
assert "8C0" == GeoPatch.from_ip({1, 2, 3, 4}) | |||
assert "F1F" == GeoPatch.from_ip({1, 1, 1, 1}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this distance good ? I mean it's almost close
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, first digit F means that longitude is >= -22.5 and < 0, when going in positive we return to 0. i.e 0 is >= 0 and < 22.5.
So just after FFF we have 000.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok .
@imnik11 can you have a last check ?
* Update geo patch calculation and correct out of bound index * Improve tests to check near location city * Fixes #253
Description
Fixes bug on GeoPatch algorithm to match the following rules :
Fixes #253
Type of change
How Has This Been Tested?
Checklist: