source: thirdparty/SZ/sz/src/sz_float_pwr.c @ 9ee2ce3

Revision 9ee2ce3, 61.9 KB checked in by Hal Finkel <hfinkel@…>, 6 years ago (diff)

importing new SZ files

  • Property mode set to 100644
Line 
1/**
2 *  @file sz_float_pwr.c
3 *  @author Sheng Di
4 *  @date Aug, 2016
5 *  @brief SZ_Init, Compression and Decompression functions
6 * This file contains the compression/decompression functions related to point-wise relative errors
7 *  (C) 2016 by Mathematics and Computer Science (MCS), Argonne National Laboratory.
8 *      See COPYRIGHT in top-level directory.
9 */
10
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <unistd.h>
16#include <math.h>
17#include "sz.h"
18#include "CompressElement.h"
19#include "DynamicByteArray.h"
20#include "DynamicIntArray.h"
21#include "TightDataPointStorageF.h"
22#include "sz_float.h"
23#include "sz_float_pwr.h"
24#include "zlib.h"
25#include "rw.h"
26#include "utility.h"
27
28void compute_segment_precisions_float_1D(float *oriData, size_t dataLength, float* pwrErrBound, unsigned char* pwrErrBoundBytes, double globalPrecision)
29{
30        size_t i = 0, j = 0, k = 0;
31        float realPrecision = oriData[0]!=0?fabs(confparams_cpr->pw_relBoundRatio*oriData[0]):confparams_cpr->pw_relBoundRatio; 
32        float approxPrecision;
33        unsigned char realPrecBytes[4];
34        float curPrecision;
35        float curValue;
36        float sum = 0;
37        for(i=0;i<dataLength;i++)
38        {
39                curValue = oriData[i];
40                if(i%confparams_cpr->segment_size==0&&i>0)
41                {
42                        //get two first bytes of the realPrecision
43                        if(confparams_cpr->pwr_type==SZ_PWR_AVG_TYPE)
44                        {
45                                realPrecision = sum/confparams_cpr->segment_size;
46                                sum = 0;                       
47                        }
48                        realPrecision *= confparams_cpr->pw_relBoundRatio;
49                       
50                        if(confparams_cpr->errorBoundMode==ABS_AND_PW_REL||confparams_cpr->errorBoundMode==REL_AND_PW_REL)
51                                realPrecision = realPrecision<globalPrecision?realPrecision:globalPrecision; 
52                        else if(confparams_cpr->errorBoundMode==ABS_OR_PW_REL||confparams_cpr->errorBoundMode==REL_OR_PW_REL)
53                                realPrecision = realPrecision<globalPrecision?globalPrecision:realPrecision;
54                               
55                        floatToBytes(realPrecBytes, realPrecision);
56                        realPrecBytes[2] = realPrecBytes[3] = 0;
57                        approxPrecision = bytesToFloat(realPrecBytes);
58                        //put the realPrecision in float* pwrErBound
59                        pwrErrBound[j++] = approxPrecision;
60                        //put the two bytes in pwrErrBoundBytes
61                        pwrErrBoundBytes[k++] = realPrecBytes[0];
62                        pwrErrBoundBytes[k++] = realPrecBytes[1];
63                       
64                        realPrecision = fabs(curValue);
65                }
66               
67                if(curValue!=0)
68                {
69                        curPrecision = fabs(curValue);
70                       
71                        switch(confparams_cpr->pwr_type)
72                        {
73                        case SZ_PWR_MIN_TYPE:
74                                if(realPrecision>curPrecision)
75                                        realPrecision = curPrecision;   
76                                break;
77                        case SZ_PWR_AVG_TYPE:
78                                sum += curPrecision;
79                                break;
80                        case SZ_PWR_MAX_TYPE:
81                                if(realPrecision<curPrecision)
82                                        realPrecision = curPrecision;                                   
83                                break;
84                        }
85                }
86        }
87        if(confparams_cpr->pwr_type==SZ_PWR_AVG_TYPE)
88        {
89                int size = dataLength%confparams_cpr->segment_size==0?confparams_cpr->segment_size:dataLength%confparams_cpr->segment_size;
90                realPrecision = sum/size;               
91        }       
92        if(confparams_cpr->errorBoundMode==ABS_AND_PW_REL||confparams_cpr->errorBoundMode==REL_AND_PW_REL)
93                realPrecision = realPrecision<globalPrecision?realPrecision:globalPrecision; 
94        else if(confparams_cpr->errorBoundMode==ABS_OR_PW_REL||confparams_cpr->errorBoundMode==REL_OR_PW_REL)
95                realPrecision = realPrecision<globalPrecision?globalPrecision:realPrecision;   
96        floatToBytes(realPrecBytes, realPrecision);
97        realPrecBytes[2] = realPrecBytes[3] = 0;
98        approxPrecision = bytesToFloat(realPrecBytes);
99        //put the realPrecision in float* pwrErBound
100        pwrErrBound[j++] = approxPrecision;
101        //put the two bytes in pwrErrBoundBytes
102        pwrErrBoundBytes[k++] = realPrecBytes[0];
103        pwrErrBoundBytes[k++] = realPrecBytes[1];
104}
105
106unsigned int optimize_intervals_float_1D_pwr(float *oriData, size_t dataLength, float* pwrErrBound)
107{       
108        size_t i = 0, j = 0;
109        float realPrecision = pwrErrBound[j++]; 
110        unsigned long radiusIndex;
111        float pred_value = 0, pred_err;
112        int *intervals = (int*)malloc(confparams_cpr->maxRangeRadius*sizeof(int));
113        memset(intervals, 0, confparams_cpr->maxRangeRadius*sizeof(int));
114        int totalSampleSize = dataLength/confparams_cpr->sampleDistance;
115        for(i=2;i<dataLength;i++)
116        {
117                if(i%confparams_cpr->segment_size==0)
118                        realPrecision = pwrErrBound[j++];
119                if(i%confparams_cpr->sampleDistance==0)
120                {
121                        //pred_value = 2*oriData[i-1] - oriData[i-2];
122                        pred_value = oriData[i-1];
123                        pred_err = fabs(pred_value - oriData[i]);
124                        radiusIndex = (unsigned long)((pred_err/realPrecision+1)/2);
125                        if(radiusIndex>=confparams_cpr->maxRangeRadius)
126                                radiusIndex = confparams_cpr->maxRangeRadius - 1;                       
127                        intervals[radiusIndex]++;
128                }
129        }
130        //compute the appropriate number
131        size_t targetCount = totalSampleSize*confparams_cpr->predThreshold;
132        size_t sum = 0;
133        for(i=0;i<confparams_cpr->maxRangeRadius;i++)
134        {
135                sum += intervals[i];
136                if(sum>targetCount)
137                        break;
138        }
139        if(i>=confparams_cpr->maxRangeRadius)
140                i = confparams_cpr->maxRangeRadius-1;
141
142        unsigned int accIntervals = 2*(i+1);
143        unsigned int powerOf2 = roundUpToPowerOf2(accIntervals);
144       
145        if(powerOf2<32)
146                powerOf2 = 32;
147       
148        free(intervals);
149        //printf("accIntervals=%d, powerOf2=%d\n", accIntervals, powerOf2);
150        return powerOf2;
151}
152
153void compute_segment_precisions_float_2D(float *oriData, float* pwrErrBound, 
154size_t r1, size_t r2, size_t R2, size_t edgeSize, unsigned char* pwrErrBoundBytes, float Min, float Max, double globalPrecision)
155{
156        size_t i = 0, j = 0, k = 0, p = 0, index = 0, J = 0; //I=-1,J=-1 if they are needed
157        float realPrecision; 
158        float approxPrecision;
159        unsigned char realPrecBytes[4];
160        float curValue, curAbsValue;
161        float* statAbsValues = (float*)malloc(R2*sizeof(float));
162       
163        float max = fabs(Min)<fabs(Max)?fabs(Max):fabs(Min); //get the max abs value.
164        float min = fabs(Min)<fabs(Max)?fabs(Min):fabs(Max);
165        for(i=0;i<R2;i++)
166        {
167                if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
168                        statAbsValues[i] = max;
169                else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
170                        statAbsValues[i] = min;
171                else
172                        statAbsValues[i] = 0; //for SZ_PWR_AVG_TYPE
173        }
174        for(i=0;i<r1;i++)
175        {
176                for(j=0;j<r2;j++)
177                {
178                        index = i*r2+j;
179                        curValue = oriData[index];                             
180                        if(((i%edgeSize==edgeSize-1 || i==r1-1) &&j%edgeSize==0&&j>0) || (i%edgeSize==0&&j==0&&i>0))
181                        {
182                                if(confparams_cpr->pwr_type==SZ_PWR_AVG_TYPE)
183                                {
184                                        int a = edgeSize, b = edgeSize;
185                                        if(j==0)
186                                        {
187                                                if(r2%edgeSize==0) 
188                                                        b = edgeSize;
189                                                else
190                                                        b = r2%edgeSize;
191                                        }
192                                        if(i==r1-1)
193                                        {
194                                                if(r1%edgeSize==0)
195                                                        a = edgeSize;
196                                                else
197                                                        a = r1%edgeSize;
198                                        }
199                                        realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J]/(a*b);
200                                }
201                                else
202                                        realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J];
203
204                                if(confparams_cpr->errorBoundMode==ABS_AND_PW_REL||confparams_cpr->errorBoundMode==REL_AND_PW_REL)
205                                        realPrecision = realPrecision<globalPrecision?realPrecision:globalPrecision; 
206                                else if(confparams_cpr->errorBoundMode==ABS_OR_PW_REL||confparams_cpr->errorBoundMode==REL_OR_PW_REL)
207                                        realPrecision = realPrecision<globalPrecision?globalPrecision:realPrecision;
208                                       
209                                floatToBytes(realPrecBytes, realPrecision);
210                                realPrecBytes[2] = realPrecBytes[3] = 0;
211                                approxPrecision = bytesToFloat(realPrecBytes);
212                                //put the realPrecision in float* pwrErBound           
213                                pwrErrBound[p++] = approxPrecision;
214                                //put the two bytes in pwrErrBoundBytes
215                                pwrErrBoundBytes[k++] = realPrecBytes[0];
216                                pwrErrBoundBytes[k++] = realPrecBytes[1];       
217                               
218                                if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
219                                        statAbsValues[J] = max;
220                                else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
221                                        statAbsValues[J] = min;
222                                else
223                                        statAbsValues[J] = 0; //for SZ_PWR_AVG_TYPE     
224                        }       
225                        if(j==0)
226                                J = 0;
227                        else if(j%edgeSize==0)
228                                J++;                   
229                        if(curValue!=0)
230                        {
231                                curAbsValue = fabs(curValue);
232                               
233                                switch(confparams_cpr->pwr_type)
234                                {
235                                case SZ_PWR_MIN_TYPE:
236                                        if(statAbsValues[J]>curAbsValue)
237                                                statAbsValues[J] = curAbsValue; 
238                                        break;
239                                case SZ_PWR_AVG_TYPE:
240                                        statAbsValues[J] += curAbsValue;
241                                        break;
242                                case SZ_PWR_MAX_TYPE:
243                                        if(statAbsValues[J]<curAbsValue)
244                                                statAbsValues[J] = curAbsValue;                                 
245                                        break;
246                                }
247                        }
248                }
249        }
250               
251        if(confparams_cpr->pwr_type==SZ_PWR_AVG_TYPE)
252        {
253                int a = edgeSize, b = edgeSize;
254                if(r2%edgeSize==0) 
255                        b = edgeSize;
256                else
257                        b = r2%edgeSize;
258                if(r1%edgeSize==0)
259                        a = edgeSize;
260                else
261                        a = r1%edgeSize;
262                realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J]/(a*b);
263        }
264        else
265                realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J];             
266
267        if(confparams_cpr->errorBoundMode==ABS_AND_PW_REL||confparams_cpr->errorBoundMode==REL_AND_PW_REL)
268                realPrecision = realPrecision<globalPrecision?realPrecision:globalPrecision; 
269        else if(confparams_cpr->errorBoundMode==ABS_OR_PW_REL||confparams_cpr->errorBoundMode==REL_OR_PW_REL)
270                realPrecision = realPrecision<globalPrecision?globalPrecision:realPrecision;
271               
272        floatToBytes(realPrecBytes, realPrecision);
273        realPrecBytes[2] = realPrecBytes[3] = 0;
274        approxPrecision = bytesToFloat(realPrecBytes);
275        //put the realPrecision in float* pwrErBound
276        pwrErrBound[p++] = approxPrecision;
277        //put the two bytes in pwrErrBoundBytes
278        pwrErrBoundBytes[k++] = realPrecBytes[0];
279        pwrErrBoundBytes[k++] = realPrecBytes[1];       
280       
281        free(statAbsValues);
282}
283
284unsigned int optimize_intervals_float_2D_pwr(float *oriData, size_t r1, size_t r2, size_t R2, size_t edgeSize, float* pwrErrBound)
285{       
286        size_t i = 0,j = 0, index, I=0, J=0;
287        float realPrecision = pwrErrBound[0];   
288        unsigned long radiusIndex;
289        float pred_value = 0, pred_err;
290        int *intervals = (int*)malloc(confparams_cpr->maxRangeRadius*sizeof(int));
291        memset(intervals, 0, confparams_cpr->maxRangeRadius*sizeof(int));
292        size_t totalSampleSize = (r1-1)*(r2-1)/confparams_cpr->sampleDistance;
293        size_t ir2;
294        for(i=1;i<r1;i++)
295        {
296                ir2 = i*r2;
297                if(i%edgeSize==0)
298                {       
299                        I++;
300                        J = 0;
301                }
302                for(j=1;j<r2;j++)
303                {
304                        index = ir2+j;
305                        if(j%edgeSize==0)
306                                J++;
307                               
308                        if((i+j)%confparams_cpr->sampleDistance==0)
309                        {
310                                realPrecision = pwrErrBound[I*R2+J];
311                                pred_value = oriData[index-1] + oriData[index-r2] - oriData[index-r2-1];
312                                pred_err = fabs(pred_value - oriData[index]);
313                                radiusIndex = (unsigned long)((pred_err/realPrecision+1)/2);
314                                if(radiusIndex>=confparams_cpr->maxRangeRadius)
315                                        radiusIndex = confparams_cpr->maxRangeRadius - 1;
316                                intervals[radiusIndex]++;
317                        }                       
318                }
319        }
320        //compute the appropriate number
321        size_t targetCount = totalSampleSize*confparams_cpr->predThreshold;
322        size_t sum = 0;
323        for(i=0;i<confparams_cpr->maxRangeRadius;i++)
324        {
325                sum += intervals[i];
326                if(sum>targetCount)
327                        break;
328        }
329        if(i>=confparams_cpr->maxRangeRadius)
330                i = confparams_cpr->maxRangeRadius-1;
331        unsigned int accIntervals = 2*(i+1);
332        unsigned int powerOf2 = roundUpToPowerOf2(accIntervals);
333
334        if(powerOf2<32)
335                powerOf2 = 32;
336
337        free(intervals);
338        //printf("confparams_cpr->maxRangeRadius = %d, accIntervals=%d, powerOf2=%d\n", confparams_cpr->maxRangeRadius, accIntervals, powerOf2);
339        return powerOf2;
340}
341
342void compute_segment_precisions_float_3D(float *oriData, float* pwrErrBound, 
343size_t r1, size_t r2, size_t r3, size_t R2, size_t R3, size_t edgeSize, unsigned char* pwrErrBoundBytes, float Min, float Max, double globalPrecision)
344{
345        size_t i = 0, j = 0, k = 0, p = 0, q = 0, index = 0, J = 0, K = 0; //I=-1,J=-1 if they are needed
346        size_t r23 = r2*r3, ir, jr;
347        float realPrecision; 
348        float approxPrecision;
349        unsigned char realPrecBytes[4];
350        float curValue, curAbsValue;
351       
352        float** statAbsValues = create2DArray_float(R2, R3);
353        float max = fabs(Min)<fabs(Max)?fabs(Max):fabs(Min); //get the max abs value.   
354        float min = fabs(Min)<fabs(Max)?fabs(Min):fabs(Max);
355       
356        for(i=0;i<R2;i++)
357                for(j=0;j<R3;j++)
358                {
359                        if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
360                                statAbsValues[i][j] = max;
361                        else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
362                                statAbsValues[i][j] = min;
363                        else
364                                statAbsValues[i][j] = 0;
365                }
366        for(i=0;i<r1;i++)
367        {
368                ir = i*r23;             
369                if(i%edgeSize==0&&i>0)
370                {
371                        realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J][K];
372                        floatToBytes(realPrecBytes, realPrecision);
373                        memset(&realPrecBytes[2], 0, 2);
374                        approxPrecision = bytesToFloat(realPrecBytes);
375                        //put the realPrecision in float* pwrErBound
376                        pwrErrBound[p++] = approxPrecision;
377                        //put the two bytes in pwrErrBoundBytes
378                        //printf("q=%d, i=%d, j=%d, k=%d\n",q,i,j,k);
379                        pwrErrBoundBytes[q++] = realPrecBytes[0];
380                        pwrErrBoundBytes[q++] = realPrecBytes[1];
381                        if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
382                                statAbsValues[J][K] = max;
383                        else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
384                                statAbsValues[J][K] = min;
385                       
386                }               
387                for(j=0;j<r2;j++)
388                {
389                        jr = j*r3;
390                        if((i%edgeSize==edgeSize-1 || i == r1-1)&&j%edgeSize==0&&j>0)
391                        {
392                                realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J][K];
393                                floatToBytes(realPrecBytes, realPrecision);
394                                memset(&realPrecBytes[2], 0, 2);
395                                approxPrecision = bytesToFloat(realPrecBytes);
396                                //put the realPrecision in float* pwrErBound
397                                pwrErrBound[p++] = approxPrecision;
398                                //put the two bytes in pwrErrBoundBytes
399                                //printf("q=%d, i=%d, j=%d, k=%d\n",q,i,j,k);
400                                pwrErrBoundBytes[q++] = realPrecBytes[0];
401                                pwrErrBoundBytes[q++] = realPrecBytes[1];
402                                if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
403                                        statAbsValues[J][K] = max;
404                                else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
405                                        statAbsValues[J][K] = min;                     
406                        }
407                       
408                        if(j==0)
409                                J = 0;
410                        else if(j%edgeSize==0)
411                                J++;                                   
412                       
413                        for(k=0;k<r3;k++)
414                        {
415                                index = ir+jr+k;                               
416                                curValue = oriData[index];                             
417                                if((i%edgeSize==edgeSize-1 || i == r1-1)&&(j%edgeSize==edgeSize-1||j==r2-1)&&k%edgeSize==0&&k>0)
418                                {
419                                        realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J][K];
420                                        floatToBytes(realPrecBytes, realPrecision);
421                                        memset(&realPrecBytes[2], 0, 2);
422                                        approxPrecision = bytesToFloat(realPrecBytes);
423                                        //put the realPrecision in float* pwrErBound
424                                        pwrErrBound[p++] = approxPrecision;
425                                        //put the two bytes in pwrErrBoundBytes
426                                        //printf("q=%d, i=%d, j=%d, k=%d\n",q,i,j,k);
427                                        pwrErrBoundBytes[q++] = realPrecBytes[0];
428                                        pwrErrBoundBytes[q++] = realPrecBytes[1];
429                                       
430                                        if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
431                                                statAbsValues[J][K] = max;
432                                        else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
433                                                statAbsValues[J][K] = min;     
434                                }       
435
436                                if(k==0)
437                                        K = 0;
438                                else if(k%edgeSize==0)
439                                        K++;
440                                       
441                                if(curValue!=0)
442                                {
443                                        curAbsValue = fabs(curValue);
444                                        if(confparams_cpr->pwr_type == SZ_PWR_MIN_TYPE)
445                                        {
446                                                if(statAbsValues[J][K]>curAbsValue)
447                                                {
448                                                        statAbsValues[J][K] = curAbsValue;
449                                                }
450                                        }
451                                        else if(confparams_cpr->pwr_type == SZ_PWR_MAX_TYPE)
452                                        {
453                                                if(statAbsValues[J][K]<curAbsValue)
454                                                {
455                                                        statAbsValues[J][K] = curAbsValue;
456                                                }
457                                        }
458                                }
459                        }                       
460                }
461        }       
462       
463        realPrecision = confparams_cpr->pw_relBoundRatio*statAbsValues[J][K];
464        floatToBytes(realPrecBytes, realPrecision);
465        realPrecBytes[2] = realPrecBytes[3] = 0;
466        approxPrecision = bytesToFloat(realPrecBytes);
467        //put the realPrecision in float* pwrErBound
468        pwrErrBound[p++] = approxPrecision;
469        //put the two bytes in pwrErrBoundBytes
470        pwrErrBoundBytes[q++] = realPrecBytes[0];
471        pwrErrBoundBytes[q++] = realPrecBytes[1];
472       
473        free2DArray_float(statAbsValues, R2);
474}
475
476unsigned int optimize_intervals_float_3D_pwr(float *oriData, size_t r1, size_t r2, size_t r3, size_t R2, size_t R3, size_t edgeSize, float* pwrErrBound)
477{       
478        size_t i,j,k, ir,jr,index, I = 0,J=0,K=0;
479        float realPrecision = pwrErrBound[0];           
480        unsigned long radiusIndex;
481        size_t r23=r2*r3;
482        size_t R23 = R2*R3;
483        float pred_value = 0, pred_err;
484        int *intervals = (int*)malloc(confparams_cpr->maxRangeRadius*sizeof(int));
485        memset(intervals, 0, confparams_cpr->maxRangeRadius*sizeof(int));
486        size_t totalSampleSize = (r1-1)*(r2-1)*(r3-1)/confparams_cpr->sampleDistance;
487        for(i=1;i<r1;i++)
488        {
489                ir = i*r23;
490                if(i%edgeSize==0)
491                {       
492                        I++;
493                        J = 0;
494                }
495                for(j=1;j<r2;j++)
496                {
497                        jr = j*r3;
498                        if(j%edgeSize==0)
499                        {       
500                                J++;
501                                K = 0;
502                        }                       
503                        for(k=1;k<r3;k++)
504                        {
505                                index = ir+jr+k;
506                                if(k%edgeSize==0)
507                                        K++;           
508                                if((i+j+k)%confparams_cpr->sampleDistance==0)
509                                {
510                                        realPrecision = pwrErrBound[I*R23+J*R2+K];                                     
511                                        pred_value = oriData[index-1] + oriData[index-r3] + oriData[index-r23] 
512                                        - oriData[index-1-r23] - oriData[index-r3-1] - oriData[index-r3-r23] + oriData[index-r3-r23-1];
513                                        pred_err = fabs(pred_value - oriData[index]);
514                                        radiusIndex = (unsigned long)((pred_err/realPrecision+1)/2);
515                                        if(radiusIndex>=confparams_cpr->maxRangeRadius)
516                                                radiusIndex = confparams_cpr->maxRangeRadius - 1;
517                                        intervals[radiusIndex]++;
518                                }
519                        }
520                }
521        }
522        //compute the appropriate number
523        size_t targetCount = totalSampleSize*confparams_cpr->predThreshold;
524        size_t sum = 0;
525        for(i=0;i<confparams_cpr->maxRangeRadius;i++)
526        {
527                sum += intervals[i];
528                if(sum>targetCount)
529                        break;
530        }
531        if(i>=confparams_cpr->maxRangeRadius)
532                i = confparams_cpr->maxRangeRadius-1;
533        unsigned int accIntervals = 2*(i+1);
534        unsigned int powerOf2 = roundUpToPowerOf2(accIntervals);
535
536        if(powerOf2<32)
537                powerOf2 = 32;
538       
539        free(intervals);
540        //printf("accIntervals=%d, powerOf2=%d\n", accIntervals, powerOf2);
541        return powerOf2;
542}
543
544void SZ_compress_args_float_NoCkRngeNoGzip_1D_pwr(unsigned char** newByteData, float *oriData, double globalPrecision, 
545size_t dataLength, size_t *outSize, float min, float max)
546{
547        size_t pwrLength = dataLength%confparams_cpr->segment_size==0?dataLength/confparams_cpr->segment_size:dataLength/confparams_cpr->segment_size+1;
548        float* pwrErrBound = (float*)malloc(sizeof(float)*pwrLength);
549        size_t pwrErrBoundBytes_size = sizeof(unsigned char)*pwrLength*2;
550        unsigned char* pwrErrBoundBytes = (unsigned char*)malloc(pwrErrBoundBytes_size);
551       
552        compute_segment_precisions_float_1D(oriData, dataLength, pwrErrBound, pwrErrBoundBytes, globalPrecision);
553       
554        unsigned int quantization_intervals;
555        if(exe_params->optQuantMode==1)
556        {
557                quantization_intervals = optimize_intervals_float_1D_pwr(oriData, dataLength, pwrErrBound);     
558                updateQuantizationInfo(quantization_intervals);
559        }
560        else
561                quantization_intervals = exe_params->intvCapacity;
562        size_t i = 0, j = 0;
563        int reqLength;
564        float realPrecision = pwrErrBound[j++]; 
565        float medianValue = 0;
566        float radius = fabs(max)<fabs(min)?fabs(min):fabs(max);
567        short radExpo = getExponent_float(radius);
568       
569        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
570
571        int* type = (int*) malloc(dataLength*sizeof(int));
572        //type[dataLength]=0;
573               
574        float* spaceFillingValue = oriData; //
575       
576        DynamicByteArray *resiBitLengthArray;
577        new_DBA(&resiBitLengthArray, DynArrayInitLen);
578       
579        DynamicIntArray *exactLeadNumArray;
580        new_DIA(&exactLeadNumArray, DynArrayInitLen);
581       
582        DynamicByteArray *exactMidByteArray;
583        new_DBA(&exactMidByteArray, DynArrayInitLen);
584       
585        DynamicIntArray *resiBitArray;
586        new_DIA(&resiBitArray, DynArrayInitLen);
587       
588        type[0] = 0;
589       
590        unsigned char preDataBytes[4] = {0};
591        intToBytes_bigEndian(preDataBytes, 0);
592       
593        int reqBytesLength = reqLength/8;
594        int resiBitsLength = reqLength%8;
595        float last3CmprsData[3] = {0};
596
597        FloatValueCompressElement *vce = (FloatValueCompressElement*)malloc(sizeof(FloatValueCompressElement));
598        LossyCompressionElement *lce = (LossyCompressionElement*)malloc(sizeof(LossyCompressionElement));
599                                               
600        //add the first data   
601        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
602        compressSingleFloatValue(vce, spaceFillingValue[0], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
603        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
604        memcpy(preDataBytes,vce->curBytes,4);
605        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
606        listAdd_float(last3CmprsData, vce->data);
607        //printf("%.30G\n",last3CmprsData[0]); 
608               
609        //add the second data
610        type[1] = 0;
611        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);                 
612        compressSingleFloatValue(vce, spaceFillingValue[1], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
613        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
614        memcpy(preDataBytes,vce->curBytes,4);
615        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
616        listAdd_float(last3CmprsData, vce->data);
617        //printf("%.30G\n",last3CmprsData[0]); 
618       
619        int state;
620        double checkRadius;
621        float curData;
622        float pred;
623        double predAbsErr;
624        checkRadius = (exe_params->intvCapacity-1)*realPrecision;
625        double interval = 2*realPrecision;
626        int updateReqLength = 0; //a marker: 1 means already updated
627       
628        for(i=2;i<dataLength;i++)
629        {
630                curData = spaceFillingValue[i];
631                if(i%confparams_cpr->segment_size==0)
632                {
633                        realPrecision = pwrErrBound[j++];
634                        checkRadius = (exe_params->intvCapacity-1)*realPrecision;
635                        interval = 2*realPrecision;
636                        updateReqLength = 0;
637                }
638                //pred = 2*last3CmprsData[0] - last3CmprsData[1];
639                pred = last3CmprsData[0];
640                predAbsErr = fabs(curData - pred);     
641                if(predAbsErr<checkRadius)
642                {
643                        state = (predAbsErr/realPrecision+1)/2;
644                        if(curData>=pred)
645                        {
646                                type[i] = exe_params->intvRadius+state;
647                                pred = pred + state*interval;
648                        }
649                        else //curData<pred
650                        {
651                                type[i] = exe_params->intvRadius-state;
652                                pred = pred - state*interval;
653                        }
654                        listAdd_float(last3CmprsData, pred);                   
655                        continue;
656                }
657               
658                //unpredictable data processing         
659                if(updateReqLength==0)
660                {
661                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
662                        reqBytesLength = reqLength/8;
663                        resiBitsLength = reqLength%8;
664                        updateReqLength = 1;           
665                }
666               
667                type[i] = 0;
668                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
669               
670                compressSingleFloatValue(vce, curData, realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
671                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
672                memcpy(preDataBytes,vce->curBytes,4);
673                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
674
675                listAdd_float(last3CmprsData, vce->data);       
676        }//end of for
677               
678//      char* expSegmentsInBytes;
679//      int expSegmentsInBytes_size = convertESCToBytes(esc, &expSegmentsInBytes);
680        int exactDataNum = exactLeadNumArray->size;
681       
682        TightDataPointStorageF* tdps;
683                       
684        new_TightDataPointStorageF2(&tdps, dataLength, exactDataNum, 
685                        type, exactMidByteArray->array, exactMidByteArray->size, 
686                        exactLeadNumArray->array, 
687                        resiBitArray->array, resiBitArray->size, 
688                        resiBitLengthArray->array, resiBitLengthArray->size, 
689                        realPrecision, medianValue, (char)reqLength, quantization_intervals, pwrErrBoundBytes, pwrErrBoundBytes_size, radExpo);
690
691//sdi:Debug
692/*      int sum =0;
693        for(i=0;i<dataLength;i++)
694                if(type[i]==0) sum++;
695        printf("opt_quantizations=%d, exactDataNum=%d, sum=%d\n",quantization_intervals, exactDataNum, sum);
696*/
697//      writeUShortData(type, dataLength, "compressStateBytes.sb");
698//      unsigned short type_[dataLength];
699//      SZ_Reset();
700//      decode_withTree(tdps->typeArray, tdps->typeArray_size, type_); 
701//      printf("tdps->typeArray_size=%d\n", tdps->typeArray_size);
702       
703        //free memory
704        free_DBA(resiBitLengthArray);
705        free_DIA(exactLeadNumArray);
706        free_DIA(resiBitArray);
707        free(type);
708       
709        convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
710       
711        int floatSize=sizeof(float);
712        if(*outSize>dataLength*floatSize)
713        {
714                size_t k = 0, i;
715                tdps->isLossless = 1;
716                size_t totalByteLength = 3 + exe_params->SZ_SIZE_TYPE + 1 + floatSize*dataLength;
717                *newByteData = (unsigned char*)malloc(totalByteLength);
718               
719                unsigned char dsLengthBytes[exe_params->SZ_SIZE_TYPE];
720                intToBytes_bigEndian(dsLengthBytes, dataLength);//4
721                for (i = 0; i < 3; i++)//3
722                        (*newByteData)[k++] = versionNumber[i];
723               
724                if(exe_params->SZ_SIZE_TYPE==4)
725                {
726                        (*newByteData)[k++] = 16;       //=00010000     
727                }
728                else 
729                {
730                        (*newByteData)[k++] = 80;
731                }
732                for (i = 0; i < exe_params->SZ_SIZE_TYPE; i++)//4 or 8
733                        (*newByteData)[k++] = dsLengthBytes[i];
734
735               
736                if(sysEndianType==BIG_ENDIAN_SYSTEM)
737                        memcpy((*newByteData)+4+exe_params->SZ_SIZE_TYPE, oriData, dataLength*floatSize);
738                else
739                {
740                        unsigned char* p = (*newByteData)+4+exe_params->SZ_SIZE_TYPE;
741                        for(i=0;i<dataLength;i++,p+=floatSize)
742                                floatToBytes(p, oriData[i]);
743                }
744                *outSize = totalByteLength;
745        }
746
747        free(pwrErrBound);
748       
749        free(vce);
750        free(lce);
751        free_TightDataPointStorageF(tdps);
752        free(exactMidByteArray);
753}
754
755void SZ_compress_args_float_NoCkRngeNoGzip_2D_pwr(unsigned char** newByteData, float *oriData, double globalPrecision, size_t r1, size_t r2, 
756size_t *outSize, float min, float max)
757{
758        size_t dataLength=r1*r2;
759        int blockEdgeSize = computeBlockEdgeSize_2D(confparams_cpr->segment_size);
760        size_t R1 = 1+(r1-1)/blockEdgeSize;
761        size_t R2 = 1+(r2-1)/blockEdgeSize;
762        float* pwrErrBound = (float*)malloc(sizeof(float)*R1*R2);
763        size_t pwrErrBoundBytes_size = sizeof(unsigned char)*R1*R2*2;
764        unsigned char* pwrErrBoundBytes = (unsigned char*)malloc(pwrErrBoundBytes_size);
765       
766        compute_segment_precisions_float_2D(oriData, pwrErrBound, r1, r2, R2, blockEdgeSize, pwrErrBoundBytes, min, max, globalPrecision);
767               
768        unsigned int quantization_intervals;
769        if(exe_params->optQuantMode==1)
770        {       
771                quantization_intervals = optimize_intervals_float_2D_pwr(oriData, r1, r2, R2, blockEdgeSize, pwrErrBound);
772                updateQuantizationInfo(quantization_intervals);
773        }       
774        else
775                quantization_intervals = exe_params->intvCapacity;
776        //printf("quantization_intervals=%d\n",quantization_intervals);
777       
778        size_t i=0,j=0,I=0,J=0; 
779        int reqLength;
780        float realPrecision = pwrErrBound[I*R2+J];     
781        float pred1D, pred2D;
782        float diff = 0.0;
783        double itvNum = 0;
784        float *P0, *P1;
785       
786        P0 = (float*)malloc(r2*sizeof(float));
787        memset(P0, 0, r2*sizeof(float));
788        P1 = (float*)malloc(r2*sizeof(float));
789        memset(P1, 0, r2*sizeof(float));
790               
791        float medianValue = 0;
792        float radius = fabs(max)<fabs(min)?fabs(min):fabs(max); 
793        short radExpo = getExponent_float(radius);
794        int updateReqLength = 1;
795       
796        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
797
798        int* type = (int*) malloc(dataLength*sizeof(int));
799        //type[dataLength]=0;
800               
801        float* spaceFillingValue = oriData; //
802       
803        DynamicByteArray *resiBitLengthArray;
804        new_DBA(&resiBitLengthArray, DynArrayInitLen);
805       
806        DynamicIntArray *exactLeadNumArray;
807        new_DIA(&exactLeadNumArray, DynArrayInitLen);
808       
809        DynamicByteArray *exactMidByteArray;
810        new_DBA(&exactMidByteArray, DynArrayInitLen);
811       
812        DynamicIntArray *resiBitArray;
813        new_DIA(&resiBitArray, DynArrayInitLen);
814       
815        type[0] = 0;
816       
817        unsigned char preDataBytes[4];
818        intToBytes_bigEndian(preDataBytes, 0);
819       
820        int reqBytesLength = reqLength/8;
821        int resiBitsLength = reqLength%8;
822
823        FloatValueCompressElement *vce = (FloatValueCompressElement*)malloc(sizeof(FloatValueCompressElement));
824        LossyCompressionElement *lce = (LossyCompressionElement*)malloc(sizeof(LossyCompressionElement));
825                       
826        /* Process Row-0 data 0*/
827        type[0] = 0;
828        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
829        compressSingleFloatValue(vce, spaceFillingValue[0], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
830        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
831        memcpy(preDataBytes,vce->curBytes,4);
832        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
833        P1[0] = vce->data;
834
835        /* Process Row-0 data 1*/
836        pred1D = P1[0];
837        diff = spaceFillingValue[1] - pred1D;
838
839        itvNum =  fabs(diff)/realPrecision + 1;
840
841        if (itvNum < exe_params->intvCapacity)
842        {
843                if (diff < 0) itvNum = -itvNum;
844                type[1] = (int) (itvNum/2) + exe_params->intvRadius;
845                P1[1] = pred1D + 2 * (type[1] - exe_params->intvRadius) * realPrecision;
846        }
847        else
848        {               
849                type[1] = 0;
850
851                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
852                compressSingleFloatValue(vce, spaceFillingValue[1], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
853                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
854                memcpy(preDataBytes,vce->curBytes,4);
855                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
856                P1[1] = vce->data;
857        }
858
859    /* Process Row-0 data 2 --> data r2-1 */
860        for (j = 2; j < r2; j++)
861        {
862                if(j%blockEdgeSize==0)
863                {
864                        J++;
865                        realPrecision = pwrErrBound[I*R2+J];
866                        updateReqLength = 0;
867                }
868
869                pred1D = 2*P1[j-1] - P1[j-2];
870                diff = spaceFillingValue[j] - pred1D;
871
872                itvNum = fabs(diff)/realPrecision + 1;
873
874                if (itvNum < exe_params->intvCapacity)
875                {
876                        if (diff < 0) itvNum = -itvNum;
877                        type[j] = (int) (itvNum/2) + exe_params->intvRadius;
878                        P1[j] = pred1D + 2 * (type[j] - exe_params->intvRadius) * realPrecision;
879                }
880                else
881                {
882                        if(updateReqLength==0)
883                        {
884                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
885                                reqBytesLength = reqLength/8;
886                                resiBitsLength = reqLength%8;
887                                updateReqLength = 1;
888                        }
889
890                        type[j] = 0;
891
892                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
893                        compressSingleFloatValue(vce, spaceFillingValue[j], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
894                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
895                        memcpy(preDataBytes,vce->curBytes,4);
896                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
897                        P1[j] = vce->data;
898                }
899        }
900
901        /* Process Row-1 --> Row-r1-1 */
902        size_t index;
903        for (i = 1; i < r1; i++)
904        {       
905                /* Process row-i data 0 */
906                index = i*r2;
907                J = 0;
908                if(i%blockEdgeSize==0)
909                        I++;
910                realPrecision = pwrErrBound[I*R2+J]; //J==0
911                updateReqLength = 0;
912               
913                pred1D = P1[0];
914                diff = spaceFillingValue[index] - pred1D;
915
916                itvNum = fabs(diff)/realPrecision + 1;
917
918                if (itvNum < exe_params->intvCapacity)
919                {
920                        if (diff < 0) itvNum = -itvNum;
921                        type[index] = (int) (itvNum/2) + exe_params->intvRadius;
922                        P0[0] = pred1D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
923                }
924                else
925                {
926                        if(updateReqLength==0)
927                        {
928                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
929                                reqBytesLength = reqLength/8;
930                                resiBitsLength = reqLength%8;
931                                updateReqLength = 1;
932                        }
933                       
934                        type[index] = 0;
935
936                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
937                        compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
938                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
939                        memcpy(preDataBytes,vce->curBytes,4);
940                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
941                        P0[0] = vce->data;
942                }
943                                                                       
944                /* Process row-i data 1 --> r2-1*/
945                for (j = 1; j < r2; j++)
946                {
947                        index = i*r2+j;
948                       
949                        if(j%blockEdgeSize==0)
950                        {
951                                J++;
952                                realPrecision = pwrErrBound[I*R2+J];
953                                updateReqLength = 0;
954                        }
955                        pred2D = P0[j-1] + P1[j] - P1[j-1];
956
957                        diff = spaceFillingValue[index] - pred2D;
958
959                        itvNum = fabs(diff)/realPrecision + 1;
960
961                        if (itvNum < exe_params->intvCapacity)
962                        {
963                                if (diff < 0) itvNum = -itvNum;
964                                type[index] = (int) (itvNum/2) + exe_params->intvRadius;
965                                P0[j] = pred2D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
966                        }
967                        else
968                        {
969                                if(updateReqLength==0)
970                                {
971                                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
972                                        reqBytesLength = reqLength/8;
973                                        resiBitsLength = reqLength%8;
974                                        updateReqLength = 1;
975                                }
976
977                                type[index] = 0;
978
979                                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
980                                compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
981                                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
982                                memcpy(preDataBytes,vce->curBytes,4);
983                                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
984                                P0[j] = vce->data;
985                        }
986                }
987
988                float *Pt;
989                Pt = P1;
990                P1 = P0;
991                P0 = Pt;
992        }
993       
994        if(r2!=1)
995                free(P0);
996        free(P1);                       
997        int exactDataNum = exactLeadNumArray->size;
998       
999        TightDataPointStorageF* tdps;
1000                       
1001        new_TightDataPointStorageF2(&tdps, dataLength, exactDataNum, 
1002                        type, exactMidByteArray->array, exactMidByteArray->size, 
1003                        exactLeadNumArray->array, 
1004                        resiBitArray->array, resiBitArray->size, 
1005                        resiBitLengthArray->array, resiBitLengthArray->size, 
1006                        realPrecision, medianValue, (char)reqLength, quantization_intervals, pwrErrBoundBytes, pwrErrBoundBytes_size, radExpo);
1007       
1008        //free memory
1009        free_DBA(resiBitLengthArray);
1010        free_DIA(exactLeadNumArray);
1011        free_DIA(resiBitArray);
1012        free(type);
1013       
1014        convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1015       
1016        free(pwrErrBound);
1017
1018        free(vce);
1019        free(lce);
1020        free_TightDataPointStorageF(tdps);     
1021        free(exactMidByteArray);
1022}
1023
1024void SZ_compress_args_float_NoCkRngeNoGzip_3D_pwr(unsigned char** newByteData, float *oriData, double globalPrecision, 
1025size_t r1, size_t r2, size_t r3, size_t *outSize, float min, float max)
1026{
1027        size_t dataLength=r1*r2*r3;
1028       
1029        int blockEdgeSize = computeBlockEdgeSize_3D(confparams_cpr->segment_size);
1030        size_t R1 = 1+(r1-1)/blockEdgeSize;
1031        size_t R2 = 1+(r2-1)/blockEdgeSize;
1032        size_t R3 = 1+(r3-1)/blockEdgeSize;
1033        float* pwrErrBound = (float*)malloc(sizeof(float)*R1*R2*R3);
1034        size_t pwrErrBoundBytes_size = sizeof(unsigned char)*R1*R2*R3*2;
1035        unsigned char* pwrErrBoundBytes = (unsigned char*)malloc(pwrErrBoundBytes_size);       
1036       
1037        compute_segment_precisions_float_3D(oriData, pwrErrBound, r1, r2, r3, R2, R3, blockEdgeSize, pwrErrBoundBytes, min, max, globalPrecision);     
1038
1039        unsigned int quantization_intervals;
1040        if(exe_params->optQuantMode==1)
1041        {
1042                quantization_intervals = optimize_intervals_float_3D_pwr(oriData, r1, r2, r3, R2, R3, blockEdgeSize, pwrErrBound);
1043                updateQuantizationInfo(quantization_intervals);
1044        }       
1045        else
1046                quantization_intervals = exe_params->intvCapacity;
1047        size_t i=0,j=0,k=0, I = 0, J = 0, K = 0;
1048        int reqLength;
1049        float realPrecision = pwrErrBound[0];           
1050        float pred1D, pred2D, pred3D;
1051        float diff = 0.0;
1052        double itvNum = 0;
1053        float *P0, *P1;
1054
1055        size_t r23 = r2*r3;
1056        size_t R23 = R2*R3;
1057        P0 = (float*)malloc(r23*sizeof(float));
1058        P1 = (float*)malloc(r23*sizeof(float));
1059        float radius = fabs(max)<fabs(min)?fabs(min):fabs(max);
1060        float medianValue = 0;
1061        short radExpo = getExponent_float(radius);
1062        int updateReqLength = 0;
1063       
1064        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1065
1066        int* type = (int*) malloc(dataLength*sizeof(int));
1067        //type[dataLength]=0;realPrecision
1068
1069        float* spaceFillingValue = oriData; //
1070       
1071        DynamicByteArray *resiBitLengthArray;
1072        new_DBA(&resiBitLengthArray, DynArrayInitLen);
1073
1074        DynamicIntArray *exactLeadNumArray;
1075        new_DIA(&exactLeadNumArray, DynArrayInitLen);
1076
1077        DynamicByteArray *exactMidByteArray;
1078        new_DBA(&exactMidByteArray, DynArrayInitLen);
1079
1080        DynamicIntArray *resiBitArray;
1081        new_DIA(&resiBitArray, DynArrayInitLen);
1082
1083        type[0] = 0;
1084
1085        unsigned char preDataBytes[4];
1086        intToBytes_bigEndian(preDataBytes, 0);
1087       
1088        int reqBytesLength = reqLength/8;
1089        int resiBitsLength = reqLength%8;
1090
1091        FloatValueCompressElement *vce = (FloatValueCompressElement*)malloc(sizeof(FloatValueCompressElement));
1092        LossyCompressionElement *lce = (LossyCompressionElement*)malloc(sizeof(LossyCompressionElement));
1093
1094
1095        ///////////////////////////     Process layer-0 ///////////////////////////
1096        /* Process Row-0 data 0*/
1097        type[0] = 0;
1098        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1099        compressSingleFloatValue(vce, spaceFillingValue[0], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1100        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1101        memcpy(preDataBytes,vce->curBytes,4);
1102        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1103        P1[0] = vce->data;
1104
1105        /* Process Row-0 data 1*/
1106        pred1D = P1[0];
1107        diff = spaceFillingValue[1] - pred1D;
1108
1109        itvNum = fabs(diff)/realPrecision + 1;
1110
1111        if (itvNum < exe_params->intvCapacity)
1112        {
1113                if (diff < 0) itvNum = -itvNum;
1114                type[1] = (int) (itvNum/2) + exe_params->intvRadius;
1115                P1[1] = pred1D + 2 * (type[1] - exe_params->intvRadius) * realPrecision;
1116        }
1117        else
1118        {
1119                if(updateReqLength==0)
1120                {
1121                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1122                        reqBytesLength = reqLength/8;
1123                        resiBitsLength = reqLength%8;
1124                        updateReqLength = 1;
1125                }               
1126               
1127                type[1] = 0;
1128
1129                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1130                compressSingleFloatValue(vce, spaceFillingValue[1], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1131                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1132                memcpy(preDataBytes,vce->curBytes,4);
1133                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1134                P1[1] = vce->data;
1135        }
1136
1137    /* Process Row-0 data 2 --> data r3-1 */
1138        for (j = 2; j < r3; j++)
1139        {
1140                if(j%blockEdgeSize==0)
1141                {
1142                        J++;
1143                        realPrecision = pwrErrBound[J];
1144                        updateReqLength = 0;
1145                }               
1146                pred1D = 2*P1[j-1] - P1[j-2];
1147                diff = spaceFillingValue[j] - pred1D;
1148
1149                itvNum = fabs(diff)/realPrecision + 1;
1150
1151                if (itvNum < exe_params->intvCapacity)
1152                {
1153                        if (diff < 0) itvNum = -itvNum;
1154                        type[j] = (int) (itvNum/2) + exe_params->intvRadius;
1155                        P1[j] = pred1D + 2 * (type[j] - exe_params->intvRadius) * realPrecision;
1156                }
1157                else
1158                {
1159                        if(updateReqLength==0)
1160                        {
1161                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1162                                reqBytesLength = reqLength/8;
1163                                resiBitsLength = reqLength%8;
1164                                updateReqLength = 1;
1165                        }                       
1166
1167                        type[j] = 0;
1168
1169                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1170                        compressSingleFloatValue(vce, spaceFillingValue[j], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1171                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1172                        memcpy(preDataBytes,vce->curBytes,4);
1173                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1174                        P1[j] = vce->data;
1175                }
1176        }
1177
1178        /* Process Row-1 --> Row-r2-1 */
1179        size_t index;
1180        K = 0;
1181        for (i = 1; i < r2; i++)
1182        {
1183                /* Process row-i data 0 */
1184                index = i*r3;   
1185
1186                J = 0;
1187                if(i%blockEdgeSize==0)
1188                        I++;
1189                realPrecision = pwrErrBound[I*R3+J]; //J==0
1190                updateReqLength = 0;
1191
1192                pred1D = P1[index-r3];
1193                diff = spaceFillingValue[index] - pred1D;
1194
1195                itvNum = fabs(diff)/realPrecision + 1;
1196
1197                if (itvNum < exe_params->intvCapacity)
1198                {
1199                        if (diff < 0) itvNum = -itvNum;
1200                        type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1201                        P1[index] = pred1D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1202                }
1203                else
1204                {
1205                        if(updateReqLength==0)
1206                        {
1207                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1208                                reqBytesLength = reqLength/8;
1209                                resiBitsLength = reqLength%8;
1210                                updateReqLength = 1;
1211                        }               
1212                                               
1213                        type[index] = 0;
1214
1215                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1216                        compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1217                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1218                        memcpy(preDataBytes,vce->curBytes,4);
1219                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1220                        P1[index] = vce->data;
1221                }
1222
1223                /* Process row-i data 1 --> data r3-1*/
1224                for (j = 1; j < r3; j++) //note that this j refers to fastest dimension (lowest order)
1225                {
1226                        index = i*r3+j;         
1227                        if(j%blockEdgeSize==0)
1228                        {
1229                                J++;
1230                                realPrecision = pwrErrBound[I*R3+J];
1231                                updateReqLength = 0;
1232                        }                       
1233               
1234                        pred2D = P1[index-1] + P1[index-r3] - P1[index-r3-1];
1235
1236                        diff = spaceFillingValue[index] - pred2D;
1237
1238                        itvNum = fabs(diff)/realPrecision + 1;
1239
1240                        if (itvNum < exe_params->intvCapacity)
1241                        {
1242                                if (diff < 0) itvNum = -itvNum;
1243                                type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1244                                P1[index] = pred2D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1245                        }
1246                        else
1247                        {
1248                                if(updateReqLength==0)
1249                                {
1250                                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1251                                        reqBytesLength = reqLength/8;
1252                                        resiBitsLength = reqLength%8;
1253                                        updateReqLength = 1;
1254                                }                                               
1255                               
1256                                type[index] = 0;
1257
1258                                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1259                                compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1260                                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1261                                memcpy(preDataBytes,vce->curBytes,4);
1262                                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1263                                P1[index] = vce->data;
1264                        }
1265                }
1266        }
1267
1268        ///////////////////////////     Process layer-1 --> layer-r1-1 ///////////////////////////
1269
1270        for (k = 1; k < r1; k++)
1271        {
1272                /* Process Row-0 data 0*/
1273                index = k*r23;                 
1274                I = 0;
1275                J = 0;
1276                if(k%blockEdgeSize==0)
1277                        K++;
1278                realPrecision = pwrErrBound[K*R23]; //J==0
1279                updateReqLength = 0;
1280               
1281                pred1D = P1[0];
1282                diff = spaceFillingValue[index] - pred1D;
1283
1284                itvNum = fabs(diff)/realPrecision + 1;
1285
1286                if (itvNum < exe_params->intvCapacity)
1287                {
1288                        if (diff < 0) itvNum = -itvNum;
1289                        type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1290                        P0[0] = pred1D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1291                }
1292                else
1293                {
1294                        if(updateReqLength==0)
1295                        {
1296                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1297                                reqBytesLength = reqLength/8;
1298                                resiBitsLength = reqLength%8;
1299                                updateReqLength = 1;
1300                        }                                       
1301                       
1302                        type[index] = 0;
1303
1304                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1305                        compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1306                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1307                        memcpy(preDataBytes,vce->curBytes,4);
1308                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1309                        P0[0] = vce->data;
1310                }
1311
1312            /* Process Row-0 data 1 --> data r3-1 */
1313                for (j = 1; j < r3; j++)
1314                {
1315                        index = k*r23+j;       
1316
1317                        if(j%blockEdgeSize==0)
1318                        {
1319                                J++;
1320                                realPrecision = pwrErrBound[K*R23+J];
1321                                updateReqLength = 0;                   
1322                        }                                       
1323                        pred2D = P0[j-1] + P1[j] - P1[j-1];
1324                        diff = spaceFillingValue[index] - pred2D;
1325
1326                        itvNum = fabs(diff)/realPrecision + 1;
1327
1328                        if (itvNum < exe_params->intvCapacity)
1329                        {
1330                                if (diff < 0) itvNum = -itvNum;
1331                                type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1332                                P0[j] = pred2D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1333/*                              if(type[index]==0)
1334                                        printf("err:type[%d]=0, index4\n", index);                                      */
1335                        }
1336                        else
1337                        {
1338                                if(updateReqLength==0)
1339                                {
1340                                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1341                                        reqBytesLength = reqLength/8;
1342                                        resiBitsLength = reqLength%8;
1343                                        updateReqLength = 1;
1344                                }                                               
1345                               
1346                                type[index] = 0;
1347
1348                                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1349                                compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1350                                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1351                                memcpy(preDataBytes,vce->curBytes,4);
1352                                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1353                                P0[j] = vce->data;
1354                        }
1355                }
1356
1357            /* Process Row-1 --> Row-r2-1 */
1358                size_t index2D;
1359                for (i = 1; i < r2; i++)
1360                {
1361                        /* Process Row-i data 0 */
1362                        index = k*r23 + i*r3;
1363                        J = 0;
1364                        if(i%blockEdgeSize==0)
1365                                I++;
1366                        realPrecision = pwrErrBound[K*R23+I*R3+J]; //J==0
1367                        updateReqLength = 0;                   
1368                       
1369                        index2D = i*r3;         
1370                        pred2D = P0[index2D-r3] + P1[index2D] - P1[index2D-r3];
1371                        diff = spaceFillingValue[index] - pred2D;
1372
1373                        itvNum = fabs(diff)/realPrecision + 1;
1374
1375                        if (itvNum < exe_params->intvCapacity)
1376                        {
1377                                if (diff < 0) itvNum = -itvNum;
1378                                type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1379                                P0[index2D] = pred2D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1380                        }
1381                        else
1382                        {
1383                                if(updateReqLength==0)
1384                                {
1385                                        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1386                                        reqBytesLength = reqLength/8;
1387                                        resiBitsLength = reqLength%8;
1388                                        updateReqLength = 1;
1389                                }                                               
1390                               
1391                                type[index] = 0;
1392
1393                                addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1394                                compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1395                                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1396                                memcpy(preDataBytes,vce->curBytes,4);
1397                                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1398                                P0[index2D] = vce->data;
1399                        }
1400
1401                        /* Process Row-i data 1 --> data r3-1 */
1402                        for (j = 1; j < r3; j++)
1403                        {
1404                                index = k*r23 + i*r3 + j;
1405                                if(j%blockEdgeSize==0)
1406                                {
1407                                        J++;
1408                                        realPrecision = pwrErrBound[K*R23+I*R3+J];
1409                                        updateReqLength = 0;                   
1410                                }                                                       
1411                                index2D = i*r3 + j;
1412                                pred3D = P0[index2D-1] + P0[index2D-r3]+ P1[index2D] - P0[index2D-r3-1] - P1[index2D-r3] - P1[index2D-1] + P1[index2D-r3-1];
1413                                diff = spaceFillingValue[index] - pred3D;
1414
1415                                itvNum = fabs(diff)/realPrecision + 1;
1416
1417                                if (itvNum < exe_params->intvCapacity)
1418                                {
1419                                        if (diff < 0) itvNum = -itvNum;
1420                                        type[index] = (int) (itvNum/2) + exe_params->intvRadius;
1421                                        P0[index2D] = pred3D + 2 * (type[index] - exe_params->intvRadius) * realPrecision;
1422                                }
1423                                else
1424                                {
1425                                        if(updateReqLength==0)
1426                                        {
1427                                                computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1428                                                reqBytesLength = reqLength/8;
1429                                                resiBitsLength = reqLength%8;
1430                                                updateReqLength = 1;
1431                                        }                                                       
1432                                       
1433                                        type[index] = 0;
1434
1435                                        addDBA_Data(resiBitLengthArray, (unsigned char)resiBitsLength);
1436                                        compressSingleFloatValue(vce, spaceFillingValue[index], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1437                                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1438                                        memcpy(preDataBytes,vce->curBytes,4);
1439                                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1440                                        P0[index2D] = vce->data;
1441                                }
1442                        }
1443                }
1444
1445                float *Pt;
1446                Pt = P1;
1447                P1 = P0;
1448                P0 = Pt;
1449        }
1450        if(r23!=1)
1451                free(P0);
1452        free(P1);
1453        int exactDataNum = exactLeadNumArray->size;
1454
1455        TightDataPointStorageF* tdps;
1456
1457        new_TightDataPointStorageF2(&tdps, dataLength, exactDataNum,
1458                        type, exactMidByteArray->array, exactMidByteArray->size,
1459                        exactLeadNumArray->array,
1460                        resiBitArray->array, resiBitArray->size,
1461                        resiBitLengthArray->array, resiBitLengthArray->size, 
1462                        realPrecision, medianValue, (char)reqLength, quantization_intervals, pwrErrBoundBytes, pwrErrBoundBytes_size, radExpo);
1463
1464//sdi:Debug
1465/*      int sum =0;
1466        for(i=0;i<dataLength;i++)
1467                if(type[i]==0) sum++;
1468        printf("opt_quantizations=%d, exactDataNum=%d, sum=%d\n",quantization_intervals, exactDataNum, sum);
1469*/
1470
1471        convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1472
1473        //free memory
1474        free_DBA(resiBitLengthArray);
1475        free_DIA(exactLeadNumArray);
1476        free_DIA(resiBitArray);
1477        free(type);
1478
1479
1480        free(pwrErrBound);
1481
1482        free(vce);
1483        free(lce);
1484        free_TightDataPointStorageF(tdps);
1485        free(exactMidByteArray);
1486}
1487
1488void createRangeGroups_float(float** posGroups, float** negGroups, int** posFlags, int** negFlags)
1489{
1490        size_t size = GROUP_COUNT*sizeof(float);
1491        size_t size2 = GROUP_COUNT*sizeof(int);
1492        *posGroups = (float*)malloc(size);
1493        *negGroups = (float*)malloc(size);
1494        *posFlags = (int*)malloc(size2);
1495        *negFlags = (int*)malloc(size2);
1496        memset(*posGroups, 0, size);
1497        memset(*negGroups, 0, size);
1498        memset(*posFlags, 0, size2);
1499        memset(*negFlags, 0, size2);
1500}
1501
1502void compressGroupIDArray_float(char* groupID, TightDataPointStorageF* tdps)
1503{
1504        size_t dataLength = tdps->dataSeriesLength;
1505        int* standGroupID = (int*)malloc(dataLength*sizeof(int));
1506
1507        size_t i;
1508        standGroupID[0] = groupID[0]+GROUP_COUNT; //plus an offset such that it would not be a negative number.
1509        char lastGroupIDValue = groupID[0], curGroupIDValue;
1510        int offset = 2*(GROUP_COUNT + 2);
1511        for(i=1; i<dataLength;i++)
1512        {
1513                curGroupIDValue = groupID[i];
1514                standGroupID[i] = (curGroupIDValue - lastGroupIDValue) + offset; 
1515                lastGroupIDValue = curGroupIDValue;
1516        }
1517       
1518        unsigned char* out = NULL;
1519        size_t outSize;
1520       
1521        HuffmanTree* huffmanTree = SZ_Reset();
1522        encode_withTree(huffmanTree, standGroupID, dataLength, &out, &outSize);
1523        SZ_ReleaseHuffman(huffmanTree);
1524       
1525        tdps->pwrErrBoundBytes = out; //groupIDArray
1526        tdps->pwrErrBoundBytes_size = outSize;
1527       
1528        free(standGroupID);
1529}
1530
1531TightDataPointStorageF* SZ_compress_float_1D_MDQ_pwrGroup(float* oriData, size_t dataLength, int errBoundMode, 
1532double absErrBound, double relBoundRatio, double pwrErrRatio, float valueRangeSize, float medianValue_f)
1533{
1534        size_t i;
1535        float *posGroups, *negGroups, *groups;
1536        float pos_01_group = 0, neg_01_group = 0; //[0,1] and [-1,0]
1537        int *posFlags, *negFlags, *flags;
1538        int pos_01_flag = 0, neg_01_flag = 0;
1539        createRangeGroups_float(&posGroups, &negGroups, &posFlags, &negFlags);
1540        size_t nbBins = (size_t)(1/pwrErrRatio);
1541        if(nbBins%2==1)
1542                nbBins++;
1543        exe_params->intvRadius = nbBins;
1544
1545        int reqLength, status;
1546        float medianValue = medianValue_f;
1547        float realPrecision = (float)getRealPrecision_float(valueRangeSize, errBoundMode, absErrBound, relBoundRatio, &status);
1548        if(realPrecision<0)
1549                realPrecision = pwrErrRatio;
1550        float realGroupPrecision; //precision (error) based on group ID
1551        getPrecisionReqLength_float(realPrecision);
1552        short radExpo = getExponent_float(valueRangeSize/2);
1553        short lastGroupNum = 0, groupNum, grpNum = 0;
1554       
1555        double* groupErrorBounds = generateGroupErrBounds(errBoundMode, realPrecision, pwrErrRatio);
1556        exe_params->intvRadius = generateGroupMaxIntervalCount(groupErrorBounds);
1557       
1558        computeReqLength_float(realPrecision, radExpo, &reqLength, &medianValue);
1559
1560        int* type = (int*) malloc(dataLength*sizeof(int));
1561        char *groupID = (char*) malloc(dataLength*sizeof(char));
1562        char *gp = groupID;
1563               
1564        float* spaceFillingValue = oriData; 
1565       
1566        DynamicIntArray *exactLeadNumArray;
1567        new_DIA(&exactLeadNumArray, DynArrayInitLen);
1568       
1569        DynamicByteArray *exactMidByteArray;
1570        new_DBA(&exactMidByteArray, DynArrayInitLen);
1571       
1572        DynamicIntArray *resiBitArray;
1573        new_DIA(&resiBitArray, DynArrayInitLen);
1574       
1575        unsigned char preDataBytes[4];
1576        intToBytes_bigEndian(preDataBytes, 0);
1577       
1578        int reqBytesLength = reqLength/8;
1579        int resiBitsLength = reqLength%8;
1580
1581        FloatValueCompressElement *vce = (FloatValueCompressElement*)malloc(sizeof(FloatValueCompressElement));
1582        LossyCompressionElement *lce = (LossyCompressionElement*)malloc(sizeof(LossyCompressionElement));
1583                       
1584        int state;
1585        float curData, decValue;
1586        float pred;
1587        float predAbsErr;
1588        double interval = 0;
1589       
1590        //add the first data   
1591        type[0] = 0;
1592        compressSingleFloatValue(vce, spaceFillingValue[0], realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1593        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1594        memcpy(preDataBytes,vce->curBytes,4);
1595        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1596       
1597        curData = spaceFillingValue[0];
1598        groupNum = computeGroupNum_float(vce->data);
1599
1600        if(curData > 0 && groupNum >= 0)
1601        {
1602                groups = posGroups;
1603                flags = posFlags;
1604                grpNum = groupNum;
1605        }
1606        else if(curData < 0 && groupNum >= 0)
1607        {
1608                groups = negGroups;
1609                flags = negFlags;
1610                grpNum = groupNum;
1611        }
1612        else if(curData >= 0 && groupNum == -1)
1613        {
1614                groups = &pos_01_group;
1615                flags = &pos_01_flag;
1616                grpNum = 0;
1617        }
1618        else //curData < 0 && groupNum == -1
1619        {
1620                groups = &neg_01_group;
1621                flags = &neg_01_flag;
1622                grpNum = 0;
1623        }
1624
1625        listAdd_float_group(groups, flags, groupNum, spaceFillingValue[0], vce->data, gp);
1626        gp++;
1627       
1628        for(i=1;i<dataLength;i++)
1629        {
1630                curData = oriData[i];
1631                //printf("i=%d, posGroups[3]=%f, negGroups[3]=%f\n", i, posGroups[3], negGroups[3]);
1632               
1633                groupNum = computeGroupNum_float(curData);
1634               
1635                if(curData > 0 && groupNum >= 0)
1636                {
1637                        groups = posGroups;
1638                        flags = posFlags;
1639                        grpNum = groupNum;
1640                }
1641                else if(curData < 0 && groupNum >= 0)
1642                {
1643                        groups = negGroups;
1644                        flags = negFlags;
1645                        grpNum = groupNum;
1646                }
1647                else if(curData >= 0 && groupNum == -1)
1648                {
1649                        groups = &pos_01_group;
1650                        flags = &pos_01_flag;
1651                        grpNum = 0;
1652                }
1653                else //curData < 0 && groupNum == -1
1654                {
1655                        groups = &neg_01_group;
1656                        flags = &neg_01_flag;
1657                        grpNum = 0;
1658                }
1659
1660                if(groupNum>=GROUP_COUNT)
1661                {
1662                        type[i] = 0;
1663                        compressSingleFloatValue(vce, curData, realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1664                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1665                        memcpy(preDataBytes,vce->curBytes,4);
1666                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1667                        listAdd_float_group(groups, flags, lastGroupNum, curData, vce->data, gp);       //set the group number to be last one in order to get the groupID array as smooth as possible.         
1668                }
1669                else if(flags[grpNum]==0) //the dec value may not be in the same group
1670                {       
1671                        type[i] = 0;
1672                        compressSingleFloatValue(vce, curData, realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1673                        updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1674                        memcpy(preDataBytes,vce->curBytes,4);
1675                        addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1676                        //decGroupNum = computeGroupNum_float(vce->data);
1677                       
1678                        //if(decGroupNum < groupNum)
1679                        //      decValue = curData>0?pow(2, groupNum):-pow(2, groupNum);
1680                        //else if(decGroupNum > groupNum)
1681                        //      decValue = curData>0?pow(2, groupNum+1):-pow(2, groupNum+1);
1682                        //else
1683                        //      decValue = vce->data;
1684                       
1685                        decValue = vce->data;   
1686                        listAdd_float_group(groups, flags, groupNum, curData, decValue, gp);
1687                        lastGroupNum = curData>0?groupNum + 2: -(groupNum+2);
1688                }
1689                else //if flags[groupNum]==1, the dec value must be in the same group
1690                {
1691                        pred = groups[grpNum];
1692                        predAbsErr = fabs(curData - pred);
1693                        realGroupPrecision = groupErrorBounds[grpNum]; //compute real error bound
1694                        interval = realGroupPrecision*2;
1695                        state = (predAbsErr/realGroupPrecision+1)/2;
1696                        if(curData>=pred)
1697                        {
1698                                type[i] = exe_params->intvRadius+state;
1699                                decValue = pred + state*interval;
1700                        }
1701                        else //curData<pred
1702                        {
1703                                type[i] = exe_params->intvRadius-state;
1704                                decValue = pred - state*interval;
1705                        }
1706                        //decGroupNum = computeGroupNum_float(pred);
1707                       
1708                        if((decValue>0&&curData<0)||(decValue<0&&curData>=0))
1709                                decValue = 0;
1710                        //else
1711                        //{
1712                        //      if(decGroupNum < groupNum)
1713                        //              decValue = curData>0?pow(2, groupNum):-pow(2, groupNum);
1714                        //      else if(decGroupNum > groupNum)
1715                        //              decValue = curData>0?pow(2, groupNum+1):-pow(2, groupNum+1);
1716                        //      else
1717                        //              decValue = pred;                               
1718                        //}
1719                       
1720                        if(fabs(curData-decValue)>realGroupPrecision)
1721                        {       
1722                                type[i] = 0;
1723                                compressSingleFloatValue(vce, curData, realPrecision, medianValue, reqLength, reqBytesLength, resiBitsLength);
1724                                updateLossyCompElement_Float(vce->curBytes, preDataBytes, reqBytesLength, resiBitsLength, lce);
1725                                memcpy(preDataBytes,vce->curBytes,4);
1726                                addExactData(exactMidByteArray, exactLeadNumArray, resiBitArray, lce);
1727
1728                                decValue = vce->data;   
1729                        }
1730                       
1731                        listAdd_float_group(groups, flags, groupNum, curData, decValue, gp);                   
1732                        lastGroupNum = curData>=0?groupNum + 2: -(groupNum+2);                 
1733                }
1734                gp++;   
1735
1736        }
1737       
1738        int exactDataNum = exactLeadNumArray->size;
1739       
1740        TightDataPointStorageF* tdps;
1741                       
1742        //combineTypeAndGroupIDArray(nbBins, dataLength, &type, groupID);
1743
1744        new_TightDataPointStorageF(&tdps, dataLength, exactDataNum, 
1745                        type, exactMidByteArray->array, exactMidByteArray->size, 
1746                        exactLeadNumArray->array, 
1747                        resiBitArray->array, resiBitArray->size, 
1748                        resiBitsLength, 
1749                        realPrecision, medianValue, (char)reqLength, nbBins, NULL, 0, radExpo); 
1750       
1751        compressGroupIDArray_float(groupID, tdps);
1752       
1753        free(posGroups);
1754        free(negGroups);
1755        free(posFlags);
1756        free(negFlags);
1757        free(groupID);
1758        free(groupErrorBounds);
1759       
1760        free_DIA(exactLeadNumArray);
1761        free_DIA(resiBitArray);
1762        free(type);     
1763        free(vce);
1764        free(lce);     
1765        free(exactMidByteArray); //exactMidByteArray->array has been released in free_TightDataPointStorageF(tdps);     
1766       
1767        return tdps;
1768}
1769
1770void SZ_compress_args_float_NoCkRngeNoGzip_1D_pwrgroup(unsigned char** newByteData, float *oriData,
1771size_t dataLength, double absErrBound, double relBoundRatio, double pwrErrRatio, float valueRangeSize, float medianValue_f, size_t *outSize)
1772{
1773        TightDataPointStorageF* tdps = SZ_compress_float_1D_MDQ_pwrGroup(oriData, dataLength, confparams_cpr->errorBoundMode, 
1774        absErrBound, relBoundRatio, pwrErrRatio, 
1775        valueRangeSize, medianValue_f);
1776
1777        convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1778
1779        if(*outSize>dataLength*sizeof(float))
1780                SZ_compress_args_float_StoreOriData(oriData, dataLength+2, tdps, newByteData, outSize);
1781
1782        free_TightDataPointStorageF(tdps);
1783}
1784
1785#include <stdbool.h>
1786
1787void SZ_compress_args_float_NoCkRngeNoGzip_1D_pwr_pre_log(unsigned char** newByteData, float *oriData, double pwrErrRatio, size_t dataLength, size_t *outSize, float min, float max){
1788
1789        float * log_data = (float *) malloc(dataLength * sizeof(float));
1790
1791        unsigned char * signs = (unsigned char *) malloc(dataLength);
1792        memset(signs, 0, dataLength);
1793        // preprocess
1794        float max_abs_log_data;
1795    if(min == 0) max_abs_log_data = fabs(log2(fabs(max)));
1796    else if(max == 0) max_abs_log_data = fabs(log2(fabs(min)));
1797    else max_abs_log_data = fabs(log2(fabs(min))) > fabs(log2(fabs(max))) ? fabs(log2(fabs(min))) : fabs(log2(fabs(max)));
1798    float min_log_data = max_abs_log_data;
1799        bool positive = true;
1800        for(size_t i=0; i<dataLength; i++){
1801                if(oriData[i] < 0){
1802                        signs[i] = 1;
1803                        log_data[i] = -oriData[i];
1804                        positive = false;
1805                }
1806                else
1807                        log_data[i] = oriData[i];
1808                if(log_data[i] > 0){
1809                        log_data[i] = log2(log_data[i]);
1810                        if(log_data[i] > max_abs_log_data) max_abs_log_data = log_data[i];
1811                        if(log_data[i] < min_log_data) min_log_data = log_data[i];
1812                }
1813        }
1814
1815        float valueRangeSize, medianValue_f;
1816        computeRangeSize_float(log_data, dataLength, &valueRangeSize, &medianValue_f); 
1817        if(fabs(min_log_data) > max_abs_log_data) max_abs_log_data = fabs(min_log_data);
1818        double realPrecision = log2(1.0 + pwrErrRatio) - max_abs_log_data * 1.2e-7;
1819        for(size_t i=0; i<dataLength; i++){
1820                if(oriData[i] == 0){
1821                        log_data[i] = min_log_data - 2.0001*realPrecision;
1822                }
1823        }
1824
1825    TightDataPointStorageF* tdps = SZ_compress_float_1D_MDQ(log_data, dataLength, realPrecision, valueRangeSize, medianValue_f);
1826    tdps->minLogValue = min_log_data - 1.0001*realPrecision;
1827    free(log_data);
1828    if(!positive){
1829            unsigned char * comp_signs;
1830                // compress signs
1831                unsigned long signSize = sz_lossless_compress(confparams_cpr->losslessCompressor, confparams_cpr->gzipMode, signs, dataLength, &comp_signs);
1832                tdps->pwrErrBoundBytes = comp_signs;
1833                tdps->pwrErrBoundBytes_size = signSize;
1834        }
1835        else{
1836                tdps->pwrErrBoundBytes = NULL;
1837                tdps->pwrErrBoundBytes_size = 0;
1838        }
1839        free(signs);
1840
1841    convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1842    if(*outSize>dataLength*sizeof(float))
1843            SZ_compress_args_float_StoreOriData(oriData, dataLength+2, tdps, newByteData, outSize);
1844
1845    free_TightDataPointStorageF(tdps);
1846}
1847
1848void SZ_compress_args_float_NoCkRngeNoGzip_2D_pwr_pre_log(unsigned char** newByteData, float *oriData, double pwrErrRatio, size_t r1, size_t r2, size_t *outSize, float min, float max){
1849
1850        size_t dataLength = r1 * r2;
1851        float * log_data = (float *) malloc(dataLength * sizeof(float));
1852
1853        unsigned char * signs = (unsigned char *) malloc(dataLength);
1854        memset(signs, 0, dataLength);
1855        // preprocess
1856        float max_abs_log_data;
1857    if(min == 0) max_abs_log_data = fabs(log2(fabs(max)));
1858    else if(max == 0) max_abs_log_data = fabs(log2(fabs(min)));
1859    else max_abs_log_data = fabs(log2(fabs(min))) > fabs(log2(fabs(max))) ? fabs(log2(fabs(min))) : fabs(log2(fabs(max)));
1860    float min_log_data = max_abs_log_data;
1861        bool positive = true;
1862        for(size_t i=0; i<dataLength; i++){
1863                if(oriData[i] < 0){
1864                        signs[i] = 1;
1865                        log_data[i] = -oriData[i];
1866                        positive = false;
1867                }
1868                else
1869                        log_data[i] = oriData[i];
1870                if(log_data[i] > 0){
1871                        log_data[i] = log2(log_data[i]);
1872                        if(log_data[i] > max_abs_log_data) max_abs_log_data = log_data[i];
1873                        if(log_data[i] < min_log_data) min_log_data = log_data[i];
1874                }
1875        }
1876
1877        float valueRangeSize, medianValue_f;
1878        computeRangeSize_float(log_data, dataLength, &valueRangeSize, &medianValue_f); 
1879        if(fabs(min_log_data) > max_abs_log_data) max_abs_log_data = fabs(min_log_data);
1880        double realPrecision = log2(1.0 + pwrErrRatio) - max_abs_log_data * 1.2e-7;
1881        for(size_t i=0; i<dataLength; i++){
1882                if(oriData[i] == 0){
1883                        log_data[i] = min_log_data - 2.0001*realPrecision;
1884                }
1885        }
1886
1887    TightDataPointStorageF* tdps = SZ_compress_float_2D_MDQ(log_data, r1, r2, realPrecision, valueRangeSize, medianValue_f);
1888    tdps->minLogValue = min_log_data - 1.0001*realPrecision;
1889    free(log_data);
1890    if(!positive){
1891            unsigned char * comp_signs;
1892                // compress signs
1893                unsigned long signSize = sz_lossless_compress(confparams_cpr->losslessCompressor, confparams_cpr->gzipMode, signs, dataLength, &comp_signs);
1894                tdps->pwrErrBoundBytes = comp_signs;
1895                tdps->pwrErrBoundBytes_size = signSize;
1896        }
1897        else{
1898                tdps->pwrErrBoundBytes = NULL;
1899                tdps->pwrErrBoundBytes_size = 0;
1900        }
1901        free(signs);
1902
1903    convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1904    if(*outSize>dataLength*sizeof(float))
1905            SZ_compress_args_float_StoreOriData(oriData, dataLength+2, tdps, newByteData, outSize);
1906
1907    free_TightDataPointStorageF(tdps);
1908}
1909
1910void SZ_compress_args_float_NoCkRngeNoGzip_3D_pwr_pre_log(unsigned char** newByteData, float *oriData, double pwrErrRatio, size_t r1, size_t r2, size_t r3, size_t *outSize, float min, float max){
1911
1912        size_t dataLength = r1 * r2 * r3;
1913        float * log_data = (float *) malloc(dataLength * sizeof(float));
1914
1915        unsigned char * signs = (unsigned char *) malloc(dataLength);
1916        memset(signs, 0, dataLength);
1917        // preprocess
1918        float max_abs_log_data;
1919    if(min == 0) max_abs_log_data = fabs(log2(fabs(max)));
1920    else if(max == 0) max_abs_log_data = fabs(log2(fabs(min)));
1921    else max_abs_log_data = fabs(log2(fabs(min))) > fabs(log2(fabs(max))) ? fabs(log2(fabs(min))) : fabs(log2(fabs(max)));
1922    float min_log_data = max_abs_log_data;
1923        bool positive = true;
1924        for(size_t i=0; i<dataLength; i++){
1925                if(oriData[i] < 0){
1926                        signs[i] = 1;
1927                        log_data[i] = -oriData[i];
1928                        positive = false;
1929                }
1930                else
1931                        log_data[i] = oriData[i];
1932                if(log_data[i] > 0){
1933                        log_data[i] = log2(log_data[i]);
1934                        if(log_data[i] > max_abs_log_data) max_abs_log_data = log_data[i];
1935                        if(log_data[i] < min_log_data) min_log_data = log_data[i];
1936                }
1937        }
1938
1939        float valueRangeSize, medianValue_f;
1940        computeRangeSize_float(log_data, dataLength, &valueRangeSize, &medianValue_f); 
1941        if(fabs(min_log_data) > max_abs_log_data) max_abs_log_data = fabs(min_log_data);
1942        double realPrecision = log2(1.0 + pwrErrRatio) - max_abs_log_data * 1.2e-7;
1943        for(size_t i=0; i<dataLength; i++){
1944                if(oriData[i] == 0){
1945                        log_data[i] = min_log_data - 2.0001*realPrecision;
1946                }
1947        }
1948
1949    TightDataPointStorageF* tdps = SZ_compress_float_3D_MDQ(log_data, r1, r2, r3, realPrecision, valueRangeSize, medianValue_f);
1950    tdps->minLogValue = min_log_data - 1.0001*realPrecision;
1951    free(log_data);
1952    if(!positive){
1953            unsigned char * comp_signs;
1954                // compress signs
1955                unsigned long signSize = sz_lossless_compress(confparams_cpr->losslessCompressor, confparams_cpr->gzipMode, signs, dataLength, &comp_signs);
1956                tdps->pwrErrBoundBytes = comp_signs;
1957                tdps->pwrErrBoundBytes_size = signSize;
1958        }
1959        else{
1960                tdps->pwrErrBoundBytes = NULL;
1961                tdps->pwrErrBoundBytes_size = 0;
1962        }
1963        free(signs);
1964
1965    convertTDPStoFlatBytes_float(tdps, newByteData, outSize);
1966    if(*outSize>dataLength*sizeof(float))
1967            SZ_compress_args_float_StoreOriData(oriData, dataLength+2, tdps, newByteData, outSize);
1968
1969    free_TightDataPointStorageF(tdps);
1970}
Note: See TracBrowser for help on using the repository browser.