2

Я пытаюсь установить переменную на vpa (арифметика с переменной точностью). Если я попробуюустановка переменных с помощью vpa в циклах

a=vpa(tanh(1)) 

then a=0.76159415595576485102924380043987 по желанию. Теперь я пытаюсь сделать это в цикле:

a=[]; 
for i=1:3 
    a(i)=vpa(tanh(1)); 
end 

Однако теперь, когда я выход a(1), я просто получить значение 0.761594155955765. Почему бы мне не получить последние цифры, как в первом случае?

+0

Как вы вывести 'a (1)'? На моей машине 'vpa (a (1))' возвращает '0.76159415595576485102924380043987'. Если вы делаете это с помощью 'fprintf', то перед выходом он преобразуется в двойную точность. –

+0

@ 2mkgz: Это потому, что 'a' является двойным. Применяя 'vpa' к вектору' a' * после *, расчет выполняется в этом случае, потому что эта операция является последней, выполняемой для каждого элемента. На этот вопрос есть два вопроса - см. Мой ответ ниже. – horchler

+0

@horchler Спасибо за разъяснение. Сначала я ожидал, что причина быть типом принуждения в 'a (i) = vpa (tanh (1))', но затем запуталась с помощью 'vpa (a (1))' кажущейся «восстанавливающей» утраченной точности. –

ответ

2

В коде есть две проблемы.

Во-первых, если вы запустите class(a)for после цикла вы увидите, что a является 'double', а не 'sym'. Причина этого в том, что вы изначально выделили a в качестве пустого массива двойной точности: a = [];. Каждый раз, когда вы вставляете в него значения точности символьной переменной, они отображаются в том же классе, что и a.

Чтобы правильно построить символический массив, вам нужно выделить как таковые:

a = sym([]); 
for i = 1:3 
    a(i) = vpa(tanh(1)); 
end 
a 
class(a) 

Еще лучше, если указать конечный размер:

n = 3; 
a = sym(zeros(n,1)); % Or a = zeros(n,1,'sym'); 
for i = 1:n 
    a(i) = vpa(tanh(1)); 
end 
a 
class(a) 

В вашем случае, оба указанных выше опций эквивалентно следующему, поскольку вы применяете vpa в качестве последней операции для каждого элемента:

n = 3; 
a = zeros(n,1); 
for i = 1:n 
    a(i) = tanh(1); 
end 
a = vpa(a); 


Это приводит ко второй проблеме, которая заключается в том, что ваши расчеты не используют преимущества переменной точности. Перед выполнением операций над ними необходимо убедиться, что все значения преобразуются в символьные или переменные. Например:

a = vpa(tanh(1)) % Calculate tanh(1) as double then convert to vpa 
b = tanh(vpa(1)) % Calculate tanh(1) using actual variable precision 
a-b 

возвращает 0.000000000000000037090214482164921742783153748416. Другими словами, vpa(tanh(1)) вычисляет гиперболический тангенс в двойной точности и tanh(vpa(1)) делает это с использованием переменной точности.