» »

[delphi] problem : Bisekcijska metoda

[delphi] problem : Bisekcijska metoda

ru7 ::

Imam problem s enim projektom v delphiju. Stvar sem si zastavil tako, vendar dobiva zelo čudne rezultate in ne najdem napake.
Bisekcijsko metodo lepo razloži ta animacija spodaj.


Imamo 2 točki, ena naprimer 0.05 druga pa 100000. Na Y-osi imam električno poljsko jakost (recimo, da je to številka 500, pač neka vrednost). Če naj bi Eh presegel vrednost E (500) potem je Hmax=H, če ni pa Hmin=H
Opis programa spodaj:

 //bisekcijska metoda
      Hmin:=R4; // je 0.05
      Hmax:=100;  
    while (abs(Hmax-Hmin)>1E-10) do  //to naj bi ponavljal dokler ni razlika med Hmax in Hmin //1E-10
    begin
      H:=(Hmin+Hmax)/2;  //izracunamo H
      X4:=(H)/(R4);  //to samo uporabimo v enačbi za Eh (ni tako pomembno)
      Eh:=(U4*sqrt(sqr(X4)-1)/(R4*(X4-1)*ln(X4+sqrt(sqr(X4)-1))));  //pač naša enačba
      if (Eh>E4) then   //če je Eh>500 potem
        Hmax:=(Hmin+Hmax)/2  //naša nova maksimalna točka je prejšnja srednja
      else Hmin:=(Hmin+Hmax)/2;   //ali pa naša nova minimalna točka je naša srednja
    end;
    LabelRezultat4.Caption:=('h = ' + FloatToStr(H));   //izpis rezultata


Zatakne se pri številkah. Jst mislim, da bi moglo štimat samo noče. Rezultat mi vrne 99.99999....
Bi pa mogu bit pomojem okoli 0.5


Upam, da sem kokr tok razulmljivo napisu.
Hvala za pomoč
  • zavarovalo slike: OwcA ()

CCfly ::

//bisekcijska metoda
      Hmin:=R4; // je 0.05
      Hmax:=100;
      C := (Hmin + Hmax) / 2
      yA := jakost(Hmin)
      yC := jakost(C );
    while (abs(yC)>1E-10) and (Hmax-Hmin > 1E-10) do
    begin
      if yA * yC < 0 then begin
            Hmax = C;
      else begin
            Hmin := C;
            yA := yC;
      end;
      H := (Hmin+Hmax)/2;
      yC := jakost(C );
    end;
    LabelRezultat4.Caption:=('h = ' + FloatToStr(H));  
"My goodness, we forgot generics!" -- Danny Kalev

Zgodovina sprememb…

  • spremenilo: CCfly ()

CCfly ::

Tista HTML koda je C.
"My goodness, we forgot generics!" -- Danny Kalev

ru7 ::

Hvala za pomoč, samo me baga kaj si mislu s tem "jakost(C)" pa to. Ne štekam.

Nerdor ::

Druga beseda za jakost je intenzivnost. Samo ali ni Jakost() metoda (aka procedura ali funkcija) !? Torej ergo nemore biti Jakost© (Alt+0169). Ali je mogoče kakšna globja razlaga, maybe?

CCfly ::

jakost ( C ) je procedura ja

edit: sem popravil
"My goodness, we forgot generics!" -- Danny Kalev

Zgodovina sprememb…

  • spremenilo: CCfly ()

ru7 ::

Bom kr začel z vprašanji:
1.) Kam je zginla enačba za Eh (A si to zamenju s temi yC, yA, ...)?
2.) Kaj sploh predstavlja yC, yA, kako to deklerirat (?), a kot funkcijo ali klasična spremenljivka?

Hmm, verjetno se bo še kako vprašanje našlo. :)
Hvala za vso pomoč!

CCfly ::

1.) Kam je zginla enačba za Eh (A si to zamenju s temi yC, yA, ...)?
Predvidevam da s to enačbo izračunah jakost v točki x (oziroma H). Naredi si torej proceduro jakost z ustreznimi parametri, ki ti vrne izračunano jakost.
2.) Kaj sploh predstavlja yC, yA, kako to deklerirat (?), a kot funkcijo ali klasična spremenljivka?
To sta spremenljivki, ki predstavljata jakost v točkah Hmin in C. Deklariraj jih kot realno število.
"My goodness, we forgot generics!" -- Danny Kalev

ru7 ::

V bistvu sem zdej še bolj zmeden.
Nism tok specialista, da bi šu sam neke procedure pisat. A se ne da bolj poenostavljeo napisat tega (/me n00b >:D ), to pa delam neki za šolo.

Okej, če se lotimo pisanja procedure, a to napišem znotraj zanke (ker rabiš H (ali C), ki se računa sproti.
yC ter yA sem dekleriral kot Double.
Kokr jst vem, ne morš kr napisat "jakost(C )", ker je delphi čist navdušen z errorji :D, dekleracija bla bla.

To bo težji oreh kot sem mislu.

CCfly ::

Pa pojdimo čez algoritem:
Imaš:
- funkcijo, ki ti izračunba jakost v določeni točki (H oziroma rečimo ji kar x)
Se pravi: y = jakost(x)
- točki a in b, ki sta izbrani točki na nekem intervalu (x os), kjer imata vrednosti funkcije jakost (vrednosti y v točkah a in b) nasprotna predznak, oz. a je negativna, b je pozivitna ali obratno.
Se pravi če imata a in b enak predznak bisekcija ne bo delovala, ker med točkama ni ničle.
- točka c, ki leži med točkama a in b

a := leva točka
b := desna točka
c := (a+b)/2
yA := jakost(A)
yC := jakost(C )
Se pravi tukaj imamo dve točki (x, y), ki ležita na tvoji funkciji.

dokler (yC ni dovolj blizu ničle) in dokler (razlika med trenutnima krajiščema a in b ni dovolj majhna) {
če je ena od vrednosti yA in yC desno krajišče b premakni v točko c
drugače pa levo krajišče a premakni v c in zračunaj jakost v tej točki

izračunaj novo točko c med krajiščema a in b (eno od teh dveh se je premaknilo zato je potrebno spet vzeti vmesno točko)
izračunaj jakost v točki c
}

Kokr jst vem, ne morš kr napisat "jakost(C )", ker je delphi čist navdušen z errorji :D, dekleracija bla bla.
Proceduro jakost moraš deklarirati.

Upam da je dovolj jasno drugače pa vprašaj.
"My goodness, we forgot generics!" -- Danny Kalev

Zgodovina sprememb…

  • spremenilo: CCfly ()

ru7 ::

Pri meni je leva točka +0.05 , desna pa 1E500 oddaljena. Jst naj bi pol izračunal h vodnika od stene. Sepravi ne more bit manj od radija vodnika (0.05) in pri meni torej ta točka ni negativna !?


PS: Glede dekleracije:
procedure TFormEmax.ButtonIzracunClick(Sender: TObject);
var
jakost, R3, ..... : Double;

Taka dekleracija ni dobra (predvidevam), ker potem mi zamori ko compajlam, da manjka ";". Ob taki dekleraciji ko napišeš
jakost(Hmin); on tega ne razume. Hoče, da mu daš za jakost podpičje.

Zgodovina sprememb…

  • spremenil: ru7 ()

CCfly ::

Eh malo slabo sva začela. Ti iščeš točko (x,y), kjer tvoja funkcija (jakost) seka x.
Se pravi rešuješ enačbo jakost(x) = 0.
To točko ti najde tvoj algoritem, toda moraš imeti eno točko kjer je jakost(x) manjša od nič in drugo kjer je jakost(x) večja od nič.

Nisem elektrotehnik, tako da bova težko debatirala o jakosti sami, toda tole je čista numeričnam matematika.
"My goodness, we forgot generics!" -- Danny Kalev

ru7 ::

EDIT: Bomo probal :)

Zgodovina sprememb…

  • spremenil: ru7 ()

ru7 ::

Hmin:=R4; // je 0.05
Hmax:=100;
C:=(Hmin + Hmax)/2;
yA:=(U4*sqrt(sqr((Hmin)/(R4))-1)/(R4*((Hmin)/(R4)-1)*ln((Hmin)/(R4)+sqrt(sqr((Hmin)/(R4))-1))));
yC:=(U4*sqrt(sqr(©/(R4))-1)/(R4*(©/(R4)-1)*ln(+sqrt(sqr(©/(R4))-1))));
while (abs(yC)>1E-10) and (Hmax-Hmin>1E-10) do
begin
if yA*yC < 0 then
Hmax:=C
else
begin
Hmin:=C;
yA:=yC;
end;
H:=(Hmin+Hmax)/2;
yC:=(U4*sqrt(sqr(©/(R4))-1)/(R4*(©/(R4)-1)*ln(+sqrt(sqr(©/(R4))-1))));
end;
LabelRezultat4.Caption:=('h = ' + FloatToStr(H));


A je to to, kot si mislu? Kaj pa un tazadnji yC (a je enkak unmu zgoraj, al maš notri končni H?)

Gundolf ::

Tvoja prva bisekcija je videti čisto v redu. Zakaj pa si tako prepričan da ti ne dela? Če dobiš rezultat 99.999... in si na začetku postavil zgornjo mejo 100, potem to pomeni, da si dal prenizko zgornjo mejo.

Na roke zračunaj koliko dobiš to tvojo jakost (ali karkoli že računaš) v točki h=100. Če dobiš več kot 500 potem ti zadeva špila, če manj potem je res nekaj narobe. Morda si se zmotil v kakšni konstanti znotraj enačbe.

V sami bisekciji pa kot pravim, ne vidim napake (lahko se motim).

Ti bo pa pmagalo, če res ločis procedure oziroma funkcije, mislim da funkcijo napišeš takole:
function jakost(h:double) : double
begin
jakost := //tista tvoja enačba
end

Če boš imel posebej funkcijo za jakost boš lahko tudi takoj reveril če je pravilno napisana:
LabelRezultat4.Caption:=('jakost(100) = ' + FloatToStr(jakost(100)));

CCfly ::

Mislim da je namesto besede function procedure.
"My goodness, we forgot generics!" -- Danny Kalev

ru7 ::

ql, bom probu z dekleracijo jakosti :)

Do zdej zgleda ql (ni errorjev), samo dobim nazaj že pri yC "invalid floating operation).

Gundolf ::

Nope, pascal (ali delphi) loči funkcije ki nič ne vračajo - procedure in funkcije ki nekaj vrnejo - function.

Še nekaj sem spregledal
v čisto prvem postu napišeš
if (Eh>E4) then   //če je Eh>500 potem

kar se sklada s sliko, k si jo dal ampak se ne sklada z mojim razumevanjem štroma. Namreč - ali se ne bi morala električna poljska jakost zmanjševati od vodnika proti neskončnosti?
Ker če je to res, potem samo obrni tisti 'večje' v manjše' in bi moralo delat. Torej tako:
if (Eh<E4) then   //če je Eh>500 potem

Zgodovina sprememb…

  • spremenil: Gundolf ()

ru7 ::

Ob prenosu slike je animacija šla pa-pa, tako da evo še enkrat povezava. Ta slika je naključna funkcija in nima veze z mojim problemom, prikaže le princip bisekcije.

Kar se tiče problema 99.99... je tako, da če dam za Hmax:=10000; potem bo rezultat 9999,999... tako da mislim, da originalen načrt ni delal kot treba.

ru7 ::

Sem obrnu un znak in mislim, da dela.
Ubistvu je bilo cel cajt sam to narobe.

Bom še mal stestiru, poročam.

EDIT: nekje dela, nekje ne :) Morm se mal poigrat.

Zgodovina sprememb…

  • spremenil: ru7 ()

ru7 ::

Jst mislim, da zdej dela.

!!!!HVALA OBEMA!!!!

Če je kdo od vaju iz LJ, gremo lahko med tednom na pir, plačam takoj :)))))


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Google maps API ne deluje v wordpress

Oddelek: Izdelava spletišč
81882 (1137) shark_nm
»

Pregrevanje CPU-ja (strani: 1 2 )

Oddelek: Pomoč in nasveti
514836 (3473) Berni_01
»

SATA 3 kartica?

Oddelek: Kaj kupiti
363545 (2573) KTr1sk
»

[Delphi] exception problem

Oddelek: Programiranje
6798 (693) Keki
»

Najhitrejši programski jezik? (strani: 1 2 )

Oddelek: Programiranje
757712 (5532) Senitel

Več podobnih tem