Атрибути та методи

Огляд

Викладання: 40 хв
Вправи: 10 хв
Питання
  • Як записати інформацію в об’єкти GAP

Цілі
  • Оголошення атрибута

  • Встановлення методу

  • Розуміння вибору методу

  • Використання інструментів для налагодження

Яка функція швидше?

Спробуйте неодноразово обчислити AvgOrdOfGroup(M11) та AvgOrdOfCollection(M11) і порівняти час виконання. Зробіть це для нової копії M11 і для тієї, для якої цей параметр уже спостерігався. Що ви спостерігаєте?

Звичайно, для будь-якої даної групи середній порядок її елементів потрібно обчислити лише один раз, оскільки наступного разу він поверне те саме значення. Однак, як ми бачимо з часу виконання нижче, кожен новий виклик AvgOrdOfGroup повторюватиме те саме обчислення знову, дещо змінюючи час виконання:

A:=AlternatingGroup(10);
Alt( [ 1 .. 10 ] )
AvgOrdOfCollection(A); time; AvgOrdOfCollection(A); time;
2587393/259200
8226
2587393/259200
8118

В останньому прикладі група, про яку йде мова, була такою самою – ми не створили іншу копію AlternatingGroup(10); однак результат обчислення не було збережено в A.

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

G:=Group([ (1,2,3,4,5,6,7,8,9,10,11), (3,7,11,8)(4,10,5,6) ]);
gap> NrConjugacyClasses(G);time;NrConjugacyClasses(G);time;
Group([ (1,2,3,4,5,6,7,8,9,10,11), (3,7,11,8)(4,10,5,6) ])
10
39
10
0

У цьому випадку група G має 10 класів спряженості, і знадобилося 39 мс, щоб встановити це під час першого виклику. Другий виклик має нульову вартість, оскільки результат було збережено в G, і тому, що NrConjugacyClasses є атрибутом:

NrConjugacyClasses;
<Attribute "NrConjugacyClasses">

Зараз наша мета — навчитися створювати власні атрибути.

Оскільки у нас вже є функція AvgOrdOfCollection, яка виконує обчислення, найпростішим способом перетворити її на атрибут є наступний:

AverageOrder := NewAttribute("AverageOrder", IsCollection);
InstallMethod( AverageOrder, "for a collection", [IsCollection], AvgOrdOfCollection);

У цьому прикладі спочатку ми оголосили атрибут AverageOrder для об’єктів у категорії IsCollection, а потім встановили функцію AvgOrdOfCollection як метод для цього атрибута. Instead of calling the function AvgOrdOfCollection, we may now call AverageOrder.

Тепер ми можемо перевірити, що наступні виклики AverageOrder з тим самим аргументом виконуються без витрат часу. У цьому прикладі час скорочено з більш ніж 16 секунд до нуля:

S:=SymmetricGroup(10);; AverageOrder(S); time; AverageOrder(S); time;
39020911/3628800
16445
39020911/3628800
0

Ви можете запитати, чому ми оголосили операцію для колекції, а не лише для групи, і чому ми встановили неефективний AvgOrdOfCollection. Зрештою, ми вже розробили набагато ефективнішу функцію AvgOrdOfGroup.

Уявіть, що Ви хочете мати можливість обчислити середній порядок як для групи, так і для списку, який складається з об’єктів, що мають мультиплікативний порядок. Ви можете мати спеціальну функцію для кожного випадку, як у нас. Якщо може трапитися так, що Ви не знаєте наперед тип об’єкта, про який йде мова, Ви можете додати перевірки в код і відправити до відповідної функції. Це може швидко стати складним, якщо у вас є кілька різних функцій для різних типів об’єктів. Натомість атрибути — це групи функцій, які називаються method, а вибір методу в GAP вибере найефективніший метод на основі типу всіх аргументів.

Щоб проілюструвати це, зараз ми встановимо метод для AverageOrder для групи:

InstallMethod( AverageOrder, [IsGroup], AvgOrdOfGroup);

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

S:=SymmetricGroup(10);; AverageOrder(S); time; AverageOrder(S); time;
39020911/3628800
26
39020911/3628800
0

Який метод викликається

  • Спробуйте викликати AverageOrder для колекції, яка не є групою (список елементів групи та/або клас спряжених елементів групи).

  • Інструменти налагодження, такі як TraceMethods, можуть допомогти вам побачити, який метод викликається.

  • ApplicableMethod у поєднанні з PageSource може вказати вам на вихідний код із усіма коментарями.

A property is атрибут із логічним значенням. Його можна створити, використовуючи NewProperty

IsIntegerAverageOrder := NewProperty("IsIntegerAverageOrder", IsCollection);

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

InstallMethod( IsIntegerAverageOrder,
  "for a collection",
  [IsCollection],
  coll -> IsInt( AverageOrder( coll ) )
);

Зауважте, що оскільки AverageOrder є атрибутом, він подбає про вибір найбільш прийнятного методу.

Чи завжди такий метод існує?

Ні. “No-method-found” є особливим видом помилки, і існують інструменти для дослідження таких помилок: див. ?ShowArguments, ?ShowDetails, ?ShowMethods та ?ShowOtherMethods.

Наступні обчислення показують, що, незважаючи на наш успіх з обчисленням середнього порядку для великих груп перестановок через класи спряженості елементів, для pc груп із бібліотеки Small Groups Library можна було б швидше перебирати їх елементи, ніж обчислювати класи спряженості::

l:=List([1..1000],i->SmallGroup(1536,i));; List(l,AvgOrdOfGroup);;time;
56231
l:=List([1..1000],i->SmallGroup(1536,i));; List(l,AvgOrdOfCollection);;time;
9141

Не панікувати!

  • Установіть метод для IsPcGroup, який повторює елементи групи замість обчислень її класів спряженості.

  • Оцініть практичні межі його можливості. Чи можете ви знайти приклад pc групи, де ітерація повільніша, ніж обчислення класів спряженості?

Ключові моменти

  • Позиційні об’єкти можуть накопичувати інформацію про себе протягом життя.

  • Це означає, що наступного разу збережену інформацію можна буде відновити без жодних витрат.

  • Методи — це групи функцій; Вибір методів GAP вибере найефективніший метод на основі типу всіх аргументів.

  • ‘Метод не знайдено’ — це особливий вид помилки з корисними інструментами налагодження, які допомагають її зрозуміти.