Uebungen  Exercices

12. Anonyme Funktionen
 Fonctions anonymes

Die Gliederung dieses Kurses folgt in groben Zügen dem Buch von Nancy Blachman: A Practical Approach.... 
Hinweis: Kapitel 12 lesen!
 L'articulation de ce cours correspond à peu près à celle du livre de Nancy Blachman: A Practical Approach.... 
Indication: Lire le chapitre 12.
WIR94/98/99 // Copyright Rolf Wirz

Aufgabe 1    Problème 1

Leseübung: Schreibe benannte Funktionen, die dasselbe ausgeben wie die folgenden anonymen Funktionen:
 Exercice de lecture: Ecris des fonctions dénommées qui sortent la même chose que les fonctions anonymes suivantes:

(a)  Anonym: (#^3)&
    Anonyme: (#^3)&

{(#^3)&[0],(#^3)&[1],(#^3)&[2],(#^3)&[3],(#^3)&[4]}

Benannt:    Dénommé:

f[x_]:=x^3;
{f[0],f[1],f[2],f[3],f[4]}

(b)  Anonym:  (#^#)&
    Anonyme: (#^#)&

{(#^#)&[0],(#^#)&[1],(#^#)&[2],(#^#)&[3],(#^#)&[4],
(#^#)&[5]}

Benannt:    Dénommé:

Remove[f];
f[x_]:=x^x;
{f[0],f[1],f[2],f[3],f[4],f[5]}

Benannt:    Dénommé:

f[x_]:=x^3;
{f[0],f[1],f[2],f[3],f[4]}

(c)  Anonym: {#,#^2}& 
    Anonyme: (#^#^2)&

{{#,#^2}&[0],{#,#^2}&[1],{#,#^2}&[2],{#,#^2}&[3],
{#,#^2}&[4],{#,#^2}&[5]}

Benannt:    Dénommé:

Remove[f];
f[x_]:={x,x^2};
{f[0],f[1],f[2],f[3],f[4],f[5]}

(d)  Anonym:  If[#>0,#,-#]&
    Anonyme: If[#>0,#,-#]&

{If[#>0,#,-#]&[-2],If[#>0,#,-#]&[-1],If[#>0,#,
-#]&[0], If[#>0,#,-#]&[1],If[#>0,#,-#]&[2]}

Benannt:    Dénommé:

Remove[f];
f[x_]:=Abs[x];
{f[-2],f[-1],f[0],f[1],f[2],f[3]}

(e)  Anonym:  (#/.x->y)&
    Anonyme:  (#/.x->y)&

{(#/.x->y)&[-2],(#/.x->y)&[-1],(#/.x->y)&[0],
(#/.x->y)&[1],(#/.x->y)&[2],(#/.x->y)&[3],
(#/.x->y)&[x],(#/.x->y)&[y],(#/.x->y)&[z]}

Benannt:    Dénommé:

Remove[f];
f[z_]:=z /. x->y;
{f[-2],f[-1],f[0],f[1],f[2],f[3],f[x],f[y],f[z]}

Aufgabe 2    Problème 2

Schreibe eine anonyme Funktion, die die 3. Potenz des Arguments berechnet.
 Ecris une fonction anonyme qui calcule la puissance 3 des arguments.

Zum Beispiel (#^3)&
  Par exemple (#^3)&

{(#^3)&[-3],(#^3)&[-2],(#^3)&[-1],(#^3)&[0],
 (#^3)&[1],(#^3)&[2],(#^3)&[3]}

Aufgabe 3    Problème 3

Verwende "Select" sowie eine anonyme Funktion, um aus einer Liste von Paaren, diejenigen Paare herauszusuchen, bei denen die erste Zahl grösser ist als die zweite.
 Utilise "Select" ainsi qu'une fonction anonyme pour choisir dans une liste de paires les paires dont le premier nombre est plus grand que le deuxième.

Ein Beispiel:
 Un exemple:

newList = {{1,2},{2,1},{3,1},{2,3},{6,4},{4,7}};
Select[newList,(#[[1]] > #[[2]])&]

Aufgabe 4    Problème 4

Definiere eine anonyme Funktion, um die Option "PlotLabel" bei den plotgenerierenden Kommandos zu setzen. Bilde die Funktion ab auf ContourPlot, DensityPlot, ParametricPlot, Plot, Plot3D.
 Définis une fonction anonyme pour joindre l'option "PlotLabel" aux commandements qui génèrent des plots. "Applique" la fonction à ContourPlot, DensityPlot, ParametricPlot, Plot, Plot3D.

Was ist "PlotLabel"?
  Qu'est "PlotLabel"?

??PlotLabel

Wie wird es eingesetzt?
  Comment l'applique-t-on?

??Plot

Ein Plot:    Un plot:

Plot[Sin[x],{x,-5,5}];

Mit Label:    Avec Label:

Plot[Sin[x],{x,-5,5},PlotLabel->FontForm[
"1. Sinus,\n zwischen {-5,5}",
					{"Courier-Bold",15}]];

Mit Hilfe einer anonymen Funktion:
  A l'aide d'une fonction anonyme:

(Plot[Sin[x],{x,-5,5},PlotLabel->#])&[FontForm[
"2. Sinus,\n zwischen {-5,5}",
					{"Courier-Bold",15}]];

(Plot[Sin[x],{x,-5,5},PlotLabel->#])&[FontForm[
"Sinus,\n zwischen {-5,5}",{"Courier-Bold",15}]];

Etwas geschraubter:
  Un peu plus sophistiqué:

Apply[Plot,{#[[1]],#[[2]],#[[3]]}]&[{Sin[x],
  {x,-5,5},(PlotLabel->#)}&[FontForm["3. 
  Sinus,\n zwischen {-5,5}",{"Courier-Bold",15}]]];

Noch etwas geschraubter:
 Ecore plus sophistiqué:

Plot @@ {#[[1]],#[[2]],#[[3]]}&[{Sin[x],{x,-5,5},
 (PlotLabel->#)}&[FontForm["4. 
 Sinus,\n zwischen {-5,5}",{"Courier-Bold",15}]]];

Ein Versuch, die Options zu ändern:
  Un essai de changer les options:

Options[Plot]

Unprotect[Options[Plot]];
Drop[Options[Plot],{11}];
Options[Plot]=Union[Options[Plot],{PlotLabel->
FontForm["5. Neues Bild",{"Courier-Bold",15}],
Frame->True}];
(*Protect[Plot]*)

Attributes[Plot]

Options[Plot]

Unprotect[Plot];
Drop[Options[Plot],{11}];
Options[Plot]=Union[Options[Plot],{PlotLabel->
FontForm["5. Neues Bild",{"Courier-Bold",15}],
Frame->True}];
(*Protect[Plot]*)

Attributes[Plot]

Options[Plot]

Was hat er nicht getan?
 Que n'a-t-il pas fait?

Plot[Sin[x],{x,-5,5}];

Wieso kam der Titel nicht?
  Pourquoi le titre n'est-il pas apparu?

Show[%];

Uebungsfeld:    Terrain d'exercice:

Aufgabe 5    Problème 5

Schreibe nochmals eine Funktion, die die Häufigkeit eines Elements in einer Liste zählt.
 Ecris encore une fonction qui compte la fréquence d'un élément dans une liste.

Verwende Union, Count und Map.
  Utilise Union, Count et Map.

Diese Funktion zählt die Häufigkeit von verschiedenen Elementen 
einer Liste:
  Cette fonction compte la fréquence de différents éléments d'une liste:

frequenz[x_List]:= Module[{elemente=Union[x]},
				Map[{#,Count[x,#]}&,elemente]];
frequenz::usage="frequenz[x_List] gibt eine Liste \
			von verschiedenen Elementen zusammen 
			mit ihrer Häufigkeit ---- \
			donne une liste avec différents \
			éléments avec leurs fréquences.";
testListe = Table[Random[Integer,{1,20}],{18}];
Sort[testListe]

frequenz[testListe]

??frequenz

Probiere eigene Listen!
 Essaie des listes à toi!

Aufgabe 6    Problème 6

Graphisches 
 Graphiques

Eine Aufgabe in mehreren Schritten
  Un problème en plusieurs étapes

(a) Generiere eine Liste von 10 Pseudo-Zufallspunkten im Raum!
   Génère une liste de 10 points pseudo-aléatoires dans l'espace!

punkte = Partition[
		  Table[Random[Integer,{1,20}],{30}],3]

(b) Generiere eine Liste von 10 Pseudo-Zufallszahlen für das
      Grau-Niveau!
    Génère une liste de 10 points pseudo-aléatoires pour le niveau 
      gris!

grau = Table[Random[Real,{0,1}],{10}]

(c)

grau1=Partition[grau,1]

trans=Transpose[{punkte,grau1}];trans

RemoveAll[mix];
mix=Map[Join[#[[1]],#[[2]]]&,trans]

menge=Map[({PointSize[0.03],GrayLevel[#[[4]]],
			Point[{#[[1]],#[[2]],#[[3]]}]				
			})&,
			mix];
menge

Show[Graphics3D[menge]];

Einige Erklärungen:
  Quelques explications:

??Show

??Graphics3D

??DefaultColor

??GrayLevel

{PlotStyle->GrayLevel[1]};
Show[Graphics3D[{PointSize[0.5],GrayLevel[0.5],
Point[{1,1,1}]
}]];

??#

Aufgabe 7    Problème 7

Das Problem deines "signifikanten Partners"
 Le problème de ton "partenaire significatif"

Hier geht es um die Analyse einer besondern Strategie zum Auffinden Deines "signifikanten Partners". Angenommen, da seinen n Personen des andern Geschlechts, die Du in Betracht ziehen willst. Du selbst bist noch ledig, jedoch heiratswillig. Jeder der n Personen ist ein unterscheidbarer Wert zugewiesen, den Du nicht kennst, bis Du das Individuum triffst. Jede Person kannst Du nur einmal treffen. Nach jedem Treffen musst Du entscheiden, ob das eben getroffene Individuum Dein "signifikanter Partner" ist und ihm dann einen Heiratsantrag stellen. Im Falle der Ablehnung gehst Du zm nächsten Treffen, wo dieselben Regeln gelten. Eine abgelehnte Person kannst Du nicht nochmals treffen, entsprechend den hier geltenden Gepflogenheiten.
Du sollst jetzt folgende Strategie analysieren: Du triffst (n/e) Partner als Testmenge, e = Eulersche Zahl. Nachdem Du jetzt einen Eindruck gewonnen hast, wählst Du den ersten Partner Deines Wunsches, der Dir besser gefällt als alle bisherigen Partner.
Wähle n = 30 und lasse eine Simulation 50 mal laufen. Bezeichne im voraus einen besten Partner. Ein Lauf sei positiv, wenn Du den vorher bezeichneten besten Partner durch das Verfahren auch findest.  

Il s'agit ici d'une stratégie spéciale pour trouver ton "partenaire significatif". Supposons n personnes de l'autre sexe que tu veux considérer. Toi-même tu es encore célibataire, mais décidé de te marier. A chacune des n personnes est attribuée une valeur qu'on peut distinguer, que tu ne connais pas, jusqu'à ce que tu rencontres l'individu. Tu ne peux rencontrer chaque personne qu'une seule fois. après chaque rencontre tu dois décider si l'individu que tu viens de rencontrer est ton "partenaire significatif" et lui faire ensuite une proposition de mariage. En cas de refus tu te rends au prochain rendez-vous, où valent les mêmes règles. Une personne refusée tu ne peux plus la rencontrer, selon les us et coutumes en vigeur ici.
Analyse la stratégie suivante: Tu rencontres (n/e) partenaires comme ensemble de test, e = nombre d'Euler. Après cette première impression tu choisis le partenaire qui te plaît le mieux que tous les précédents. Choisis n = 30 et fais marcher la simulation 50 fois. Désigne à l'avance le meilleur partenaire. Un parcours soit positif si tu trouves le partenaire désigné à l'anvance par cette méthode.

(a) Berechne den prozentualen Anteil der positiven Läufe.
   Calcule la partie proportionelle des parcours positifs:

Definiere zuerst eine Funktion "zufall", die eine Liste von Leuten in zufälliger Reihenfolge wieder ausgibt.
  Définis d'abord une fonction "hasard", qui sort une liste de personnes en ordre aléatoire.

Definiere zuerst die Funktion "zufall1". Diese Funktion stellt die Liste rekursiv zufällig um.
  Définis d'abord la fonction "zufall1" ("hasard"). Cette fonction redonne la liste de façon récursive aléatoire.

zufall1[{}]:={};
zufall1[personen_List]:=
  Block[{n=Random[Integer,{1,Length[personen]}]},
	Prepend[zufall1[Drop[personen,{n}]],
	personen[[n]]]];

Einige Details zum Test:
  Quelques détails quant au test:

personen={a,b,c,d};
zufall1[personen]

n=Random[Integer,{1,Length[personen]}]

n=Random[Integer,{1,Length[personen]}];
Drop[personen,{n}]

zufall1[Drop[{a,b,c,d},{2}]]

Oder definiere dann die Funktion "zufall2". Diese Funktion tut dasselbe wie "zufall1":
  Ou bien définis la fonction "zufall2". Cette fonction fait la même chose que "zufall2":

zufall2[{}]:={};
zufall2[personen_List]:=
 Block[{n=Random[Integer,{0,Length[personen]-1}],
				 shifted},
		shifted=RotateLeft[personen,n];
		Prepend[zufall2[Drop[shifted,1]],
		shifted[[1]]]];

Einige Details zum Test:
  Quelques détails quant au test:

personen={a,b,c,d};
zufall2[personen]

n=Random[Integer,{0,Length[personen]-1}]

n=Random[Integer,{0,Length[personen]-1}];
shifted=RotateLeft[personen,n]

n=Random[Integer,{0,Length[personen]-1}];
shifted=RotateLeft[personen,n];
Drop[shifted,1]

Oder definiere dann die Funktion "zufall" mit Hilfe der Funktion "Sort". 
Hier werden Paare {a,b} benützt, wobei a eine Zufallszahl und b die 
Ordnungszahl der Person ist. Die Paare werden dann nach a geordnet. Diese Funktion tut dasselbe wie "zufall1":
  Ou bien définis la fonction "zufall" à l'aide de la fonction "Sort". Ici on emploie des paires {a,b}, a étant le nombre aléatoire, b le nombre ordinal de la personne. Les paires sont rangées selon a. Cette fonction fait la même chose que "zufall1":

zufall[{}]:={};
zufall[personen_List]:=
	Map[Last, 
		Sort[Map[{Random[], #}&, personen],
			 (#1[[1]] > #2[[1]])&
		]];
zufall::usage="zufall[list] gibt eine zufällige \
			Permutation der Elemente der Liste \
			--- donne une permutation aléatoire \
			des éléments de la liste."

Einige Details zum Test:
 Quelques détails quant au test:

personen={a,b,c,d};
zufall[personen]

{Random[], #}&[personen]

Map[{Random[], #}&, personen]

Sort[Map[{Random[], #}&, personen],
			 (#1[[1]] > #2[[1]])&]

Map[Last, Sort[Map[{Random[], #}&, personen],
			 (#1[[1]] > #2[[1]])& ]]

Gib nun den Personen statt Namen Ordnungszahlen von 1 bis n. 1 bedeutet "am meisten bevorzugt" etc..
  Donne aux personnes au lieu de noms des nombres ordinaux de 1 jusqu'à n. 1 signifie "préféré le plus" etc..

n = 30;
personen = zufall[Range[n]]

Die Funktion "wahlVorzug" soll nun n Personen nehmen und diese in zufällige Reihenfolge bringen. Sie soll die ersten (n/e) (gerundet) Personen nehmen und den Wert der meist bevorzugten Person in dieser Menge in die Variable mmin speichern. Der Wert der ersten noch mehr bevorzugten Person, die dann folgt, soll in die Variable wahl gespeichert werden. Wenn wahl eine Zahl grösser gleich 1 enthält, soll wahlVorzug diese Zahl als Element einer Menge ausgeben. Andernfalls soll die leere Menge kommen. 
  La fonction "wahlVorzug" prenne maintenant n personnes et les mette dans un ordre aléatoire. Qu'elle prenne les premières (n/e) (arrondi) personnes et qu'elle mémorise dans la variable mmin la valeur de la personne préférée de cet ensemble. La valeur de la personne préférée encore davantage, qui suit, doit être mémorisée dans la variable wahl. Si wahl contient un nombre plus grand ou égal 1, wahl doit sortir ce nombre comme élément d'un ensemble. Autrement doit apparaître l'ensemble vide.

wahlVorzug[n_Integer]:= 
    	Module[{personen=zufall[Range[n]],
    	m=Round[N[n/E]],
		mmin, wahl},
		mmin=Min[Take[personen,m]];
		wahl=Select[personen,(#<mmin)&];
		If[Length[wahl]>0,First[wahl],{}]];
anzahlPersonen=30;
anzahlLauf=50;
resultat=Table[wahlVorzug[anzahlPersonen],
		{anzahlLauf}]

Anzahl positive Simulationen mit Resultat 1, 2 oder 3:
  Nombre de simulations avec le résultat 1, 2 ou 3:

posSim1={Map[(N[Count[resultat,#]/anzahlLauf])&,
								{1,2,3}]}

Kürzer mit Vergleich mit (1/e):
  Plus brièvement avec la comparaison avec (1/e):

posSim1={(N[Count[resultat,#]/anzahlLauf
						])&/@{1,2,3},N[1/E]}

(b) Prozentualer Anteil der Läufe, die mit einem signifikanten 
     Partner enden:
   Partie propositionelle des parcours qui terminent par un
     partenaire significatif:

Studiert man den Output, so sieht man, dass meistens die Anzahl der Fälle, in denen die leere Menge herauskommt, sehr gering ist. Dann hat die Strategie keinen Erfolg. Falls die Strategie eine Zahl ergibt, so wollen wir von Erfolg insofern reden, dass dann eine kleine Nummer erwartet werden kann. Wir sagen dann, es hätte sich ein "signifikanter Partner" finden lassen. Wie oft kommt das prozentual vor?
  Si on étudie l'output, on voit que pour la plupart le nombre des cas où sort l'ensemble vide et très petit. Dans ces cas la stratégie n'a pas de succès. Si la stratégie donne un nombre, nous pouvons nous attendre à un nombre bas. Nous dirons qu'un "partenaire significatif" a pu être trouvé. Dans quel pourcentage cela arrive-t-il?

signifikant = 1- N[Count[resultat,{}]/50]

c) Wie gut oder schlecht war die Auswahl nun?
  Combien le choix était donc bon ou mauvais?

Wir berechnen, in wievielen Läufen prozentual die Simulation mit einer Person endete, die unter "den favorisierten 10%" einzureihen ist.
  Nous calculons dans combien de parcours la simulation s'est terminée par une personne qu'on a pu placer parmi les "10 % facorisés".

signifikant10Prozent = 
		N[Length[Select[resultat,
		(#<=Round[N[anzahlPersonen 0.1]])&]]/50]

(d) Bei einer grösseren Laufzahl:
   Lors d'un nombre supérieur de parcours:

anzahlLauf=50;
resultat=Table[wahlVorzug[anzahlPersonen],
					{anzahlLauf}];					
posSim1={Map[(N[Count[resultat,#]/anzahlLauf])&,
					{1,2,3}]};
signifikant = 1- N[Count[resultat,{}]/50];	
signifikant10Prozent = 
		N[Length[Select[resultat,
		(#<=Round[N[anzahlPersonen 0.1]])&]]/50];
Print["resultat = ", resultat];	
Print["posSim1 				= ", posSim1];
Print["signifikant 			= ", signifikant];
Print["signifikant10Prozent = ", 
							signifikant10Prozent]

"Putzmaschine" einsetzen
 Employer la "machine de nettoyage"

Remove["Global`@*"]