www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

vorherige Seite 1 2  

HaskellToigerl

Gepostet:
15.08.2011 16:12

Ja das wäre sicher eine sinnvolle Alternative  
... allerding hat mich Haskell \"gepackt\" und ein falscher Ehrgeiz hat sich breitgemacht ...

was mich ärgert, dass Haskell keine \"einfache\" Form liefert Kontrollausgaben vorzunehmen .. der Code wäre ja nicht all zu lang -:(


Zum Seitenanfang Homepage      
 
Landei

Gepostet:
15.08.2011 21:20

   
Ich habe gerade die Idee mit unsafePerformIO probiert, und es klappt einwandfrei:


import System.IO.Unsafe

output :: Show b => a -> b -> a
output a text = unsafePerformIO $ print text >> return a

-- original
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

-- mit Ausgabe
fib 0 = 0
fib 1 = 1
fib n = let result = fib (n-1) + fib (n-2)
in output result (\"fib \" ++ show n ++ \" = \" ++ show result)

{-Ausgabe bei Aufruf:
\"fib 2 = 1\"
\"fib 3 = 2\"
\"fib 2 = 1\"
\"fib 2 = 1\"
\"fib 3 = 2\"
\"fib 4 = 3\"
\"fib 5 = 5\"
-}


Dabei hat output zwei Argumente. Das erste wird unverändert als Ergebnis geliefert. Das zweite muss zur Typklasse Show gehören und wird ausgegeben. Das kannst du sicher an deine Bedürfnisse anpassen.
Zum Seitenanfang    
 
HaskellToigerl

Gepostet:
17.08.2011 16:11

Danke ... werde es versuchen  
Danke für den Hinweis .. ich hoffe, dass ich das so adaptieren kann, dass ich die Ausgaben geschrieben bekomme. Nach dem Hinweis, dass das kein \"klassischer\" Haskell-Ansatz ist
habe ich mich mit dem Code auseinandergesetzt .. ja für limit habe ich noch keine Erklärung gefunden und auch sonst muss ich erst genau verstehen was das Programm tut .. bis zu einer
gewissen Stelle (inhomoSum) geht es komform mit einem VBA Programm dann allerdings bekomme ich \"gewaltig\" andere Ergebnisse...

Danke vorerst ... mfg HT
Zum Seitenanfang Homepage      
 
HaskellToigerl

Gepostet:
17.08.2011 19:04

.. WinHugs vs. WinGHCi  
.. das von mir präsentierte Programm läuft unter WinGHCi aber nicht unter WinHugs ...

.. beim Test mit deinem Fallbeispiel st es gerade verkehrt rum .. sind hier lib. zu installieren?

mfg HT
Zum Seitenanfang Homepage      
 
Landei

Gepostet:
18.08.2011 08:37

   
Schon möglich. Hugs gilt als veraltet, auch wenn es viele Unis noch einsetzen. WinGHCi habe ich nicht ausprobiert. Ich habe bei mir die Haskell-Platform (und damit GHC) installiert, und dann die IDE Leksah, die ganz ordentlich arbeitet. Hin und wieder habe ich dort unbekannte Packages eintragen müssen, aber in diesem Fall nicht, es hat sofort funktioniert.

Was limit angeht: Das ist sogenannter punktfreier (\"pointfree\", böse Zungen sagen auch \"pointless\") Stil. Nicht wundern, die \"Punkte\" sind dabei nicht die \".\", sondern Variablen. Eine freie Übersetzung wäre also \"variablenloser Stil\". Zur \"Übersetzung\" gibt es eine Daumenregel, die meistens funktioniert: Auf der linken und rechten Seite am Ende eine Variable anfügen und jeden \".\" durch ein \"$\" ersetzen.


limit x = min 1 $ max 0 x

--oder

limit x = min 1 (max 0 x)


Wie du siehst wird x hier auf den Bereich von 0 bis eins beschränkt (von der 3D-Grafik kenne ich diese Funktion als \"clamp\")

Zum Seitenanfang    
 
HaskellToigerl

Gepostet:
18.08.2011 15:09

min 1 . max 0  
prob x = limit (
sum [ (if i < huge then 2 else 1) *
(-1)**(n-1) * exp (-n**2 * x)
| i <- [1..huge], n <- [fromIntegral i] ]
)

limit = (min 1 . max 0)

Habe mich der Funktionskomposition beschäftigt - theoretisch konnte ich nachvollziehen, was dieses \"Konstrukt\" tut -
aber was genau die oben eingefügten Programmzeilen machen ...??




Zum Seitenanfang Homepage      
 
Landei

Gepostet:
18.08.2011 23:03

   
Eine direkte Übersetzung nach Java sähe so aus (ungetestet)


public double prob(double x) {
double sum = 0;
for(int i = 1; i <= huge; i++) {
double factor = i < huge ? 2 : 1;
double sign = i % 2 == 0 ? -1 : 1
sum += factor*sign*Math.exp(i*i*x);
}
return limit(sum);
}

public double limit(double x) {
return x < 0 ? 0 : x > 1 ? 1 : x;
}


Die Formel wurde ziemlich seltsam geschrieben, z.B. ist das Quadrat von -n ja das gleiche wie von n.

Das n <- [fromIntegral i] taucht in der Übersetzung gar nicht auf, weil man in Java ints auch an Stellen verwenden kann, wo doubles erwartet werden, aber in Haskell nicht. Üblicherweise würde man das allerdings so schreiben:


[... | i <- [1..huge], let n = fromIntegral i]


Die let-Anweisung definiert direkt eine neue Variable, man braucht also nicht wie im Original-Code mit einer einelementigen Liste zu tricksen.

Falls dir die Schreibweise [x*y| x<- [1..3], y <- [4..5]] gar nichts sagt, ist das Schlagwort \"List Comprehension\": http://www.haskell.org/haskellwiki/List_comprehension
Zum Seitenanfang    
 
HaskellToigerl

Gepostet:
19.08.2011 12:09

... ein wenig wurde erledigt -:)  
import Debug.Trace
import System.IO.Unsafe
import Debug.Hood.Observe

inhomoSum :: RealFloat a => [a] -> a
inhomoSum xs
= sum [ ((s1 n)**2 + (s2 n)**2) / n**2
| i <- [1..huge], n <- [fromIntegral i] ]
where
s1 n = let result = sum [ cos (2 * pi * n * x) | x <- xs ]
in output result (\"s1 n: \" ++ show n ++ \" = \" ++ show result)
s2 n = let result = sum [ sin (2 * pi * n * x) | x <- xs ]
in output result (\"s2 n: \" ++ show n ++ \" = \" ++ show result)

huge = 3



output :: Show b => a -> b -> a
output a text = unsafePerformIO $ print text >> return a


inhomoSignificance :: RealFloat a => [a] -> a
inhomoSignificance xs
| xs == [] = error \"inhomoSignificance undefined for empty list\"
| otherwise = prob (inhomoSum xs / count)
where
count = fromIntegral (length xs)

prob x = let result = limit (
sum [ (if i < huge then 2 else 1) *
(-1)**(n-1) * exp (-n**2 * x)
| i <- [1..huge], n <- [fromIntegral i] ]
)
in output result (\"prob x: \" ++ show x ++ \" ...-= \" ++ show result)

limit = (min 1 . max 0)

huge = 3

inhomogeneity :: RealFloat a => [a] -> a
inhomogeneity xs
| xs == [] = error \"inhomogenity undefined for empty list\"
| length xs == 1 = error \"inhomogenity undefined for single value\"
| otherwise = sqrt ( limit (
(inhomoSum xs * 6 / pi**2 - 1) /
(count**2 - 1)
) )
where
count = fromIntegral (length xs)
limit = max 0

Die Ausgabe ist mir noch nicht ganz klar ...

inhomoSignificance [0.96195316,0.87144583, 0.05623686, 0.94955665, 0.36401868]
\"prob x: \"s1 n: 1.0 = 2.894440757078356\"
\"s2 n: 1.0 = -0.1709560566435756\"
\"s1 n: 2.0 = 2.271902746882097\"
\"s2 n: 2.0 = -2.3925599662305053\"
\"s1 n: 3.0 = 1.9079908081366614\"
\"s2 n: 3.0 = -0.7102717235849991\"
2.317806136856376 ...-= 0.1967906565726379\"
0.1967906565726379

was ich erreichen möchte ist, dass mein vba programm das Haskell vice versa überprüft ..
jedoch macht mir dieswe limit - anweisung mit min max probleme

darf ich im Zusammenhang mit Haskell davon ausgehen, dass sich hier programme aufrufen, die dann abgearbeitet werde?

inhomoSum kann ich kontrollieren - ... aber sionst fehlt der Durchblick

wie komme ich an die Auswertung heran .. oder ist das illusorisch, da inhomoSum \"geschlpssen\" ist
oder brauche ioch eione andere Art der Auswertung ...??
Zum Seitenanfang Homepage      
 
HaskellToigerl

Gepostet:
19.08.2011 12:19

.. danke für den java-sourcecode vorschlag  
... mir bereitet die schreibweise (min 1 . max 0) schwierigkeiten .. ggf. wird das nach studium deines java programms aus der welt geschafft sein ..
lg HT
Zum Seitenanfang Homepage      
 
Landei

Gepostet:
19.08.2011 14:44

   
Habe ich doch schon weiter oben geklärt, das fällt unter den \"point free\"-Stil. Betrachten wir einmal folgende Funktion:


foo x = max 0 x


Was die tut, sollte klar sein: Sie berechnet das Maximum 0 und x. Was tut nun folgende Funktion?


bar = max 0


Überraschung, sie tut genau das gleiche! Falls du nicht weißt, warum, schlag unter \"Currying\" nach.

Das gleiche gilt für min 1. Der Ausdruck (f . g) x ist definiert ist als f (g x), z.B. ist ((2*).(1+)) 3 das gleiche wie 2*(1+3), also 8. Deshalb ist umgekehrt


limit x = min 1 (max 0 x)


das gleiche wie


limit x = ((min 1) . (max 0)) x


oder durch Weglassen von x wie ganz oben


limit = (min 1) . (max 0)






Zum Seitenanfang    
 

vorherige Seite 1 2