Home > src > sosHistory.m

# sosHistory

## PURPOSE

- object for storing the detailed history of an optimization

## SYNOPSIS

This is a script file.

## DESCRIPTION

     - 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.

## CROSS-REFERENCE INFORMATION

This function calls:

- sosHistory - object for storing the detailed history of an optimization
- verbosePrint - master print function that regulates cmd line output based on verbosity flags

This function is called by:

- sos - SOS optimization object
- sosHistory - object for storing the detailed history of an optimization

## SUBFUNCTIONS

- function obj = sosHistory(sosObj)
- function updateHistory(obj,curIt,cost,deltaCost,pFlip,
- function setBufferedHistoryOutfile(obj,outFile)
- function disableBufferedHistoryWrite(obj)
- function enableBufferedHistoryWrite(obj)
- function writeBuffer(obj,updateHeader)
- function writeHistory(obj,outFile)
- function addStatTestName(obj,name)
- function writeHeader(obj,fid)
- function writeData(obj,fid,index)

## SOURCE CODE

    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