⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floatcompressorold.cpp

📁 对浮点型数据进行压缩
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
===============================================================================

  FILE:  floatcompressorold.cpp
  
  CONTENTS:

    see corresponding header file

  PROGRAMMERS:
  
    martin isenburg@cs.unc.edu
  
  COPYRIGHT:
  
    Copyright (C) 2000  Martin Isenburg (isenburg@cs.unc.edu)
    
    This software 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.
  
  CHANGE HISTORY:
  
    see corresponding header file
  
===============================================================================
*/

#include "floatcompressorold.h"

#include <stdlib.h>

// 0  1  2  3  4   5   6   7    8    9  10     11    12  13  14  15  16  17  18   19   20   21    22    23    24

const int bitsLowTable[] = {
   0, 0, 1, 2, 3,  4,  5,  6,   7,   8,  9,    10,   11,  1,  2,  3,  4,  5,  6,   7,   8,   9,   10,   11,   12
};

const int bitsMaskTable[] = {
   0, 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047,  1,  3,  7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4096
};

const int bitsHighTable[] = {
   0, 0, 0, 0, 0,  0,  0,  0,   0,   0,   0,    0,    0, 11, 11, 11, 11, 11, 11,  11,  11,  11,   11,   11,   11
};

FloatCompressorOld::FloatCompressorOld()
{
  bits = 0;
  min_float = F32_MAX;
  max_float = F32_MIN;
  bits_for_mantissa = (int*)malloc(sizeof(int)*256);
  stats_on_k = (int**)malloc(sizeof(int*)*256);
  for (int i = 0; i < 256; i++) stats_on_k[i] = 0;

  num_predictions_none = 0;
  num_predictions_last = 0;
  num_predictions_across = 0;
  num_predictions_within = 0;
}

FloatCompressorOld::~FloatCompressorOld()
{
  free(bits_for_mantissa);
}

void FloatCompressorOld::SetupCompressor(RangeEncoder* re, bool within)
{
  if (re == 0)
  {
    // none predictions
    ae_sign_none = new RangeEncoder(0);
    ae_exponent_none = new RangeEncoder(0);
    ae_mantissa_none = new RangeEncoder(0);

    // last predictions
    ae_sign_last = new RangeEncoder(0);
    ae_exponent_last = new RangeEncoder(0);
    ae_mantissa_last = new RangeEncoder(0);

    // across predictions
    ae_sign_across = new RangeEncoder(0);
    ae_exponent_across = new RangeEncoder(0);
    ae_mantissa_across = new RangeEncoder(0);

    if (within)
    {
      // use within predictions
      ae_sign_within = new RangeEncoder(0);
      ae_exponent_within = new RangeEncoder(0);
      ae_mantissa_within = new RangeEncoder(0);
    }
    else
    {
      // do not use within predictions
      ae_sign_within = 0;
      ae_exponent_within = 0;
      ae_mantissa_within = 0;
    }
  }
  else
  {
    // none predictions
    ae_sign_none = re;
    ae_exponent_none = re;
    ae_mantissa_none = re;

    // last predictions
    ae_sign_last = re;
    ae_exponent_last = re;
    ae_mantissa_last = re;

    // across predictions
    ae_sign_across = re;
    ae_exponent_across = re;
    ae_mantissa_across = re;

    if (within)
    {
      // use within predictions
      ae_sign_within = re;
      ae_exponent_within = re;
      ae_mantissa_within = re;
    }
    else
    {
      // do not use within predictions
      ae_sign_within = 0;
      ae_exponent_within = 0;
      ae_mantissa_within = 0;
    }
  }
  alloc_range_tables(within);
  reset_precision();
  if (bits)
  {
    float min = min_float;
    float max = max_float;

    if (min != F32_MAX)
    {
      update_precision(min);
    }
    if (max != F32_MIN)
    {
      update_precision(max);
    }
  }
}

void FloatCompressorOld::SetupDecompressor(RangeDecoder* rd, bool within)
{
  if (rd == 0)
  {
    // none predictions
    ad_sign_none = new RangeDecoder(ae_sign_none->getChars(), ae_sign_none->getNumberChars());
    ad_exponent_none = new RangeDecoder(ae_exponent_none->getChars(), ae_exponent_none->getNumberChars());
    ad_mantissa_none = new RangeDecoder(ae_mantissa_none->getChars(), ae_mantissa_none->getNumberChars());

    // last predictions
    ad_sign_last = new RangeDecoder(ae_sign_last->getChars(), ae_sign_last->getNumberChars());
    ad_exponent_last = new RangeDecoder(ae_exponent_last->getChars(), ae_exponent_last->getNumberChars());
    ad_mantissa_last = new RangeDecoder(ae_mantissa_last->getChars(), ae_mantissa_last->getNumberChars());

    // across predictions
    ad_sign_across = new RangeDecoder(ae_sign_across->getChars(), ae_sign_across->getNumberChars());
    ad_exponent_across = new RangeDecoder(ae_exponent_across->getChars(), ae_exponent_across->getNumberChars());
    ad_mantissa_across = new RangeDecoder(ae_mantissa_across->getChars(), ae_mantissa_across->getNumberChars());

    if (within)
    {
      // use within predictions
      ad_sign_within = new RangeDecoder(ae_sign_within->getChars(), ae_sign_within->getNumberChars());
      ad_exponent_within = new RangeDecoder(ae_exponent_within->getChars(), ae_exponent_within->getNumberChars());
      ad_mantissa_within = new RangeDecoder(ae_mantissa_within->getChars(), ae_mantissa_within->getNumberChars());
    }
    else
    {
      // do not use within predictions
      ad_sign_within = 0;
      ad_exponent_within = 0;
      ad_mantissa_within = 0;
    }
  }
  else
  {
    // none predictions
    ad_sign_none = rd;
    ad_exponent_none = rd;
    ad_mantissa_none = rd;

    // last predictions
    ad_sign_last = rd;
    ad_exponent_last = rd;
    ad_mantissa_last = rd;

    // across predictions
    ad_sign_across = rd;
    ad_exponent_across = rd;
    ad_mantissa_across = rd;

    if (within)
    {
      // use within predictions
      ad_sign_within = rd;
      ad_exponent_within = rd;
      ad_mantissa_within = rd;
    }
    else
    {
      // do not use within predictions
      ad_sign_within = 0;
      ad_exponent_within = 0;
      ad_mantissa_within = 0;
    }
  }
  alloc_range_tables(within);
  reset_precision();
}

void FloatCompressorOld::alloc_range_tables(bool within)
{
  int i;

  rmSignNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmExponentNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaNoneLow = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaNoneHigh = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmCorrectorBitsNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);


  rmSignLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmExponentLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaLastLow = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaLastHigh = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmCorrectorBitsLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  rmSignAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmExponentAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaAcrossLow = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaAcrossHigh = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmCorrectorBitsAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  if (within)
  {
    rmSignWithin = (RangeModel**)malloc(sizeof(RangeModel*)*256);
    rmExponentWithin = (RangeModel**)malloc(sizeof(RangeModel*)*256);
    rmMantissaWithinLow = (RangeModel**)malloc(sizeof(RangeModel*)*256);
    rmMantissaWithinHigh = (RangeModel**)malloc(sizeof(RangeModel*)*256);
    rmCorrectorBitsWithin = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  }
  else
  {
    rmSignWithin = 0;
    rmExponentWithin = 0;
    rmMantissaWithinLow = 0;
    rmMantissaWithinHigh = 0;
    rmCorrectorBitsWithin = 0;
  }

  rmZeroOrExtremeValue = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmPositiveOrNegativeValue = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  for (i = 0; i < 256; i++)
  {
    rmSignNone[i] = 0;
    rmExponentNone[i] = 0;
    rmMantissaNoneLow[i] = 0;
    rmMantissaNoneHigh[i] = 0;
    rmCorrectorBitsNone[i] = 0;

    rmSignLast[i] = 0;
    rmExponentLast[i] = 0;
    rmMantissaLastLow[i] = 0;
    rmMantissaLastHigh[i] = 0;
    rmCorrectorBitsLast[i] = 0;

    rmSignAcross[i] = 0;
    rmExponentAcross[i] = 0;
    rmMantissaAcrossLow[i] = 0;
    rmMantissaAcrossHigh[i] = 0;
    rmCorrectorBitsAcross[i] = 0;

    if (within)
    {
      rmSignWithin[i] = 0;
      rmExponentWithin[i] = 0;
      rmMantissaWithinLow[i] = 0;
      rmMantissaWithinHigh[i] = 0;
      rmCorrectorBitsWithin[i] = 0;
    }

    rmZeroOrExtremeValue[i] = 0;
    rmPositiveOrNegativeValue[i] = 0;
  }
}

void FloatCompressorOld::dealloc_range_tables(bool within)
{
  int i;

  for (i = 0; i < 256; i++)
  {
    if (rmSignNone[i]) delete rmSignNone[i];
    if (rmExponentNone[i]) delete rmExponentNone[i];
    if (rmMantissaNoneLow[i]) delete rmMantissaNoneLow[i];
    if (rmMantissaNoneHigh[i]) delete rmMantissaNoneHigh[i];

    if (rmSignLast[i]) delete rmSignLast[i];
    if (rmExponentLast[i]) delete rmExponentLast[i];
    if (rmMantissaLastLow[i]) delete rmMantissaLastLow[i];
    if (rmMantissaLastHigh[i]) delete rmMantissaLastHigh[i];

    if (rmSignAcross[i]) delete rmSignAcross[i];
    if (rmExponentAcross[i]) delete rmExponentAcross[i];
    if (rmMantissaAcrossLow[i]) delete rmMantissaAcrossLow[i];
    if (rmMantissaAcrossHigh[i]) delete rmMantissaAcrossHigh[i];

    if (within)
    {
      if (rmSignWithin[i]) delete rmSignWithin[i];
      if (rmExponentWithin[i]) delete rmExponentWithin[i];
      if (rmMantissaWithinLow[i]) delete rmMantissaWithinLow[i];
      if (rmMantissaWithinHigh[i]) delete rmMantissaWithinHigh[i];
    }

    if (rmZeroOrExtremeValue[i]) delete rmZeroOrExtremeValue[i];
    if (rmPositiveOrNegativeValue[i]) delete rmPositiveOrNegativeValue[i];
  }

  free(rmSignNone);
  free(rmExponentNone);
  free(rmMantissaNoneLow);
  free(rmMantissaNoneHigh);

  free(rmSignLast);
  free(rmExponentLast);
  free(rmMantissaLastLow);
  free(rmMantissaLastHigh);

  free(rmSignAcross);
  free(rmExponentAcross);
  free(rmMantissaAcrossLow);
  free(rmMantissaAcrossHigh);

  if (within)
  {
    free(rmSignWithin);
    free(rmExponentWithin);
    free(rmMantissaWithinLow);
    free(rmMantissaWithinHigh);
  }

  free(rmZeroOrExtremeValue);
  free(rmPositiveOrNegativeValue);
}

void FloatCompressorOld::FinishCompressor(bool within)
{
  if (ae_sign_none != ae_sign_last)
  {
    ae_sign_none->done();
    ae_sign_last->done();
    ae_sign_across->done();
    ae_exponent_none->done();
    ae_exponent_last->done();
    ae_exponent_across->done();
    ae_mantissa_none->done();
    ae_mantissa_last->done();
    ae_mantissa_across->done();
  }

  if (0)
  {
    for (int i = 0; i < 256; i++)
    {
      if (stats_on_k[i])
      {
        printf("%d:",i);
        for (int j = 0; j < 23; j++)
        {
          printf(" %d",stats_on_k[i][j]);
        }
        printf("\n");
      }
    }
  }

  if (0)
  {
    fprintf(stderr,"none %d last %d across %d within %d\n", num_predictions_none, num_predictions_last, num_predictions_across, num_predictions_within);

    fprintf(stderr,"TOTAL: sign bytes %d bpf %5.2f bpv %5.2f\n",ae_sign_none->getNumberChars()+ae_sign_last->getNumberChars()+ae_sign_across->getNumberChars(),
      (float)(ae_sign_none->getNumberBits()+ae_sign_last->getNumberBits()+ae_sign_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across),
      (float)(ae_sign_none->getNumberBits()+ae_sign_last->getNumberBits()+ae_sign_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across)*3.0f);

    fprintf(stderr,"TOTAL: expo bytes %d bpf %5.2f bpv %5.2f\n",ae_exponent_none->getNumberChars()+ae_exponent_last->getNumberChars()+ae_exponent_across->getNumberChars(),
      (float)(ae_exponent_none->getNumberBits()+ae_exponent_last->getNumberBits()+ae_exponent_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across),
      (float)(ae_exponent_none->getNumberBits()+ae_exponent_last->getNumberBits()+ae_exponent_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across)*3.0f);

    fprintf(stderr,"TOTAL: mant bytes %d bpf %5.2f bpv %5.2f\n",ae_mantissa_none->getNumberChars()+ae_mantissa_last->getNumberChars()+ae_mantissa_across->getNumberChars(),
      (float)(ae_mantissa_none->getNumberBits()+ae_mantissa_last->getNumberBits()+ae_mantissa_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across),
      (float)(ae_mantissa_none->getNumberBits()+ae_mantissa_last->getNumberBits()+ae_mantissa_across->getNumberBits())/(float)(num_predictions_none+num_predictions_last+num_predictions_across)*3.0f);

    if (ae_sign_none == ae_exponent_none)
    {
      fprintf(stderr,"none: total bytes %d\n",ae_sign_none->getNumberChars());
    }
    else
    {
      fprintf(stderr,"none: sign bytes %d bpf %5.2f bpv %5.2f\n",ae_sign_none->getNumberChars(),(float)ae_sign_none->getNumberBits()/(float)num_predictions_none,(float)ae_sign_none->getNumberBits()/(float)num_predictions_none*3.0f);
      fprintf(stderr,"none: expo bytes %d bpf %5.2f bpv %5.2f\n",ae_exponent_none->getNumberChars(),(float)ae_exponent_none->getNumberBits()/(float)num_predictions_none,(float)ae_exponent_none->getNumberBits()/(float)num_predictions_none*3.0f);
      fprintf(stderr,"none: mant bytes %d bpf %5.2f bpv %5.2f\n",ae_mantissa_none->getNumberChars(),(float)ae_mantissa_none->getNumberBits()/(float)num_predictions_none,(float)ae_mantissa_none->getNumberBits()/(float)num_predictions_none*3.0f);
    }

    if (ae_sign_last == ae_exponent_last)
    {
      fprintf(stderr,"Last: total bytes %d\n",ae_sign_last->getNumberChars());
    }
    else
    {
      fprintf(stderr,"Last: sign bytes %d bpf %5.2f bpv %5.2f\n",ae_sign_last->getNumberChars(),(float)ae_sign_last->getNumberBits()/(float)num_predictions_last,(float)ae_sign_last->getNumberBits()/(float)num_predictions_last*3.0f);
      fprintf(stderr,"Last: expo bytes %d bpf %5.2f bpv %5.2f\n",ae_exponent_last->getNumberChars(),(float)ae_exponent_last->getNumberBits()/(float)num_predictions_last,(float)ae_exponent_last->getNumberBits()/(float)num_predictions_last*3.0f);
      fprintf(stderr,"Last: mant bytes %d bpf %5.2f bpv %5.2f\n",ae_mantissa_last->getNumberChars(),(float)ae_mantissa_last->getNumberBits()/(float)num_predictions_last,(float)ae_mantissa_last->getNumberBits()/(float)num_predictions_last*3.0f);
    }

    if (ae_sign_across == ae_exponent_across)
    {
      fprintf(stderr,"Across: total bytes %d\n",ae_sign_across->getNumberChars());
    }
    else
    {
      fprintf(stderr,"Across: sign bytes %d bpf %5.2f bpv %5.2f\n",ae_sign_across->getNumberChars(),(float)ae_sign_across->getNumberBits()/(float)num_predictions_across,(float)ae_sign_across->getNumberBits()/(float)num_predictions_across*3.0f);
      fprintf(stderr,"Across: expo bytes %d bpf %5.2f bpv %5.2f\n",ae_exponent_across->getNumberChars(),(float)ae_exponent_across->getNumberBits()/(float)num_predictions_across,(float)ae_exponent_across->getNumberBits()/(float)num_predictions_across*3.0f);
      fprintf(stderr,"Across: mant bytes %d bpf %5.2f bpv %5.2f\n",ae_mantissa_across->getNumberChars(),(float)ae_mantissa_across->getNumberBits()/(float)num_predictions_across,(float)ae_mantissa_across->getNumberBits()/(float)num_predictions_across*3.0f);
    }
  }

  dealloc_range_tables(within);
}

int FloatCompressorOld::GetTotalBytes()
{
  return GetSignBytes()+GetExponentBytes()+GetMantissaBytes();
}

int FloatCompressorOld::GetSignBytes()
{
  return ae_sign_none->getNumberChars()+ae_sign_last->getNumberChars()+ae_sign_across->getNumberChars();
}

int FloatCompressorOld::GetExponentBytes()
{
  return ae_exponent_none->getNumberChars()+ae_exponent_last->getNumberChars()+ae_exponent_across->getNumberChars();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -