Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 28. 03. 2010 15:15

jardasmid
Příspěvky: 65
Reputace:   
 

Polynomální aproximace množiny bodů

Mám nějakou obecnou množinu bodů [X;Y], např. { [0;40]; [1;36]; [2;20]; [3;19]; [4;18]; [5;18,5]; [6;18,4] }

Jak spočítám koeficienty pro polynomální aproximaci n-tého řádu (3., 4.)?

Offline

  • (téma jako vyřešené označil(a) byk7)

#2 05. 04. 2010 01:29

Kondr
Veterán
Místo: Linz, Österreich
Příspěvky: 4246
Škola: FI MU 2013
Pozice: Vývojář, JKU
Reputace:   38 
 

Re: Polynomální aproximace množiny bodů

Zkus hledat "metodu nejmenších čtverců", např. zde: http://mathworld.wolfram.com/LeastSquar … omial.html
nějaké použitelné odkazy dávala na fórum Jelena.


BRKOS - matematický korespondenční seminář pro střední školy

Offline

 

#3 09. 04. 2010 18:24

pietro
Příspěvky: 4762
Reputace:   187 
 

Re: Polynomální aproximace množiny bodů

↑ jardasmid: sice po uzavierke ale ide to aj takto:
http://forum.matweb.cz/upload/1270830277-khgkg.JPG

Offline

 

#4 20. 04. 2010 20:26

jardasmid
Příspěvky: 65
Reputace:   
 

Re: Polynomální aproximace množiny bodů

↑ pietro:

Moc to nepobírám. Co když chci ty body proložit jenom polynomem 2. řádu? Z tohodle bych dostal co počet bodů, takového stupně-1 polynom.

Offline

 

#5 20. 04. 2010 23:14

pietro
Příspěvky: 4762
Reputace:   187 
 

Re: Polynomální aproximace množiny bodů

↑ jardasmid: tak ked polynomy nizsieho stupna, tak len metoda najmensich stvorcov, alebo aj v exceli sa da urobit elegantne regresia, krivka potom prebieha co najblizsie okolo bodov.

Offline

 

#6 21. 04. 2010 00:39

jardasmid
Příspěvky: 65
Reputace:   
 

Re: Polynomální aproximace množiny bodů

↑ pietro:
Už to mám, něco jsem spatlal :-) Je to sice dost pomalé, ale (snad) funkční. Kdyžtak sem dam zítra zdroják v C++.

Offline

 

#7 21. 04. 2010 14:50

pietro
Příspěvky: 4762
Reputace:   187 
 

Re: Polynomální aproximace množiny bodů

↑ jardasmid: dik.. :-)

Offline

 

#8 22. 04. 2010 00:04

jardasmid
Příspěvky: 65
Reputace:   
 

Re: Polynomální aproximace množiny bodů

↑ pietro:
Jelikož dneska nebyl moc čas (zítra písemka), tak až ve čtvrtek někdy k večeru.

Offline

 

#9 22. 04. 2010 19:25

jardasmid
Příspěvky: 65
Reputace:   
 

Re: Polynomální aproximace množiny bodů

↑ jardasmid:
V kódu je na pár místech použito C++0x, takže třeba upravit při použití kompilátoru, který ho nepodporuje (podpora v GCC 4.4: g++ -std=c++0x)

Matrix.h

Code:

/* Rychle spatlaná třída, obsahuje spoustu bugů - nejsou ošetřeny velikosti matic, apod. Taky jsem možná měl indexovad (row,col) místo (col,row), ale zatím mi to stačí */
#ifndef _GF_MATRIX_H
#define _GF_MATRIX_H

#include <iostream>

namespace Gf
{
    template<class Elem>
    class Matrix
    {
        protected:
            size_t _cols;
            size_t _rows;
            Elem *_d;
        public:
            Matrix(const Matrix& matrix)
            {
                _cols = matrix._cols;
                _rows = matrix._rows;
                _d = new Elem[_cols*_rows];

                for (size_t i = 0; i < _cols*_rows; ++i)
                {
                    _d[i] = matrix._d[i];
                }
            }
            
            Matrix(Matrix&& matrix)
            {
                _cols = matrix._cols;
                _rows = matrix._rows;
                _d = matrix._d;
                
                matrix._d = 0;
                matrix._cols = 0;
                matrix._rows = 0;
            }
            
            Matrix(size_t cols, size_t rows)
            {
                _cols = cols;
                _rows = rows;
                _d = new Elem[cols*rows];
            }
            
            Matrix(size_t cols, size_t rows, const Elem& val)
            {
                _cols = cols;
                _rows = rows;
                _d = new Elem[cols*rows];

                for (size_t i = 0; i < _cols*_rows; ++i)
                {
                    _d[i] = val;
                }
            }

            ~Matrix() { delete []_d; }

            Matrix& operator=(const Matrix& matrix)
            {
                if (&matrix == this) return *this;
                if (_cols != matrix._cols || _rows != matrix._rows)
                {
                    delete []_d;
                    _cols = matrix._cols;
                    _rows = matrix._rows;
                    _d = new Elem[_cols*_rows];
                }
                
                for (size_t i = 0; i < _cols*_rows; ++i)
                {
                    _d[i] = matrix._d[i];
                }
                return *this;
            }
            
            Matrix& operator=(Matrix&& matrix)
            {
                if (&matrix == this) return *this;
                delete []_d;
                _cols = matrix._cols;
                _rows = matrix._rows;
                _d = matrix._d;
                
                matrix._d = 0;
                matrix._cols = 0;
                matrix._rows = 0;
                return *this;
            }

            const Elem& operator()(size_t col, size_t row) const { return _d[_cols*row + col]; }
            Elem& operator()(size_t col, size_t row)             { return _d[_cols*row + col]; }

            size_t cols() const          { return _cols; }
            size_t rows() const          { return _rows; }
            Elem*  row(size_t row) const { return _d+_cols*row; }

            Matrix& operator/=(const Elem& elem)
            {
                for (size_t i = 0; i < _cols*_rows; ++i) _d[i] /= elem;
                return *this;
            }

            Matrix& operator*=(const Elem& elem)
            {
                for (size_t i = 0; i < _cols*_rows; ++i) _d[i] /= elem;
                return *this;
            }

            Matrix transpose() const
            {
                Matrix result(_rows, _cols);

                for (size_t i = 0; i < _cols; ++i)
                    for (size_t j = 0; j < _rows; ++j)
                        result(j, i) = (*this)(i, j);

                return result;
            }

            void setIdentity()
            {
                for (size_t i = 0; i < _cols; ++i)
                    for (size_t j = 0; j < _rows; ++j)
                        (*this)(j, i) = ((j == i) ? 1 : 0);
            }

            Matrix submatrix(size_t excl_col, size_t excl_row) const
            {
                Matrix result(_cols-1, _rows - 1);
                size_t res_col = 0, res_row = 0;

                for (size_t i = 0; i < _rows; ++i)
                {
                    if (i == excl_row) continue;
                    
                    res_col = 0;
                    for (size_t j = 0; j < _cols; ++j)
                        if (j != excl_col) result(res_col++, res_row) = (*this)(j, i);
                        
                    ++res_row;
                }
                
                return result;
            }

            /*
             * Returns Cofactor Matrix (square matrix only)
             */
            Matrix cofactor() const
            {
                Matrix result(_cols, _rows);
                Elem sign;

                if (_cols == 1)
                {
                    result(0, 0) = 1;
                }
                else for (size_t row = 0; row < _rows; ++row)
                {
                    for (size_t col = 0; col < _cols; ++col)
                    {
                        sign = ((col+row) % 2 == 0 ? 1 : -1);
                        result(col, row) = sign * submatrix(col, row).determinant();
                    }
                }
                return result;
            }
            
            /*
             * Returns Adjugate Matrix (square matrix only)
             */
            Matrix adjugate() const
            {
                Matrix result(_rows, _cols);
                Elem sign;
                
                if (_cols == 1)
                {
                    result(0, 0) = 1;
                }
                else for (size_t row = 0; row < _rows; ++row)
                {
                    for (size_t col = 0; col < _cols; ++col)
                    {
                        sign = ((col+row) % 2 == 0 ? 1 : -1);
                        result(row, col) = sign * submatrix(col, row).determinant();
                    }
                }
                return result;
            }

            /*
             * Matrix determinant (square matrix only)
             */

            Elem determinant() const
            {
                if (_cols != _rows) return 0;

                if (_cols == 0) return 1;
                if (_cols == 1) return _d[0];
                if (_cols == 2) return _d[0] * _d[3] - _d[1] * _d[2];

                Elem det = 0;
                Elem sign;
                
                for (size_t i = 0; i < _cols; ++i)
                {
                    sign = (i % 2 == 0 ? 1 : -1);
                    det += sign * (*this)(i, 0) * submatrix(i, 0).determinant();
                }

                return det;
            }

            /*
             * Returns inverse matrix (square matrix only)
             */

            Matrix inverse() const
            {
                Elem det = determinant();
                Matrix result = adjugate();
                result /= det;

                return result;
            }

            /*
             * Matrix filling:
             *   Matrix<elem> a(3,3);
             *   a <<  5,  6,  7,
             *         8,  9, 10,
             *        11, 12, 13;
             */

            struct Filler
            {
                Elem *_d;

                Filler(Elem *d, const Elem& first) : _d(d) { *_d = first; ++_d; }
                Filler& operator,(const Elem& elem) { *_d = elem; ++_d; return *this; }
            };

            Filler operator<<(const Elem& elem) { return Filler(_d, elem); }

            /*
             * Write Matrix to std::ostream
             */
            friend std::ostream& operator<<(std::ostream& strm, const Matrix& m)
            {
                strm << "Matrix[";
                for (size_t i = 0; i < m._rows; ++i)
                {
                    strm << "[";
                    for (size_t j = 0; j < m._cols; ++j)
                    {
                        if (j != 0) strm << ", ";
                        strm << m(j, i);
                    }
                    strm << "]";
                }
                strm << "]";
                return strm;
            }
    };

    template<class Elem>
    Matrix<Elem> operator*(const Matrix<Elem>& m1, const Matrix<Elem>& m2)
    {
        Matrix<Elem> result(m2.cols(), m1.rows());

        size_t row, col, i;

        for (row = 0; row < result.rows(); ++row)
        {
            for (col = 0; col < result.cols(); ++col)
            {
                result(col, row) = 0;
                for (i = 0; i < m1.cols(); ++i)
                    result(col, row) += m1(i, row) * m2(col, i);
            }
        }
        
        return result;
    }
}

#endif

PolynomalApprox.h

Code:

#ifndef _GF_POLYNOMAL_APPROX_H
#define _GF_POLYNOMAL_APPROX_H

#include <map>
#include <vector>
#include <string>

#include "Matrix.h"

namespace Gf
{
    Matrix<long double> PolynomalApprox(
        const std::map<long double, long double>& values,
        size_t degree);
}
#endif

PolynomalApprox.cpp

Code:

#include "PolynomalApprox.h"

#include <iostream>
#include <cmath>
#include <sstream>

namespace Gf
{
    Matrix<long double> PolynomalApprox(const std::map<long double, long double>& values, size_t degree)
    {
        typedef Matrix<long double> MT;
        
        size_t i, j;
        MT y(1, values.size());
        MT A(degree + 1, values.size());

        i = 0;
        for (auto it = values.begin(); it != values.end(); ++it)
        {
            y(0, i) = it->second;
            for (j = 0; j < degree+1; ++j)
            {
                if (j == 0) A(j, i) = 1;
                else if (j == 1) A(j, i) = it->first;
                else A(j, i) = std::pow(it->first, (long double)j);
            }
            ++i;
        }

        MT AT = A.transpose();
        MT coefs = ((AT*A).inverse() * AT) * y;

        //std::cout << "coefs:" << std::endl << coefs;

        return coefs;
    }
}

Offline

 

#10 22. 04. 2010 22:03

pietro
Příspěvky: 4762
Reputace:   187 
 

Re: Polynomální aproximace množiny bodů

vdaka za ochotu...som iba zaciatocnik v tomto...tak budem husto studovat....rad sa poucim...hodne zdaru a nech sa podaria pisomky. :-)

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson