Почему в этом примере отображается «Нет значащих цифр для отображения»? - PullRequest
1 голос
/ 25 декабря 2011

V 8.0.4, windows 7.

Поскольку я пытался понять, смогу ли я получить более быстрые вычисления, если я смогу заставить M работать в аппаратном режиме с одной точностью (я не знаю, даже если это возможно, я пытался что-то сделать), я заметил, что AbsoluteTiming возвращает 0 только для время Pause, когда я получаю точность чуть меньше, чем в два раза, но лучше, чем один:

Вот пример:

Я перезагружаю ядро ​​и набираю

r=AbsoluteTiming[Pause[2]]
{2.00111440000,Null}

Accuracy[r]

Out[26]= 11.438897913739035

Теперь я установил M на удвоение

 $MinPrecision=$MachinePrecision;
 $MaxPrecision=$MachinePrecision;
 r=AbsoluteTiming[Pause[2]]

 Out[32]= {2.001114400000000,Null}

 Accuracy[r]
 Out[33]= 15.653317853034773

Нет проблем.

Но когда я делаю

 prec=Log[10,2]*29;
 $MaxPrecision=prec;
 $MinPrecision=prec;

 r=AbsoluteTiming[Pause[2]]

 Out[41]= {0.,Null}

Вы видите, это ноль.

 Accuracy[r]
 Out[42]= 307.6526555685888

Но я продолжал пытаться увидеть, где именно он переворачивается с нуля до возврата фактических секунд, и получил это за одну попытку

enter image description here

Я знаю, что M использует произвольные числа точности для внутреннего использования:

http://reference.wolfram.com/mathematica/tutorial/ArbitraryPrecisionNumbers.html

Из приведенной выше ссылки написано:

In doing calculations that degrade precision, it is possible 
to end up with numbers that have no significant digits at all

Мой вопрос здесь: может ли кто-нибудь объяснить это поведение в этом примере? Почему измерение времени всего лишь Pause[] требует гораздо большей точности, чем одинарная? Какие именно вычисления необходимы для измерения AbsoluteTime как минимум вдвое? Помощь говорит:

AbsoluteTiming is always accurate down to a granularity of $TimeUnit 
seconds, but on many systems is much more accurate.

и

In[22]:= $TimeUnit//N
Out[22]= 0.001

На самом деле моей главной целью было просто посмотреть, смогу ли я заставить М выполнить вычисления с использованием аппаратных вычислений с плавающей запятой одинарной точности, просто чтобы посмотреть, будет ли оно работать быстрее. Я прочитал в книге, что одна Точность может быть в 2 раза быстрее двойной, и просто пытался проверить это на чем-то, что у меня есть, когда я заметил это.

В настоящее время я запускаю все со следующим наверху

$MinPrecision = $MachinePrecision;
$MaxPrecision = $MachinePrecision;

Так что M работает с использованием аппаратного обеспечения double.

Спасибо, пс. и на этот раз я проверил консоль раньше, я не вижу синтаксических ошибок.

1 Ответ

1 голос
/ 25 декабря 2011

Во-первых, я не думаю, что установка $MaxPrecision и / или $MachinePrecision даст желаемый эффект.Вот пример.

$MaxPrecision = $MinPrecision = $MachinePrecision;
result1 = Nest[4 # (1 - #) &, 0.123, 10^6]; // Timing
result2 = Nest[4 # (1 - #) &, SetPrecision[0.123, 
   $MinPrecision], 10^6]; // Timing

На моем компьютере первое вычисление занимает 8 сотен секунды, а второе вычисление занимает почти три секунды.Реальность такова, что первое вычисление выполняется в машинной арифметике, а второе - в программной арифметике, которая имеет одинаковую числовую точность.

Я думаю, что самый простой способ форсировать машинную арифметику в Mathematica 8должен использовать Compile с "CatchMachineOverflow" и "CatchMachineUnderflow", установленными на False;или, что еще лучше, просто установите "RuntimeOptions" на "Speed".

Кроме того, я думаю, что причина, по которой вы получаете 0 для своей команды AbsoluteTiming, заключается в том, что вы установили слишком низкую точность для представления результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...