Autor Zpráva
Lukeroll
Profil *
Zdravím, pracuji na implementaci integrálu a derivace do JS a narazil jsem na problém. Mé řešení pracuje tak, že si jako diferenciál zvolím konečné, velmi malé číslo. Zkoušel jsem 1/pow(10,9). Zatím jsem skončil u jedničky, protože u derivace zprůměruji výsledek při přičtení diferenciálu a výsledek při odečtení diferenciálu a u běžných funkcí to zatím vychází přesně. Integrál ale s jedničkou jako diferenciálem vychází o dost jinak a v případě 1/pow(10,9) se script kousne. Jak velké by bylo ideální "konečné, velmi malé číslo", popř. máte jiný nápad jak to řešit?

Math.der = function(f, x) {                                             // f je funkce, x je bod derivace
    return Math.avg(
      (f(x) - f(x - 1)) / (x - (x - 1)),
      (f(x) - f(x + 1)) / (x - (x + 1))
    );
  }
  
 Math.integrate = function(f, a, b) {                               //f je funkce, a a b jsou integrační meze
    var d = 1 / Math.pow(10,9);                                      // inicializace "hodně" malého čísla
    var result = 0;
    for(; a < b; a += d) {                                           
      result += Math.avg(Math.abs(f(a))*d, Math.abs(f(a + d))*d);
    }                                                               
    return result;  
  }



PS: funkce Math.avg je Witikova funkce na spočítání aritmetického průměru
Witiko
Profil
Lukeroll:
funkce Math.avg je Witikova funkce
Je tomu tak, funkce vypadá nějak takto:
  Math.avg = function() {
    if(arguments.length === 0) return 0;
    var sum = 0, count = 0, length = arguments.length;
    do {
      sum += arguments[count];
    } while(++count < length)
    return sum / count;
  }


Hodnota Number.MIN_VALUE se nezdá být pro zastoupení diferenciálu vhodná, jelikož daný float zřejmě zabírá veškerých 64 bitů potřebných k jeho reprezentaci v paměti. Při přičítání a odečítání od něj se proto chová jako 0, viz.:
Number.MIN_VALUE + 1 === 1
Navíc čím menší číslo s desetinnou čárkou je jako diferenciál namísto výše zmíněné konstanty použito, z tím menšího rozsahu může být číslo, k němuž je tento diferenciál přičítán. Výběr ideální generické hodnoty diferenciálu je tedy poměrně těžký a nejspíš bude nutné určit si jej ve výpočtech ručně případ od případu alespoň v derivacích. Rád bych se mýlil, má někdo nějaké postřehy / návrhy?
Lukeroll
Profil *
Zajímavé, právě jsem zkoušel, jak budou fungovat různé hodnoty diferenciálů od 1/10 až po 1/10^7. Integroval jsem funkci x^2+2*x+1 v mezích 2, 4 (podle kalkulačky vychází 32,6 per.). Při hodnotě diferenciálu 1 vyhazuje funkce číslo 33. Při hodnotě 1/10 vyhazuje 32,67. Pak se to mírně znepřesní (1/10^2 vyhazuje asi 32,69) a od té doby se to až do dif. 1/10^5 zpřesňuje. Od této hodnoty už se script začíná výrazně zpomalovat a výsledek znepřesňovat.
peta
Profil
Programovaci jazyk, pokud nepouzije specialni mat. knihovnu, neplytva ani casem ani pameti, aby pocital cisla na 30 desetinnych mist. Programator tedy pocita s jistou nepresnosti v normalnim rezimu.
Witiko
Profil
peta:
Nejde o nepřesnost, jde o to, jak zjistit nejmenší číslo mezi 1 a 0 ke kterému lze javascriptem přičíst jiné číslo, aniž by se
číslo + malé číslo == číslo
Problém je v tom, že čím větší je číslo, tím méně desetinných míst může mít malé číslo. Reprezentace čísla v paměti.
_es
Profil
Lukeroll:
Prečo v tej derivácii pričítávaš a odčítávaš od x práve číslo jedna?
Napríklad funkcia y = x³ Aká ti z toho vzorca vychádza derivácia a aká je naozaj?
Asi ti stačí len pohľadať numerické vzorce, kde je diferencia pri derivácii aj integráli zvolená ručne - podľa charakteristiky funkcie.
Pri integráli môže byť miesto toho zadaný počet krokov v cykle.
Lukeroll
Profil *
_es:
Zatím tam mám jedničku, protože zatím nevím, co jiného by se tam hodilo víc. Je to zatím spíš demonstrace toho, jak to má fungovat.
Při
y = x<sup>3</sup>
to vychází jinak, to jsem čekal, že se to bude lišit. Proto hledám řešení, při kterém by se to nelišilo.
Volba vlastního diferenciálu je samozřejmě řešení, ovšem nevím přesně jak, vzorce neznám. Pak by bylo řešení nechat tu volbu na uživateli.
U toho integrálu to zkusím.
Nemáš náhodou zkušenosti s tím, jak tyhle funkce implementují jiné programy?

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0