Programas en C++


logo de sanat

Método: Bisección

#include <iostream>
#include <cmath>
using namespace std;

double f(double x) {
    return x * x * x - x - 2;
}

int main() {
    double a = 1.0, b = 2.0;
    double tol = 1e-6;
    int maxIter = 100;

    if (f(a) * f(b) >= 0) {
        cout << "No hay raíz garantizada en [a,b]" << endl;
        return 1;
    }

    double c;
    for (int i = 0; i < maxIter; i++) {
        c = (a + b) / 2.0;

        cout << "Iter " << i + 1 << ": c = " << c
             << "  f(c) = " << f(c) << endl;

        if (fabs(f(c)) < tol || (b - a) / 2 < tol)
            break; // Convergió

        if (f(a) * f(c) < 0)
            b = c;
        else
            a = c;
    }

    cout << "Raíz aproximada: " << c << endl;
    return 0;
}

Salida esperada:

biseccion

Método: Punto fijo

#include <iostream>
#include <cmath>
using namespace std;

double g(double x) {
    return cbrt(x + 2);
}

int main() {
    double x = 1.5;
    double tol = 1e-6;
    int maxIter = 100;
    double xNuevo;

    for (int i = 0; i < maxIter; i++) {
        xNuevo = g(x);

        cout << "Iter " << i + 1 << ": x = " << xNuevo
             << "  |error| = " << fabs(xNuevo - x) << endl;

        if (fabs(xNuevo - x) < tol)
            break;

        x = xNuevo;
    }

    cout << "Punto fijo (raíz): " << xNuevo << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Newton

#include <iostream>
#include <cmath>
using namespace std;

double f(double x) { return x * x * x - x - 2; }
double df(double x) { return 3 * x * x - 1; }

int main() {
    double x = 1.5;
    double tol = 1e-8;

    for (int i = 0; i < 50; i++) {
        double fx  = f(x);
        double dfx = df(x);

        if (fabs(dfx) < 1e-12) {
            cout << "Derivada nula, el método falla." << endl;
            return 1;
        }

        double xNuevo = x - fx / dfx;

        cout << "Iter " << i + 1 << ": x = " << xNuevo
             << "  f(x) = " << f(xNuevo) << endl;

        if (fabs(xNuevo - x) < tol) break;
        x = xNuevo;
    }

    cout << "Raíz: " << x << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Gauss

#include <iostream>
#include <cmath>
using namespace std;
const int N = 3;

int main() {
    double mat[N][N + 1] = {
        {2,  1, -1,   8},
        {-3, -1,  2, -11},
        {-2,  1,  2,  -3}
    };

    for (int col = 0; col < N; col++) {
        int pivot = col;
        for (int row = col + 1; row < N; row++)
            if (fabs(mat[row][col]) > fabs(mat[pivot][col]))
                pivot = row;

        swap(mat[col], mat[pivot]);

        for (int row = col + 1; row < N; row++) {
            double factor = mat[row][col] / mat[col][col];
            for (int k = col; k <= N; k++)
                mat[row][k] -= factor * mat[col][k];
        }
    }

    double x[N] = {0};
    for (int i = N - 1; i >= 0; i--) {
        x[i] = mat[i][N];
        for (int j = i + 1; j < N; j++)
            x[i] -= mat[i][j] * x[j];
        x[i] /= mat[i][i];
    }

    cout << "Solución:" << endl;
    for (int i = 0; i < N; i++)
        cout << "x[" << i << "] = " << x[i] << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Gauss Seidel

#include <iostream>
#include <cmath>
using namespace std;
const int N = 3;

int main() {
    double A[N][N] = {
        {10, -1,  2},
        { 1,  11, -1},
        { 2, -1,  10}
    };
    double b[N] = {6, 25, -11};
    double x[N] = {0, 0, 0};
    double tol = 1e-6;

    for (int iter = 0; iter < 100; iter++) {
        double maxErr = 0;

        for (int i = 0; i < N; i++) {
            double suma = b[i];
            for (int j = 0; j < N; j++)
                if (j != i) suma -= A[i][j] * x[j];

            double xNew = suma / A[i][i];
            maxErr = max(maxErr, fabs(xNew - x[i]));
            x[i] = xNew;
        }

        cout << "Iter " << iter + 1 << ": ["
             << x[0] << ", " << x[1] << ", " << x[2]
             << "]  err=" << maxErr << endl;

        if (maxErr < tol) break;
    }

    cout << "x=" << x[0] << " y=" << x[1] << " z=" << x[2] << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Determinante

#include <iostream>
#include <cmath>
using namespace std;
const int N = 3;

double determinante(double mat[N][N]) {
    double temp[N][N];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            temp[i][j] = mat[i][j];

    double det = 1.0;
    int signo = 1;

    for (int col = 0; col < N; col++) {
        int pivot = col;
        for (int row = col + 1; row < N; row++)
            if (fabs(temp[row][col]) > fabs(temp[pivot][col]))
                pivot = row;

        if (pivot != col) {
            swap(temp[col], temp[pivot]);
            signo = -signo;
        }

        if (fabs(temp[col][col]) < 1e-12) return 0;

        det *= temp[col][col];

        for (int row = col + 1; row < N; row++) {
            double f = temp[row][col] / temp[col][col];
            for (int k = col; k < N; k++)
                temp[row][k] -= f * temp[col][k];
        }
    }
    return signo * det;
}

int main() {
    double A[N][N] = {{1, 2, 3}, {4, 5, 6}, {7, 2, 9}};
    cout << "det(A) = " << determinante(A) << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Descomposición Lu

#include <iostream>
using namespace std;
const int N = 3;

int main() {
    double A[N][N] = {{2, 1, -1}, {-3, -1, 2}, {-2, 1, 2}};
    double b[N] = {8, -11, -3};
    double L[N][N] = {}, U[N][N] = {};

    for (int i = 0; i < N; i++) {
        L[i][i] = 1.0;

        for (int k = i; k < N; k++) {
            double s = 0;
            for (int p = 0; p < i; p++) s += L[i][p] * U[p][k];
            U[i][k] = A[i][k] - s;
        }

        for (int k = i + 1; k < N; k++) {
            double s = 0;
            for (int p = 0; p < i; p++) s += L[k][p] * U[p][i];
            L[k][i] = (A[k][i] - s) / U[i][i];
        }
    }

    double y[N] = {};
    for (int i = 0; i < N; i++) {
        double s = b[i];
        for (int j = 0; j < i; j++) s -= L[i][j] * y[j];
        y[i] = s;
    }

    double x[N] = {};
    for (int i = N - 1; i >= 0; i--) {
        double s = y[i];
        for (int j = i + 1; j < N; j++) s -= U[i][j] * x[j];
        x[i] = s / U[i][i];
    }

    for (int i = 0; i < N; i++)
        cout << "x[" << i << "] = " << x[i] << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Newton multivariable

#include <iostream>
#include <cmath>
using namespace std;
const int N = 2;

void evalF(double x, double y, double f[N]) {
    f[0] = x * x + y * y - 4;
    f[1] = x * y - 1;
}

void evalJ(double x, double y, double J[N][N]) {
    J[0][0] = 2 * x;
    J[0][1] = 2 * y;
    J[1][0] = y;
    J[1][1] = x;
}

void solve2x2(double J[N][N], double f[N], double dx[N]) {
    double det = J[0][0] * J[1][1] - J[0][1] * J[1][0];
    dx[0] = (-f[0] * J[1][1] + f[1] * J[0][1]) / det;
    dx[1] = (-f[1] * J[0][0] + f[0] * J[1][0]) / det;
}

int main() {
    double x = 1.5, y = 0.5;

    for (int i = 0; i < 50; i++) {
        double f[N], J[N][N], dx[N];
        evalF(x, y, f);
        evalJ(x, y, J);
        solve2x2(J, f, dx);

        x += dx[0];
        y += dx[1];

        double err = sqrt(dx[0] * dx[0] + dx[1] * dx[1]);
        cout << "Iter " << i + 1 << ": x=" << x << " y=" << y
             << " err=" << err << endl;

        if (err < 1e-8) break;
    }

    cout << "Solución: x=" << x << " y=" << y << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Potencias

#include <iostream>
#include <cmath>
using namespace std;
const int N = 3;

void matvec(double A[N][N], double v[N], double w[N]) {
    for (int i = 0; i < N; i++) {
        w[i] = 0;
        for (int j = 0; j < N; j++)
            w[i] += A[i][j] * v[j];
    }
}

int main() {
    double A[N][N] = {{4, 1, 0}, {2, 3, 0}, {0, 0, 5}};
    double v[N] = {1, 0, 0};
    double lambda = 0, tol = 1e-8;

    for (int i = 0; i < 100; i++) {
        double w[N];
        matvec(A, v, w); // w = A·v

        double lNew = 0;
        for (int k = 0; k < N; k++)
            lNew = max(lNew, fabs(w[k]));

        for (int k = 0; k < N; k++)
            v[k] = w[k] / lNew;

        cout << "Iter " << i + 1 << ": λ = " << lNew << endl;

        if (fabs(lNew - lambda) < tol) {
            lambda = lNew;
            break;
        }
        lambda = lNew;
    }

    cout << "Eigenvalor dominante: " << lambda << endl;
    cout << "Eigenvector: [";
    for (int i = 0; i < N; i++)
        cout << v[i] << (i < N - 1 ? "," : "");
    cout << "]" << endl;
    return 0;
}
  

Salida esperada:

biseccion

Método: Polinomio de lagrange

#include <iostream>
using namespace std;


double lagrange(double xs[], double ys[], int n, double x) {
    double resultado = 0;

    for (int i = 0; i < n; i++) {
        double Li = 1.0;
        for (int j = 0; j < n; j++) {
            if (j != i)
                Li *= (x - xs[j]) / (xs[i] - xs[j]);
        }
        resultado += ys[i] * Li;
    }
    return resultado;
}

int main() {
    double xs[] = {0, 1, 2, 3};
    double ys[] = {1, 3, 2, 5};
    int n = 4;

    double pts[] = {0.5, 1.5, 2.5};
    for (double xp : pts)
        cout << "P(" << xp << ") = "
             << lagrange(xs, ys, n, xp) << endl;

    return 0;
}
  

Salida esperada:

biseccion

Método: Diferencias divididas

#include <iostream>
using namespace std;
const int N = 4;

int main() {
    double x[N] = {0, 1, 2, 3};
    double y[N] = {1, 3, 2, 5};

    double dd[N][N] = {};
    for (int i = 0; i < N; i++) dd[i][0] = y[i];

    for (int j = 1; j < N; j++)
        for (int i = 0; i < N - j; i++)
            dd[i][j] = (dd[i + 1][j - 1] - dd[i][j - 1])
                        / (x[i + j] - x[i]);

    cout << "Coeficientes: ";
    for (int k = 0; k < N; k++)
        cout << dd[0][k] << " ";
    cout << endl;

    auto evalP = [&](double xp) {
        double p = dd[0][N - 1];
        for (int k = N - 2; k >= 0; k--)
            p = p * (xp - x[k]) + dd[0][k];
        return p;
    };

    cout << "P(0.5) = " << evalP(0.5) << endl;
    cout << "P(1.5) = " << evalP(1.5) << endl;
    cout << "P(2.5) = " << evalP(2.5) << endl;
    return 0;
}
  

Salida esperada:

biseccion