


- object for storing the detailed history of an optimization
copyright 2009-2012 Blair Armstrong, Christine Watson, David Plaut
This file is part of SOS
SOS is free software: you can redistribute it and/or modify
it for academic and non-commercial purposes
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. For commercial or for-profit
uses, please contact the authors (sos@cnbc.cmu.edu).
SOS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.


0001 % - object for storing the detailed history of an optimization 0002 % 0003 % copyright 2009-2012 Blair Armstrong, Christine Watson, David Plaut 0004 % 0005 % This file is part of SOS 0006 % 0007 % SOS is free software: you can redistribute it and/or modify 0008 % it for academic and non-commercial purposes 0009 % under the terms of the GNU General Public License as published by 0010 % the Free Software Foundation, either version 3 of the License, or 0011 % (at your option) any later version. For commercial or for-profit 0012 % uses, please contact the authors (sos@cnbc.cmu.edu). 0013 % 0014 % SOS is distributed in the hope that it will be useful, 0015 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 % GNU General Public License for more details. 0018 0019 % You should have received a copy of the GNU General Public License 0020 % along with SOS (see COPYING.txt). 0021 % If not, see <http://www.gnu.org/licenses/>. 0022 0023 classdef sosHistory < handle 0024 %% records and provides writing support for detailed optimization history data 0025 % 0026 % This class provides support for recording and writing several metrics 0027 % related to the optimization process. Specifically, the following 0028 % items are recorded: 0029 % 0030 % creates plots for several optimization parameters, as follows: 0031 % - cost 0032 % - deltaCost 0033 % - temperature 0034 % - pFlipHistory 0035 % - sosStatTestpvals (for all stat tests in the sos Object) 0036 % 0037 % This class also inherits from the handle CLASS to gain standard 0038 % object-oriented behavior 0039 % 0040 % PROPERTIES: 0041 % sosObj % the sos object the history data originated from 0042 % itHistory % history of iteration numbers where reports were made 0043 % tempHistory % history of temperature 0044 % costHistory % history of cost 0045 % deltaCostHistory % history of deltaCost 0046 % pFlipHistory % history of the probability of flipping 0047 % pvalTestNames % names of the ttests for use as labels 0048 % pvalHistory % history of pvalues for t-tests (2d; seperate column for each test) 0049 % outFile % filename to write buffered output to 0050 % bufferedWrite % switch indicating whether buffered writing is enabled/disabled 0051 % 0052 % METHODS 0053 % obj = sosHistory(sosObj) % Constructor - creates an sosHistory object 0054 % updateHistory(curIt,cost,deltaCost,pFlip,testNames,testps,temp) % updates the history with the passed data 0055 % setBufferedHistoryOutfile(outFile) % writes the history on-line, one update at a time. Overrides the existing file. 0056 % disableBufferedHistoryWrite() % disables buffered writing 0057 % enableBufferedHistoryWrite() % enables buffered writing 0058 % writeBuffer(updateHeader) % writes out the most recent update to outFile. 0059 % writeHistory(outFile) % writes the entire history to outFile 0060 % addStatTestName(name) % adds a new stat test name to the list of stat test names. 0061 % 0062 % METHODS (Private) 0063 % writeHeader(fid) % writes the header information to fid 0064 % 0065 0066 0067 %% PROPERTIES 0068 properties 0069 sosObj % the sos object the history data originated from 0070 itHistory % history of iteration numbers where reports were made 0071 tempHistory % history of temperature 0072 costHistory % history of cost 0073 deltaCostHistory % history of deltaCost 0074 pFlipHistory % history of the probability of flipping 0075 pvalTestNames % names of the ttests for use as labels 0076 pvalHistory % history of pvalues for t-tests (2d; seperate column for each test) 0077 outFile % filename to write buffered output to 0078 bufferedWrite % switch indicating whether buffered writing is enabled/disabled 0079 end %# properties 0080 0081 %% METHODS 0082 methods 0083 0084 %% sosHistory() CONSTRUCTOR 0085 function obj = sosHistory(sosObj) 0086 % Constructor - creates an sosHistory object 0087 % 0088 % PARAMETERS: 0089 % -sosObj - SOS object the history will be associated with 0090 0091 obj.sosObj = sosObj; 0092 0093 obj.costHistory = []; 0094 obj.deltaCostHistory = []; 0095 obj.pvalTestNames = {}; 0096 obj.pvalHistory = []; 0097 obj.tempHistory= []; 0098 obj.pFlipHistory = []; 0099 obj.itHistory = []; 0100 0101 obj.bufferedWrite = false; 0102 0103 0104 % get the labels for all of the ttests that already exist 0105 for i=1:length(sosObj.sosstattests) 0106 obj.pvalTestNames = horzcat(obj.pvalTestNames,... 0107 sosObj.sosstattests{i}.label); 0108 end 0109 0110 verbosePrint('Detailed optimization history will now be recorded...', ... 0111 'sosHistory_constructor_end'); 0112 0113 end % constructor 0114 0115 0116 %% updateHistory(obj,curIt,cost,deltaCost,pFlip,testNames,testps,temp) METHOD 0117 function updateHistory(obj,curIt,cost,deltaCost,pFlip, ... 0118 testNames,testps,temp) 0119 % updates the history with the passed data 0120 % 0121 % PARAMETERS: 0122 % curIt - current iteration 0123 % cost - current cost 0124 % deltaCost - current deltaCost 0125 % pFlip - current pFlip 0126 % testNames - cell array containing names of all stattests 0127 % testps - array containing p-values for all stattests 0128 % temp - current temperature 0129 0130 0131 % append data 0132 obj.costHistory = vertcat(obj.costHistory,cost); 0133 obj.deltaCostHistory = vertcat(obj.deltaCostHistory,deltaCost); 0134 obj.tempHistory= vertcat(obj.tempHistory, temp); 0135 obj.pFlipHistory = vertcat(obj.pFlipHistory, pFlip); 0136 obj.itHistory = vertcat(obj.itHistory, curIt); 0137 0138 % check to make sure that no stat tests have been added 0139 0140 newRow = nan(1,length(obj.pvalTestNames)); 0141 updateHeader = false; 0142 0143 for i=1:length(testNames) 0144 index = -1; 0145 for j =1:length(obj.pvalTestNames) 0146 if strcmp(testNames{i},obj.pvalTestNames{j}) 0147 index = j; 0148 break; 0149 end 0150 end 0151 0152 %if the index was never found, a new column must be created 0153 %to hold its data. 0154 if index == -1 0155 updateHeader = true; 0156 obj.pvalTestNames = horzcat(obj.pvalTestNames,testNames{i}); 0157 newRow = horzcat(newRow,testps(i)); %#ok<AGROW> 0158 else 0159 %the index already exists. Put in the p-value 0160 newRow(index)=testps(i); 0161 end 0162 0163 end 0164 0165 %check to see if new ttests have been added. If they have, 0166 %newRow will be longer than an existing row in the pvalHistory, 0167 %and you'll need to add some NaN fillers. 0168 0169 if(size(obj.pvalHistory,2) == length(newRow)) 0170 obj.pvalHistory = vertcat(obj.pvalHistory, newRow); 0171 elseif(size(obj.pvalHistory,2) < length(newRow)) 0172 % add in NaN's to the existing matrix 0173 diff = length(newRow) - size(obj.pvalHistory,2); 0174 len = size(obj.pvalHistory,1); 0175 newCols = nan(len,diff); 0176 0177 %append the pval data 0178 obj.pvalHistory = horzcat(obj.pvalHistory,newCols); 0179 obj.pvalHistory = vertcat(obj.pvalHistory, newRow); 0180 else 0181 error('An error occured when adding a new row to pvalHistory'); 0182 end 0183 0184 % if buffered output is enabled, write out the new line. 0185 if obj.bufferedWrite 0186 obj.writeBuffer(updateHeader); 0187 end 0188 0189 end % updateHistory 0190 0191 0192 %% setBufferedHistoryOutfile(outFile) METHOD 0193 function setBufferedHistoryOutfile(obj,outFile) 0194 % writes the history on-line, one update at a time. Overrides 0195 % the existing file. 0196 % 0197 % PARAMETERS: 0198 % outFile - string name of file to write to. 0199 % 0200 0201 % test to make sure that the outFile is valid 0202 if exist('outFile','var') == 0 0203 error('"Outfile" argument was not supplied to writeHistory()'); 0204 end 0205 0206 if(ischar(outFile) == false) 0207 error('Outfile has not been set to a string != "null".'); 0208 end 0209 0210 if ischar(outFile) == false || strcmp(outFile,'null') 0211 error('Outfile has not been set to a string != "null".'); 0212 end 0213 0214 %outFile name is valid. Try writing the header 0215 0216 try 0217 fid = fopen(outFile,'w'); 0218 catch exception 0219 error(['Could not open file: ', outFile]); 0220 end 0221 0222 obj.writeHeader(fid); 0223 0224 fclose(fid); 0225 0226 obj.outFile = outFile; 0227 obj.bufferedWrite = true; 0228 0229 verbosePrint(['Current and future history will be written to: ' outFile,' on each report...'],... 0230 'sosHistory_bufferedHistoryWrite_end'); 0231 end 0232 0233 0234 %% disableBufferedHistoryWrite() METHOD 0235 function disableBufferedHistoryWrite(obj) 0236 % disables buffered writing 0237 0238 obj.bufferedWrite = false; 0239 0240 verbosePrint('Buffered writing of history disabled',... 0241 'sosHistory_disableBufferedHistoryWrite_end'); 0242 end 0243 0244 0245 %% enableBufferedHistoryWrite() METHOD 0246 function enableBufferedHistoryWrite(obj) 0247 % enables buffered writing 0248 0249 % can only enable writing if an outFile has been set 0250 if isempty(obj.outFile) == 0 0251 0252 obj.bufferedWrite = true; 0253 0254 verbosePrint('Buffered writing of history enabled',... 0255 'sosHistory_enableBufferedHistoryWrite_end'); 0256 else 0257 error('bufferedHistoryWrite(outFile) must be called to specify an outFile first!'); 0258 end 0259 end 0260 0261 0262 %% writeBuffer(updateHeader) 0263 function writeBuffer(obj,updateHeader) 0264 % writes out the most recent update to outFile. 0265 % 0266 % PARAMETERS: 0267 % updateHeader - flag indicating if the header changed and 0268 % hence needs to be reprinted 0269 % 0270 0271 try 0272 fid = fopen(obj.outFile,'a'); 0273 catch exception 0274 error(['Could not open file: ', obj.outFile]); 0275 end 0276 0277 if updateHeader 0278 obj.writeHeader(fid); 0279 end 0280 0281 % write the data 0282 for i=length(obj.itHistory):length(obj.itHistory) 0283 obj.writeData(fid,i); 0284 end 0285 0286 fclose(fid); 0287 0288 end 0289 0290 0291 %% writeHistory(outFile) METHOD 0292 function writeHistory(obj,outFile) 0293 % writes the entire history to outFile 0294 % 0295 % PARAMETERS: 0296 % outFile - string name of file to write to 0297 % 0298 0299 % check to see if the outFile is valid 0300 if exist('outFile','var') == 0 0301 error('"Outfile" argument was not supplied to writeHistory()'); 0302 end 0303 0304 if(ischar(outFile) == false) 0305 error('Outfile has not been set to a string != "null".'); 0306 end 0307 0308 if ischar(outFile) == false || strcmp(outFile,'null') 0309 error('Outfile has not been set to a string != "null".'); 0310 end 0311 0312 verbosePrint(['Writing optimization history to: ' outFile,' ...'],... 0313 'sosHistory_writeHistory_begin'); 0314 0315 try 0316 fid = fopen(outFile,'w'); 0317 catch exception 0318 error(['Could not open file: ', outFile]); 0319 end 0320 0321 % write the header 0322 obj.writeHeader(fid); 0323 0324 %now we can write the data. Since we forcibly collect all data 0325 %at the same time (i.e., no missing data allowed in any column) 0326 %we can just index the itHistory 0327 0328 % print each piece of data 0329 for i=1:length(obj.itHistory) 0330 obj.writeData(fid,i); 0331 end 0332 0333 fclose(fid); 0334 0335 end 0336 0337 %% addStatTestName(name) METHOD 0338 function addStatTestName(obj,name) 0339 % adds a new stat test name to the list of stat test names. 0340 % 0341 % This function is currently used by the sos object which owns 0342 % the history object to inform the history 0343 % object when a new stat test is added 0344 % 0345 % PARAMETERS: 0346 % name - string name of new stat test 0347 0348 obj.pvalTestNames = horzcat(obj.pvalTestNames,name); 0349 0350 end 0351 0352 end % methods 0353 0354 %% METHODS (Access = private) 0355 methods (Access = private) 0356 0357 %% writeHeader(fid) METHOD 0358 function writeHeader(obj,fid) 0359 % writes the header information to fid 0360 % 0361 % PARAMETERS: 0362 % fid - pointer to file to write to 0363 0364 fprintf(fid,'%s\t','iteration'); 0365 fprintf(fid,'%s\t','temp'); 0366 fprintf(fid,'%s\t','cost'); 0367 fprintf(fid,'%s\t','deltaCost'); 0368 fprintf(fid,'%s\t','pFlip'); 0369 0370 for i=1:length(obj.pvalTestNames) 0371 fprintf(fid,'%s\t',obj.pvalTestNames{i}); 0372 end 0373 0374 fprintf(fid,'\r\n'); 0375 0376 end 0377 0378 %% writeData(fid,index) METHOD 0379 function writeData(obj,fid,index) 0380 % writes the data at row 'index' to fid 0381 % 0382 % PARAMETERS: 0383 % fid - pointer to file to write to 0384 % index - row number to write 0385 0386 fprintf(fid,'%s\t',num2str(obj.itHistory(index))); 0387 fprintf(fid,'%s\t',num2str(obj.tempHistory(index))); 0388 fprintf(fid,'%s\t',num2str(obj.costHistory(index))); 0389 fprintf(fid,'%s\t',num2str(obj.deltaCostHistory(index))); 0390 fprintf(fid,'%s\t',num2str(obj.pFlipHistory(index))); 0391 0392 %print the p-vals 0393 0394 for j=1:length(obj.pvalTestNames) 0395 fprintf(fid,'%s\t',num2str(obj.pvalHistory(index,j))); 0396 end 0397 0398 fprintf(fid,'\r\n'); 0399 0400 end 0401 0402 end % methods (private) 0403 0404 end 0405