Virtual Reality 3D Graphing Calculator na bazie mXparser

Virtual Reality 3D Graphing Calculator

W ostatnim czasie powstał bardzo ciekawy projekt edukacyjny o nazwie "Virtual Reality 3D Graphing Calculator", który umożliwia poznawanie matematyki poprzez zabawę i niemal fizyczną interakcję z wykresami różnych funkcji. Oprogramowanie powstało na bazie gogli wirtualnej rzeczywistości (Oculus Rift), sensora ruchu dłoni / palców (Leep Motion Controller) oraz parsera / silnika matematycznego mojego autorstwa (mXparser).

mXparser - mathparser.org

Autorem projektu są studenci z College of Coastal Georgia, inicjatywą opiekuje się German Vargas, Ph.D., Assistant Vice President for Academic Student Engagement, Associate Professor of Mathematics College of Coastal Georgia, One College Drive, Brunswick, GA 31520.

VR 3D Calculator można pobrać tutaj.

Poniżej również filmy prezentujące działanie kalkulatora.

Pozdrowienia,

Mariusz Gromada

Janet Sudoku - Sudoku Solver i Sudoku Generator w jednym

Janet Sudoku

Janet Sudoku - elastyczna i wydajna biblioteka dostarczające metody generacji oraz rozwiązywania łamigłówek Sudoku 9x9 (platformy Java, Android, .NET, MONO).

Serdecznie zapraszam (link) do zapoznania się z moim nowym projektem "Janet Sudoku". Biblioteka została osobno przygotowana dla platform Java (od 1.5) oraz .NET (od 2.0 - język C#), w związku z tym "Janet" jest akronimem od Java Android, .NET. Główne funkcjonalności biblioteki

Janet Sudoku - icon

  • Sudoku Generator - generacja różnych kombinacji Sudoku przy wykorzystaniu wielu opcji / metod (np. łamigłówka zupełnie losowa, inna łamigłówka z tym samym rozwiązaniem, itp.).
  • Sudoku Solver - rozwiązywanie dowolnego Sudoku, weryfikacja czy rozwiązanie istnieje, poszukiwanie wszystkich rozwiązań jeśli rozwiązanie nie jest unikalne. Ocena trudności danego Sudoku.
  • Sudoku Store - analiza i transformacja Sudoku (np. obroty, permutacje, zamiana kolejności, transpozycje, odbicia, itp.  - są to przykłady transformacji nie wpływających na istnienie rozwiązania).
  • Janet Sudoku Demo App - aplikacja z prostym interfejsem tekstowym, jednak o bardzo rozbudowanych możliwościach. Jest to demo wykorzystujące jednie część funkcjonalności biblioteki Janet Sudoku.

Janet Sudoku - screenshot 1

Janet Sudoku - screenshot 2

Janet Sudoku - screenshot 3

Pozdrowienia

Mariusz Gromada

MathParser.org - mXparser - zapraszam

Witajcie,

W ostatnim czasie pracowałem nad projektem MathParser.org - w efekcie powstała strona w pełni dokumentująca projekt mXparser. Strona zawiera:

Serdecznie zapraszam! Poniżej trochę grafiki mXparsera z linkami do odpowiednich stron 🙂

MathParser.org - mXparser - logo

MathParser.org - mXparser - logo - Tutorial

MathParser.org - mXparser - logo - API

Pozdrowienia,

Mariusz Gromada

Polowanie na czarownice - czyli zabawy z rekurencją (część 1)

Rozpocznijmy branżowym humorem

Okres średniowiecza, kobieta winna uprawiania magii, kara straszna - spalenie na stosie! Nadszedł dzień, tłum gawiedzi, czarownica na stosie, płomienie, wiedźma krzyczy - więcej drewna! Więcej drewna! Tłum zdziwiony, mimo wszystko spełnia ostatnie życzenie opętanej. Wiedźma nie przerywa - jeszcze więcej drewna! Więcej drewna! Z oddali dobiega nagły i stanowczy sprzeciw - STOP! Czarownica chce przepełnić stos!

🙂

Czym jest rekurencja?

Zazwyczaj o rekurencji myślimy jako o procesie podziału zadania na mniejsze, następnie podziału na jeszcze mniejsze, i jeszcze mniejsze ... dochodząc do zadań, dla których rozwiązanie jest znane. Od tego momentu zaczyna się składanie "mniejszych" rozwiązań w "większe", następnie tych większych w jeszcze większe, ... i w jeszcze większe ... kończąc na rozwiązaniu zadania początkowego. Dla przykładu zapiszmy funkcję n! w postaci rekurencyjnej.

n!=\begin{cases}n\cdot(n-1)!&\text{dla}\quad n>0\\1,&\text{dla}\quad n=0\end{cases}

W celu zobrazowania reprezentacja powyższego podana w mXparser:

/* Definicja funkcji rekurencyjnej */
Function silnia = new Function("s(n) = if( n>0, n*s(n-1), 1 )");

/* Obliczenia i wyświetlenie wyniku */
System.out.println( "n = 0, s(n) = " + silnia.calculate(0) );
System.out.println( "n = 1, s(n) = " + silnia.calculate(1) );
System.out.println( "n = 2, s(n) = " + silnia.calculate(2) );
System.out.println( "n = 3, s(n) = " + silnia.calculate(3) );
System.out.println( "n = 4, s(n) = " + silnia.calculate(4) );
System.out.println( "n = 5, s(n) = " + silnia.calculate(5) );

+ wynik:

n = 0, s(n) = 1.0
n = 1, s(n) = 1.0
n = 2, s(n) = 2.0
n = 3, s(n) = 6.0
n = 4, s(n) = 24.0
n = 5, s(n) = 120.0

Wynik jest zgodny z oczekiwanym. Innym przykład rekurencji to iterowany operator sumowania, niech

A_n=a_1+a_2+\ldots+a_n=\sum_{i=1}^n a_i

Łatwo zauważyć, że

A_n=\begin{cases}a_n+A_{n-1},&\text{dla}\quad n>1\\a_1,&\text{dla}\quad n=1\end{cases}

Jak więc widzicie, rekurencja jest powszechna, często będąc nieco innym sposobem patrzenia na iteracje.

Formalna definicja rekurencji

O rekurencji mówimy jeśli metoda (funkcja, zachowanie, obiekt) może być opisana przez:

  1. elementy bazowe / rozwiązania bazowe;
  2. zestaw reguł, które redukuję (sprowadzają) każdy inny przypadek do (w kierunku) elementów bazowych.

Rekurencja
Powyższe określenie jest szerokie, ale takie być musi, bo i typów rekurencji jest wiele.

Rekurencja jako złożenie funkcji

Jednym (ale nie jedynym) sposobem zapisu ogólnych równań rekurencyjnych jest złożenie funkcji:

f_n=\begin{cases}F\big(f_{n-1},f_{n-2},\ldots,f_{n-k}\big)&\text{dla}\quad n>k\\f_1,f_2,\ldots,f_k&\text{el. baz. dla}\quad n<=k\end{cases}

Dobrą ilustracją powyższego jest ciąg Fibonacciego:

f_n=\begin{cases}0&\text{dla}\quad n=0\\1&\text{dla}\quad n=1\\f_{n-1}+f_{n-2}&\text{dla}\quad n>1\end{cases}

Zapiszmy ciąg Fibonacciego w mXparser:

/* Definicja funkcji rekurencyjnej */
Function fib = new Function("fib(n) = if( n>1, fib(n-1)+fib(n-2), if(n=1,1,0) )");

/* Obliczenia i wyświetlenie wyniku */
System.out.println( "fib(0) = " + fib.calculate(0) );
System.out.println( "fib(1) = " + fib.calculate(1) );
System.out.println( "fib(2) = " + fib.calculate(2) );
System.out.println( "fib(3) = " + fib.calculate(3) );
System.out.println( "fib(4) = " + fib.calculate(4) );
System.out.println( "fib(5) = " + fib.calculate(5) );

+ rezultat:

fib(0) = 0.0
fib(1) = 1.0
fib(2) = 1.0
fib(3) = 2.0
fib(4) = 3.0
fib(5) = 5.0

Rekurencja w roli pętli "For"

Podane wyżej przykłady zapisów rekurencyjnych (n!, suma n-pierwszych wyrazów ciągu, ciąg Fibonacciego) są tak naprawdę rekurencyjną realizacją pętli "for" - znamy przecież dokładnie liczbę niezbędnych operacji do wykonania, a i same operacje są raczej łatwe oraz czytelne - zatem zagnieżdżenie ich w pętli "for" nie powinno spowodować utraty przejrzystości kodu.

Poszukiwanie rozwiązania - czyli rekurencja w roli pętli "While/Until"

W metodach numerycznych często stosuje się strategie rekurencyjne - w takiej sytuacji, będąc w kroku n, weryfikujemy czy propozycja rozwiązania n spełnia kryterium stopu (np. jakość oszacowania), jeśli tak - kończymy z rozwiązaniem n, jeśli nie - przechodzimy do badania propozycji rozwiązania n+1. Procedurę rozpoczynamy od kroku 0 (zerowego).

Przykład: znając definicję silni chcemy znaleźć pierwsze n, dla którego n! >= 100 - takie zadanie formalnie możemy zapisać jako:

S_n=\begin{cases}S_{n+1},&\text{dla}\quad n!<100\\n,&\text{dla}\quad n!>=100\end{cases}

n_{100} = S(0)

Reprezentacja w mXparser:

/* Definicja funkcji rekurencyjnej */
Function S = new Function("S(n) = if( n! < 100, S(n+1), n )"); /* Obliczenia i wyświetlenie wyniku */ System.out.println( "Pierwsze n, że n! >= 100 to n = " + S.calculate(0) );

+ wynik:

Pierwsze n, że n! >= 100 to n = 5.0

Rekurencja bezpośrednia

Wszystkie omawiane wyżej typy rekurencji polegają na wywołaniu z ciała funkcji "siebie samej", dlatego należą do bardziej ogólnej klasy nazywanej rekurencją bezpośrednią.

Wydajność

Implementacje na bazie rekurencji są bardzo czytelne, o często minimalnym rozmiarze kodu. Jednak coś za coś - tracimy bardzo dużo na złożoności obliczeniowej (powtarzane operacje, dzielenie zadań, operacje na stosie) oraz wymogach pamięci (głównie struktura stosu) - to właśnie dlatego czarownica błagała o drewno - licząc na przerwanie procesu z tytułu przepełnienia stosu 🙂

Cdn 🙂

Pozdrowienia,

Mariusz Gromada

BTW: jeśli planujecie uruchamiać kody mXparsera nie zapomnijcie o dodaniu

import org.mariuszgromada.math.mxparser.*;

Zobacz również:

  1. Prędkość ucieczki do nieskończoności - czyli zabawy z rekurencją (część 2)
  2. Naiwny test pierwszości - czyli zabawy z rekurencją (część 3)
  3. Rekurencja pośrednia - czyli zabawy z rekurencją (część 4)

 

mXparser - wersja 1.0.2 dostępna do pobrania

mXparser - wysoce elastyczny parser (interpreter) wyrażeń matematycznych dla JAVA oraz C# .NET

mXparser - parser matematyczny

mXparser - wersja 1.0.2 dostępna do pobrania

Zmiana w stosunku do 1.0.1 to poprawa kontroli składni w funkcji definiowanej przez użytkownika. Do wersji 1.0.1 użycie argumentu rekurencyjnego w funkcji definiowanej przez użytkownika powodowało zwiększenie liczby oczekiwanych parametrów wywołania funkcji. Wartość argumentu rekurencyjnego jest wyznaczana automatycznie, stąd w kontroli składni (weryfikując liczbę podanych parametrów) taki argument należy pominąć. Od wersji 1.0.2 liczba parametrów funkcji definiowanej przez użytkownika opiera się na bazie liczby argumentów pomniejszonej o argumenty rekurencyjne.

Przykład

Poniżej przykład demonstrujący działanie wprowadzonej zmiany - proszę przesunąć tekst w celu uwidocznienia komentarzy.


import org.mariuszgromada.math.mxparser.*;

public class mXparserTests {
  public static void main(String[] args) {
    RecursiveArgument z = new RecursiveArgument("z","z(n-1)^2+c", "n"); /* Definicja argumentu rekurencyjnego */
    z.addBaseCase(0, 0);                                                /* Definicja elementu początkowego */
    Constant c = new Constant("c", 0.3);                                /* Deklaracja stałej występującej w równaniu rekurencyjnym */
    z.addConstants(c);                                                  /* Wskazanie argumentowi oczekiwanej stałej 'c' */
    Function diff1 = new Function("diff1", "z(n) - z(n-1)", "n");       /* Definicja funkcji o parametrze n opartej również na argumencie rekurencyjnym */
    diff1.addArguments(z);                                              /* Wskazanie funkcji oczekiwanego argumentu 'z' */
    System.out.println(diff1.calculate(10));                            /* Obliczenie wartości funkcji + wyświetlenie wyniku */
  }
}

Rezultat


0.17863353779409574

 

Pozdrowienia,

Mariusz Gromada

mXparser - wysoce elastyczny parser (interpreter) wyrażeń matematycznych dla JAVA oraz C# .NET

mXparser - parser matematyczny

Serdecznie zapraszam do zapoznania się z wysoce elastycznym interpreterem wyrażeń matematycznych. Oprogramowanie jest mojego autorstwa, powstało w 2010 roku i wtedy zostało opublikowane w serwisie SourceForge.net. Z racji, że teraz posiadam stronę o odpowiedniej tematyce, zdecydowałem się przygotować dedykowany opis, który znajdziecie pod tym linkiem. Dostępne są również tutorial oraz specyfikacja API.

Pozdrowienia,

Mariusz Gromada

Pobierz mXparser - parser matematyczny

Download mXparser

Download mXparser

TensorFlow - czyli Machine Learning od Google udostępniony na zasadzie open source!

TensorFlow by Google

Kilka dni temu Google udostępnił na zasadzie open source (licencja Apache 2.0) własną platformę "TensorFlow" przeznaczoną do uczenia maszynowego. TensorFlow obecnie wspiera większość usług Google, między innymi transkrypcja mowy na tekst, rozpoznawanie pisma ludzkiego, Google Translate, rozpoznawanie i kategoryzowanie obrazów, Gmail, i wiele innych. TensorFlow dostarcza wysokowydajne API w językach C++ i Python również w wersjach dla urządzeń mobilnych.

Geneza powstania TensorFlow

TensorFlow jest następcą rozwiązania DistBelief (Large Scale Distributed Deep Networks), którego Google używał z sukcesem od 2011 roku np. zwyciężając w konkursie Large Scale Visual Recognition Challenge 2014. DistBelief koncentrował się wyłącznie na sieciach neuronowych i był mocno osadzony w infrastrukturze Google, co uniemożliwiało udostępnienie platformy w ramach open source.

Na stronie www.tensorflow.org znajdziecie kody, pakiety instalacyjne, tutoriale i dokumentacje.

Pozdrowienia,

Mariusz Gromada