Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

postgresql create function Euclidean distance n dimensions

Tags:

postgresql

I am noob in postgresql and I am trying to create a function to calculate the distances between a specific value and a set of values(records). Here is the table:

CREATE TABLE test
(
  id serial NOT NULL,
  name text,
  values real[]
)   

I want to create a function but I can't figure out how to loop every element in values[]

For example, I would like to select the name with the smallest distance. I didn't find any built-in function for this purpose.

I wrote the code in c# of what I am looking for:

List<double> res = new List<double>();
List<double[]> listDataBase=new List<double[]>();
double[] query = new double[] {12, 13, 13, 121};

double[] b = new double[] { 121, 1, 12, 124 };
double[] c = new double[] { 123, 123, 15, 122 };
double[] d = new double[] { 121, 1, 12, 124 };
double[] e = new double[] { 123, 123, 15, 122 };
listDataBase.Add(b);
listDataBase.Add(c);
listDataBase.Add(d);
listDataBase.Add(e);
foreach (double[] k  in listDataBase)
{
    double sum = 0;
    for (int i = 0; i < query.Length; i++)
    {
        sum += Math.Pow(query[i] - k[i], 2);
    }
    res.Add(Math.Sqrt(sum));
}

res.Sort();
like image 645
topo Avatar asked Oct 18 '22 20:10

topo


1 Answers

First I would change the name of the column you called values to vals. values is a keyword ofcourse you can write "values" in your queries but I would prefer to circumvent that issue by changing the name.

If I understand your question correctly I think it would be enough in your case to create a distance function then use that in a query. Here is the function:

CREATE OR REPLACE FUNCTION distance(l real[], r real[]) RETURNS real AS $$
DECLARE
  s real;
BEGIN
  s := 0;
  FOR i IN 1..4 LOOP
    s := s + ((l[i] - r[i]) * (l[i] - r[i]));
  END LOOP;
  RETURN |/ s;
END;
$$ LANGUAGE plpgsql;

If you want the name of the closest the query is:

SELECT name
FROM test
ORDER BY distance(test.values, ARRAY[12, 13, 13, 121]) DESC
LIMIT 1
like image 69
Eelke Avatar answered Nov 15 '22 06:11

Eelke