#!/usr/bin/perl

sub dopasowanie_wielomianu {
    my @punkty = @_;
    my ($i, $j, $y, @rozwiazanie);
    for ($i = 0; $i < @punkty; $i++) {
        ($x, $y) = ( @ {$punkty[$i]} );

        for ($j = 0; $j < @punkty-1; $j++) {
            $punkty[$i][$j] = $x ** (@punkty - $j - 1);
        }
        $punkty[$i][@punkty-1] = 1;
        $punkty[$i][@punkty]   = $y;
    }
    return rownania_liniowe( @punkty );
}

@rozwiazanie = dopasowanie_wielomianu( [2,7000], [3,6000], [4,9000] );
print "@rozwiazanie\n";                         # 2000 -11000 21000

use Math::MatrixReal;  # http://www.perl.com/CPAN/modules/by-module/Math

sub rownania_liniowe {
    my @rownania = @_;
    my ($i, $j, $rozwiazanie, @rozwiazanie, $wymiar, $bazowa_macierz);

    # Tworzymy $macierz reprezentujaca lewa strone ukladu rownan.
    #
    my $macierz = new Math::MatrixReal( scalar @rownania,
                                       scalar @rownania );

    # Tworzymy $wektor reprezentujacy wartosci y.
    my $wektor = new Math::MatrixReal( scalar @rownania, 1 );

    # Zapelniamy $macierz oraz $wektor.
    #
    for ($i = 0; $i < @rownania; $i++) {
        for ($j = 0; $j < @rownania; $j++) {
            assign $macierz ( $i+1, $j+1, $rownania[$i][$j] );
        }
        assign $wektor ( $i+1, 1, $rownania[$i][-1] );
    }

    # Przeksztalcamy $macierz do postaci LR.
    #
    my $LR = decompose_LR $macierz;

    # Rozwiazujemy macierz LR dla wektora $wektor.
    #
    ($wymiar, $rozwiazanie, $bazowa_macierz) = $LR->solve_LR( $wektor );

    for ($i = 0; $i < @rownania; $i++) {
        $rozwiazanie[$i] = element $rozwiazanie( $i+1, 1 );
    }
    return @rozwiazanie;
}
