1 // Implementation of learningsyl methods
2 // Copyright © 2009 The University of Chicago
3 #include "DCNlearningsyl.h"
10 #include "DCNgrammarsyl.h"
11 #include "DCNnetworksyl.h"
12 #include "DCNcorpussyl.h"
13 #include "DCNdcnword.h"
14 #include "ui/Status.h"
18 using linguistica::ui::status_user_agent
;
21 learningsyl::learningsyl()
33 increaseWhenWrong(0.02f
),
34 decreaseWhenRight(0.95f
),
38 startingBeta(-0.3f
) { }
40 learningsyl::~learningsyl() { }
42 void learningsyl::runHelper(std::ostream
&logstream
, status_user_agent
& status
)
48 srand(static_cast<unsigned>(time(0)));
52 //careful, i'm specifying values
54 int cutoff
= cutoffFromUser
;
57 int maxCorpusIndex
= numberOfWords
;
64 grammar
.setValues(startingAlpha
,startingBeta
);
65 net
.setGrammar(&grammar
);
67 status
.progress
.clear();
68 status
.progress
.set_denominator(cutoffFromUser
);
70 while (T
> 0.01 && cutoff
>= 0) {
71 status
.progress
= updateNumber
;
74 << "#: " << cutoffFromUser
- cutoff
<< "\t"
75 << "a: " << grammar
.getAlpha() << "\t"
76 << "b: " << grammar
.getBeta() << "\t"
77 << "w: " << grammar
.getSonority(QChar('w')) << "\t"
78 << "a: " << grammar
.getSonority(QChar('a')) << "\t"
79 << "k: " << grammar
.getSonority(QChar('k')) << "\t"
80 << "u: " << grammar
.getSonority(QChar('u')) << "\n";
83 // 1) take a word from the corpus
84 dcnword word
= corpus
.wordAt(corpusIndex
);
86 // 2) check all the letters -- if any are new, assign a random float
87 QString text
= word
.getText();
88 for (int i
= 0; i
< text
.length(); i
++)
90 if (!grammar
.isInMap(text
.at(i
)))
92 const float randomNum
=
93 static_cast<float>(rand()) /
94 static_cast<float>(RAND_MAX
) / 2 +
96 grammar
.setSonority(text
.at(i
), randomNum
);
100 // 3) make sonority vector
103 // 4) run network with word & alpha & beta
106 // 5) compare network & word.maxima
107 QString expMaxima
= net
.getMaxima(); // experimental maxima
108 QString targetMaxima
= word
.getMaxima();
110 // 6) make changes to letters associated with word
111 bool changes
= false;
112 for (int j
= 0; j
< text
.length(); j
++)
114 QChar letter
= text
.at(j
);
115 float s
= grammar
.getSonority(letter
);
116 QChar expChar
= expMaxima
.at(j
);
117 QChar targetChar
= targetMaxima
.at(j
);
119 if (expChar
== 'H' && targetChar
!= 'H')
121 // make sure there are no negative letters...
122 // I don't know if this is necessary or not...
124 grammar
.setSonority(letter
, s
- 0.1f
);
127 else if (expChar
!= 'H' && targetChar
== 'H')
129 grammar
.setSonority(letter
, s
+ 0.1f
);
134 // 7) modify alpha & beta
136 using linguistica::random_small_float
;
137 // random float between -1 and 1
138 float deltaAlpha
= T
* random_small_float();
139 alpha
= grammar
.getAlpha() + deltaAlpha
;
141 float deltaBeta
= T
* random_small_float();
142 beta
= grammar
.getBeta() + deltaBeta
;
144 possibleGrammar
.setValues(alpha
, beta
);
145 possibleNet
.setWord(text
);
146 possibleNet
.setGrammar(&possibleGrammar
);
147 possibleNet
.equilibrium();
149 if (possibleNet
.isConverged())
151 // alpha * beta > .3 may be another thing to put in here
158 grammar
.setValues(alpha
, beta
);
160 T
= T
+ increaseWhenWrong
;
161 //T = T + sqrt( pow(deltaAlpha, 2.0) + pow(deltaBeta, 2.0)
162 // + pow(deltaI, 2.0) + pow(deltaF, 2.0) );
167 T
= T
* decreaseWhenRight
;
170 cutoff
--; updateNumber
++;
171 corpusIndex
= (corpusIndex
+ 1)%maxCorpusIndex
;
172 if (corpusIndex
% 256 == 0)
175 status
.progress
.clear();
177 possibleGrammar
.setValues(alpha
, beta
);
178 possibleNet
.setGrammar(&possibleGrammar
);
179 possibleNet
.equilibrium();
180 if (cutoff
> 2 && possibleNet
.isConverged())
184 void learningsyl::run(status_user_agent
& status_display
)
191 std::ofstream
logstream("DCNsyllog.txt"); // declare and open file stream
195 logstream
<< "Learning Algorithm run at " << ctime(&rawtime
);
197 for (int i
= 0; i
< numberOfTries
; i
++)
199 logstream
<< "\n\tTRIAL NUMBER " << i
+1 << "\n";
200 runHelper(logstream
, status_display
);
201 if (this->isSuccessful()) break;
205 rGrammar
= new grammarsyl(grammar
); // can do this because of the magic of copying QMaps
209 void learningsyl::setCorpus(corpussyl corpus
)
211 this->corpus
= corpus
;
212 this->numberOfWords
= corpus
.numberOfWords();