2025(e)ko otsailaren 18(a), asteartea

Ariketa 29 | Newton-en metodoa, bigarren graduko edozein parabolarekin

ZER DAKIDAN:
Dagoeneko for, do-while eta while agindu errepikakorra erabili ditut. Baina bakoitza edozein egoeratan erabil baiteke?



ZER IKASIKO DUDAN:
Prozesu errepikorraren iterazio kopurua ezezaguna denean, do-while edo while agindu errepikakorrek erabiliko ditut.


Newton-Raphson hurbilketa-metodoa ax2+bx+c=0 ekuazioaren erro bat kalkulatzeko

Newton–Raphson metodoa (Newton-en metodo gisa ere ezagutzen dena) zenbakizko analisi-metodo bat da. Metodo honek funtzioen erro gero eta hobeak lortzen ditu, hau da, funtzioa zero egiten duen x balioa bilatzen du. Beste modu batez esanik, funtzioak OX ardatza mozten duen balioa (funtzioaren erroa) ematen du Newton–Raphson metodoak. Algoritmoa erroaren hurbilketa batekin hasten da eta urrats bakoitzean erroaren hurbilketa hobea lortzen du.

Matematikan funtzio koadratikoa funtzio polinomiko mota bat da, itxura kanonikoan honela definitua:

ax2 + bx + c = 0

Non a, b eta c zenbaki errealak diren (eta a ≠ 0).

Funtzio koadratikoren deribatua lerro zuzena da eta bere integrala funtzio kubikoa da.



Aldagai bakarreko funtzio errealen kasuan honakoa da metodoa:
Izan bedi ƒ funtzioa x errealentzat definitua, eta izan bedi ƒ' bere deribatua. Erroaren hasierako hurbilketa bat behar dugu, x0. Erroaren hurbilketa horretan oinarrituz hurbilketa hobea izango den x1 honelaxe lortzen da:
Iterazioak eginez, n+1 hurbilketa n hurbilketan oinarritzen da formula honen arabera:
Formula horren zergatia geometrikoki adieraz daiteke. Hurrengo irudiko lerro urdina  f(x) funtzioa da, eta lerro zuzen gorria f(x) funtzioaren tangentea (xn, f(xn)) puntuan:
Berde koloreko distantziari hobekuntza deitzen badiogu, orduan alfa angeluaren tangentea f(xn)/hobekuntza litzateke, baina tangente hori f(x) funtzioaren deribatua (xn, f(xn))puntuan da, lerro zuzen gorriaren malda alfa angeluaren tangentea da. Horregatik:
tag(alfa)= f(xn)/hobekuntza   eta aldi berean   tag(alfa)=malda= f'(xn)
beraz    f'(xn)= f(xn)/hobekuntza     (non  hobekuntza=xn-xn+1)
f'(xn)= f(xn)/(xn-xn+1)    nondik    xn-xn+1= f(xn)/f'(xn)
xn+1 = xn f(xn)/f'(xn)


ax2+bx+c parabolaren erro bat kalkula dezagun Newton–Raphson metodoa aplikatuz non a, b eta c koefizienteak ezagunak diren. Hona hemen, Newton–Raphson metodotik eratorren formula:
xn+1 = xn f(xn)/f'(xn)
a, b eta c ezagunak izanik x lortu:
f(x)=ax2+bx+c
f'(x)=2ax+b

xi+1 = xi f(xi)/f'(xi)
xi+1 = xi - (axi2+bxi+c)/(2axi+b)

Kontu berezia eduki beharko dugu 2axi+b adierazpenaren balioarekin. Ez dugu onartuko zero izatea bestela programa era desegokian bukatuko delako, hots, goiko irudiko tangentea den lerro gorria ezin daiteke horizontala izan (tangente horrek ez luke OX ardatza moztuko).



Demagun a=1, b=-4 eta c=3 koefizienteak dituen parabolaren erroa kalkulatu nahi dugula. Irudian ikus daitekeen bezala x2-4x+3 parabolaren erroak 1 eta 3 dira. Bestalde, irudian ikusten da ere hurbilketa bezala ez dugula x=2 emango, puntu horretan maldak 0 balio duelako eta lerro horizontalak ez duelako OX ardatza mozten eta ondorioz programak abortatzen duelako.


Hurbilketa desberdinen araberako programaren hiru irteera hauek erakusten dira jarraian:

Hasierako hurbilketa 2.0000000001 edo handiagoa bada, emaitza 3.0 izango da

Hasierako hurbilketa 1.9999999999 edo txikiagoa bada, emaitza 1.0 izango da

Hasierako hurbilketa 2.0 bada algoritmoak huts egingo du

Zer gertatzen da hurbilketa 1.0 eta 3.0 artean badago (2.0 izan gabe, noski). Adibidez, zer gertatzen da hurbilketa 1.5 bada edo 2.5 bada. Kasu bietan emaitzak zuzenak dira, baina lortuko den erroa lehen hurbilketaren araberakoa da izango da:
  • Lehen hurbilketa 1.5 bada, emaitza den erroa 1.0 izango da
  • Lehen hurbilketa 2.5 bada, emaitza den erroa 3.0 izango da
Beraz, ikertzen ari garen x2-4x+3 parabolaren kasuan:
  • Lehen hurbilketa 2.0 baino txikiagoa bada, emaitza den erroa 1.0 izango da
  • Lehen hurbilketa 2.0 baino handiagoa bada, emaitza den erroa 3.0 izango da
  • Lehen hurbilketa 2.0 bada, ezin daiteke Newton–Raphson metodoa aplikatu



Demagun a=1, b=0 eta c=-9 koefizienteak dituen parabolaren erroa kalkulatu nahi dugula. Irudian ikus daitekeen bezala x2-9 parabolaren bi erroak 3 dira. Bestalde, irudian ikusten da ere hurbilketa bezala x=3 emango bagenu, puntu horretan malda 0 izan arren programa ondo ibiliko litzatekeela puntu hori soluzioa delako.

Hurbilketa desberdinen araberako programaren hiru irteera hauek erakusten dira jarraian:

2.1 hasierako hurbilketa 4.0 baino txikiagoa bada, emaitza 4.0 izango da

5.9 hasierako hurbilketa 4.0 baino handiagoa bada, emaitza 4.0 izango da

Hasierako hurbilketa 4.0 bada, iterazioa bakarrarekin 4.0 emaitza lortzen da




Lerroa horizontala ezin daitekeela izan arestian aipatu dugu, ikus dezagun orain zer gertatzen den ax2+bx+c parabolak OX ardatza ez duenan mozten ezta ikutzen ere ez.

Gogoratu Ariketa 14 | Bigarren graduko ekuazioa ariketa non Δ diskriminatzailearen arabera bigarren mailako ekuazio batek soluzio desberdinak izan ditzakeela:
  • Δ > 0, diskriminatzailea positiboa bada, bi soluzioak zenbaki erreal dira. Egoera hau aintzakotzat hartzen du aurreko NewtonErroErrealak.exe programak eta arazorik ez da sortzen (baldin eta lerro gorri horizontalik gertatzen ezbada)
  • Δ = 0, diskriminatzailea 0 bada, soluzioa bakarra da eta gainera zenbaki erreala. Egoera hau aintzakotzat hartzen du aurreko NewtonErroErrealak.exe programak eta arazorik ez da sortzen (nahiz eta hurbilketa puntuari dagokion lerro gorria lerro horizontala izan, hurbilketa puntu hori soluzioa baita)
  • Δ < 0, diskriminatzailea negatiboa bada, ez dago erro errealik eta bi soluzioak zenbaki konplexuak dira eta bata bestearen zenbaki konplexu konjugatu dira. Egoera hau ez du aintzakotzat hartzen aurreko NewtonErroErrealak.exe programak eta programaren exekuzioa ez da eteten, hurrengo adibidearen NewtonEdozeinParabola.exe programa  ikusi

Demagun a=1, b=-4 eta c=6 koefizienteak dituen polinomioaren erroa kalkulatu nahi dugula. Irudian ikus daitekeen bezala x2-4x+6 parabolak ez du OX ardatza mozten eta ondorioz erro errealik ez daukala.

x2-4x+6=0 polinomioaren kasuan ez dugu Newton-en metodoa aplikatuko, eta horren ordez bigarren graduko ekuazioaren formula erabiliko dugu:

Programa exekutatzean erro irudikarien kasua erakusten da hemen:

 Irudikariak direnean, hurbilketarik ez eskatu eta Newton-en metodoa ez aplikatu
(erro irudikariak bigarren graduko ekuazioaren formularen bitartez lortzen dira)


Bigarren graduko polinomio baten erro bat kalkulatu Newton–Raphson metodoa aplikatuz, non fA, fB eta fC koefizienteak teklatuz ematen diren eta prozesu errepikakorra gauzatzeko do-while agindua erabiltzen den:

/* Ariketa-29a_NewtonHurbilketaMetodoa: do-while agindua erabiliz */

//    Newton-Raphson metodoa
//    ----------------------
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (X¡*Xi - N) / 2*Xi
//    Xi+1 = (N/Xi + Xi) / 2

//    Irteteko baldintza:
//    fabs(Xi+1 - Xi) < fDoitasuna

//    -------

//    Bigarren graduko edozein parabola
//    Ax^2 + Bx + C = 0

//    f(x) = Ax^2 + Bx + C
//    f'(x) = 2Ax + B

//    Newton-Raphson metodoa
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (AXi^2 + BXi + C)/(2AXi + B)

//    Kontuz (2AXi+B) ez dadila zero izan,
//    halakoetan beste hurbilketa bat hautatu.

//    Kontuz parabolak OX ardatza ez duenean mozten ez ikutzen.
//    Halakoetan programaren exekuzioa ez da eteten, horregatik
//    B^2-4AC diskriminatzailea kalkulatu eta negatiboa izanez
//    gero erro irudikariak kalkulatu eta balioak pantailaratu.

#include <stdio.h>   // printf() eta scanf() funtzioetarako
#include <math.h>    // sqrt() funtziorako

#define fEPSILON  0.000000001

int main()
{
    float fA, fB, fC, fEmaitza, fAurrekoa, fDiskriminatzailea;

    printf("\n\n");
    printf("\n Bigarren graduko parabola baten erro bat kalkulatu");
    printf("\n --------------------------------------------------\n");

    printf(" x^2-ren A koefizientea eman (adibidez 1): ");
    scanf("%f", &fA);
    printf(" x-ren B koefizientea sartu (adibidez -4): ");
    scanf("%f", &fB);
    printf(" C koefiziente librea sartu (esaterako 3): ");
    scanf("%f", &fC);

    fDiskriminatzailea = fB*fB - 4*fA*fC;

    if (fDiskriminatzailea >= 0.0)
    {
        do
        {
            printf("\n Erroaren hurbilpen bat eman, x bat eman: ");
            scanf("%f", &fEmaitza);   // lehendabiziko hurbilketa

            printf("\n fEPSILON = %.9f   fHurbilpena = %.9f", fEPSILON, fEmaitza);

            if (2*fA*fEmaitza + fB == 0.0)
            {
                printf("\n Lehen lerroa horizontala da.");
                printf("\n Erroa ezin daiteke kalkulatu,");
                printf("\n beste hurbilpen bat eman.\n");
            }
        } while (2*fA*fEmaitza + fB == 0.0);

        do
        {
            fAurrekoa = fEmaitza;
            fEmaitza = fAurrekoa - (fA*fAurrekoa*fAurrekoa + fB*fAurrekoa + fC) / (2*fA*fAurrekoa + fB);
            printf("\n fAurrekoa = %.16f     fEmaitza = %.16f", fAurrekoa, fEmaitza);
        } while (fabs(fEmaitza - fAurrekoa) > fEPSILON);


        printf("\n %.1fX^2", fA);
        if (fB >= 0)
            printf(" +%.1fX", fB);
        else
            printf(" %.1fX", fB);
        if (fC >= 0)
            printf(" +%.1f = 0  ekuazioaren emaitza %.16f da", fC, fEmaitza);
        else
            printf(" %.1f = 0  ekuazioaren emaitza %.16f da", fC, fEmaitza);
    }
    else   // Diskriminatzailearen if-else
    {
        printf("\n %.1f X^2 + %.1f X + %.1f parabolak ez du OX ardatza mozten", fA, fB, fC);
        printf("\n Erroak irudikariak dira:");
        printf("\n x1 = %.2f X^2 +i(%.2f) eta", -fB/(2*fA), sqrt(-fDiskriminatzailea)/(2*fA));
        printf("\n x2 = %.2f X^2 -i(%.2f)", -fB/(2*fA), sqrt(-fDiskriminatzailea)/(2*fA));
    }

    printf("\n\n");
    return 0;
}


Bigarren graduko polinomio baten erro bat kalkulatu Newton–Raphson metodoa aplikatuz, non fA, fB eta fC koefizienteak teklatuz ematen diren eta prozesu errepikakorra gauzatzeko do-while agindua erabiltzen den:

/* Ariketa-29b_NewtonHurbilketaMetodoa: while agindua erabiliz */

//    Newton-Raphson metodoa
//    ----------------------
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (X¡*Xi - N) / 2*Xi
//    Xi+1 = (N/Xi + Xi) / 2

//    Irteteko baldintza:
//    fabs(Xi+1 - Xi) < fDoitasuna

//    -------

//    Bigarren graduko edozein parabola
//    Ax^2 + Bx + C = 0

//    f(x) = Ax^2 + Bx + C
//    f'(x) = 2Ax + B

//    Newton-Raphson metodoa
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (AXi^2 + BXi + C)/(2AXi + B)

//    Kontuz (2AXi+B) ez dadila zero izan,
//    halakoetan beste hurbilketa bat hautatu.

//    Kontuz parabolak OX ardatza ez duenean mozten ez ikutzen.
//    Halakoetan programaren exekuzioa ez da eteten, horregatik
//    B^2-4AC diskriminatzailea kalkulatu eta negatiboa izanez
//    gero erro irudikariak kalkulatu eta balioak pantailaratu.


#include <stdio.h>   // printf() eta scanf() funtzioetarako
#include <math.h>    // sqrt() funtziorako

#define fEPSILON  0.000000001

int main()
{
    float fA, fB, fC, fEmaitza, fAurrekoa, fDiskriminatzailea;

    printf("\n\n");
    printf("\n Bigarren graduko parabola baten erro bat kalkulatu");
    printf("\n --------------------------------------------------\n");

    printf(" x^2-ren A koefizientea eman (adibidez 1): ");
    scanf("%f", &fA);
    printf(" x-ren B koefizientea sartu (adibidez -4): ");
    scanf("%f", &fB);
    printf(" C koefiziente librea sartu (esaterako 3): ");
    scanf("%f", &fC);

    fDiskriminatzailea = fB*fB - 4*fA*fC;

    if (fDiskriminatzailea >= 0.0)
    {
        do
        {
            printf("\n Erroaren hurbilpen bat eman, x bat eman: ");
            scanf("%f", &fAurrekoa);   // lehendabiziko hurbilketa

            printf("\n fEPSILON = %.9f   fHurbilpena = %.9f", fEPSILON, fAurrekoa);

            if (2*fA*fAurrekoa + fB == 0.0)
            {
                printf("\n Lehen lerroa horizontala da.");
                printf("\n Erroa ezin daiteke kalkulatu,");
                printf("\n beste hurbilpen bat eman.\n");
            }
        } while (2*fA*fAurrekoa + fB == 0.0);

        fEmaitza = fAurrekoa - (fA*fAurrekoa*fAurrekoa + fB*fAurrekoa + fC) / (2*fA*fAurrekoa + fB);
        printf("\n fAurrekoa = %.16f     fEmaitza = %.16f  <-- kanpoan", fAurrekoa, fEmaitza);

        while (fabs(fEmaitza - fAurrekoa) > fEPSILON)
        {
            fAurrekoa = fEmaitza;
            fEmaitza = fAurrekoa - (fA*fAurrekoa*fAurrekoa + fB*fAurrekoa + fC) / (2*fA*fAurrekoa + fB);
            printf("\n fAurrekoa = %.16f     fEmaitza = %.16f", fAurrekoa, fEmaitza);
        }

        printf("\n %.1fX^2", fA);
        if (fB >= 0)
            printf(" +%.1fX", fB);
        else
            printf(" %.1fX", fB);
        if (fC >= 0)
            printf(" +%.1f = 0  ekuazioaren emaitza %.16f da", fC, fEmaitza);
        else
            printf(" %.1f = 0  ekuazioaren emaitza %.16f da", fC, fEmaitza);
    }
    else   // Diskriminatzailearen if-else
    {
        printf("\n %.1f X^2 + %.1f X + %.1f parabolak ez du OX ardatza mozten", fA, fB, fC);
        printf("\n Erroak irudikariak dira:");
        printf("\n x1 = %.2f X^2 +i(%.2f) eta", -fB/(2*fA), sqrt(-fDiskriminatzailea)/(2*fA));
        printf("\n x2 = %.2f X^2 -i(%.2f)", -fB/(2*fA), sqrt(-fDiskriminatzailea)/(2*fA));
    }

    printf("\n\n");
    return 0;
}



Ondoko Irudiaren gainean klik egin x3-3x funtzioa aztertzeko:

Ax3+Cx=0 itxurako hirugarren graduko polinomio baten erro bat kalkulatu Newton–Raphson metodoa aplikatuz, non fB eta fD koefizienteak 0.0 diren, eta fA teklatuz ematen den balio positiboa den, eta fC teklatuz ematen den balio negatiboa den:

/* Ariketa-29c1_HirugarrenGradukoPolinomioBat: do-while agindua erabiliz */

//    Newton-Raphson metodoa
//    ----------------------
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (X¡*Xi - N) / 2*Xi
//    Xi+1 = (N/Xi + Xi) / 2

//    Irteteko baldintza:
//    fabs(Xi+1 - Xi) < fDoitasuna

//    -------

//    Hirugarren graduko itxura hau duen polinomioa:
//    Ax^3 + Bx^2 + Cx + D = 0
//    Non:  # A positiboa
//          # B zero
//          # C negatiboa
//          # D zero

//    f(x) = Ax^3 + Cx
//    f'(x) = 3Ax^2 + C

//    Newton-Raphson metodoa
//    Xi+1 = Xi - f(Xi)/f'(Xi)
//    Xi+1 = Xi - (AXi^3 + CXi)/(3AXi^2 + C)

//    Kontuz (3AXi^2+C) ez dadila zero izan,

#include <stdio.h>   // printf() eta scanf() funtzioetarako
#include <math.h>    // sqrt() funtziorako

#define fEPSILON  0.000000001

int main()
{
    float fA, fC, fEmaitza, fAurrekoa;
    int iMoztu;  // lerro horizontala denean iMoztu=0 bestela iMoztu=0

    printf("\n\n");
    printf("\n Hirugarren graduko 1x^3-3x=0 polinomioaren erro bat kalkulatu");
    printf("\n -----------------------------=-------------------------------\n");

    do
    {
        printf(" x^3-ren A koefiziente positiboa eman (adibidez 1): ");
        scanf("%f", &fA);
    } while (fA <= 0.0);

    do
    {
        printf(" x-ren C koefiziente negatiboa sartu (adibidez -3): ");
        scanf("%f", &fC);
    } while (fC >= 0.0);

    do
    {
        printf("\n Erroaren hurbilpen bat eman, x bat eman: ");
        scanf("%f", &fEmaitza);   // lehendabiziko hurbilketa, edozein izan daiteke
        if (0.0 == 3*fA*fEmaitza*fEmaitza + fC)
            printf(" Lehen lerroa horizontala da, beste hurbilpen batekin saiatu...\n");
    } while (0.0 == 3*fA*fEmaitza*fEmaitza + fC);

    printf("\n fEPSILON = %.9f   fHurbilpena = %.9f", fEPSILON, fEmaitza);
    iMoztu = 0;
    do
    {
        fAurrekoa = fEmaitza;
        if (3*fA*fAurrekoa*fAurrekoa + fC == 0.0)   // lerroa horizontala bada errepikatze prozesua moztu
            iMoztu = 1;
        else
            fEmaitza = fAurrekoa - (fA*fAurrekoa*fAurrekoa*fAurrekoa + fC*fAurrekoa) / (3*fA*fAurrekoa*fAurrekoa + fC);
        printf("\n fAurrekoa = %.16f     fEmaitza = %.16f", fAurrekoa, fEmaitza);
    } while ((fabs(fEmaitza - fAurrekoa) > fEPSILON) && (iMoztu == 0));


    if (iMoztu == 1)   // lerroa horizontalik atera bada, mezua eta amaitu
    {
        printf("\n Lerro horizontala atera da.");
        printf("\n Erroa ezin daiteke kalkulatu,");
        printf("\n hurbilpen berriarekin saiatu.");
    }
    else
    {
        printf("\n %.1fX^3 %.1fX = 0 ekuazioaren emaitzaren bat %.16f da", fA, fC, fEmaitza);
    }

    printf("\n\n");
    return 0;
}

Ariketa-29c2_HirugarrenGradukoPolinomioBat.cbp proiektuan kalkulu bera egiten da baina prozesu errepikakora gauzatzeko while agindua erabiltzen da.







  • Ariketa-29a_NewtonHurbilketaMetodoa.cbp | main.c         [do-while]
  • Ariketa-29b_NewtonHurbilketaMetodoa.cbp | main.c         [while]
  • Ariketa-29c1_NewtonHurbilketaMetodoa.cbp | main.c       [do-while]
  • Ariketa-29c2_NewtonHurbilketaMetodoa.cbp | main.c       [while]


 

iruzkinik ez:

Argitaratu iruzkina