Diskuze: Integrál v C#
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
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.
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é.
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..
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.
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!
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
). 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.
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
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.
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
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ů.
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ě
Zobrazeno 11 zpráv z 11.