Алгебра в программе Mathematica


Пример 7



Пример 7



  действительно очень близко к целому числу 1, от него оно отличается менее, чем на 8x10-13! Между прочим, когда системы компьютерной алгебры не были столь доступны, как сейчас, число еv163? доставляло немало хлопот не только студентам, но и многим вполне серьезным "дядям и тетям", недостаточно знакомым с признаками трансцендентности чисел. Некоторые шутники с вполне серьезным видом заявляли, что все говорит о том, что число е является целым, но никто этого пока не доказал, и что за доказательство обещана кругленькая сумма и т.д. А ведь чтобы прямым вычислением установить ложность этого высказывания, необходимо было провести вычисления более чем с 30 десятичными знаками! Даже вычислить его целую часть на машинах серии JBM/360 или БЭСМ-6 без ухищрений было невозможно! Конечно, на зарубежных машинах были доступны системы компьютерной алгебры, например MACSYMA на IBM/360. Однако на территории СССР доступ к таким системам имели весьма немногие. Кроме того, в советской системе образования следствием застойных явлений были ориентация на идеологические дисциплины (история КПСС, разнообразный марксизм и т.д.), отсутствие свободно выбираемых (студентом, а не деканатом!) курсов и сохранение подчиненной роли курса алгебры (всего три семестра) на уровне прошлого века. В советских университетах даже для студентов-математиков программой не было предусмотрено знакомство с современной алгеброй. О компьютерной алгебре не слышали и многие преподаватели. Поэтому на территории СССР вера в необходимость прямого вычисления с довольно большим количеством значащих цифр была не простым заблуждением обывателя, а подкреплялась советской системой образования. Поэтому именно те, кто был заинтересован в финансировании произвольноразрядной арифметики, и устраивали такие розыгрыши, предварительно тщательно выискивая потенциальных жертв. Фактически из отечественных машин для проверки гипотезы подходили только машины серии МИР. Но машина МИР-1, во входном языке (Алмир) которой была реализована произвольноразрядная арифметика, имела память объемом всего лишь 4 Кбайт, а машина МИР-2 — 8 Кбайт, причем быстродействие машины МИР-2 из-за частой сборки мусора падало подчас до 200 операций в секунду! Тем не менее благодаря встроенному языку Аналитик, в котором была реализована произвольноразрядная арифметика и элементы компьютерной алгебры, она справлялась с задачами, одна лишь постановка которых на БЭСМ-6 была весьма трудоемка, и потому очередь к этой машине стояла в десятки раз больше, чем за колбасой. А поскольку заранее никто не мог сказать, сколько времени потребуется на вычисление, спланировать его не представлялось возможным. Что же касается машины МИР-3 (особенно модели МИР-32), то фактически она была доступна только разработчикам, из числа которых и находились самые злостные шутники'! Кстати, в те годы системы компьютерной алгебры часто не могли определить, является ли заданное число алгебраическим. Начиная с версии 4 в системе Mathematica не составляет труда записать (и вычислить!) нужный предикат.
Ехр[  Pi*Sqrt[163]]sAlgebraics False
Всякая история имеет мораль, и эта не исключение: вычисляя дробную часть, не забывайте указывать нужную разрядность и, кроме того, не упускайте из виду цель, ради которой вы проводите вычисления, — подумайте, нельзя ли достичь цели более простым способом. (Мы бы, например, могли сразу спросить систему Mathematica, является ли еv163?алгебраическим числом.) Не забывайте также о том, что подчас с помощью систем компьютерной алгебры удается разрешить вопрос, который остается открытым в течение длительного времени. Впрочем, иногда достаточно вспомнить всего лишь несколько теорем.

Упражнение 3.1. Вычислите не менее k десятичных цифр числа я, начиная с n-й после десятичной точки. Можете ли вы провести вычисления, например, для n = 100 000, k = 1000? Иными словами, можете ли вы вычислить сто первую тысячу (после запятой) знаков в представлении этого числа десятичной дробью?

Решение. Вот самое простое решение, которое обычно приходит в голову неискушенному читателю. Сначала нужно вычислить п с разрядностью, которая гарантирует n + k + 1 верную цифру, например n + k + 10, а затем в полученной дроби выбрать нужные десятичные знаки. Что касается вычисления я с разрядностью хотя бы 101001, то оно для системы Mathematica никакого труда не представляет. Но вот что касается отсчитать сто тысяч знаков после запятой... Впрочем, в системе Mathematica и для этого предусмотрены нужные функции! Но если немного поразмыслить, то окажется, что решить поставленную задачу можно с помощью функции FractionalPart, "Ну, я об этом сразу догадался!" — высокомерно воскликнет искушенный читатель. Действительно, чего же можно было еще ожидать, если этот раздел посвящен функции FractionalPart? Ну разве что каких-либо трудностей при составлении программы. Но ее составить как раз совсем нетрудно.

n=100000; k=1000; m= N[FractionalPart[10^ (n-1)*Pi],k+10]

Правда, ее нужно предварительно. проверить. Это совсем просто, достаточно уменьшить значения пик, затем провести вычисления
n=1;   k=5;   m= N[FractionalPart[10^(n-1)*Pi],k+10] 0.141592653589793 n=2;   k=5;   m= N[FractionalPart [10^(n-1)*Pi],k+10] 0.415926535897932 n=10;   k=5;   m= N[FractionalPart[10^(n-1)*Pi],k+10] 0.589793238462643 и сверить результаты с таблицами. Как легко убедиться, результаты совпадают, так что беспокоиться вроде бы не о чем. Но вот если положить n = 50, появляется предупреждение о недостаточной разрядности.
N::meprec: Internal precision limit $MaxExtraPrecision =50. reached while evaluating - 31415926535897«21»841971693993751«1» «1» .
А при n = 1000 результат выглядит вообще странно: 0.х1034, да и предупреждений целых два! Давайте разберемся, в чем тут дело. Для этого придется проанализировать ход вычислений. Сначала вычисляется Pi с некоторой точностью, притом с запасом (не более $MaxExtraPrecision десятичных знаков, как следует из предупреждения), а затем это число умножается на степень 10, так что в итоге получается 10^ (n-l) *Pi с некоторой точностью, после чего мы пытаемся взять у этого полученного числа его дробную часть. Но вот теперь и оказывается, что число было вычислено с недостаточной точностью, и система Mathematica предупреждает об этом! Впрочем, выход очевиден: нужно просто увеличить значение $MaxExtraPrecision. Но увеличение будет весьма значительным, и потому лучше всего сделать так, чтобы увеличенное значение $MaxExtraPrecision использовалось системой Mathematica только при вычислении результата, нужного для функции FractionalPart. Иными словами, увеличенное значение $MaxExtraPrecision нужно сделать локальным. Для этого достаточно воспользоваться функцией Block. Тогда можно написать следующую тестовую программу.
Do[Block[{k=10},Block[{$MaxExtraPrecision = n+k+10), Print[n+1,":",N[FractionalPart[10^n*Рi],k+10]]]],{n,0,2030,5}]
Едва ли стоит полностью приводить распечатку результата, но вот отдельные ее части явно заслуживают обсуждения. Вот банальное начало, подтверждающее правильность задания в программе степеней, умножений и всей подобной тривиальной чепухи, в записи которой так легко допустить ошибку.
1  : 0.14159265358979323846 6 : 0.26535897932384626434 11  0.89793238462643383280 16 0.23846264338327950288 21 0.26433832795028841972 26  0.83279502884197169399 31  0.50288419716939937511 36 0.41971693993751058210
Правильность цифр можно проверить по таблицам, имеющимся почти в любом солидном справочнике по математике или в какой-нибудь монографии, посвященной арифметике произвольной разрядности, например во втором томе бессмертного труда Дональда Кнута Искусство программирования. Что касается продолжения распечатки, то в ней правильность цифр проверить уже сложнее. Ведь найти книгу с более чем пятидесятые знаками л существенно сложнее. Из опыта знаю, что на территории СССР научному сотруднику, не связанному со спецслужбами вроде КГБ или ГРУ, получить доступ к серьезному фолианту по истории вычисления я практически было невозможно. Тем больше наша благодарность организатору первых математических олимпиад в Ленинграде (и СССР; первые олимпиады в Москве и Киеве проводились только через год) Василию Августовичу Кречмару, который в последних изданиях своего труда Задачник по алгебре (предназначенного для любознательных школьников!) поместил результат вычисления л с 2035 знаками после запятой. Разрабатывая арифметику произвольной разрядности для различных программных комплексов (в том числе и систем компьютерной алгебры), я при проверке получаемых результатов неоднократно пользовался шестым изданием этого бестселлера. Вполне подойдет эта книга и для проверки (хотя бы и выборочной) результатов, выдаваемых нашей программой. Так что можем читать нашу распечатку дальше.
41      0.69399375105820974945 46      0.37510582097494459231 51      0.58209749445923078164 56      0.74944592307816406286 61      0.59230781640628620900 66      0.78164062862089986280 71      0.062862089986280348253 76      0.20899862803482534212 81      0.86280348253421170680 86      0.34825342117067982148 91      0.34211706798214808651 96      0.70679821480865132823 101   :   0.82148086513282306647 106   :   0.086513282306647093845
Вы заметили, что распечатан один "лишний" знак? А знаете, почему? Продолжаем читать дальше.
111   :   0.32823066470938446096 116   :   0.066470938446095505822 121   :   0.093844609550582231725
И вот опять появились "лишние" знаки. Правда, и в этом случае после точки стоит сразу 0. Но не случайность ли это?
126   :   0.46095505822317253594 131   :   0.50582231725359408128 136   :   0.23172535940812848112 141   :   0.53594081284811174503 146   :   0.081284811174502841027
И вот опять появился "лишний" знак. И опять после точки стоит сразу 0. Да не закономерность ли это? Давайте пропустим часть распечатки и поищем еще "лишние" знаки (я выделяю их курсивом, знак после точки — полужирным).
286      0.60726024914127372459 291      0.024914127372458700661 296      0.41273724587006606316 301      0.72458700660631558817 306      0.70066063155881748815 311      0.063155881748815209210 316      0.58817488152092096283 356      0.90360011330530548820 361      0.011330530548820466521 366      0.053054882046652138415 371      0.48820466521384146952 416      0.91953092186117381933 421     0.092186117381932611793 426     0.61173819326117931051
О, действительно, это, должно быть, закономерность. Итак, мы полагаем, что если после точки идет нуль, то вычисляется дополнительная цифра. Ну а если нулей несколько? Может быть, количество ведущих нулей равно количеству "лишних" цифр?

Давайте попробуем подтвердить (или опровергнуть) эту гипотезу.
446       0.18548074462379962750 451       0.074462379962749567352 456       0.23799627495673518858 556       0.70277053921717629318 561       0.053921717629317675234 566       0.17176293176752384675 591       0.76694051320005681271 596       0.051320005681271452636 601       0.00056812714526356082773 606       0.81271452635608277858 741       0.47713099605187072113 746       0.099605187072113500000 751       0.51870721134999999837 776       0.49951059731732816096 781       0.059731732816096318595 786       0.17328160963185950245 851       0.71010003137838752887 856       0.0031378387528865875332 861       0.78387528865875332084 991       0.21642019893809525720 996       0.019893809525720106549 1041   0.82303019520353018530 1046   0.01952035301852968995S 1051   0.035301852968995773623 1111   0.45415069595082953312 1116   0.069595082953311686173 1121   0.50829533116861727856 1166   0.19255060400927701671 1171   0.060400927701671139010 1176  0.092770167113900984882 1181  0.016711390098488240129 1266   0.68471040475346462080 1271   0.040475346462080466843 1276  0.53464620804668425907 1331   0.66024058038150193511 1336  0.058038150193511253382 1386   0.92726042699227967824 1391   0.042699227967823547816 1516   0.75596023648066549912 1521   0.023648066549911988183 1551 0.63698074265425278626 1556 0.074265425278625518184 1601 0.81647060016145249192 1606 0.060016145249192173217 1756 0.67179049460165346680 1761 0.049460165346680498863 1766 0.01653466804988627232S 1831 0.95068006422512520512 1836 0.00642251252051173929S5 1856 0.84896084128488626946 1861 0.084128488626945604242 1896 0.11863067442786220392 1901 0.067442786220391949450 1916 0.94945047123713786961 1921 0.047123713786960956364 1966 0.41389086583264599581 1971 0.08658326459958133904S 2021 0.98352595709825822621 2026 0.59570982582262052249 2031 0.98258226205224894077
Итак, все говорит о том, что эта гипотеза верна! А знаете, почему? Потому что ведущие нули не учитываются при подсчете значащих цифр (а ведь именно их количество и равно разрядности). "Ну, это я знал с шестого класса, если не с пеленок. Давайте лучше решим задачу до конца, раз уж мы столь тщательно проверили предложенный мною вариант программы и убедились в его правильности!" — воскликнет иной искушенный читатель. Что же, не возражаю. Давайте зададим параметры и получим результат.








Начало  Назад  Вперед


Книжный магазин