Diskuze: Integrál v C#

C# .NET .NET (C# a Visual Basic) Integrál v C# American English version English version

Avatar
Stargate
Člen
Avatar
Stargate:

Ahojte, měl bych dotaz. Dělám na formulářové aplikaci k integrování pomocí různých metod a pořád nemůžu dojít na to, jak spočítat funkční hodnotu v určitém bodě. Prakticky to mám tak, že do jednoho Textboxu zadá uživatel funkci (např. x2+2), do druhého pak zadá hodnotu x (např. 3) a po kliknutí na tlačítko se vypočítá hodnota a zapíše do třetího Textboxu (zde by tedy vyšla 11). Nemohu dojít na to, jak převést tu funkci z Textboxu1, abych do ní pak mohl dosadit zadanou hodnotu x. Nevíte někdo, jak na to?

 
Odpovědět 13.12.2014 16:56
Avatar
Ziki
Redaktor
Avatar
Ziki:

vyhodnocení textu jako matematického výrazu je podle mě dost složitá věc (hlavně pokud se používají závorky), podle mě by sis na to musel napsat aparát, kterej bude řetězec postupně rozebírat a vyhodnocovat. Sám jsem jednou něco takovýho chtěl zkusit napsat (uživatel by napsal výraz a program by jej vyhodnotil), ale dostal jsem se pouze k myšlenkovému návrhu.

To co tady máš ty je složitější ještě v tom, že tam máš neznámou, jedna možnost je že v řetězci nahradíš neznámou její hodnotou a pak to zpracuješ.

Pokud ale potom hodláš počítat integrál tý funkce pomocí její primitivní funkce tak ti přeju hodně štěstí, protože by sis musel napsat ještě aparát kterej by ti jí zintegroval (jde to, viz www.wolframalpha.com), spíš bych zvolil nějakou aproximační metodu.

Editováno 19.12.2014 22:15
Nahoru Odpovědět 19.12.2014 22:12
Ve vědění je síla.
Avatar
rwn
Člen
Avatar
Odpovídá na Stargate
rwn:

Jestli to správně chápu, tak problém je v tom, převést funkci jako text do něčeho co jí bude chápat jako funci. Napadá mě, žebys to mohl udělat tak, že vezmeš klasický string zadané funkce a z něj vytaháš obsah. Realizaci bych si dovedl představit, že projíždíš každý znak textu cyklem for a podle toho co představuje daný operátorový znak se provede následně jeho funce. :) Zkusil jsem něco rychle napsat:

string zadani = "X^2+2"; // textBox1
string neznama = "3"; // textBox2
string vysledek = string.Empty; // textBox3

string meziVysledek = string.Empty; // plní funci meziuložiště

zadani = zadani.ToLower().Replace("x", neznama); // modifikace zadání = dosazení za x

for (int i = 0; i < zadani.Length; i++)
{
    if (zadani[i].ToString() == "^")
    {
        // operátor pracuje jen se znakem před a za operátorem (proto -1 a +1 u indexů)
        meziVysledek = Math.Pow(double.Parse(zadani[i - 1].ToString()),double.Parse(zadani[i + 1].ToString())).ToString();
        zadani = zadani.Remove(i-1, 3); // operátor ovlivní vždy jen 3 znaky z řetězce (před operátorem, operátor, za operátorem)
        zadani = zadani.Insert(i-1, meziVysledek); // následně se na novou pozici zapíše nový znak (mezivýpočet)
        i = -1;
    }
}

for (int i = 0; i < zadani.Length; i++)
{
    if (zadani[i].ToString() == "*")
    {
        meziVysledek = (double.Parse(zadani[i - 1].ToString()) * double.Parse(zadani[i + 1].ToString())).ToString();
        zadani = zadani.Remove(i-1, 3);
        zadani = zadani.Insert(i-1, meziVysledek);
        i = -1;
    }
}

for (int i = 0; i < zadani.Length; i++)
{
    if (zadani[i].ToString() == "+")
    {
        meziVysledek = (double.Parse(zadani[i - 1].ToString()) + double.Parse(zadani[i + 1].ToString())).ToString();
        zadani = zadani.Remove(i - 1, 3);
        zadani = zadani.Insert(i - 1, meziVysledek);
        i = -1;
    }
}

vysledek = zadani;

Kdybych to měl zhrnout, tak první věc co se udělá je, že se vezme stringová rovnice a všechny písmena se přejmenují na malá (aby nedošlo k nedorozumění pro jistotu :) ) potom, se do textové rovnice dosadí za všechna "x" naše zadaná hodnota. :) a tuhle rovnici projíždím cyklem znak po znaku, pokud se narazí na operátorový znak, tak se provede operace. :) Co se týče hierarchie operátorů, tak mě ted nic lepšího nenapadlo, než projíždět vždy všechny symboly jeden po jednom, přičemž se vždy vyřeší ten s největší prioritou jako první a tak dál postupně.. :) Tady jsem dal jen 3operátory na ukázku, protože je to všechno na jedno brdo. Jediné co tam není vyřešeno je závorkování abych to neřešil celé. :D Jinak ted kód ber s nadsázkou, je tam docela dost redundantního kódu, ale chtěl jsem spíš aby šlo vidět co se tam děje, než abych tam dával víc funkcí atd.. :)

Editováno 20.12.2014 6:42
Nahoru Odpovědět 20.12.2014 6:39
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
rwn
Člen
Avatar
Odpovídá na Stargate
rwn:

to i = -1; tam samozřejmě být nemusí, měl jsem to původně v jednom cyklu kde jsem tím trochu řešil hierarchii. Tady by stačilo místo toho i--, aby nemohl uniknout operátor tím mazáním a neprojíždělo se od začátku. :)

Nahoru Odpovědět 20.12.2014 6:53
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Stargate
Člen
Avatar
Stargate:

Díky za nápady, určitě to vyzkouším. Už jsem to zkoušel i sám, ale přeci jen jsem v C# doteď vůbec nedělal, tak to mám mnohem komplikovanější (i když ta část, co jsem udělal, tak fungovala), ale toto by mi mohlo dost usnadnit. Problém trochu je, že ve funkci mohou být také např. sin(x), cos(x), tg(x), log(x), ln(x) či e^(x) (alespoň s těmito by to mělo fungovat, ale to si myslím, že by šlo).
Pokusím se teda vysvětlit ve zkratce princip toho mého projektu, protože nevím, jestli to má smysl dělat v C#, i kdybych teda zvládl udělat ten výpočet funkcí. Aplikace má být na numerické integrování (konkrétně Newton-Cotesovy vzorce, Gaussovy vzorce, pomocí Taylorova rozvoje a metody Monte Carlo), kdy vždy by uživatel si vybral jednu metodu, zadal funkci, počet dělících bodů, dolní a horní mez. Jako výsledek by pak dostal odhadnutou hodnotu integrálu, maximální možnou chybu, interval, ve kterém se nachází skutečná hodnota (což je jednoduše jen odhadnutá hodnota +- chyba) a pak skutečnou hodnotu integrálu pro porovnání (i když ta by se možná dala oželet, protože numerické integrování se využívá především pro funkce, které nejdou spočítat přesnými postupy, tudíž by to žádný výsledek v mnoha případech asi ani nevrátilo). Otázkou je, jestli existuje v C# přímo příkaz pro výpočet určitého integrálu, dále pro výpočet derivcací u obecně zadané funkce (to je potřeba pro výpočet chyby a výpočet pomocí Taylorova rozvoje) a také pro generování náhodných čísel (pro metodu Monte Carlo). Hledal jsem teda zatím jen pro výpočet toho integrálu, a ani to jsem nějak nezjistil. Nevíte, jestli takové příkazy jsou nebo bych si musel udělat vlastní aparát, stejně jako pro ten výpočet funkcí? Protože v tom případě by to asi bylo už příliš komplikované a radši bych využil nějaký matematický SW, i když to v něm zdaleka nebude uživatelsky vypadat tak přívětivě. Každopádně díky za rady! :)

 
Nahoru Odpovědět 20.12.2014 12:02
Avatar
rwn
Člen
Avatar
Odpovídá na Stargate
rwn:

Záleží jestli to děláš tak, že to musíš programovat nebo ti stačí to jen realizovat. Na tyto čistě matematické operace jsou vhodnější programy. Například Maple, který je k těmto věcem určen a má velice uživatelsky příjemný interface. :) Zmíněné vzorce by měl mít v sobě už naprogramované (možná všechny matematické vzorce co vůbec jsou :D). Eventuelně dovoluje vytvářet i vlastní metody, takže by tam neměl být problém si vytvořit třeba nějakou metodu, které dáš třeba nějaké parametry a v jeho těle je jen použiješ. Pokud nemáš programátorské zkušenosti, tak ti to bude víc vyhovovat, protože program dělá vše za tebe a ty v podstatě voláš jen metody popřípadě přiřazuješ do proměnných. Navíc program obsahuje i pěkné vykreslení. :)

Jinak co se týče realizace v C#, tak mě napadá se leda podívat po nějakých knihovnách, ale asi by s realizací bylo dost práce a přitom výsledek by nepřekoval například zmíněný Maple. :)

Editováno 20.12.2014 16:36
Nahoru Odpovědět 20.12.2014 16:33
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Stargate
Člen
Avatar
Odpovídá na rwn
Stargate:

Stačí to jakkoliv realizovat, aby se s tím dobře pracovalo, já to jen chtěl zkusit udělat v C# proto, aby to vypadalo trošku lépe, ale jak vidím, tak by to zabralo spoustu času, takže to zkusím v jiném SW. V Maple jsem dělal, vím, že to tam jde velmi snadno, ale přímo u mě na škole se uznává spíš Matlab a Mathematica (ale v té jsem nikdy nedělal), takže to asi udělám v Matlabu, v tom trošku umím a i když to nebude vypadat tak dobře, tak to rozhodně postačovat bude :)
Ono dřív na střední jsem dělal v Paschalu a v Delphi, takže z toho důvodu jsem chtěl zkusit C#, že to bude podobné jak v Deplhi a těch pár věcí si dohledám na netu, ale netušil jsem, že je s integrováním, derivováním a dokonce i dosazováním do funkce až takový problém. Ale tak aspoň jsem si trochu zkusil i jiný jazyk :) Díky za rady ;)

 
Nahoru Odpovědět 20.12.2014 18:37
Avatar
rwn
Člen
Avatar
Odpovídá na Stargate
rwn:

Pokud něco takového chceš dělat v Matlabu, tak se zkus porozhlédnout po toolboxech, vím že jsem v tom kdysi něco dělal (jinačího) a těch toolboxu co se tam dali přidat bylo hodně a ani bych se nedivil kdyby byl nějakej matematicky přívětivej. :)

Nahoru Odpovědět 21.12.2014 0:11
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Stargate
Člen
Avatar
Odpovídá na rwn
Stargate:

No s toolboxy jsem nikdy nedělal, ani nevím, které mám přímo ve své verzi třeba již nainstalované, ale vyzkouším, pohledám na netu a snad na to dojdu, díky ;)

 
Nahoru Odpovědět 21.12.2014 16:22
Avatar
rwn
Člen
Avatar
Odpovídá na Stargate
rwn:

Teď nechci kecat, protože jsem s ním dělal už hodně dávno, ale myslím, že při instalaci mě to samo nabídlo asi 30 různých toolboxů. :)

Nahoru Odpovědět 22.12.2014 3:11
Co můžeš naprogramovat dnes, neodkládej na zítřek.
Avatar
Stargate
Člen
Avatar
Odpovídá na rwn
Stargate:

Jo máš pravdu, že již při instalaci jich bylo plno na výběr a jelikož jsem si nechal myslím všechny, tak ten potřebný tam mám a už se mi povedlo i udělat obdélníkové, lichoběžníkové i Simpsonovo pravidlo, celkem jednoduše to šlo :) Ostatní přístupy by už měly snad jít taky v pohodě :)

 
Nahoru Odpovědět 22.12.2014 14:49
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.