2014-02-19 4 views
1

Это для моего курса по числовым методам. Я очень стараюсь понять MATLAB и его синтаксис, но я на 100% самоучка, поэтому, пожалуйста, несите меня, если мои попытки кажутся смешными.Выполнение функции, чувствительной к векторному вводу

Я написал эту очень легко функцию, чтобы приблизить число е

function e= calcEulerLimit(n) 
e = (1 + 1./n).^n; 
end 

Это «основной» определение числа е, используя предел п к бесконечности подхода. Для MATLAB я определил следующий вектор (когда я говорю о п в последнем, я всегда со ссылкой на этот вектор n)

n=[1:1:10]=[ 1 2 3 4 5 6 7 8 9 10 ] 

и выходных работает просто отлично, как я и ожидал, он чувствителен к вектору n ввод, когда я вызываю свою функцию в MATLAB.

>> calcEulerlimit(n) 

ans = 

    2.0000 2.2500 2.3704 2.4414 2.4883 2.5216 2.5465 2.5658 2.5812 2.5937 

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

function e = calcEulerSum(n) 
e=1;    % base-case, start variable 
for i=1:1:n  % for loop with step size one 
    e=e+1/factorial(i) 
end 
end 

но этот вход, конечно, не работает, когда я хочу ввести вектор, такой как n, который вычисляет все переменные.

Я пытался что-то вдоль линии с другой цикл, и время цикла, но цикл в то время как кажется, никогда не прекращается:

function e = calcEulerSum3(n) 
while n 
e=1; 
e = e + 1./cumprod(n); 
end 
end 

Использование cumprod(n), чтобы получить факторный значение каждого элемента столбца моего вектора n.

ответ

3

Вы пытаетесь вномнить в вектограмму своей функции. Ваше решение для скаляров работает так давайте посмотрим на то, что он делает, как i увеличивается:

 e0 = 1; 
i = 1: e(1) = e0 + 1/factorial(1) 
i = 2: e(2) = e(1) + 1/factorial(2) = e0 + 1/factorial(1) + 1/factorial(2) 
            = e0 + sum(1./factorial(1:2)) 
i = 3: e(3) = e(2) + 1/factorial(3) = ... 
            = e0 + sum(1./factorial(1:3)) 
    ... 
i = n: e(n) = e(n-1) + 1/factorial(n) = e0 + 1/factorial(1) + ... + 1/factorial(n) 
             = e0 + sum(1./factorial(1:n)) 

Так что вы можете придумать общее выражение для вычисления вектора e данных n? Функция cumsum пригодится.

+0

Спасибо за ваш ответ, я буду читать о cumsum, До сих пор я в для I = п, е = 1, е = е + 1./factorial(n); , который мне казался понятным, но выход, который я получаю, равен 2, 1.5, 1.1667, 1.0417 , так что кажется, что он «работает» помимо добавочной части. – Spaced

+0

@Spaced: 'n' - вектор. Если вы используете цикл 'for', вам, вероятно, потребуется индексировать его:' n (i) '. И вам, вероятно, также понадобится сохранить выходы в векторе: 'e (i)'. – horchler

+0

См. Приведенный выше пример псевдокода. Выход 'e' будет вектором, не так ли? Вы можете рассчитать первый элемент 'e'? Учитывая первый элемент, можете ли вы рассчитать второй ('i = 2')? И так далее ... Вы можете сделать это в цикле 'for', а затем вы можете увидеть, как все это можно реализовать только в одной строке кода, используя' cumsum'. – horchler

1

for i=whatsoever,statement(i);end выполняет инструкцию по каждому элементу whatsoever. Если это один номер, то на этом, если это вектор/массив, то на каждый его элемент.

1:1:n создает массив целых чисел от 1 к n на месте (1:n бы тоже). Если n уже есть вектор с элементами, которые вы хотите перебрать, вы можете использовать его напрямую: for i=n.

Однако почему вы использовали точечные версии операций в вашем первом и третьем блоках кода, но не в вашей второй? Потому что вы читали о векторизации MATLAB? Тогда вы, кажется, на правильном пути, но помните, что векторизация точки состоит в том, чтобы полностью избавиться от явного цикла.

+0

Большое спасибо за ваше объяснение @ arne.b Я читаю каждое руководство по Matlab, которое я могу найти в Интернете, и во втором примере я делясь на factorial (i), который всегда будет числом. В третьем примере, однако, я разделил бы на вектор, и я прочитал, что в этом случае мне пришлось бы использовать ./ для указания элементарного разделения. Выход работает, однако это неверно. Я постараюсь это понять лучше. – Spaced

+0

@horchler Как насчет «уменьшения числа явных циклов»? По крайней мере, если раньше существовал цикл 'for', а цикл while while делал то же самое, не было векторизации. :-) –

+0

@ arne.b: Ваша отредактированная версия намного лучше (точнее/осторожно). Я проголосовал за это за ваши объяснения того, как циклы for for работают с векторами. – horchler

-1
function e = calcEulerSum(n) 
e=nan(1,length(n));    % initialize to nan 
for j=1:length(n)    % for each element in the input 
    e(j)=sum(1./factorial(0:n(j))); %each entry is computed in this step, one at a time 
end 

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

В исходном примере время никогда не заканчивается, потому что n никогда не изменяется.

Этого должно быть достаточно, чтобы помочь вам начать работу.

Cheers!

Смежные вопросы