Grupy dyskusyjne Google nie obsługują już nowych postów ani subskrypcji z Usenetu. Treści historyczne nadal będą dostępne.

[VBA] Excel - obliczanie szeregu funkcji - przydługie

503 wyświetlenia
Przejdź do pierwszej nieodczytanej wiadomości

Paweł

nieprzeczytany,
20 sty 2015, 15:13:2920.01.2015
do
Witam
Piszę makro w Excelu w VBA do liczenia rozwinięcia funkcji trygonometrycznej: f
= cos(5*x) w nieskończony szereg Taylora w postaci:

s = 1 - (5^2∙x^2)/2! + (5^4∙x^4)/4! - (5^6∙x^6)/6! + ......

Cechą charakterystyczną tego szeregu jest to, że poszczególne wyrazy szeregu są
odejmowane i dodawane naprzemiennie.
Napisałem sobie pętlę, która ma liczyć sumę szeregu "s" poprzez obliczenie i
sumowanie poszczególnych wyrazów szeregu "a" dla zadanej wartości "x" z zadaną
dokładnością "eps". Bo nie można liczyć w nieskończoność :)
Kod pętli wygląda następująco:
-----------------------------------------------
n = 2
If eps < 0 Then
Do
a = (5 ^ n * x ^ n) / silnia(n)
w = 1
If a > eps Then
If (w Mod 2 = 1) Then
a = -a
End If
s = 1 + a
End If
If Abs(f - s) >= -eps Then
n = n + 2
w = w + 1
Else
Exit Do
End If
Loop While (Abs(f - s) < eps)
End If
-------------------------------------------------------
gdzie:
n - zadana początkowa wartość potęgi (typ Integer)
eps - dokładność porównawcza (mniejsza od 0) zadana przez użytkownika (typ
Double)
a - obliczany wyraz szeregu zgodnie ze wzorem (typ Double)
x - zadana wartość przez użytkownika (typ Double)
silnia(n) - wywołanie zewnętrznej funkcji silnia
w - licznik wyrazów szeregu
s - suma szeregu dla zadanego "x" (typ Double)
f - wartość funkcji cos(5*x) dla zadanego "x" (typ Double)

Pętla wg idei ma działać następująco:
1. Oblicza pierwszy wyraz szeregu "a".
2. Do sumy szeregu "s" ma dodać lub odjąć (dodać ujemnie - stąd If dla
"nieparzystych" argumentów dla licznika "w" = 1, 2, 3, itd. i podstawienie dla
nich a = -a) jeden wyraz "a" zgodnie z ogólnym powyższym wzorem na sumę szeregu.
3. Po dodaniu każdego wyrazu "a" sprawdza czy suma szeregu "s" jest większa lub
równa wynikowi obliczonego wcześniej "f" o zadaną wartość "eps".
4. Jeżeli tak to zwiększa współczynnik potęgi "n" o wartość "2" oraz licznik
kolejnego wyrazu o 1.
5. Wraca do początku i liczy kolejny wyraz "a" i jeśli spełnia warunki to dodaje
lub odejmuje go do/od sumy "s"
6. Operacje 1 - 6 są wykonywane dopóki różnica pomiędzy "f" i "s" będzie
mniejsza niż dokładność "eps".

Niestety mam problem, że pętla liczy tylko "a" dla pierwszego obiegu, co jest
poprawne dla podstawionego x = 0,
ale dla x <> 0 powinna wykonywać kilka obiegów, a też robi tylko jeden.

Zaznaczam, że wynikiem funkcji "f" są wartości ujemne lub dodatnie, zgodnie z
wykresem sinusoidalnym. Zbliżone do nich powinny być wartości "s".
Niestety ta pętla działa tak, że wartości są jedynie coraz bardziej ujemnie
dlatego, że liczony jest tylko jeden wyraz "a".

W czym jest tu błąd myślowy/składniowy? Podejrzewam warunek While, a może typy
zmiennych powinny być inne...... :/
Mimo różnych prób nie znalazłem rozwiązania.
Proszę o wskazówki :)

Pozdrawiam
Paweł

Paweł

nieprzeczytany,
20 sty 2015, 15:20:0620.01.2015
do
> 2. Do sumy szeregu "s" ma dodać lub odjąć (dodać ujemnie - stąd If dla
> "nieparzystych" argumentów dla licznika "w" = 1, 2, 3, itd. i podstawienie dla
> nich a = -a) jeden wyraz "a" zgodnie z ogólnym powyższym wzorem na sumę
> szeregu.

errata:
a = -a przyjmuje znak ujemny co drugi wyraz, zatem licznik "w" ma jakby wartości
1, 3, 5....... :)

Pozdrawiam
Paweł

Skylla

nieprzeczytany,
21 sty 2015, 16:59:5521.01.2015
do
> s = 1 + a
S nie równa się 1+a ale raczek s+a


Paweł

nieprzeczytany,
21 sty 2015, 18:25:5821.01.2015
do
> s = 1 + a
> S nie równa się 1+a ale raczek s+a

W międzyczasie doszedłem do tego i zmodyfikowałem całą pętlę:
-------------------------------------
n=2
s=1
w=1
a = (5 ^ n * x ^ n) / silnia(n) ' oblicz pierwszy wyraz
Do
a = (5 ^ n * x ^ n) / silnia(n) ' oblicz pierwszy argument
If a > eps Then ' jeśli wyraz jest większy od eps
to dodaj go do szeregu
If (w Mod 2 = 1) Then ' jeśli obliczony wyraz jest
krokiem nieparzystym "w" to....
a = -a ' ustaw wyraz "a" jako ujemny
End If
s = s + a ' dodaj wyraz do sumy szeregu
If Abs(f - s) > eps Then ' jeśli różnica wartości funkcji
i szeregu jest większa epsilon to licz kolejny wyraz szeregu
n = n + 2 ' zwiększ potęgę n o 2
a = (5 ^ n * x ^ n) / silnia(n) ' oblicz kolejny wyraz "a" ze
wzoru
w = w + 1 ' zwiększ licznik wyrazów o 1
s = s + a ' dodaj wyraz do sumy szeregu
End If
If Abs(f - s) <= eps Then ' jeśli różnica wartości
bezwzględnych funkcji i szeregu jest mniejsza lub równa epsilon to licz ostatni
wyraz szeregu
n = n + 2
a = (5 ^ n * x ^ n) / silnia(n)
w = w ' nie zwiększaj w
s = s + a
End If
End If
Loop While Abs(f - s) < eps
-------------------------------------
Ale dalej nie liczy więcej niż 2 obiegi pętli i dalej jest to bardzo niedokładne
:(

Skylla

nieprzeczytany,
22 sty 2015, 13:02:3122.01.2015
do

> -------------------------------------
> Ale dalej nie liczy więcej niż 2 obiegi pętli i dalej jest to bardzo
> niedokładne :(
Nie wiadomo co to jest f.
Sprawdź działanie warunków, albo wklej całość z funkcjami.
Tak trudno powiedzieć.

Paweł

nieprzeczytany,
22 sty 2015, 17:47:0122.01.2015
do
> Nie wiadomo co to jest f.
> Sprawdź działanie warunków, albo wklej całość z funkcjami.
> Tak trudno powiedzieć.

f - to wynik działania funkcji cos(5*x) dla podanego x.

Na etapie działania tej pętli ma już przydzieloną stałą wartość np. 0,8776 dla x
= 0,1

slawek

nieprzeczytany,
5 lut 2015, 10:27:175.02.2015
do
On Tue, 20 Jan 2015 21:13:25 +0100, Pawe <br...@wp.pl> wrote:
> Pisz makro w Excelu w VBA do liczenia rozwini cia funkcji
trygonometrycznej: f

Hmmm... Je eli nie chcesz gotowych funkcji z biblioteki... Troch
czym innym jest obliczanie funkcji trygonometrycznej (jest par
trików np. redukcja do pierwszego oktantu), a czym innym sumowanie
szeregu takim jaki on jest (i to bez przyspieszenia zbie no ci).
Sugerowa bym sumowanie od ostatniego, najmniejszego wyrazu oraz mniej
naiwne obliczanie silni. Ilo wyrazów koniecznych dla osi gni cia
zadanej dok adno ci atwo znale , bo szereg jest naprzemienny.

slawek

nieprzeczytany,
5 lut 2015, 11:59:465.02.2015
do
On Thu, 05 Feb 2015 16:27:14 +0100, slawek <fa...@fakeemail.com> wrote:
> Hmmm... Je eli nie chcesz gotowych funkcji z biblioteki... Troch

Kodowanie popłynęło

Paweł

nieprzeczytany,
8 lut 2015, 14:32:328.02.2015
do

Już to rozwiązałem.
Zmieniłem sposób obliczania argumentu "a", a pętlę uzależniłem od: loop while
(a > eps) i liczy poprawnie.

Ale dzięki za próby pomocy.... :)

Nowe wiadomości: 0