# v_finishat

## PURPOSE

V_FINISHAT print estimated finish time of a long computation (FRAC,TOL,FMT)

## SYNOPSIS

function [eta,etaf]=v_finishat(frac,tol,fmt)

## DESCRIPTION

    V_FINISHAT print estimated finish time of a long computation (FRAC,TOL,FMT)
     Usage:  (1)  for i=1:many
                      v_finishat((i-1)/many);  % initializes on first pass when i=1
                      ... computation ...
                  end

             (3)  v_finishat(0);               % explicit initialization before loop
                  for i=1:many
                      ... computation ...
                      v_finishat(i/many);      % calculate fraction completed
                  end

             (5)  for i=MI:NI
                      for j=MJ:NJ
                          for k=MK:NK
                              v_finishat([i MI NI; j MJ NJ; k MK NK]); % one row per nested loop
                              ... computation ...
                          end
                      end
                  end

             (6)  for i=MI:DI:NI
                      for j=MJ:DJ:NJ
                          for k=MK:DK:NK
                              v_finishat([i MI DI NI; j MJ DJ NJ; k MK DK NK]); % one row per nested loop
                              ... computation ...
                          end
                      end
                  end

     Inputs: FRAC = fraction of total comutation that has been completed
                    Alternatively at start of inner loop: [i MI DI NI; j MJ DJ NJ; k MK DK NK; ...] where i, j, k are
                    nested loop indices and MI:DI:NI, MJ:DJ:NJ, MK:DK:NK their limits. If the DI, DJ, DK, ... all equal 1
                    The may be omitted. Use k+1 instead of k if placed at the end of the inner loop.
                    As a special case, FRAC=0 initializes the routine.
             TOL  = Tolerance in minutes. If the estimated time has changed by less
                    than this, then nothing will be printed. [default 10% of remaining time]
             FMT  = Format string which should include:
                       %s for estimated finish time
                       %d for remaining minutes
                       %t for remaining hr:min:sec
                       %f for fraction complete
                       %p for % complete
                    The %t, %f and %p options can include optional width and/or decimal-place dimensions (e.g. %.2f)

     Output: ETA  = string containing the expected finish time
                    specifying this will suppress printing message to std err (fid=2)
             ETAF = expected finish time as a daynumber

     Example:       v_finishat(0);
                    for i=1:many
                        long computation;
                        v_finishat(i/many);
                    end

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

## SOURCE CODE

    0001 function [eta,etaf]=v_finishat(frac,tol,fmt)
    0002 %V_FINISHAT print estimated finish time of a long computation (FRAC,TOL,FMT)
    0003 % Usage:  (1)  for i=1:many
    0004 %                  v_finishat((i-1)/many);  % initializes on first pass when i=1
    0005 %                  ... computation ...
    0006 %              end
    0007 %
    0008 %         (3)  v_finishat(0);               % explicit initialization before loop
    0009 %              for i=1:many
    0010 %                  ... computation ...
    0011 %                  v_finishat(i/many);      % calculate fraction completed
    0012 %              end
    0013 %
    0014 %         (5)  for i=MI:NI
    0015 %                  for j=MJ:NJ
    0016 %                      for k=MK:NK
    0017 %                          v_finishat([i MI NI; j MJ NJ; k MK NK]); % one row per nested loop
    0018 %                          ... computation ...
    0019 %                      end
    0020 %                  end
    0021 %              end
    0022 %
    0023 %         (6)  for i=MI:DI:NI
    0024 %                  for j=MJ:DJ:NJ
    0025 %                      for k=MK:DK:NK
    0026 %                          v_finishat([i MI DI NI; j MJ DJ NJ; k MK DK NK]); % one row per nested loop
    0027 %                          ... computation ...
    0028 %                      end
    0029 %                  end
    0030 %              end
    0031 %
    0032 % Inputs: FRAC = fraction of total comutation that has been completed
    0033 %                Alternatively at start of inner loop: [i MI DI NI; j MJ DJ NJ; k MK DK NK; ...] where i, j, k are
    0034 %                nested loop indices and MI:DI:NI, MJ:DJ:NJ, MK:DK:NK their limits. If the DI, DJ, DK, ... all equal 1
    0035 %                The may be omitted. Use k+1 instead of k if placed at the end of the inner loop.
    0036 %                As a special case, FRAC=0 initializes the routine.
    0037 %         TOL  = Tolerance in minutes. If the estimated time has changed by less
    0038 %                than this, then nothing will be printed. [default 10% of remaining time]
    0039 %         FMT  = Format string which should include:
    0040 %                   %s for estimated finish time
    0041 %                   %d for remaining minutes
    0042 %                   %t for remaining hr:min:sec
    0043 %                   %f for fraction complete
    0044 %                   %p for % complete
    0045 %                The %t, %f and %p options can include optional width and/or decimal-place dimensions (e.g. %.2f)
    0046 %
    0047 % Output: ETA  = string containing the expected finish time
    0048 %                specifying this will suppress printing message to std err (fid=2)
    0049 %         ETAF = expected finish time as a daynumber
    0050 %
    0051 % Example:       v_finishat(0);
    0052 %                for i=1:many
    0053 %                    long computation;
    0054 %                    v_finishat(i/many);
    0055 %                end
    0056
    0057 %      Copyright (C) Mike Brookes 1998-2023
    0058 %      Version: $Id: v_finishat.m 10865 2018-09-21 17:22:45Z dmb $
    0059 %
    0060 %   VOICEBOX is a MATLAB toolbox for speech processing.
    0061 %   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
    0062 %
    0063 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0064 %   This program is free software; you can redistribute it and/or modify
    0065 %   it under the terms of the GNU Lesser General Public License as published by
    0066 %   the Free Software Foundation; either version 3 of the License, or
    0067 %   (at your option) any later version.
    0068 %
    0069 %   This program is distributed in the hope that it will be useful,
    0070 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
    0071 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0072 %   GNU Lesser General Public License for more details.
    0073 %
    0074 %   You can obtain a copy of the GNU Lesser General Public License from
    0075 %   https://www.gnu.org/licenses/ .
    0076 %
    0077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    0078
    0079 persistent oldt oldnw tstart
    0080 [nf,nv]=size(frac);
    0081 if nargin<3
    0082     fmt='Estimated finish at %s (%.0p done, %t remaining)\n';
    0083 end
    0084 if isempty(tstart) || nv<3 && all(frac(:,1)<=[ones(nf-1,1); 0]) || nv>=3 && all(frac(:,1)==frac(:,2)) % initialize if fraction done is <=0
    0085     oldt=0;
    0086     eta='Unknown';
    0087     tstart=tic;
    0088 else
    0089     if nv==2 % obsolete format that assumes all loop indices start at 1
    0090         fp=cumprod(frac(:,2));
    0091         frac=sum((frac(:,1)-1)./fp)+1/fp(end);
    0092     elseif nv==3
    0093         fp=cumprod(frac(:,3)-frac(:,2)+1);
    0094         frac=sum((frac(:,1)-frac(:,2))./fp);
    0095     else
    0096         fp=cumprod(floor((frac(:,4)-frac(:,2))./frac(:,3))+1);
    0097         frac=sum(round((frac(:,1)-frac(:,2))./frac(:,3))./fp);
    0098     end
    0099     nw=now;                             % current time as serial number
    0100     sectogo=(1/frac-1)*toc(tstart);      % seconds to go
    0101     newt=nw+sectogo/86400;       % add estimated time in days
    0102     if nargin<2 || ~numel(tol)
    0103         tol=max(0.1*(newt-nw)*1440,1);
    0104     end
    0105     if ~exist('oldt','var') || length(oldt)~=1 || oldt==0 || (abs(newt-oldt)>tol/1440 && (nw-oldnw)>10/86400) || (nw-oldnw)>10/1440 || nargout>0
    0106         oldt=newt;
    0107         if floor(oldt)==floor(nw)
    0108             df='HH:MM';
    0109         else
    0110             df='HH:MM dd-mmm-yyyy';
    0111         end
    0112         eta=datestr(oldt,df);
    0113         if ~nargout
    0114             ix=find(fmt=='%',1);
    0115             while ~isempty(ix)
    0116                 fprintf(2,fmt(1:ix-1));
    0117                 fmt=fmt(ix:end);
    0118                 ix=find(fmt>='a' & fmt<='z',1); % find letter
    0119                 switch fmt(ix)
    0120                     case 's'
    0121                         fprintf(2,fmt(1:ix),eta);
    0122                     case 'd'
    0123                         fprintf(2,fmt(1:ix),round(sectogo/60));
    0124                     case 'f'
    0125                         if ix>2
    0126                             fprintf(2,fmt(1:ix),frac);
    0127                         else
    0128                             fprintf(2,'%.2f',frac);
    0129                         end
    0130                     case 'p'
    0131                         if ix>2
    0132                         fprintf(2,[fmt(1:ix-1) 'f%%'],frac*100);
    0133                         else
    0134                             fprintf(2,'%.0f%%',frac*100);
    0135                         end
    0136                     case 't'
    0137                         if ix>2
    0138                             if sectogo>=3600
    0139                                 fprintf(2,[fmt(1:ix-1) 'f hr'],sectogo/3600);
    0140                             elseif sectogo>=60
    0141                                 fprintf(2,[fmt(1:ix-1) 'f min'],sectogo/60);
    0142                             else
    0143                                 fprintf(2,[fmt(1:ix-1) 'f sec'],sectogo);
    0144                             end
    0145                         else
    0146                             if sectogo>=36000
    0147                                 fprintf(2,'%.0f hr',sectogo/3600);
    0148                             elseif sectogo>=3600
    0149                                 fprintf(2,'%.1f hr',sectogo/3600);
    0150                             elseif sectogo>=600
    0151                                 fprintf(2,'%.0f min',sectogo/60);
    0152                             elseif sectogo>=60
    0153                                 fprintf(2,'%.1f min',sectogo/60);
    0154                             else
    0155                                 fprintf(2,'%.0f sec',sectogo);
    0156                             end
    0157                         end
    0158                 end
    0159                 fmt=fmt(ix+1:end);
    0160                 ix=find(fmt=='%',1);
    0161             end
    0162             fprintf(2,fmt);
    0163         end
    0164         oldnw=nw;                           %
    0165     end
    0166 end
    0167 etaf=oldt;