Я потратил большую часть своего времени на программирование в R или MATLAB. Эти языки обычно используются для управления массивами и матрицами, и, следовательно, они имеют векторизованные операторы для сложения, равенства и т.д.
Например, в MATLAB добавление двух массивов
[1.2 3.4 5.6] + [9.87 6.54 3.21]
возвращает массив того же размера
ans =
11.07 9.94 8.81
Переходя к С#, нам нужен цикл, и он чувствует себя как много кода.
double[] a = { 1.2, 3.4, 5.6 };
double[] b = { 9.87, 6.54, 3.21 };
double[] sum = new double[a.Length];
for (int i = 0; i < a.Length; ++i)
{
sum[i] = a[i] + b[i];
}
Как мне реализовать векторные операторы с использованием С#? Они должны предпочтительно работать для всех типов числовых массивов (и bool[]
). Работа для многомерных массивов - это бонус.
Первой идеей я должен был перегрузить операторы для System.Double[]
и т.д. напрямую. Однако у этого есть ряд проблем. Во-первых, это может вызвать проблемы с путаницей и ремонтопригодностью, если встроенные классы не bahave, как ожидалось. Во-вторых, я не уверен, возможно ли изменить поведение этих встроенных классов.
Итак, моя следующая идея заключалась в том, чтобы вывести класс из каждого численного типа и перегрузить там операторы. Это создает трудности с преобразованием с double[]
в MyDoubleArray
и обратно, что уменьшает выгоду от того, что я делаю меньше ввода текста.
Кроме того, я действительно не хочу повторять загрузку почти одинаковой функциональности для каждого числового типа. Это приводит к моему следующему представлению об общем классе операторов. Фактически, у кого-то еще была эта идея: есть общий операторный класс в библиотеке Jon Skeet MiscUtil.
Это дает вам примерный синтаксис для префикса для операций, например
double sum = Operator<double>.Add(3.5, -2.44); // 1.06
Проблема в том, что, поскольку типы массивов не поддерживают добавление, вы не можете просто сделать что-то вроде
double[] sum = Operator<double[]>.Add(a, b); // Throws InvalidOperationException
У меня закончились идеи. Можете ли вы придумать что-нибудь, что сработает?
Вероятно, вы должны создать класс Vector, который внутренне обертывает массив и перегружает арифметические операторы. Здесь есть достойная матрица/векторный код.
Но если вам действительно нужно работать с голой решеткой по какой-то причине, вы можете использовать LINQ:
var a1 = new double[] { 0, 1, 2, 3 };
var a2 = new double[] { 10, 20, 30, 40 };
var sum = a1.Zip( a2, (x,y) => Operator<double>.Add( x, y ) ).ToArray();
Создайте векторный класс (на самом деле я сделаю его структурой) и перегружаю арифметические операторы для этого класса... Это, вероятно, уже было сделано, если вы выполняете поиск в Google, есть многочисленные хиты... Здесь один что выглядит перспективным Векторный класс...
Чтобы обрабатывать векторы произвольной размерности, я бы:
Взгляните на CSML. Это довольно полная матричная библиотека для С#. Я использовал его для нескольких вещей, и он работает хорошо.
XNA Framework имеет классы, которые вы можете использовать. Вы можете использовать его в своем приложении, как и любую другую часть .NET. Просто захватите XNA, распространяемый и код прочь.
Кстати, вам не нужно делать что-либо особенное (например, получить студию игры или присоединиться к клубу создателя), чтобы использовать ее в своем приложении.