Anuncio

Colapsar
No hay ningún anuncio todavía.

Método de la bisección

Colapsar
X
 
  • Filtro
  • Hora
  • Mostrar
Borrar todo
nuevos mensajes

  • Matlab Método de la bisección

    Buenas a todos! La primera vez en mi vida de forero que me paso por el subforo de informática

    les vengo con una pregunta que me está trayendo muchos quebraderos de cabeza. Se trata de programar el método de la bisección. Mi código es:
    [FONT=Fixedsys]
    function [y0]=mdo_biseccion(xi,xf)
    %Método de la bisección con f(x)=x^2-9

    tol=1e-3;
    flag=1;

    while (flag)
    xm=(xf-xi)/2;
    ym=f(xm);
    if (ym~=0)
    if (ym*f(xi)>0)
    xi=xm;
    else
    xf=xm;
    end
    else
    flag=0;
    end
    flag=(xf-xi>tol);
    end
    y0=ym;
    end

    function [r]=f(x)
    r=x*x-9;
    end
    [/FONT]

    Para los que no sepan en qué consiste el método de la bisección: miren la página 10 y 11 de este Link

    El problema está en que me entra en un bucle infinito. La verdad, no entiendo por qué leches lo hace, si debería salir del while principal de una forma u otra.

    Gracias por vuestra ayuda, que ojalá sea temprana dado que el lunes me examino de esto.

    Saludos
    Última edición por skinner; 04/06/2011, 20:49:31.

  • #2
    Re: Método de la bisección

    ¿Con qué instrucción llamaste la rutina? Específicamente, ¿te aseguraste de que la función tiene signos diferentes en xi y xf? Pregunto porque veo que en la función no hay ningún chequeo.

    Bueno, supongo que si los extremos tuviesen el mismo signo la rutina debería morir en uno de los extremos cuando xf-xi sea menor que tol... o lo haría, si el valor de xm lo calculases en la mitad del intervalo. Debería decir xm=(xf+xi)/2. <--- Nota el signo

    Saludos,

    Al

    PD. ¿Tu función no debería devolver el valor de la coordenada xm de la raiz? Porque lo que devuelve es el valor de la función, que debe ser cero o próximo a cero siempre.
    Última edición por Al2000; 04/06/2011, 21:28:50. Motivo: Añadir postdata.
    Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

    Comentario


    • #3
      Re: Método de la bisección

      Hola Al, antes de nada gracias por tu respuesta.

      Aunque el programa no haga ningún chequeo, yo me aseguro que ambos puntos de abscisas den un valor positivo y otro negativo de la función. No puse ningún chequeo para simplificar un pelín las cosas, pero puede hacerse con un bucle while y una variable bandera (flag). Digamos que el usuario tiene que cerciorarse antes de que los valores son correctos.

      Por otro lado me he dado cuenta que en mi programa hago xm=(xf-xi)/2 en lugar dexm=(xf+xi)/2. He probado a cambiarlo (tanto en la condición flag[FONT=Fixedsys]=(xf+xi>tol) [FONT=Tahoma][FONT=Verdana]como en el cálculo[/FONT] [/FONT][/FONT][FONT=Fixedsys]xm=(xf+xi)/2;[/FONT][FONT=Fixedsys] [FONT=Verdana]pero aún así sigue sin funcionarme. Mi llamada a la función es:

      >> mdo_biseccion(0,4)

      Sigue entrando en bucle infinito... lo curioso es que si le pongo un valor lo suficientemente alto a [/FONT]
      [/FONT]tol[FONT=Fixedsys][FONT=Verdana] (por ejemplo, tol=1), el programa sí me devuelve un valor.

      Un saludo y espero tu ayuda.
      [/FONT]
      [/FONT]

      Comentario


      • #4
        Re: Método de la bisección

        Hola Al, antes de nada gracias por tu respuesta.

        Aunque el programa no haga ningún chequeo, yo me aseguro que ambos puntos de abscisas den un valor positivo y otro negativo de la función. No puse ningún chequeo para simplificar un pelín las cosas, pero puede hacerse con un bucle while y una variable bandera (flag). Digamos que el usuario tiene que cerciorarse antes de que los valores son correctos.

        Por otro lado me he dado cuenta que en mi programa hago xm=(xf-xi)/2 en lugar dexm=(xf+xi)/2. He probado a cambiarlo (tanto en la condición flag[FONT=Fixedsys]=(xf+xi>tol) [FONT=Tahoma][FONT=Verdana]como en el cálculo[/FONT] [/FONT][/FONT][FONT=Fixedsys]xm=(xf+xi)/2;[/FONT][FONT=Fixedsys] [FONT=Verdana]pero aún así sigue sin funcionarme. Mi llamada a la función es:

        >> mdo_biseccion(0,4)

        Sigue entrando en bucle infinito... lo curioso es que si le pongo un valor lo suficientemente alto a [/FONT]
        [/FONT]tol[FONT=Fixedsys][FONT=Verdana] (por ejemplo, tol=1), el programa sí me devuelve un valor.

        Muchas gracias por tu paciencia. Un saludo!
        [/FONT]
        [/FONT]

        Comentario


        • #5
          Re: Método de la bisección

          Código:
          [FONT=Fixedsys]function [x0]=mdo_biseccion(xi,xf)  [/FONT][FONT=Arial]<--- cambiada la variable a devolver[/FONT]
          [FONT=Fixedsys]%Método de la bisección con f(x)=x^2-9 [/FONT]
           
          [FONT=Fixedsys] tol=1e-3;[/FONT]
          [FONT=Fixedsys] flag=1;[/FONT]
           
          [FONT=Fixedsys] while (flag)[/FONT]
          [FONT=Fixedsys]  xm=(xf+xi)/2;  [/FONT][FONT=Arial]<--- cambiado el signo a suma[/FONT]
          [FONT=Fixedsys]  ym=f(xm);[/FONT]
          [FONT=Fixedsys]  if (ym~=0)[/FONT]
          [FONT=Fixedsys]   if (ym*f(xi)>0)[/FONT]
          [FONT=Fixedsys]    xi=xm;[/FONT]
          [FONT=Fixedsys]   else[/FONT]
          [FONT=Fixedsys]    xf=xm;[/FONT]
          [FONT=Fixedsys]   end[/FONT]
          [FONT=Fixedsys][FONT=Fixedsys]   flag=(xf-xi>tol);  [FONT=Arial]<--- línea movida de posición, mantener resta[/FONT][/FONT]
            else[/FONT]
          [FONT=Fixedsys]   flag=0;[/FONT]
          [FONT=Fixedsys]  end[/FONT]
          [FONT=Fixedsys] end[/FONT]
          [FONT=Fixedsys] x0=xm;  [/FONT][FONT=Arial]<--- cambiada la variable a devolver[/FONT]
          [FONT=Fixedsys]end[/FONT]
           
          [FONT=Fixedsys]function [r]=f(x)[/FONT]
          [FONT=Fixedsys] r=x*x-9;[/FONT]
          [FONT=Fixedsys]end[/FONT]
          Arriba te sugiero algunos cambios. Unos comentarios puntuales:

          - La determinación del punto medio se hace tomando el promedio de los extremos, pero el chequeo de la convergencia se hace midiendo el ancho del intervalo [FONT=Fixedsys]xf-xi[/FONT].

          - Cada lenguaje tiene sus peculiaridades. Yo no conozco este y no se cual es el orden de las precedencias. Ante la duda, yo haría el chequeo de tolerancia con paréntesis extra para asegurar que la resta se haga primero: [FONT=Fixedsys]flag=((xf-xi)>tol)[/FONT].

          - Como no estás haciendo ningún chequeo, en la llamada debes tomar la precaución de que [FONT=Fixedsys]xf>xi[/FONT] y [FONT=Fixedsys]f(xi)*f(xf)<0[/FONT]. Anbos chequeos podrían ser incorporados al principio de la rutina y tomar la acción apropiada (mensaje de error en el primero, intercambiar [FONT=Fixedsys]xi[/FONT] y [FONT=Fixedsys]xf[/FONT] en el segundo).

          Saludos,

          Al

          PD. Perdón por la mala indentación. Quise hacerla correctamente, pero al final el editor puso lo que le dio la gana .
          Última edición por Al2000; 05/06/2011, 16:28:55. Motivo: Añadir postdata.
          Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

          Comentario


          • #6
            Re: Método de la bisección

            Gracias de nuevo Al2000. Todos los cambios los he realizado y he tomado en verdadera consideración tus comentarios. Sin embargo el programa sigue sin funcionar. También he puesto los paréntesis en la condición, para asegurarnos de que la resta se hace primero.

            A ver si alguien que sepa de Matlab puede probar este programa y decirme qué está fallando

            Saludos y muchas gracias!
            Última edición por skinner; 05/06/2011, 19:29:07.

            Comentario


            • #7
              Re: Método de la bisección

              skinner, lo tipee lo mas textualmente posible en Mathcad y funciona como sería de esperar. Te pego una copia de pantalla:

              Haz clic en la imagen para ampliar

Nombre:	m
Vitas:	1
Tamaño:	13,7 KB
ID:	300335

              Lo único que se me ocurre decirte que pruebes es poner tol = 0.001, no sea que no te esté aceptando el formato 1e-3.

              Saludos,

              Al
              Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

              Comentario


              • #8
                Re: Método de la bisección

                Gracias por tu tiempo Al2000. Cambié el formato como dijiste, pero nada de nada. Veré si el profesor puede solucionarlo, y si no, será un misterio de por vida, jeje.

                Por cierto, ¿cómo puedes indentar el texto en tus posts? Yo lo intenté y no pude.

                Un saludo!

                Comentario


                • #9
                  Re: Método de la bisección

                  Usa las etiquetas [CODE][/CODE] que cambia el font a monoespaciado y respeta los espacios, al menos de forma limitada, no estoy seguro. Al parecer cada vez que haces un preview elimina los espacios iniciales, aún dentro de las etiquetas code.

                  Comentario final: métele la lupa a todo lo que tipeaste, no vayas a tener un duende camuflado por ahí jejeje

                  Saludos,

                  Al
                  Don't wrestle with a pig in the mud. You'll both get dirty, but the pig will enjoy it. - Parafraseando a George Bernard Shaw

                  Comentario

                  Contenido relacionado

                  Colapsar

                  Trabajando...
                  X