Структури даних для кінцевого томового коду: масиви проти класів


11

Я маю написати код обмеженого обсягу для магнітогідродинаміки (MHD). Я раніше писав числовий код, але не в цій шкалі. Я просто хотів запитати, який буде вдалий вибір, використовуючи структуру даних (орієнтований на об’єктний підхід) з класами або просто використовуючи декілька масивів для різних властивостей, з точки зору швидкості, масштабованості тощо. Я планую записати код у python та використовувати фортран для числово інтенсивної частини.

Прикладом для класу в python буде

class Cell:
   def __init__(self, x, y, z, U):

Масиви можна просто визначити як

x[nx][ny][nz]
y[nx][ny][nz]
z[nx][ny][nz]
U[nx][ny][nz]

тощо.

Відповіді:


9

Проста відповідь: у сучасному python кожен тип даних є класом, тому формально немає різниці між двома запропонованими вами рішеннями. (Будь ласка, не забудьте використовувати класи нового стилю: класичні класи застаріли! Див. Http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes )

Тепер слід запитати: як я можу організувати ефективну структуру даних у python? Немає сумнівів, що сама ідея організації комірок як масиву class Cellекземплярів є занадто неефективною. У вас з’явиться безлад вказівників та непостійних даних, організованих як складний зв’язаний список. Звичайно, ви маєте можливість легко вставляти нові клітинки у свій список: але чи потрібна вам ця функція? Навпаки, у вас буде безперервне зберігання даних, і вам доведеться отримувати доступ до кожної комірки різними рівнями непрямості.

Якщо ви впорядковуєте свої дані як numpy.ndarrayтоді, дані зберігаються в пам'яті безперервно, а доступ до різних комірок здійснюється просто крокуючи через ваш блок пам'яті: обсяг простору (не витрачається пам'ять на покажчики) та швидкий .

Як вказував Етан, слід використовувати концепції OO, але на більш високому рівні, як тільки буде впроваджена ефективна структура даних низького рівня, як правило, через numpy.ndarray"s".

Програмування ОО означає прив'язку даних до методів, які працюють над самими даними на більш високому рівні абстракції. (Приклад: я реалізував FEM-код, у якому матриця жорсткості була визначена як клас із методом розрідженої надвузлової факторизації холески. Перша реалізація була по суті: коли потрібна була позаязова реалізація, це було отримано шляхом успадкування та мінімальних коригувань підкреслюваного сховища даних. Майже 100% надвузлового холеського коду було повторно використане.)

Останній коментар, але важливий: ефективна числова процедура є результатом розумного відображення алгоритму та структури даних до вашої цільової архітектури обчислень. Якщо ви почнете з неправильної структури даних , без повного перезапису неможливо відновити ефективність.


@EthanCoon Дякую за Ваш коментар до іншої відповіді, що змусив мене написати свою.
Стефано М

10

Я розмірковував над цим кілька днів тому (також у Python). Особисто я не думаю, що об'єктно-орієнтоване програмування завжди добре підходить для чисельного програмування. Ви можете відволікатися на розробку класів, а не просто на розв’язування рівнянь. Я вважаю за краще залишатися з простими функціями, і з numpy ви можете мати свої рівняння векторизованими, тому кількість потрібних рядків дуже мала. Numpy досить швидкий, оскільки фактичні обчислення робляться із заднім кінцем C (або FORTRAN?).

Що б я рекомендував вам зробити,

  1. Напишіть сценарій Python, який вирішує найпростішу можливу версію вашої проблеми, використовуючи функціональний підхід з numpy. Наприклад, мати все у довільній одиниці та спробувати лише 1D (або 2D). На цьому етапі це прекрасно, якщо код безладний. Важливим є те, що ви рухаєтеся вперед зі своїм проектом.
  2. Як тільки у вас є щось, що працює. Визначте, де в коді є багатослівний та рефрактор. На цьому етапі ви можете пограти з різними ідеями, як спростити код. Можливо, введіть функції там, де помітите, що ви повторюєтесь. Ви можете порівняти з оригінальною версією, щоб ви знали, що ви не вводите помилок.
  3. Вирішіть, чи об’єктно-орієнтований підхід ще більше знизить складність коду.

Головне повідомлення - не починайте писати заняття, поки ви вже не вирішили проблему найпростішим можливим способом. Лише отримавши досвід вирішення проблеми, ви зможете визначити свій об'єктно-орієнтований інтерфейс. Якщо ви зробите це перед рукою, швидше за все, це просто перешкодить.


3
Я категорично не погоджуюся з твердженням, що ОО не дуже підходить для чисельного програмування, але там, де воно добре підходить, знаходиться на набагато вищому рівні. OO дуже корисний для таких речей, як фізичні моделі, сітки, розв'язувачі тощо, але майже завжди є недоцільним на рівні клітин.
Етан Кун

У своєму дописі я хотів попередити про можливі падіння ями про "передчасне об'єктивування" числового коду, особливо коли він починається. Я не загрожую використанню об’єктів, дивіться третій пункт: якщо об’єкти можуть зменшити складність, то вони є гарною ідеєю. Я згоден, що приклади, які ви цитуєте, корисні, але для досягнення цього потрібен досвід.
boyfarrell
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.