Векторизация операторов в C #

2

Я потратил большую часть своего времени на программирование в 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

У меня закончились идеи. Можете ли вы придумать что-нибудь, что сработает?

  • 1
    Есть много библиотек шаблонов, в первую очередь для графики, связанных с векторной и матричной алгеброй, вы можете посмотреть в этом направлении. Обычно они также используют перегрузку операторов, что делает его более читабельным.
Теги:
arrays
operators

4 ответа

2
Лучший ответ

Вероятно, вы должны создать класс 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();
  • 0
    Приветствия. Я только недавно перешел на использование 3.5 Framework и откладывал изучение LINQ. Я думаю, это моя причина, чтобы пойти на это. Быстрый вопрос: откуда взялся метод Zip?
  • 0
    Zip доступен либо с библиотекой MoreLINQ (см. URL), либо с .NET 4.0. Это самый простой способ объединить две последовательности. MoreLINQ: code.google.com/p/morelinq
4

Создайте векторный класс (на самом деле я сделаю его структурой) и перегружаю арифметические операторы для этого класса... Это, вероятно, уже было сделано, если вы выполняете поиск в Google, есть многочисленные хиты... Здесь один что выглядит перспективным Векторный класс...

Чтобы обрабатывать векторы произвольной размерности, я бы:

  • создайте внутренний массив, который будет сохранять отдельные поплавки для каждого из векторы размерных значений список массивов произвольного размера,
  • заставить конструктор Vector принимать размерность как параметр конструктора,
  • В арифметических перегрузках оператора добавьте проверку того, что два вектора, которые добавляются или вычитаются, имеют одинаковую размерность.
  • 0
    Спасибо, но не нужно ли мне создавать множество производных классов (DoubleVector, IntVector, BoolVector и т. Д.), Поскольку объект + объект не работают.
  • 0
    Общий Vector <T> тогда?
Показать ещё 1 комментарий
1

Взгляните на CSML. Это довольно полная матричная библиотека для С#. Я использовал его для нескольких вещей, и он работает хорошо.

  • 0
    Это кажется довольно полезным. Он решает проблему работы с различными типами, сохраняя все как ArrayList из ArrayLists со «сложными» значениями (фактически, парой двойников).
0

XNA Framework имеет классы, которые вы можете использовать. Вы можете использовать его в своем приложении, как и любую другую часть .NET. Просто захватите XNA, распространяемый и код прочь.

Кстати, вам не нужно делать что-либо особенное (например, получить студию игры или присоединиться к клубу создателя), чтобы использовать ее в своем приложении.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню