Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Interpolacja Liniowa

Ostatnio zmodyfikowano 2016-09-06 21:34
Autor Wiadomość
efekt_motyla
Temat założony przez niniejszego użytkownika
» 2016-08-24 23:09:23
Dziękuję! :) Wszystko działa :)

Tak jak doszedłeś wcześniej, chciałem  zrobić program dla współrzędnych a dokładnie  [x,y,z].

Dopisałem tylko zeta :).

C/C++
#include <iostream>
#include <fstream>
#include <vector>

template < typename T >
void interpolate( std::vector < T >& numbers )
{
    for( auto i = 0u; i + 1 < numbers.size(); i++ )
    {
        if( numbers[ i + 1 ] == 0 )
        {
            auto beginVal = numbers[ i ];
            auto index = i;
           
            while( numbers[ ++i ] == 0 )
                 continue;
           
            auto endVal = numbers[ i ];
            auto diff = i - index;
           
            i = index;
           
            while( numbers[ ++i ] == 0 )
                 numbers[ i ] = beginVal +( endVal - beginVal ) / diff *( i - index );
           
        }
    }
}

int main()
{
    std::ifstream in( "liczby.txt" );
   
    std::vector < double > x;
    std::vector < double > y;
    std::vector < double > z;
   
    for( int i, j, k; in >> i >> j >> k; )
    {
        x.push_back( i );
        y.push_back( j );
        z.push_back( k );
    }
   
    interpolate( x );
    interpolate( y );
    interpolate( z );
   
    for( auto i = 0u; i < x.size() && i < y.size(); ++i )
         std::cout << "Klatka: " << i << " [" << x[ i ] << ", " << y[ i ] << ", " << z[ i ] << "]" << std::endl;
   
    return 0;
}

I jest super; ).dzi ę kuje

Jeszcze ostatnia sprawa , ponieważ chciałbym  zera zamienić na pustą linijkę, to  za pomocą jakiej  funkcji to zrobić ?
Pustą linijkę wczytać jako: " " ??
P-151074
Gibas11
» 2016-08-25 00:23:09
To uzna linię za pustą, jeśli jest w niej tylko ciąg znaków „EMPTY”. Bez jakiejkolwiek kontroli poprawności danych na wyjściu.
C/C++
#include <algorithm> //std::find
#include <iostream>
#include <fstream>
#include <sstream> //std::stringstream
#include <string> //std::string
#include <vector>

template < typename T >
void interpolate( std::vector < T >& numbers, std::vector < size_t >& emptyLines )
{
    for( auto i = 0u; i + 1 < numbers.size(); i++ )
    {
        /* Jeśli następny indeks jest na liście pustych linii */
        if( std::find( emptyLines.begin(), emptyLines.end(), i + 1 ) != emptyLines.end() )
        {
            auto beginVal = numbers[ i ];
            auto index = i;
           
            while( std::find( emptyLines.begin(), emptyLines.end(), ++i ) != emptyLines.end() )
                 continue;
           
            auto endVal = numbers[ i ];
            auto diff = i - index;
           
            i = index;
           
            while( std::find( emptyLines.begin(), emptyLines.end(), ++i ) != emptyLines.end() )
                 numbers[ i ] = beginVal +( endVal - beginVal ) / diff *( i - index );
           
        }
    }
}

int main()
{
    std::ifstream in( "liczby.txt" );
   
    std::vector < double > x;
    std::vector < double > y;
    std::vector < double > z;
   
    /* Vector na indeksy pustych linii */
    std::vector < size_t > emptyLines;
   
    std::string line;
    for( size_t i = 0u; getline( in, line ); ++i )
    {
        double X, Y, Z;
       
        /* Jeśli linia jest pusta */
        if( line == "EMPTY" )
        {
            /* Zapisanie jej indeksu */
            emptyLines.push_back( i );
           
            /* Wyzerowanie wartości tych współrzędnych, nie będą potrzebne,
            * ale wygodniej zachować dla nich miejsce w vectorze */
            X = Y = Z = 0;
        }
        else
        {
            /* Utworzenie strumienia na podstawie linii i wczytanie liczb do zmiennych */
            std::stringstream stream( line );
            stream >> X >> Y >> Z;
        }
       
        x.push_back( X );
        y.push_back( Y );
        z.push_back( Z );
    }
   
    /* Interpolacja z uwzględnieniem indeksów pustych linii */
    interpolate( x, emptyLines );
    interpolate( y, emptyLines );
    interpolate( z, emptyLines );
   
    for( auto i = 0u; i < x.size() && i < y.size(); ++i )
         std::cout << "Klatka: " << i << " [" << x[ i ] << ", " << y[ i ] << ", " << z[ i ] << "]" << std::endl;
   
    return 0;
}

Wprawdzie mógłbym nie wrzucać niepotrzebnych zer do vectora i dodawać je tam potem, ale i tak trzeba koniec końców zaalocować tą pamięć i za dużo z tym zachodu, żebym się w tym grzebał o tej godzinie. :P
P-151078
efekt_motyla
Temat założony przez niniejszego użytkownika
» 2016-08-25 21:59:44
no tak :). Właśnie zapomniałem napisać, że jeżeli np "x" jest pusty , to i "y" oraz "z" także. Czyli uznajemy całą linię za pustą (pomijając fakt że co jeśli x jest pusty a y i z mają wartosci*(taki przypadek wykluczam,) ). Analizuje kod który mi wysłałeś, gdzieś musi być błąd ponieważ na wyjściu  dostaje powtarzające się liczby.


np dla:

12 12 20
13 14 21
14 14 22



18 18 26
19 19 27
20 20 28

otrzymuję wynik:

Klatka: 0 [12, 12, 20]
Klatka: 1 [13, 14, 21]
Klatka: 2 [14, 14, 22]
Klatka: 3 [14, 14, 22]
Klatka: 4 [14, 14, 22]
Klatka: 5 [14, 14, 22]
Klatka: 6 [18, 18, 26]
Klatka: 7 [19, 19, 27]
Klatka: 8 [20, 20, 28]

Process returned 0 (0x0)   execution time : 0.023 s
Press any key to continue.







P-151114
Gibas11
» 2016-08-25 23:01:36
Przeczytaj dokładnie mój kod. :P Linia jest uznawana za pustą nie gdy jest pusta (a jak ktoś da tam spację? ;-;), tylko kiedy znajduje się w niej tylko słowo „EMPTY”.
//edit:

12 12 20
13 14 21
14 14 22
EMPTY
EMPTY
EMPTY
18 18 26
19 19 27
20 20 28
Wynik:

Klatka: 0 [12, 12, 20]
Klatka: 1 [13, 14, 21]
Klatka: 2 [14, 14, 22]
Klatka: 3 [15, 15, 23]
Klatka: 4 [16, 16, 24]
Klatka: 5 [17, 17, 25]
Klatka: 6 [18, 18, 26]
Klatka: 7 [19, 19, 27]
Klatka: 8 [20, 20, 28]
P-151116
efekt_motyla
Temat założony przez niniejszego użytkownika
» 2016-08-25 23:58:10
Odrazu się za czytanie kodu, a nie przeczytałem tego co powyżej napisałęś... :) . Fajnie działa, dziękuje ! :)

zamieniłem

line == Empty na    line == "" || linie==" " || line=="   "   

hehe ;) i jest tak jak chciałem  :) 
 
Dziękuje jeszcze raz, no i dodatkowo dowiedziałem się do czego służą kontenery oraz typ zmiennej 'auto' o którym wcześniej nie słyszałem.

Pozdrawiam. 
P-151120
efekt_motyla
Temat założony przez niniejszego użytkownika
Interpolacja Lagrange'a
» 2016-09-01 23:11:44
Dobry wieczór. Mam jeszcze jedno pytanie . Po interpolacji liniowej chciałem zrobić program, który liczyłby mi interpolacje lagrange'a.

Zrobiłem to dla 4  skrajnych punktów,  a dokładnie dla dwóch punktów znajdujących się "poniżej " niewiadomych oraz wziołem dwa punkty "powyżej" niewiadomych. W programie zakładamy, że brakuje mi całej linijki ( czyli jeśli nie ma x to nie ma tez y oraz z (jak poprzednio :) ) ). Punktem zaczepienia jest dla mnie sekunda. (zamiast pustej linijki wstawiłem zera.... (poniżej wyjaśniam dlaczego :) ) )

czyli na przykład dla współrzędnych:
 
sekunda  x    y    z

0       12   111  1000
1       13   122  2000
2       14   133  3000
3       0    0     0
4       0    0     0
5       0    0     0
6       0    0     0
7       0    0     0
8       0    0     0
9       0    0     0
10      0    0     0
11      23   232   12000
12      24   243   13000
13      25   154   14000

będą to punkty:

A=(1,13), B=(2,14), C=(11,23), D=(12,24)  ,  tak wyliczę x.  Następnie mając x wyliczę w podobny sposób y oraz z.

Chodzi o to czy tak można obliczyć współrzędne za pomocą interpolacji lagrage'a ???

Jeśli moje myślenie jest poprawne to , chciałbym po raz kolejny proszę o pomoc związaną z czytaniem  linijek... :). Mianowicie
chciałbym aby to wyglądało tak :  zamiast zer są spacje (lub Empty, tak jak pomogłeś mi ostatnio :) ) , ale .... musi zostać ta pierwsza kolumna z sekundami (to ona rana jest jako punkt zachaczenia. Proszę o pomoc jeszcze raz. ( Czy to będzie coś z zamianą stringa na inta w czyaniu linii ???)


To program który zrobiłem (raczej przerobiłem program który wczesniej pomógł mi napisać użytkownik Gibas11 (dziękuję !))

C/C++
#include <iostream>
#include <fstream>
#include <vector>

template < typename T >
void interpolacja( std::vector < T >& czas, std::vector < T >& x )
{
   
    /* Iteracja po wszystkich elementach vectora poza ostatnim */
    for( auto i = 0u; i + 1 < x.size(); i++ )
    {
       
        /* Jeśli następna liczba to zero */
        if( x[ i + 1 ] == 0 )
        {
            auto czas1 = czas[ i - 1 ]; // to inaczej wspolrzedna x w punkcie A
            auto czas2 = czas[ i ]; // to inaczej wspolrzedna x w punkcie B
           
            auto punktA = x[ i - 1 ]; // to inaczej wspolrzedna y w punkcie A
            auto punktB = x[ i ]; // to inaczej wspolrzedna y w punkcie B
           
           
           
            /* Zapisać obecny indeks */
            auto index = i;
           
            /* Inkrementować 'i' aż trafimy na nie-zero */
            while( x[ ++i ] == 0 )
                 continue;
           
            auto czas3 = czas[ i ]; // to inaczej wspolrzedna x w punkcie C
            auto czas4 = czas[ i + 1 ]; // to inaczej wspolrzedna x w punkcie D
           
            auto punktC = x[ i ]; // to inaczej wspolrzedna y w punkcie C
            auto punktD = x[ i + 1 ]; // to inaczej wspolrzedna y w punkcie A
           
           
           
            /* Różnica indeksów - ilość zer ('i') */
            double diff = i - index;
           
            /* Powrót na poczatek */
            i = index;
           
           
            /* Iteracja po wszystkich zerach */
           
            while( x[ ++i ] == 0 )
           
            // tu wzór Lagragr'a  dla 4 znanych punktów
            x[ i ] =( punktA *(( czas[ i ] - czas2 ) *( czas[ i ] - czas3 ) *( czas[ i ] - czas4 ) ) /(( czas1 - czas2 ) *( czas1 - czas3 ) *( czas1 - czas4 ) ) ) +
            ( punktB *(( czas[ i ] - czas1 ) *( czas[ i ] - czas3 ) *( czas[ i ] - czas4 ) ) /(( czas2 - czas1 ) *( czas2 - czas3 ) *( czas2 - czas4 ) ) ) +
            ( punktC *(( czas[ i ] - czas1 ) *( czas[ i ] - czas2 ) *( czas[ i ] - czas4 ) ) /(( czas3 - czas1 ) *( czas3 - czas2 ) *( czas3 - czas4 ) ) ) +
                ( punktD *(( czas[ i ] - czas1 ) *( czas[ i ] - czas2 ) *( czas[ i ] - czas3 ) ) /(( czas4 - czas1 ) *( czas4 - czas2 ) *( czas4 - czas3 ) ) );
           
        }
    }
}


int main()
{
    std::ifstream in( "liczby.txt" );
   
    std::vector < double > sekunda;
    std::vector < double > x;
    std::vector < double > y;
    std::vector < double > z;
   
   
    /* Wczytanie liczb */
    for( int i, j, k, l; in >> i >> j >> k >> l; )
    {
        sekunda.push_back( i );
        x.push_back( j );
        y.push_back( k );
        z.push_back( l );
    }
    interpolacja( sekunda, x );
    interpolacja( x, y );
    interpolacja( y, z );
   
    /* Wypisanie wszystkich liczb */
    for( auto r = 0u; r < sekunda.size() && r < x.size(); ++r )
         std::cout << sekunda[ r ] << "     " << x[ r ] << "     " << y[ r ] << "    " << z[ r ] << std::endl;
   
    return 0;
}



P-151306
Gibas11
» 2016-09-01 23:43:59
C/C++
for( std::string line; getline( in, line ); )
{
    int i, j, k, l;
    std::stringstream lineStream( line );
    lineStream >> i;
    if( lineStream.str().find( "EMPTY" ) != std::string::npos )
         j = k = l = 0;
    else
         lineStream >> j >> k >> l;
   
    sekunda.push_back( i );
    x.push_back( j );
    y.push_back( k );
    z.push_back( l );
}
Kod na tyle krótki, że raczej się połapiesz. Nie dam dokładnych komentarzy bo lecę spać. :P W skrócie, ładuję stringa do strumienia, pobieram liczbę pozbywając się jej, sprawdzam czy w reszcie jest ciąg "EMPTY" i jeśli nie to wczytuję z tego samego strumienia kolejne liczby.

Pamiętaj o
#include <sstream>
 na początku. Plik, którego użyłem do testów wyglądał tak:

0       12   111  1000
1       13   122  2000
2       14   133  3000
3       EMPTY
4       EMPTY
5       EMPTY
6       EMPTY
7       EMPTY
8       EMPTY
9       EMPTY
10      EMPTY
11      23   232   12000
12      24   243   13000
13      25   154   14000
I dał takie wyniki:

0     12     111    1000
1     13     122    2000
2     14     133    3000
3     15     144    4000
4     16     155    5000
5     17     166    6000
6     18     177    7000
7     19     188    8000
8     20     199    9000
9     21     210    10000
10     22     221    11000
11     23     232    12000
12     24     243    13000
13     25     154    14000

//edit: Poprawiłem błąd. ;-; Poprzedni nie wyłapywał „pustości” linii i zostawiał dane z poprzedniego obiegu pętli poza pierwszą zmienną. Zawiła sprawa, ale już chyba działa. :D
P-151308
efekt_motyla
Temat założony przez niniejszego użytkownika
» 2016-09-02 00:06:37
Hmm tylko wtedy liczy samego x-a  a y i z są błędne ponieważ cały czas się powtarzają w pustych miejscach :)
P-151310
1 « 2 » 3 4
Poprzednia strona Strona 2 z 4 Następna strona