# Generic method to calcuate Euclidean Distance using expressions

c# expression expression-trees linq ### Question

I'd like a method that can calculate the Euclidean distance using expressions and order an IQueryable:

sqrt[(q1 - p1)^2 + (q2 - p2)^2 + ... + (qn - pn)^2]

This is the method signature I've come up with:

``````public static IOrderedQueryable<T> EuclideanDistanceOrder<T>(
this IQueryable<T> query, IEnumerable<Expression<Func<T, double>>> expressions)
{
var orderedQuery = query.OrderBy(i => Math.Sqrt(expressions.Aggregate((total, item) => total + Math.Pow(item, 2))));
return orderedQuery;
}
``````

I'm not sure what to do with `item` and `total` (since they are `Expression<Func<T, double>>`). I've tried this a few different ways, including using `Expression.Power` and `Expression.Add`. I've tried defining the expressions to be composed separately:

``````Expression<Func<double, double>> power = i => Math.Pow(i, 2);
Expression<Func<List<Expression<Func<T, double>>>, double>> dist = (items) => Math.Sqrt(items.Sum(power));
``````

But I still don't know what to do with `power`.

Can I get some help? Is there a better way to approach this?

To get it working with EF or LinqToSQL you would have to pass all information as Expressions even property accessors for P and Q. So that is why I have modified your method declaration:

``````public static class Extension
{
public static IOrderedQueryable<T> EuclideanDistanceOrder<T>(
this IQueryable<T> query,
IEnumerable<Expression<Func<T, double>>> pExpressions,
IEnumerable<Expression<Func<T, double>>> qExpressions)
{
var parameter = Expression.Parameter(typeof(T));
var pBodies = pExpressions
.Select(x => ReplaceParameter(x.Body, parameter))
.ToArray();

var qBodies = qExpressions
.Select(x => ReplaceParameter(x.Body, parameter))
.ToArray();

var distances = pBodies
.Select((x, i) => CreateDistance(x, qBodies[i]))
.ToArray();

var squers = distances
.Select(x => CreateSquerExpression(x))
.ToArray();

var sum = squers.First();
for (int i = 1; i < squers.Count(); i++)
{
sum = Expression.Add(sum, squers[i]);
}
var funcExpression = Expression.Lambda<Func<T, double>>(sum, parameter);
//the sqrt is irrelevant to order of this sequence
return query.OrderBy(funcExpression);
}

private static Expression CreateDistance(Expression p, Expression q)
{
return Expression.Subtract(q, p);
}

private static Expression CreateSquerExpression(Expression x)
{
var method = typeof(Math).GetMethod("Pow", BindingFlags.Static | BindingFlags.Public);
return Expression.Call(method, x, Expression.Constant(2.0));
}

private static Expression ReplaceParameter(Expression expression, ParameterExpression parameter)
{
var unaryExpression = expression as UnaryExpression;
MemberExpression memberExpression;
if (unaryExpression != null)
{
memberExpression = unaryExpression.Operand as MemberExpression;
}
else
{
memberExpression = expression as MemberExpression;
}

if (memberExpression == null)
throw new NotImplementedException();

if (!(memberExpression.Expression is ParameterExpression) || !(memberExpression.Member is PropertyInfo))
throw new NotImplementedException();

return Expression.Property(parameter, (PropertyInfo)memberExpression.Member);
}
}
``````

While invoking like this:

``````    var list = new[]{ new Item
{
P1 = 0,
Q1 = 0,
P2 = 3,
Q2 = 1,
},
new Item
{
P1 = 0,
Q1 = 0,
P2 = 2,
Q2 = 1,
}
};

var query = list.AsQueryable();

var result = query.EuclideanDistanceOrder(new Expression<Func<Item, double>>[]{
x => x.P1,
x => x.P2
},
new Expression<Func<Item, double>>[]{
x => x.Q1,
x => x.Q2
}).ToArray();

internal class Item
{
public double P1 { get; set; }
public double Q1 { get; set; }
public double P2 { get; set; }
public double Q2 { get; set; }
}
``````

It works for liq to objects. I'm only not sure if EF or linqtoSql will map `Math.Power` method to sql. If not it is easy enough to change to multiplication.

Prime Library

More Projects...