# Linear interpolation written as OOP class

a guest
Apr 4th, 2012
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. class interpolators {
2.
3. ////////////////////////////////////////////////////////////////
4. ///
5. ///         some statistical functons.
6. ///
7. ////////////////////////////////////////////////////////////////
8. function stat_mean (\$data) {
9. // calculates mean
10. return (array_sum(\$data) / count(\$data));
11. }
12.
13. function stat_median (\$data) {
14. // calculates median
15. sort (\$data);
16. \$elements = count (\$data);
17. if ((\$elements % 2) == 0) {
18. \$i = \$elements / 2;
19. return ((\$data[\$i - 1] + \$data[\$i]) / 2);
20. } else {
21. \$i = (\$elements - 1) / 2;
22. return \$data[\$i];
23. }
24. }
25.
26. function stat_range (\$data) {
27. // calculates range
28. return (max(\$data) - min(\$data));
29. }
30.
31. function stat_var (\$data) {
32. // calculates sample variance
33. \$n = count (\$data);
34. \$mean = stat_mean (\$data);
35. \$sum = 0;
36. foreach (\$data as \$element) {
37. \$sum += pow ((\$element - \$mean), 2);
38. }
39. return (\$sum / (\$n - 1));
40. }
41.
42. function stat_varp (\$data) {
43. // calculates population variance
44. \$n = count (\$data);
45. \$mean = stat_mean (\$data);
46. \$sum = 0;
47. foreach (\$data as \$element) {
48. \$sum += pow ((\$element - \$mean), 2);
49. }
50. return (\$sum / \$n);
51. }
52.
53. function stat_stdev (\$data) {
54. // calculates sample standard deviation
55. return sqrt (stat_var(\$data));
56. }
57.
58. function stat_stdevp (\$data) {
59. // calculates population standard deviation
60. return sqrt (stat_varp(\$data));
61. }
62. /////////////////////////end statistical functions///////////////////////////
63. /////////////should make it in seperate class, i think///////////////////////
64. /////////////////////////////////////////////////////////////////////////////
65.
66.
67.
68.
69.
70. /////////////////////////////////////////////////////////////////////////////
71. //function which returns year and month according to:
72. //if it is the first day on the month, it returns the current year and month,
73. //otherwise it returns next month with according year
74. /////////////////////////////////////////////////////////////////////////////
75.     function firstFullYearMonth(\$dateString)
76.         {
77.         try {
78.             \$firstDate = new DateTime(\$dateString);
79.         }
80.         catch (Exception \$e) {
81.             echo \$e->getMessage();
82.         exit(1);
83.         }
84.                 \$firstDate= new DateTime(\$dateString);
85.                 \$currentDay=(int) \$firstDate->format('d');
86.                 \$currentMonth=(int) \$firstDate->format('m');
87.                 \$currentYear=(int) \$firstDate->format('y');
88.                 \$prevMonth = (int) date("m", mktime(0, 0, 0, \$currentMonth, \$currentDay-1, \$currentYear));
89.
90.                 if (\$currentMonth>\$prevMonth)
91.                     {
92.                     \$firstDay=date("Y-m", mktime(0, 0, 0, \$currentMonth, \$currentDay, \$currentYear));
93.                     }
94.                 else
95.                     {
96.                     \$firstDay = date("Y-m", mktime(0, 0, 0, \$currentMonth+1, 1, \$currentYear));
97.                     }
98.         return \$firstDay;
99.     }
100.
101. /////////////////////////////////////////////////////////////////////////////
102. //function which returns year and month according to:
103. //if the date consists of the last day on the month, it returns the current year and month,
104. //otherwise it returns previous month with according year
105. /////////////////////////////////////////////////////////////////////////////
106.     function lastFullYearMonth(\$dateString)
107.         {
108.         try {
109.             \$firstDate = new DateTime(\$dateString);
110.         }
111.         catch (Exception \$e) {
112.             echo \$e->getMessage();
113.         exit(1);
114.         }
115.                 \$firstDate= new DateTime(\$dateString);
116.                 \$currentDay=(int) \$firstDate->format('d');
117.                 \$currentMonth=(int) \$firstDate->format('m');
118.                 \$currentYear=(int) \$firstDate->format('y');
119.                 \$nextMonth = (int) date("m", mktime(0, 0, 0, \$currentMonth, \$currentDay+1, \$currentYear));
120.
121.                 if (\$currentMonth<\$nextMonth)
122.                     {
123.                     \$lastDay = date("Y-m", mktime(0, 0, 0, \$currentMonth, \$currentDay, \$currentYear));
124.                     }
125.                 else
126.                     {
127.                     \$lastDay = date("Y-m", mktime(0, 0, 0, \$currentMonth, 0, \$currentYear)); // 0tā diena - iepriekšējā mēneša pēdējā diena.
128.                     }
129.         return \$lastDay;
130.     }
131.
132. /////////////////////////////////////////////////////////////////////////////
133. //Function interpolates values from 2d array where measurement date is in the first
134. //dimension and measured value in the second dimension.
135. //Function returns 2d array with interpolated values for each date between measurements
136. /////////////////////////////////////////////////////////////////////////////
137.     function interpolate(\$arrays)
138.     {
139.
140.         \$oldDate=\$this->firstValDate(\$arrays);
141.         \$oldVal=\$this->firstValVal(\$arrays);
142.
143.         next(\$arrays);
144.
145.         foreach (\$arrays as \$key=>\$tmpArray)
146.             {
147.             \$ii=0;
148.             foreach (\$tmpArray as \$value)
149.                 {
150.                     \$keys= new DateTime(\$key);      //try different date formats
151.                     \$keys=\$keys->format("Y-m-d");   //compare with standart
152.                     if (\$keys!=\$oldDate)
153.                         {
154.                         \$datums=\$keys;
155.                         \$vertiba=\$value;
156.
157.                         \$datetimeOld     = new DateTime(\$oldDate);
158.                         \$datetimeCurrent = new DateTime(\$datums);
159.
160.                         \$lastForInt = strtotime(\$oldDate);
161.                         \$firstForInt = strtotime(\$datums);
162.
163.                         \$intervals = round((\$firstForInt-\$lastForInt)/60/60/24);
164.                         if (\$intervals<0)
165.                             {
166.                             echo "Nākošais datums ir senāks par iepriekšējo.\nLaiks parasti iet uz priekšu un nenāk atpakaļ.";
167.                             die;
168.                             }
169.                         //echo \$intervals;
170.
171.                         \$delta=\$vertiba-\$oldVal;
172.                         \$increment = \$delta/\$intervals;
173.
174.                         if (\$intervals>1)
175.                             {
176.                                 for (\$i=1;\$i<=\$intervals;\$i++)
177.                                 {
178.                                     \$datetimeOld->modify('+1 day');                     //vecajam datumam pieliek vienu dienu klāt
179.                                     \$currentDay=\$datetimeOld->format('Y-m-d');          //pārtaisa datumobjektu uz string
180.                                     \$interpValue=round(\$oldVal+\$increment*\$i,2);        //aprēķina patreizējās dienas vērtību pēc formulas
181.                                                                                         //vecā vērtība plus esošais solis reiz soļa lielums
182.                                     \$interpBoolText=((\$i!=\$intervals)?"\ti":"");        //visos soļos atrastajai vērtībai galā būs strings "i",
183.                                                                                         //tas ļauj uzskatāmi redzēt, ka tieši šī vērtība ir interpolēta
184.                                     \$interpArray[\$currentDay][\$ii]=\$interpValue;
185.                                     \$ii++;
186.                                 }
187.                         \$oldDate=\$datums;                                               //definējam nākošo "iepriekšējo" datumu un vērtību
188.                         \$oldVal=\$vertiba;
189.                             }
190.                         else
191.                             {
192.                             \$interpArray[\$datums][\$ii]=\$vertiba;
193.                             \$oldDate=\$datums;
194.                             \$oldVal=\$vertiba;
195.                             \$ii++;
196.                             }
197.
198.                         }
199.                     else
200.                         {
201.                         \$interpArray[\$key][\$ii]=\$value;
202.                         \$ii++;
203.                         }
204.                 }
205.             }
206.             //print_r (\$interpArray);
207.         return \$interpArray;
208.     }
209.
210.
211. /////////////////////////////////////////////////////////////////////////////
212. //Returns first key - date value from 2 dimensional associative key array.
213. //
214. //
215. /////////////////////////////////////////////////////////////////////////////
216.     function firstValDate(\$arrays)
217.     {
218.         foreach (\$arrays as \$key=>\$tempArray)
219.             {
220.                 return \$key;
221.                 break;
222.             }
223.     }
224.
225. /////////////////////////////////////////////////////////////////////////////
226. //Returns last key - date value from 2 dimensional associative key array.
227. //
228. //are there direct way how to get the last key of associative array?
229. //such loop seems kind of stupid...
230. /////////////////////////////////////////////////////////////////////////////
231.     function lastValDate(\$arrays)
232.     {
233.         \$i=1;
234.         foreach (\$arrays as \$key=>\$tempArray)
235.             {
236.                 if (\$i==count(\$arrays))
237.                 {
238.                 return \$key;
239.                 break;
240.                 }
241.                 \$i++;
242.             }
243.     }
244.
245. /////////////////////////////////////////////////////////////////////////////
246. //Returns first key - date value from 2 dimensional associative key array.
247. //
248. //
249. /////////////////////////////////////////////////////////////////////////////
250.     function firstValVal(\$arrays)
251.     {
252.         return \$arrays[\$oldDate=\$this->firstValDate(\$arrays)][0];
253.
254.     }
255. /////////////////////////////////////////////////////////////////////////////
256. //Function checks element first two symbols (are they tabs), checks, if the value
257. //is null or empty and deletes such element.
258. //
259. /////////////////////////////////////////////////////////////////////////////
260.     function unsetEmpty(\$arrays)
261.     {
262.         \$i=0;
263.         foreach(\$arrays as \$key=>\$value)
264.             {
265.             \$rest = substr(\$value, 0, 2);
266.             if(!(is_null(\$value) || \$value=="" || \$rest=="\t\t"))
267.                 {
268.                 \$arrayNew[\$i]=\$value;
269.                 \$i++;
270.                 }
271.             }
272.     return \$arrayNew;
273.     }
274.
275. /////////////////////////////////////////////////////////////////////////////
276. //Function makes 2 dimensional array from string which is formatted by default
277. //as "date (tab) value".
278. //
279. //should make possibility to divide string in parts and define them (seperator, etc)
280. //by giving optional parameters.
281. /////////////////////////////////////////////////////////////////////////////
282.     function make2dArrayFromDateValueString(\$dateValueString)
283.     {
284.         \$text = str_replace("\r", "", \$dateValueString);
285.         \$text = str_replace("\n", "+", \$text);
286.         \$text = str_replace(",",".",\$text);
287.         \$arrtext = explode("+", \$text);
288.         \$arrtext=\$this->unsetEmpty(\$arrtext);
289.
290.         \$i=0;
291.         foreach(\$arrtext as \$key=>\$value)
292.             {
293.                 \$bothValues= explode ("\t",\$value);
294.                 \$datums=\$bothValues[0];
295.                 \$vertiba=\$bothValues[1];
296.                 \$masivs2d[\$datums][\$i]=\$vertiba;
297.                 \$i++;
298.             }
299.         return \$masivs2d;
300.     }
301.
302. /////////////////////////////////////////////////////////////////////////////
303. //Function cuts the months which has unfilled daily mesaured values
304. //
305. //
306. /////////////////////////////////////////////////////////////////////////////
307.     function cutInterpolated(\$arrays)
308.         {
309.         \$FirstDateFrom2dArray=\$this->firstValDate(\$arrays);
310.         \$LastDateFrom2dArray=\$this->lastValDate(\$arrays);
311.         \$FirstFullYearMonth=\$this->firstFullYearMonth(\$FirstDateFrom2dArray);
312.         \$LastFullYearMonth=\$this->lastFullYearMonth(\$LastDateFrom2dArray);
313.         \$validDayCount=round((strtotime(\$LastFullYearMonth."-2")-strtotime(\$FirstFullYearMonth."-01"))/60/60/24)+1;
314.
315.         //echo \$validDayCount;
316.         //echo \$FirstFullYearMonth;
317.         //\$LastDateFrom2dArray
318.         if (\$validDayCount>0)
319.             {
320.                 \$i=0;
321.                 foreach (\$arrays as \$key=>\$tmpArray)
322.                 {
323.                     foreach (\$tmpArray as \$value)
324.                         {
325.                         if ((\$key>=\$FirstFullYearMonth) and (\$key<=\$LastFullYearMonth))
326.                             {
327.                             \$array[\$key][\$i]=\$value;
328.                             \$i++;
329.                             }
330.                         }
331.                 }
332.             }
333.         return \$array;
334.         }
335.
336.
337. /////////////////////////////////////////////////////////////////////////////
338. //create 2d array with year and month in first dimension and respective
339. //daily data valuesin seceond
340. /////////////////////////////////////////////////////////////////////////////
341.     function createByYearMonth(\$arrays)
342.         {
343.                 \$k=0;
344.                 foreach (\$arrays as \$key=>\$tmpArray)
345.                 {
346.                     foreach (\$tmpArray as \$value)
347.                         {
348.                         \$currDate=new datetime(\$key."-01");
349.                         \$Months=(int)\$currDate->format("m");
350.                         if ((\$oldmonth<\$Months) or ((\$oldmonth==12) and (\$Months==1)))                  //skatamies, ja nākamais mēnesis, tad ieliekam iekš masīva
351.                                 {
352.                                 \$k=0;
354.                                 \$paMenesiem[\$currDate->format("Y-m")][\$k]=\$value;                               //izdala gadu un pareizo mēnesi masīvam
355.                                 \$k++;
356.                                 }
357.                             else
358.                                 {
359.                                 //echo \$value;
360.                                 \$paMenesiem[\$currDate->format("Y-m")][\$k]=\$value;
361.                                 \$k++;
362.                                 }
363.                                 \$oldmonth=\$Months;
364.
365.                         }
366.                 }
367.                 //print_r (\$paMenesiem);
368.         return \$paMenesiem;
369.         }
370. /////////////////////////////////////////////////////////////////////////////
371. //create 2d array with year and month in first dimension and statistical values
372. //for respective monthly data in second.
373. //0 - count
374. //1 - min
375. //2 - max
376. //3 - sum
377. //4 - average
378. //5 - median
379. //6 - variance (for sample)
380. //7 - variance (for population)
381. //8 - standart deviation (for sample)
382. //9 - standart deviation (for population)
383. /////////////////////////////////////////////////////////////////////////////
384.
385.     function getStatistics(\$arrays)
386.         {
387.         foreach (\$arrays as \$key=>\$tempone) {
388.                 \$array[\$key]["count"]=count(\$tempone);
389.                 \$array[\$key]["min"]=min(\$tempone);
390.                 \$array[\$key]["max"]=max(\$tempone);
391.                 \$array[\$key]["sum"]=array_sum(\$tempone);
392.                 \$array[\$key]["average"]=stat_mean(\$tempone);
393.                 \$array[\$key]["median"]=stat_median(\$tempone);
394.                 \$array[\$key]["variance"]=stat_var(\$tempone);
395.                 \$array[\$key]["variancep"]=stat_varp(\$tempone);
396.                 \$array[\$key]["stdev"]=stat_stdev(\$tempone);
397.                 \$array[\$key]["stdevp"]=stat_stdevp(\$tempone);
398.                 }
399.             return \$array;
400.         }
401.
402. }
403.
404.
405.
406. \$interpolators = new interpolators();   //create interpolator object
407. \$masivStrings=\$_POST['tabula']; //get some data (date\tvalue\n(\r)) format
408. \$arrays2d= \$interpolators->make2dArrayFromDateValueString(\$masivStrings); //create from gathered data 2dimensional array
409. \$interpolatedArray = \$interpolators->interpolate(\$arrays2d);                //interpolate it daily
410. \$cuttedArray=\$interpolators->cutInterpolated(\$interpolatedArray);           //cut end and last month, if it is not started/lasted from beginning/till end
411. \$paMenesiem=\$interpolators->createByYearMonth(\$cuttedArray);                //sepereate values for each month
412. \$statistika=\$interpolators->getStatistics(\$paMenesiem);                     //get some monthly statistics