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

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