Metoda regula falsi

Michal

Metoda regula falsi
« kdy: 15. 03. 2012, 20:47:03 »
Dobrý deň, potreboval by som pomocť s úpravou tohto programu bisekice na progrma regula falsi vedeli by ste pomocť?

// Bisekcia.cpp : Defines the entry point for the console application.
//


#include <stdio.h>
#include <math.h>



double fcia(double x)
{
   //return (sin(x)-5*x-3);
return ((x*x)-x-sin(x));
}


main(void)
{
double x,a,b;
float e;

int n=0;//MAX;

   //printf("Max Pocet iteracii: ");
   //scanf("%d",&MAX);


   printf("Zadaj x1: ");
   scanf("%f",&e);
   a=e;
   printf("Zadaj x2: ");
   scanf("%f",&e);
   b=e;
   printf("Zadaj eps: ");
   scanf("%f",&e);

   while ((fabs(b-a)>e))//&&(n<MAX))
   {
      n++;
      x=a-((b-a)/(fcia(b)-fcia(x)))*fcia(x);

      printf("x[%d]= %f\n",n,x);
   }
   printf("\n Koren je: %f\nPocet iteracii: %d\n",x,n);
}


b00n

Re:Metoda regula falsi
« Odpověď #1 kdy: 15. 03. 2012, 21:44:01 »
Sice to vyzera ako domaca uloha, ale tak aby si nepovedal ze su na teba vsetci zli...

1) Ani ta bisekcia nevyzera ze by fungovala. Nemas ten while nahodou nekonecny? Alebo sa tam niekde meni a, b alebo e, ktore tvoria podmienku?
2) Regula falsi z toho dostanes tak, ze v cykle vypocitas x (resp. c) podla vzorca na http://en.wikipedia.org/wiki/False_position_method, a potom ak x ma rovnake znamienko ako a, tak sa stane novym a, ak rovnake ako b, stane sa novym b.

Waseihou

Re:Metoda regula falsi
« Odpověď #2 kdy: 15. 03. 2012, 21:53:51 »
A co přesně na tom chceš upravovat? Kód je nečitelný, pravda.

scanf jde udělat přímo do cílových proměnných a,b,c bez použití mezikroku přes e

mainu dej návratovou hodnotu int byť je to jen kvůli čitelnosti, je to dobrá praxe

přidej to zakomentované max a dej mu rozumnou hodnotu tak aby to mělo jistotu že to někdy skončí, nejsem si u regula falsi jistý

main by mělo vracet nějakou hodnotu, hoď tam return 0 na konec

Vypadá to jako projekt do školy, pokud pod pojmem "upravit" myslíš "obfuskaci" tak zkus "svoji" verzi testovat Sherlockem.

http://sydney.edu.au/engineering/it/~scilect/sherlock/

Vím že se to nemá, ale v takto krátkém případě asi moc navíc neuděláš takže obfuskace bude složitější a naučení se používat sherlock a účinně pozměnit kód bude více edukativní než ta regula falsi ;)

Aby jsi mohl úspěšně přepsat kód tak aby nebylo poznat z čeho vycházíšm musíš umět jazyk c na velmi dobré dobré úrovni. Já když jsem si před pár lety takto párkrát "přividělal" tak jsem dosahoval shody menší než 3%, ale byla to makačka ;)

- odstraň comment, lol
- závorky změn styl odsazení
- double nahraď typedef double Real; a všude použij Real místo doublu, přidej comment že je to aby bylo možno snadno změnit typ pro reprezentaci reálných čísel kvůli porovnání rychlosti
- změn pořadí include
- do main přihoď int argc, char *argv[] které buď použiješ int MAX=atoi(argv[1]) nebo nepoužiješ vůbec
- max může být i konstanta const MAX = 100000; nebo makro #define MAX 100000
- načtení parametrů do oddělené funkce na procvičení je hoď do struktury kterou předáš pomocí ukazatele
- celý algoritmus regula falsi také přepiš do oddělené funkce která vrátí výsledek, parametr pro zápis do souboru (třeba stdout) se použije pokud není NULL
hint: double regula_falsi(double a, double b, double eps, FILE *fw) { ... if (fw) fprintf(fw,"..."); }
- výpis hodnot pole tak také oddělenou funkci pro procvičení paradigmatu funkcionální programování a rozkladu problému na podproblémy, výpis opět do libovolného souboru
- čtení taky přes parametr na soubor a přihodit výběr in a out souborů pomocí argc, argv
- a v main z toho poskládat program
- komenty udělej ve tvaru kompatibilní s doxygenem: http://www.stack.nl/~dimitri/doxygen/

No a pokud toto vše uděláš, tak nikdo nepozná z čeho jsi vyšel, ale ta práce navíc. No a máš to, študáku líný  ;D
Za výše popsané řešení dostaneš určitě plný počet bodů  ;)

Waseihou

Re:Metoda regula falsi
« Odpověď #3 kdy: 15. 03. 2012, 21:57:51 »
Jo a ten cyklus nikdy neskončí protože podmínka cyklu se nemění, máš ten algoritmus blbě ;)

Stanley

Re:Metoda regula falsi
« Odpověď #4 kdy: 16. 03. 2012, 10:43:21 »
Několik málo částí programu je dobře, ale podstatné je to, že jsi asi ani nepochopil samotnou metodu a co se s tím má dělat, ani jsi nás zcela neseznámil se zadáním. Zadání nejspíš zní pomocí metody regula falsi najdi kořen funkce x*x-x-sin(x) v intervalu <x1;x2> se zadanou přesností epsilon, výpočet omezte počtem iterací n.

Jak psal kolega, můžeš načíst proměnné a, b přímo, takže
 printf("Zadaj x1: ");
 scanf("%f",&a);
 printf("Zadaj x2: ");
 scanf("%f",&b);
 printf("Zadaj eps: ");
 scanf("%f",&e);

Měla by i proběhnout kontrola, že hodnota funkce f v bodě x1 má opačné znaménko než funkční hodnota v bodě x2, dá se vyřešit podmínkou f(x1)*f(x2)<0, z toho je jasné, že kořen musí mezi body x1 a x2 existovat

Pak jsi vypočítal novou hodnotu x (lepší by bylo označit c, když už je x1=a, x2=b), kterou jsi vypočetl úplně špatně (ten vzorec je úplně mimo, evidentně jsi to nepochopil), mělo být:
x=(fcia(b)*a-fcia(a)*b)/(fcia(b)-fcia(a))

Pak následuje další krok, co udělat s novou hodnotou x, pokud f(x) má stejné znaménko jako f(a) (opět lze použít podmínku součinu), pak přiřaď x do a, tedy a=x, hodnota b zůstane bez změny, pokud má f(x) stejné znaménko jako f(b), pak se naopak přiřadí x do b, tedy b=x.

Po tomto kroku teprve probíhá nějaká iterace a můžeš se dobrat k výsledku, pak si tam odpoznámkuj omezující podmínku pro počet iterací (to máš dobře) a výsledek je na světě.

Mohl bych tady napsat celý program, ale trochu tvé snahy snad neuškodí, napověděl jsem snad dost.

Stanley