[C#] Wyznaczanie sumy szeregu

zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

Witam,

jestem nowy na forum, ale to na pewno początek długiej przygody - niedawno zacząłem studia na kierunku Informatyka - tak się składa, że jakieś 18 lat po maturze i matematyka będzie na pewno (przynajmniej na początku) sporym wyzwaniem.

Mam do napisania program w C#, który będzie liczył sumę szeregu funkcyjnego:

\(\displaystyle{ \sum_{i=1}^{k} \frac{x^n}{n}, \ x\in\left( -1;1\right)}\)

I nie bardzo wiem jak to ugryźć... Generalnie z programowaniem na tym początkowym poziomie to sobie poradzę, ale nie wiem jak podejść do tego od strony analitycznej. Jak obliczyć sumę takiego szeregu?

Będę wdzięczny za naprowadzenie mnie na jakiś właściwy tor... Sporo czasu muszę nadrobić, ale jakoś trzeba zacząć.

Z góry dziękuję za pomoc.

Pozdrawiam
Marcin
Ostatnio zmieniony 14 lis 2016, o 06:06 przez Afish, łącznie zmieniany 2 razy.
Powód: Nieczytelny zapis - brak LaTeX-a. Proszę zapoznaj się z instrukcją: http://matematyka.pl/latex.htm .
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

To się naucz obsługi LateX-a, bo inaczej to nici z pomocą (tj. moderatorzy wywalą takiego posta)

\(\displaystyle{ \sum_{i=1}^{k} \frac{x^n}{n}, \ x\in\left( -1;1\right)}\)

Matematycznie jak to obliczyć to jedno, ale programistycznie - bardzo prosto (do pewnej dokładności), czyli coś w tym stylu (to \(\displaystyle{ k}\) odpowiada wartości STALA w tym kodzie)

Kod: Zaznacz cały

#include <iostream>
#include <cmath>
using namespace std;

int main() {
	const int STALA = 10000;
	float x;
	double suma = 0;
	cout << "Podaj x: ";
	cin >> x;
	for(int n = 1; n < STALA; ++n)
		suma += pow(x, n) / n;
	cout << suma << endl;
	return 0;
}


w C# nigdy nie pisałem, ale pewnie składnia jest dosyć zbliżona (pozmieniaj sobie wartości zmiennej STALA, aby zobaczyć jaki to ma wpływ na dokładność sumy).

Suma ta, swoją drogą jest równa dokładnie \(\displaystyle{ sum_{i=1}^{infty} frac{x^n}{n} = -lnleft( 1-x
ight), xinleft[ -1;1
ight)}\)
zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

cześć,

dzięki - dobrze rozumiem, że ta stała to określenie dokładności?

LateX-a oczywiście się nauczę.
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

ta stała to określenie dokładności
Pośrednio tak. Aczkolwiek zdaje się, że trochę przesadziłem z wartością tej stałej.

Kod: Zaznacz cały

Podaj x: 0.5
STALA = 5, suma = 0.688542

STALA = 10, suma = 0.693065

STALA = 15, suma = 0.693145

STALA = 20, suma = 0.693147

STALA = 25, suma = 0.693147

STALA = 30, suma = 0.693147
Im więcej składników, tym dokładniejsza wartość tej sumy
Awatar użytkownika
kinia7
Użytkownik
Użytkownik
Posty: 704
Rejestracja: 28 lis 2012, o 11:58
Płeć: Kobieta
Lokalizacja: Wrocław
Podziękował: 89 razy
Pomógł: 94 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kinia7 »

zangiev79 pisze: \(\displaystyle{ \sum_{i=1}^{k} \frac{x^n}{n}, \ x\in\left( -1;1\right)}\)

I nie bardzo wiem jak to ugryźć...
\(\displaystyle{ \sum_{i=1}^{k} \frac{x^n}{n}=\frac{k(k+1)x^n}{2n}}\)
zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

Mhm.. ale skąd wzięliście to \(\displaystyle{ k}\)? W moim wzorze tam jest nieskończoność. czy to \(\displaystyle{ k}\) to stała, którą deklaruje użytkownik? i względem niej liczy się pewna dokładność?

Długa droga przede mną, długa i wyboista... (chyba ustawię sobie to jako sygnaturkę)
Ostatnio zmieniony 15 lis 2016, o 11:58 przez Afish, łącznie zmieniany 1 raz.
Powód: Całe wyrażenia matematyczne umieszczaj w tagach [latex] [/latex].
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

zangiev79 pisze:Mhm.. ale skąd wzięliście to k? W moim wzorze tam jest nieskończoność. czy to k to stała, którą deklaruje użytkownik? i względem niej liczy się pewna dokładność?
Tak, \(\displaystyle{ k}\) to stała, którą deklaruje użytkownik. A właściwie to autor programu, tj. \(\displaystyle{ k}\) we wzorze \(\displaystyle{ \sum_{i=1}^{k} \frac{x^n}{n}}\)

odpowiada

Kod: Zaznacz cały

const int STALA = 10000;
w kodzie
tj. \(\displaystyle{ k=10000}\) tutaj. Wydaje mi się, że nie wiesz za bardzo jak ten znak sumy się odczytuje:

\(\displaystyle{ \sum_{i=1}^{1} \frac{x^n}{n}=\frac{x^1}{1} \\
\sum_{i=1}^{2} \frac{x^n}{n}=\frac{x^1}{1}+\frac{x^2}{2} \\
\sum_{i=1}^{3} \frac{x^n}{n}=\frac{x^1}{1}+\frac{x^2}{2} +\frac{x^3}{3}}\)


I tak dalej. A pamiętaj, że \(\displaystyle{ \left| x\right| <1}\), więc z każdą kolejną potęgą jest ono coraz mniejsze.



Krótko mówiąc - w programowaniu nie możesz liczyć tego do nieskończoności, bo
1) program by się wykonywał nieskończenie długo
2) typy zmiennych mają swoją największą oraz najmniejszą możliwą wartość i tego nie obejdziesz (a przynajmniej nie w taki sposób)
3) to nie ma sensu, bo dla \(\displaystyle{ k=20}\) już masz dokładność 4 cyfr po przecinku dla większości x-ów z danego zakresu
zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

Kalwi, wielkie dzięki - robi się coraz jaśniej.

podsumowując - w programie mogę zadeklarować k, bądź zapytać użytkownika. Ta stała określa dokładność obliczeń. Ale musi się zawierać w jakimś zadeklarowanym zakresie (w jakimś przykładowym zadaniu była określona jako Eps i miała spełniać warunek 0<Eps<1

To samo dla zmiennej x - no tej nie deklaruję, pytam o nią użytkownika. Tu nie ma warunku, musi to być po prostu INT.

Potem wykonuję obliczenia w pętli dla zadanego x, aż zostanie osiągnięte k.

Czy coś pokręciłem...?
Ostatnio zmieniony 15 lis 2016, o 11:58 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

Tak, pokręciłeś,albo przynajmniej tak mi się wydaje, że utożsamiasz k z eps.
k nie określa dokładności obliczeń w sposób bezpośredni, tylko mówi ile elementów tego szeregu ma zsumować. Jeżeli chcesz sobie wprowadzić stałą odpowiedzialną za dokładność, czyli eps, to należałoby zrobić coś w stylu

Kod: Zaznacz cały

double eps=0.000001;
for(int n = 1; (double) pow(x, n)/n >eps; ++n)
      sum+= pow(x, n)/n;
I wtedy w ogóle to k Cię nie obchodzi, bo program będzie się wykonywał tak długo, aż któryś tam element tego szeregu będzie miał wartość mniejszą niż eps.

I nie, x to nie jest int, ponieważ masz w treści zadania, że ma być to liczba zmiennoprzecinkowa, czyli float albo double
Ostatnio zmieniony 15 lis 2016, o 11:59 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
Awatar użytkownika
kinia7
Użytkownik
Użytkownik
Posty: 704
Rejestracja: 28 lis 2012, o 11:58
Płeć: Kobieta
Lokalizacja: Wrocław
Podziękował: 89 razy
Pomógł: 94 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kinia7 »

kalwi pisze:\(\displaystyle{ \sum_{i=1}^{3} \frac{x^n}{n}=\frac{x^1}{1}+\frac{x^2}{2} +\frac{x^3}{3}}\)
Ja jednak upieram się, że:

\(\displaystyle{ \sum_{i=1}^{3} \frac{x^n}{n}=\frac{3x^n}{n}}\)
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

Aj, masz mnie :/
zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

Coś niestety jest całkiem nie tak jak trzeba. Wydaje mi się, że należałoby zastosować wzór na n-ty wyraz ciągu... czy nie?

Taki mam kod, niestety nie chce działać, działa dla wzoru poniżej (\(\displaystyle{ \sin (x)}\)):

Kod: Zaznacz cały

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ConsoleApplication2
{
    class Program
    {

        static void mm_SumaSzereguFunkcyjnego (float mm_x, float mm_Eps, out float mm_SumaSzeregu, out int mm_LicznikWyrazowSzeregu)
        {
            float mm_a;
            int mm_k;
            
            mm_a = mm_x;
            mm_k = 0;
            mm_SumaSzeregu = mm_a;
            do
            {
                mm_k++;

                mm_a += (Double)Math.Pow(mm_x, mm_k) / mm_k;
                //mm_a = -mm_x * mm_x / ((2 * mm_k + 1) * (2 * mm_k));
                mm_SumaSzeregu += mm_a;
            }
            while (Math.Abs(mm_a) > mm_Eps);
            mm_LicznikWyrazowSzeregu = mm_k;
        }
        static void Main(string[] args)
        {
            float mm_x, mm_Eps, mm_SumaSzeregu;
            int mm_LicznikZsumowanychWyrazow;

            Console.Write("\n\tProgram wyznacza sumę szeregu funkcyjnego ...");
            Console.Write("\n\t dla podanej wartości zmiennej niezależnej x oraz dokładności obliczeń Eps");
            Console.Write("\n\tPodaj wartość zmiennej niezależnej x: ");

            while (!float.TryParse(Console.ReadLine(), out mm_x))
            {
                Console.Write("\n\tBŁĄD: W podanym zapisie wartości zmiennej niezależnej wystąpił niedozwolony znak!");
                Console.Write("\n\tWprowadź ponownie wartość zmiennej niezależnej x: \n\t");
            }

            do
            {
                Console.Write("\n\tPodaj dokładność obliczeń Eps: ");
                while (!float.TryParse(Console.ReadLine(), out mm_Eps))
                {
                    Console.Write("\n\tBŁĄD: W podanym zapisie wartości dokładności obliczeń wystąpił niedozwolony znak!");
                    Console.Write("\n\tWprowadź ponownie wartość dokładności obliczeń Eps \n\t");
                }

                if ((mm_Eps <= 0) || (mm_Eps >= 1))
                {
                    Console.Write("\n\tBŁĄD: Dokładność obliczeń musi spełniać warunek wejściowy - 0 < Eps < 1");
                    Console.Write("\n\tPodaj dokładność obliczeń jeszcze raz");
                }
            }
            while ((mm_Eps <= 0) || (mm_Eps >= 1));

            mm_SumaSzereguFunkcyjnego(mm_x, mm_Eps, out mm_SumaSzeregu, out mm_LicznikZsumowanychWyrazow);

            Console.WriteLine("\n\nWyniki obliczeń: ");
            Console.WriteLine("Suma Szeregu: {0,10:E}", mm_SumaSzeregu);
            Console.WriteLine("Liczba Zsumowanych wyrazów k: = {0,3} ", mm_LicznikZsumowanychWyrazow);

            Console.WriteLine("Naciśnij dowolny klawisz aby kontynuować");
            Console.ReadKey();
        }
    }
}
podkreśla również linię:

Kod: Zaznacz cały

mm_a += (Double)Math.Pow(mm_x, mm_k) / mm_k;
z błędem: cannot implicitly convert type 'double' to 'float'...
Ostatnio zmieniony 15 lis 2016, o 11:59 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

Kod: Zaznacz cały

mm_a += (Double)Math.Pow(mm_x, mm_k) / mm_k;
ten plus jest niepotrzebny
oraz
double na float (w sumie nie wiem jak wygląda rzutowanie typów w C#, ale na pewno ten warning zniknie)



Kod: Zaznacz cały

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
	float eps, element, x;
	float sum = 0;
	float count = 1;
	cout << "Podaj dokladnosc: ";
	cin >> eps;
	cout << "Podaj liczbe x: ";
	cin >> x;

	do
	{
		element = pow(x, count) / count;
		sum += element;
		++count;
	}
	while(abs(element) > eps);
	cout << "suma = " << sum << endl;
	cout << "liczba iteracji = " << count << endl;
	
	return 0;
}
zangiev79
Użytkownik
Użytkownik
Posty: 19
Rejestracja: 13 lis 2016, o 22:35
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 1 raz

[C#] Wyznaczanie sumy szeregu

Post autor: zangiev79 »

Rzutowanie udało się zrobić, błędów nie ma, ale wzór nic niestety nie liczy... Program się nie wywala, tylko jakby zatrzymywał po podaniu Eps.

Problem na pewno tkwi we wzorze, bo gdy podmienię go na inny, to program działa.

Kod: Zaznacz cały

static void mm_SumaSzereguFunkcyjnego(float mm_x, float mm_Eps, out float mm_SumaSzeregu, out int mm_LicznikWyrazowSzeregu)
        {
            float mm_a;
            int mm_k;

            mm_a = mm_x;
            mm_k = 0;
            mm_SumaSzeregu = mm_a;
            do
            {
                mm_k++;

                mm_a = (float) Math.Pow(mm_x, mm_k) / mm_k;
                //mm_a = -mm_x * mm_x / ((2 * mm_k + 1) * (2 * mm_k));
                mm_SumaSzeregu += mm_a;
            }
            while (Math.Abs(mm_a) > mm_Eps);
            mm_LicznikWyrazowSzeregu = mm_k;
        }
Ostatnio zmieniony 15 lis 2016, o 11:59 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
kalwi
Użytkownik
Użytkownik
Posty: 1931
Rejestracja: 29 maja 2009, o 11:58
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 145 razy
Pomógł: 320 razy

[C#] Wyznaczanie sumy szeregu

Post autor: kalwi »

Tak, trochę źle to napisałeś. Wychodzi taki sam wynik jak u mnie tutaj:



Kod: Zaznacz cały

static void mm_SumaSzereguFunkcyjnego (float mm_x, float mm_Eps, out float mm_SumaSzeregu, out int mm_LicznikWyrazowSzeregu)
        {
            float mm_a;
            int mm_k = 1;
            
            mm_SumaSzeregu = 0;
            do
            {
                mm_a = (float)Math.Pow(mm_x, mm_k) / mm_k;
                mm_SumaSzeregu += mm_a;
                ++mm_k;
            }
            while (Math.Abs(mm_a) > mm_Eps);
            mm_LicznikWyrazowSzeregu = mm_k;
        }
No i nie rozumiem, czemu wszystkie zmienne mają prefix mm_. To zdecydowanie obniża czytelność kodu.
Ostatnio zmieniony 15 lis 2016, o 11:59 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
ODPOWIEDZ