Wyznaczanie środkowych wartości

Wyznaczanie środkowych wartości
ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

Witam wszystkich. Chciałbym prosić o pomoc, ponieważ chciałbym wyliczyć wartość środkową, (interpolacja liniowa). skorzystałem ze wzoru x=(x-1) + (x+1) / 2. Program wczytuje dane z pliku i jeśli widzi że jakaś wartość jest pusta (na razie u mnie wartość pusta to "0" pózniej będę myślał jak zastąpić to pustą linijką :) ) to bierze dwie skrajne wartości i wylicza środkową. Zrobiłem program, który działa poprawnie tylko dla jednej pustej wartości w pliku, natomiast nie wiem jak zrobić aby program wyliczał wartości puste jeśli jest ich kilka z kolei.

Kopiuj
 
12 13
2 2 
3 3
0 0
0 0
0 0
5 6
9 9
22 66
100 100

w tym miejscu programu jest liczona wartość środkowa , tylko dla jednej wartości, proszę o pomoc ponieważ stoję od kilku dni w miejscu i niewiem jak rozwiązać ten problem. Myślałem nad rekurencią, ale wole się zapytać tutaj.

Kopiuj
 

for (int i=0; i<=10; i++){


    if ( (k[i](0,0) == 0) && (k[i](1,0) == 0) ){


    k[i]=(k[i-1]+k[i+1])/2;
{
     cout<<endl<<"Klatka "<<i<<": "<<endl<<k[i];
}

    }


    else {

        cout<<endl<<"Klatka "<<i<<": "<<endl;
        cout<<k[i];
    }

}

 


a tu cały program żeby było wiadomo o co chodzi:

Kopiuj
 



#include <iostream>
#include <fstream>
#include <cstdlib>
#include <Eigen/Dense>

using namespace std;
using Eigen::Vector2d;


 Vector2d k[99];

 int x[100];
 int y[100];


int main()
{
    int liczba[10][2];
    ifstream plik("zrodlo.txt");

    for(int i = 0; i < 10; i++)
        for(int j = 0; j < 2; j++)
            plik >> liczba[i][j];


    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 2; j++)
       {
         x[i]=liczba[i][0];
         y[i]=liczba[i][1];

         cout << liczba[i][j] << " ";
        }
        cout << "\n";
    }


for ( int i=0;i<10; i++){
cout<<endl<<endl<<"x: "<<x[i];
cout<<endl<<endl<<"y: "<<y[i];
}


for ( int i=0; i<10; i++)
{
    k[i]<<x[i],y[i];
}

for (int i=0; i<=10; i++){


    if ( (k[i](0,0) == 0) && (k[i](1,0) == 0) ){


    k[i]=(k[i-1]+k[i+1])/2;
{
     cout<<endl<<"Klatka "<<i<<": "<<endl<<k[i];
}

    }


    else {

        cout<<endl<<"Klatka "<<i<<": "<<endl;
        cout<<k[i];
    }

}

    system("pause");


    return 0;
}


KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
1

Co rozumiesz przez "wartość środkową"? Średnią? Medianę? Jeśli średnią, to liczysz tylko z dwóch elementów, a nie ze zbioru. Jeśli medianę, to musisz sortować i dopiero brać to, co jest w połowie tablicy, ew. wyliczać średnią dwóch środkowych wartości.

Poza tym:

  1. Styl.
  2. Po co Ci ten Vector2d? Naprawdę nie da się tego zrobić tablicą dwuelementową?

Edit:
3. Jeśli to interpolacja, to użycie wszędzie typów int skutecznie wspomaga nas w gubieniu ważnych danych i wyliczaniu bzdur, czyż nie?

edytowany 1x, ostatnio: kapojot
ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

Wiem że Vector2d jest niepotrzebny, i można to zrobić inaczej. Uczę się operacji na wektorach i macierzach i chciałem sprawdzić jak są one czytane przez program. Wartość środkową rozumiem w taki sposób: jeśli program czyta klatki a w każdej klatce znajduje się x oraz y , to program powinien policzyć wartość gdy w jakiejś klatce zabraknie x oraz y. Program liczy mi wartość dla jednej klatki, a ja chciałbym aby liczył wartości dla kilku klatek(bez wartości) po kolei.
np :

Kopiuj
klatka1: x=1  y=1
klatka2: x=2  y=2
klatka3: x=3  y=3
klatka4: x=  y=
klatka5: x=  y=
klatka6: x=  y=
klatka7: x=7 y=8
...     ....
...     ....
 

a więc chcę aby program wyliczył wartości dla klatek 4,5,6. U mnie wartości puste są zapisane jako "0" ponieważ nie wiem na razie jak zrobić aby czytało mi: " " jako x oraz y, ale nie o to prosze, poradze sobie z tym pózniej.

Wiem że aby policzyć dane z przykładu który podałem muszę wyliczyć najpierw za pomocą klatki 3 oraz klatki 7, klatke 5 , aby za jej pomocą policzyć klatkę 4 oraz klatkę 6.Ale to tylko prosty przykłąd, a co w przypadku większej ilości pustych klatek ...? Dlatego proszę o pomoc , ponieważ nie wiem jak to zrobić.

KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

O widzisz, to teraz rozumiemy, o co chodzi. Próbujesz za pomocą interpolacji uzyskać wartości w brakujących punktach. Moim zdaniem, to, co powinieneś policzyć to tzw. wielomian interpolujący i na jego bazie wyciągać brakujące wartości. Zwróć też uwagę, że brakujące wartości mogą niekoniecznie znajdować się dokładnie w środku przedziałów (masz na to jakieś gwarancje?). Poniżej wklejam kod do liczenia interpolacji Lagrange'a - korzystaj do woli.

Kopiuj
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int
main(int argc, char ** argv)
{
	double *x, *y;
	int t, n, k, i, j, n_a;

	scanf("%d", &t);
	for (; t > 0; t--) {
		scanf("%d", &n);

		assert(n > 0);
		x = calloc(n, sizeof(double));
		y = calloc(n, sizeof(double));
		assert(x != NULL);
		assert(y != NULL);

		for (i = 0; i < n; i++)
			scanf("%lf %lf", x+i, y+i);

		scanf("%d", &n_a);
		assert(n_a > 0);
		/* W zmiennej ask mamy współrzędną x punktu, o który pytamy. */
		for (k = 0; k < n_a; k++) {
			double res;
			double ask;

			res = 0;
			scanf("%lf", &ask);
			for (i = 0; i < n; i++) {
				double tmp;

				tmp = y[i];
				/* Wyliczamy wartość wielomianu w punkcie (ask). */
				for (j = 0; j < n; j++) {
					if (j != i)
						tmp *= (ask - x[j]) / (x[i] - x[j]);
				}
				res += tmp;
			}
			/* Wyświetlamy f(ask). */
			printf("%.3lg\n", res);
		}

		free(x);
		free(y);
	}

	return (0);
}

Edit: +komentarz, +asercje po calloc

edytowany 3x, ostatnio: kapojot
ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

dziękuję, tylko chodziło mi o zwykłą interpolację liniową :). Czyli co w moim kodzie zrobić, aby program liczył mi brakujące wartości. Może jakiś wzór rekurencyjny? Chodzi o to że nie, próbowałem już różne kombinacje ale zawsze wywala mi niepoprawne wartości (dla przykładowych 1,2,3,4 żeby było łatwiej).

KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

Jak byś robił interpolację liniową, to miałbyś tylko dwa punkty i wtedy zadanie wyglądałoby tak:

Kopiuj
x1 y1
x2 y2
// policz f((x1 + x2) / 2) i kolejny zestaw...

Ty masz więcej punktów, a to raczej implikuje wielomianową.

No chyba, że bawimy się w interpolację łamaną, ale wtedy zaczyna mi to przypominać aproksymację wielomianową stopnia pierwszego stosowaną np. w metodzie elementów skończonych. Wtedy to może iść rekurencyjnie, a nawet potrafi mieć adaptację kroku - gdyby punkty nie były rozmieszczone równomiernie.

KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

Chyba zrozumiałem do końca o co Ci chodziło.

Chcesz podać do programu znane wartości funkcji w zadanych punktach (w interpolacji: węzły interpolacyjne). Chcesz też podać punkty, w których oczekiwałbyś, że program poda Ci wartości funkcji. I teraz masz dwie opcje:

  1. Interpolacja wielomianowa, która znając tylko znane punkty funkcji poda Ci interpolowane wartości funkcji w punktach, w których nie znamy wartości funkcji explicite.
  2. Aproksymacja, w której przybliżamy funkcję inną funkcją, ale w takim przypadku musimy wiedzieć "coś więcej" o funkcji. Np. wiesz, że Twoja funkcja jest np. parabolą albo wielomianem trzeciego stopnia. W szczególności dla MRS i MES musisz znać równanie różniczkowe, czyli wiedzieć coś o pochodnych tej funkcji + warunki na końcach przedziału (von Neumanna, Cauchyego, Dirichleta, Robina, ew. wariacje powyższych). Tej wiedzy nie posiadasz, a akurat MES z bazą wielomianową stopnia 1 potrafiłby Ci skonstruować dokładnie taką łamaną, jaką jak mniemam oczekujesz. Ale u Ciebie nie podałeś w żaden sposób informacji o pochodnych.

Moim zdaniem jedyne, co możesz zrobić w przypadku, który podałeś to jest dokładnie interpolacja wielomianowa, do której kod podałem Ci wyżej. Niczego innego nie osiągniesz, bo albo robisz po prostu odcinek między kolejnymi znanymi punktami i wtedy masz wszystkie nieznane punkty na jednym odcinku (np. jak w Twoim pierwszym przypadku) albo po prostu wróżysz z fusów i wtedy każdy wynik jest jednakowo dobry (lub zły).

edytowany 1x, ostatnio: kapojot
ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

Chodzi mi o interpolację liniową. Mam znane wartości które wczytuje z pliku , linijka po linijce. I jeśli w pliku usunę kilka linijek to muszę za pomocą interpolacji liniowej podać ich wartości. (wartości nie muszą być takie jak były wczsniej ) Interpolacja ma mi z znanych wartości policzyć te nieznane, a jeśli się będą różnic to nic, o to chodzi. czyli jeszcze raz na spokojnie:

mam plik tekstowy a w nim :

Kopiuj
1 1
2 2
3 3
4 4



8 8
9 9 
10 10

 

Program czyta pierwszą kolumnę jako x drugą jako y , tak mi to wczytuje do programu. wiersz 5 , 6 ,7 ma mi policzyc za pomocą interpolacji liniowej. Podałęm funkcje liniową, wiadomo ze policzy wartości takie jak powinny być. to przykład w bardziej zagmatwanej funkcji wiadomo ze intrpolacja podała by wartości całkiem inne niż funkcja powinna przyjąć, ale o to chodz mi właśnie. Program ma ro robić za pomocą wzoru : x=(x-1)+(x+1)/2 . I tak mi robi właśnie, ale niestety dla jednej brakującej wartości, a ja proszę tylko o to jaki wzór mam dać w moim kodzie aby liczył to dla kilku brakujących wartości jak w powyższym przykładzie(nie ma 3 wierszy).

KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

No to bierzesz pierwszy i ostatni wiersz i na jego podstawie liczysz wszystkie pozostałe. Nie do końca widzę w czym problem.
Inne pytanie, masz taki zestaw:

Kopiuj
-3 9
-2 4
-1 1
0 0
1 1
2 4
3 9

Usuwasz z niego (-1, 1), (0, 0) oraz (1, 1). Zadajesz pytanie tylko o (0, 0). Jaka powinna być Twoim zdaniem prawidłowa wartość? (0, 4) jak wynika z częściowej interpolacji łamaną bez 3 środkowych punktów czy (0, 0)?

edytowany 1x, ostatnio: kapojot
ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

Właśnie :) biorę pierwszy i ostatni wiersz :) , dzięki temu otrzymuje środkowy brakujący, dzieki któremu wyliczę pozostałe :).

przykład:

wiersz1: 12 15
wiersz2: 26 8
wiersz3:
wiersz4:
wiersz5:
wiersz6:
wiersz7:
wiersz8: 17 12
wiersz9 28 27

więc program bierze mi wiersz2 oraz wiersz8 i wylicza mi wiersz5 . Tak to ma wyglądać. x=26+17/2 i y=8+12/2 ; x=12.5 y = 10 . Właśnie o to chodzi :). A potem dzięki wartości wiersz5 chce wyliczyć inne brakujące: wiersz3, wiersz4, wiersz6 i wiersz7. Tylko że jestem początkowym programistą i od samego początku próbuję zapytać jak to zrobić ???? za pomocą rekurencji jakiejś???

Umiem tylko zrobić taki program (liczy tylko jedną brakującą wartość ponieważ nie wiem co zrobić w przypadku takim jak powyżej gdy brakujących wartosci jest więcej ):

podawałem go powyżej ale ten kod wysle jeszcze raz bo wiem ze to tu trzeba cos zrobić

Kopiuj

for (int i=0; i<=10; i++){

if (x[i] == 0)
{
x[i]=(x[i-1]+x[i+1])/2;
cout<<endl<<"Klatka "<<i<<": "<<endl<<x[i]<<endl;
}

else {

        cout<<endl<<"Klatkaa "<<i<<": "<<endl<<x[i]<<endl;
     }
}
 
KA
Wartości x nie powinny być w takim przypadku posortowane rosnąco? Teraz to wygląda jak łączenie odcinkami losowych punktów.
KA
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:192
0

Możesz też odnaleźć sąsiadujące punkty, które nie są (0, 0). Tzn. poprzedzający (0, 0) i taki, który jest zaraz za nim. Do tego nie trzeba rekurencji.

Tak swoją drogą - to dziwne zadanie robisz. Nie odbieraj tego jako krytykę siebie, ale zajmuję się m.in. profesjonalną numeryką i akcja pt. "zrobię sobie prosty odcinek zamiast wycinka paraboli" powoduje, że włos mi się jeży na głowie. Załóżmy, że coś takiego odstawia inżynier Boeinga konstruujący nowy samolot. Zastępuje sobie po cichu w programie kawałek siatki nowego samolotu takim "wypłaszczeniem", po czym wysyła tak zmodyfikowaną siatkę dalej, np. do jakiegoś innego inżyniera, który będzie na niej robił symulację przepływu powietrza. Teraz zagadka: jak szybko koleś wyleci z roboty i z jak dużym hukiem?

ZM
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 6 lat
  • Postów:23
0

Prosty odcinek podałem dla zrozumienia i łatwiejszego wytłumaczenia mojego problemu, równie dobrze mogą to być trudniejsze funkcje, mi tylko chodzi żeby ktoś na prostym przykładzie pomógł mi w wyznaczeniu brakujących wartości, które będą oczywiście błędne jesli nie będzie to funkcja liniowa, ale po prostu BĘDĄ , bo potem muszę zrobić analize, jak bardzo punkty z intrpolacji liniowej różnią się od punktów które były wczesniej. A że c++ ucze się od niedawna to nie wiem jak wyznaczyć te wartości, jak powinien wyglądać mój kod, dlatego tutaj zamieszczam swój post.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)