Ignore:
Timestamp:
01/26/21 18:50:37 (3 years ago)
Author:
Maciej Komosinski
Message:

Properly allocated and de-allocated dynamic arrays of size calculated in runtime, not relying on g++ "extension"

Location:
cpp/frams/model/similarity/EMD
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/model/similarity/EMD/emd.c

    r1063 r1064  
    22    emd.c
    33
    4     Last update: 3/14/98
     4    Last update: 3/14/98 (but see emd.h for a list newer changes)
    55
    66    An implementation of the Earth Movers Distance.
     
    1313    E-Mail: rubner@cs.stanford.edu   URL: http://robotics.stanford.edu/~rubner/emd/default.htm
    1414*/
     15
     16// For a list of changes since 2020, see emd.h
    1517
    1618#include <stdio.h>
     
    98100{
    99101  int itr;
    100   int max_n = (_n1 > _n2) ? _n1 : _n2;
     102  int max_n = max(_n1, _n2); //max_n was introduced in r1062 instead of the #defined constant MAX_SIG_SIZE1=1000 in the original implementation. max_n is better than the constant, but it would be even better to use either _n1 or _n2, if we only knew what size each individual array should precisely have.
    101103  double totalCost;
    102104  float w;
    103105  node2_t *XP;
    104106  flow_t *FlowP;
    105   node1_t U[max_n], V[max_n];
     107  node1_t *U=new node1_t[max_n], *V=new node1_t[max_n];
    106108  /* THE COST MATRIX */
    107109  float** _CM = new float*[_n1];
     
    189191  delete[] _RowsX;
    190192  delete[] _ColsX; 
     193
     194  delete[] U;
     195  delete[] V;
    191196 
    192197  /* RETURN THE NORMALIZED COST == EMD */   
     
    206211{
    207212  int i, j;
    208   int max_n = (_n1 > _n2) ? _n1 : _n2;
     213  int max_n = max(_n1, _n2); //max_n was introduced in r1062 instead of the #defined constant MAX_SIG_SIZE1=1000 in the original implementation. max_n is better than the constant, but it would be even better to use either _n1 or _n2, if we only knew what size each individual array should precisely have.
    209214  double sSum, dSum, diff;
    210215  feature_t *P1, *P2;
    211   double S[max_n], D[max_n];
     216  double *S=new double[max_n], *D=new double[max_n];
    212217
    213218 
     
    272277
    273278  _EnterX = _EndX++;  /* AN EMPTY SLOT (ONLY _n1+_n2-1 BASIC VARIABLES) */
     279
     280  delete[] S;
     281  delete[] D;
    274282
    275283  return sSum > dSum ? dSum : sSum;
     
    465473static void newSol(int _n1, int _n2, node2_t * _XV, char **_IsX, node2_t **_RowsX, node2_t **_ColsX)
    466474{
    467     int i, j, k, max_n = (_n1 > _n2) ? _n1 : _n2;
     475    int i, j, k;
     476    int max_n = max(_n1, _n2); //max_n was introduced in r1062 instead of the #defined constant MAX_SIG_SIZE1=1000 in the original implementation. max_n is better than the constant, but it would be even better to use either _n1 or _n2, if we only knew what size each individual array should precisely have.
    468477    double xMin;
    469478    int steps;
    470     node2_t *Loop[2*max_n], *CurX, *LeaveX;
     479    node2_t **Loop=new node2_t*[2*max_n], *CurX, *LeaveX;
    471480 
    472481#if DEBUG_LEVEL > 3
     
    534543    /* SET _EnterX TO BE THE NEW EMPTY SLOT */
    535544    _EnterX = LeaveX;
     545
     546        delete[] Loop;
    536547}
    537548
     
    543554static int findLoop(node2_t **Loop, int _n1, int _n2, node2_t *_XV, node2_t **_RowsX, node2_t **_ColsX)
    544555{
    545   int i, steps, max_n = (_n1 > _n2) ? _n1 : _n2;
     556  int i, steps;
     557  int max_n = max(_n1, _n2); //max_n was introduced in r1062 instead of the #defined constant MAX_SIG_SIZE1=1000 in the original implementation. max_n is better than the constant, but it would be even better to use either _n1 or _n2, if we only knew what size each individual array should precisely have.
    546558  node2_t **CurX, *NewX;
    547   char IsUsed[2*max_n];
     559  char *IsUsed=new char[2*max_n];
    548560 
    549561  for (i=0; i < _n1+_n2; i++)
     
    627639#endif
    628640
     641  delete[] IsUsed;
     642
    629643  return steps;
    630644}
     
    637651static void russel(double *S, double *D, int _n1, int _n2, float **_CM, char **_IsX, node2_t **_RowsX, node2_t **_ColsX)
    638652{
    639   int i, j, found, minI, minJ, max_n = (_n1 > _n2) ? _n1 : _n2;
     653  int i, j, found, minI, minJ;
     654  int max_n = max(_n1, _n2); //max_n was introduced in r1062 instead of the #defined constant MAX_SIG_SIZE1=1000 in the original implementation. max_n is better than the constant, but it would be even better to use either _n1 or _n2, if we only knew what size each individual array should precisely have.
    640655  double deltaMin, oldVal, diff;
    641656  double** Delta = new double*[_n1];
    642657  for(int k = 0; k < _n1; ++k)
    643658    Delta[k] = new double[_n2];
    644   node1_t Ur[max_n], Vr[max_n];
     659  node1_t *Ur=new node1_t[max_n], *Vr=new node1_t[max_n];
    645660  node1_t uHead, *CurU, *PrevU;
    646661  node1_t vHead, *CurV, *PrevV;
     
    790805        }
    791806    } while (uHead.Next != NULL || vHead.Next != NULL);
     807
     808        delete[] Ur;
     809        delete[] Vr;
    792810    for(int k = 0; k < _n1; ++k)
    793811      delete[] Delta[k];
  • cpp/frams/model/similarity/EMD/emd.h

    r1063 r1064  
    44    emd.h
    55
    6     Last update: 3/24/98
     6    Last update: 3/24/98 (but see below for newer changes)
    77
    88    An implementation of the Earth Movers Distance.
     
    1515    E-Mail: rubner@cs.stanford.edu   URL: http://robotics.stanford.edu/~rubner/emd/default.htm
    1616*/
     17
     18// List of changes since 2020, compared to the original implementation:
     19// r1050: Renamed variables that caused problems with g++ 7.3.0
     20// r1062: Global static arrays moved to a function and now allocated dynamically; removed #defined limit of MAX_SIG_SIZE=1000
     21
    1722
    1823/* DEFINITIONS */
Note: See TracChangeset for help on using the changeset viewer.