Атрибути та методи
Огляд
Викладання: 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 вибере найефективніший метод на основі типу всіх аргументів.
‘Метод не знайдено’ — це особливий вид помилки з корисними інструментами налагодження, які допомагають її зрозуміти.