Repository: freedeaths/mathbox-py (language: python)

Issue:
[feat]: add some functions about time series data processing
1. Correlation between different signals.
2. Additive/multiplicative decompose a signal
3. Outliers detection
4. Change points detection with EDM


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index e067d17..bf274a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
-venv/
+*venv*/
 **/.DS_Store
 dist/
-*.egg-info/
\ No newline at end of file
+*.egg-info/
+.pytest_cache/
+__pycache__/
\ No newline at end of file
diff --git a/README.md b/README.md
index daf94eb..54d06a1 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,13 @@
 # Mathbox
 
-> Author: freedeaths
-> 
-> Date: 2021.Dec.18
-> 
-> Version: v0.1.0
-
 ## Overview
 
-A math toolbox
+A math toolbox without numpy and scipy.
+
+## Usage
+
+1. `pip install mathbox` (NOT TESTED)
+2. Download from source code, `export PYTHONPATH='/<path>/<to>/mathbox-py'`. And then get into examples folder `cd examples`, install dependencies from requirements.txt (recommended in virtualenv) and run `python xxx.py`. 
 
 ## Time series 1D real data
 
diff --git a/examples/corr_detect.py b/examples/corr_detect.py
new file mode 100644
index 0000000..fb8cb9e
--- /dev/null
+++ b/examples/corr_detect.py
@@ -0,0 +1,32 @@
+import pandas as pd
+import matplotlib.pyplot as plt
+
+from mathbox.app.signal.correlation import max_corr
+
+# repeat https://anomaly.io/detect-correlation-time-series/index.html
+# TODO：
+# interpolation
+# TODO:
+# Correlation with time shift
+# https://anomaly.io/understand-auto-cross-correlation-normalized-shift/index.html#/time_shift
+
+
+if __name__ == '__main__':
+    src_data = pd.read_csv('./data/graphs45.csv')
+
+    plt.subplot(2,1,1)
+    n = range(src_data.shape[0])
+
+    dfs = []
+    for col in src_data.columns:
+        dfs.append((col,src_data[col]))
+        plt.plot(n, src_data[col])
+    
+    
+    similar_5 = max_corr(dfs[3], dfs, 5)
+    print("most likely 5 line to No.4: ",[x[0] for x in similar_5], "likelihood: ",[x[1] for x in similar_5])
+
+    plt.subplot(2,1,2)
+    for item in similar_5:
+        plt.plot(n, src_data[item[0]])
+    plt.show()
\ No newline at end of file
diff --git a/examples/cpd.py b/examples/cpd.py
new file mode 100644
index 0000000..7cf2649
--- /dev/null
+++ b/examples/cpd.py
@@ -0,0 +1,32 @@
+import matplotlib.pyplot as plt
+import random
+
+from mathbox.app.signal.change_point import e_divisive
+
+def one_time():
+    return e_divisive(data,jump=3,pvalue=0.05,permutations=100)
+    
+    
+if __name__ == "__main__":
+    data_1 = [0 for _ in range(10)] + [100 for _ in range(10)] + [50 for _ in range(10)] + [100 for _ in range(10)] + [0 for _ in range(10)] + [100 for _ in range(10)] + [0 for _ in range(10)]
+    data_1 = [x + random.randint(-1, 1) for x in data_1]
+
+    data_2 = [0 for _ in range(10)] + [100 for _ in range(10)] + [50 for _ in range(10)] + [50+5*x for x in range(10)] + [100 for _ in range(10)] + [100-10*x for x in range(10)] + [0 for _ in range(10)]
+    data_2 = [x + random.randint(-1, 1) for x in data_2]
+
+    data_3 = [0,0,0,0,0,0,1,1,1,1,1,5,5,5,5,5]
+
+    data = data_1
+    
+    #'''
+    cp = one_time()
+    print("x:",cp)
+    plt.plot(data)
+    plt.plot([x for x in cp],[data[x] for x in cp],'ro')
+    plt.show()
+    '''
+    for i in range(100):
+        print("i:",i)
+        cp = one_time()
+        print("x:",cp)
+    '''
\ No newline at end of file
diff --git a/examples/data/graphs45.csv b/examples/data/graphs45.csv
new file mode 100644
index 0000000..61bae35
--- /dev/null
+++ b/examples/data/graphs45.csv
@@ -0,0 +1,107 @@
+Graph_01,Graph_02,Graph_03,Graph_04,Graph_05,Graph_06,Graph_07,Graph_08,Graph_09,Graph_10,Graph_11,Graph_12,Graph_13,Graph_14,Graph_15,Graph_16,Graph_17,Graph_18,Graph_19,Graph_20,Graph_21,Graph_22,Graph_23,Graph_24,Graph_25,Graph_26,Graph_27,Graph_28,Graph_29,Graph_30,Graph_31,Graph_32,Graph_33,Graph_34,Graph_35,Graph_36,Graph_37,Graph_38,Graph_39,Graph_40,Graph_41,Graph_42,Graph_43,Graph_44,Graph_45
+591192,57936,199358,563213,540495,360382,621211,513449,205137,258217,361593,7727,520874,395604,394797,214004,593736,376971,288478,713873,280288,544854,622374,271145,303004,505604,440399,91394,29960,336968,91679,193519,145230,246647,507989,82150,672667,379970,84661,83338,212339,796451,272182,92265,720552
+602978,58131,203272,567583,540907,358811,620618,517225,209326,255073,361947,8085,534106,404254,396408,211173,596864,381665,289232,712801,281650,545630,626746,272278,301121,507452,467412,92790,30289,375787,95226,191528,142007,247417,518822,81163,703825,381348,81130,85297,217264,810251,271809,94851,710894
+611076,58517,199824,561770,554392,352047,607532,521323,201941,253428,369780,8071,539510,405914,383547,201701,573346,375813,284718,695441,283484,538877,611628,266830,292416,476540,396246,94221,29944,342933,88528,183140,125614,255501,502621,79487,668177,350933,79258,70149,218271,820046,272093,92821,723526
+621616,59005,197737,556324,560911,364824,621142,534357,205924,256242,371359,7856,545466,409413,397612,207173,595286,379796,277703,694899,288643,550068,627228,274311,310006,464050,398913,94577,30544,378840,95460,197548,136566,253583,500614,76517,625658,378351,79033,82728,220917,824137,282511,92112,740409
+607457,59092,206956,572799,550977,365106,637281,529119,209843,256793,364089,8059,548047,409349,397422,216048,609109,386110,295783,723556,284780,560289,624072,276571,296551,490122,413299,94537,30565,383830,93214,198837,127249,252966,498610,81578,675865,369623,83294,78761,220644,818115,276514,94060,730382
+612784,59385,205401,572903,557101,357289,625608,531841,211336,266514,367700,8038,545139,409094,390736,216670,606133,390170,298573,720323,286549,559047,629670,281233,294984,481548,432672,95040,30767,386919,91111,208114,140345,256175,503065,81475,691164,373738,85668,82704,218691,818207,274182,97584,723449
+608429,59497,200878,546029,557609,353071,618121,522132,195768,248771,373198,7626,542556,408356,393359,201073,554413,389160,278629,688789,288597,542007,609504,268943,289580,457282,426665,96545,30396,380156,90454,181572,109781,257182,506270,72768,590248,383201,78136,82873,219878,825087,275064,89134,679819
+590945,56545,181072,518528,544843,345465,597809,522356,192852,239581,361120,7078,506979,387165,391919,193582,549426,385088,269617,657144,284453,499616,587013,259407,303680,462100,365357,95578,27581,342941,88849,185578,111244,249400,505668,69558,546435,370514,74170,78621,208156,783838,252698,89977,673703
+567336,52971,141500,396642,506495,253839,483734,527167,198598,233725,366639,5697,519157,392980,392937,195833,536660,388494,268665,652183,286442,518778,435947,259775,299385,401294,354919,96122,27260,336220,91818,161842,108510,250529,523114,70354,532230,377296,73688,77554,175530,658689,235095,59323,503420
+588172,55029,144798,412021,519987,265544,484493,515295,194008,229729,378836,5783,518188,389729,390868,188952,529560,382755,262411,632795,284053,500344,436900,250678,292020,422659,311685,98082,25873,283861,86377,158574,89513,263768,514366,67945,517762,356832,67115,64758,180801,687322,246276,64120,553729
+613937,56926,148019,426621,544031,277946,503649,535298,194413,231697,379531,5826,520249,391879,401631,190612,540782,386900,257162,631771,291017,506093,471453,258337,302156,427168,313271,96730,26280,322045,95577,157060,98394,265924,503022,63908,464237,369705,70857,74667,187256,707574,262924,73329,595195
+617199,58381,170360,479748,555920,298659,540337,521486,198733,255384,375625,6048,535138,403963,392875,217271,588839,391533,286437,700530,285229,538197,508831,264912,299938,461741,413480,98766,28064,338041,92306,189663,113403,259793,514668,75547,620003,378785,75666,76226,197834,750731,272111,80660,632988
+627863,58752,176233,498187,556283,311531,564889,521741,214959,258565,364606,6401,565313,422485,397917,221005,615059,388376,303932,733940,289168,564650,533740,279445,290235,458105,390562,97433,31784,390460,91398,182761,137490,256576,522805,78292,681079,369267,83476,82654,206639,779664,270874,81758,673840
+634627,59559,170090,491244,562074,303042,550494,534136,206105,244159,377336,6449,532597,402735,393796,197106,565789,388721,283601,691038,287067,526530,533368,267152,295475,449287,381106,97079,29345,356285,95226,167942,113244,263094,507115,69758,564901,381393,76563,79715,198682,756426,273350,78854,628694
+636877,59216,170012,479237,565730,301218,546774,525005,207642,253308,370985,6340,523155,398562,393981,207465,573570,388457,289825,693681,287959,521856,528578,265046,285521,473979,403043,97500,27771,344190,90698,189067,124472,258183,508618,73666,597120,369629,73583,77079,196601,749149,273968,80553,618601
+644815,60672,171418,480383,559109,303664,551700,521329,222461,264722,363972,6696,553326,414274,391895,213588,602180,389002,303062,733693,286888,567044,551340,278000,293246,500723,453655,96207,31223,384938,93400,206199,132669,251169,518456,81535,694931,377977,86673,83979,194638,741357,271346,80246,617677
+648437,60185,166169,477850,554571,284448,528027,521380,215078,259342,373529,6248,554544,414701,385565,215981,591458,383055,301673,725751,281902,543364,521241,269791,292164,474168,372813,97691,30396,342287,90733,193489,117844,266684,511141,80102,674435,355329,81816,70391,190112,732106,269004,75039,604238
+656048,60103,164077,485641,568069,304851,553223,537545,212085,263089,380225,6397,567470,420012,399518,215150,607375,383859,290724,719432,288641,562055,539292,277949,295795,483683,417680,99448,31300,374318,96092,188809,132990,270020,511122,76297,639085,384197,83119,80179,198070,750117,278970,78724,643111
+653698,62004,178212,502132,570676,322421,566169,526512,218831,266180,372810,6769,565160,421002,397995,219438,597181,386518,304039,740070,285357,567328,558950,278620,299071,461209,408132,98217,32031,382767,94816,183396,148656,266896,514443,77875,671933,379067,83600,81076,202521,764659,283563,83823,636978
+653637,61855,180600,509130,572195,317834,564021,527841,214751,266041,359684,6871,570291,423318,396479,218222,606532,391916,309377,748902,286451,572401,563603,279291,291079,520477,438707,98471,32027,388359,95400,186565,130984,265490,503904,78704,686329,378636,85737,82916,204067,770693,281379,79036,637199
+651504,61917,180656,515036,567686,321267,569851,498718,203622,246366,371796,6921,556439,415581,359116,191002,542883,369193,286772,692705,277627,552572,570675,277245,297826,480060,441042,98264,32034,388389,93736,202422,135948,268308,510581,78925,704967,377479,81970,87320,204818,764188,280536,80776,641611
+657623,61676,181109,500465,541859,305646,543628,490751,191670,227243,367635,6998,524822,389860,340852,188507,514889,343920,266521,642913,243710,485863,561637,238426,290363,457502,349213,99215,31106,331796,85871,193342,110384,267539,503019,78991,627118,306970,79816,63914,203154,770370,278850,82105,637933
+660821,61432,174442,503157,558779,320741,551045,514764,187211,226738,357036,6999,511960,385166,367212,185057,520593,361145,255284,631193,264531,492458,564465,243558,302899,461277,401594,97673,31152,371960,94832,189004,130541,265974,498962,77250,630556,347085,81855,75617,202158,768148,285611,83668,638466
+659636,61183,176457,505722,554662,302867,536406,518189,186030,221507,368794,6936,500705,377856,366707,183919,501735,365889,251800,620586,269059,476815,551564,234954,305006,504448,383405,98396,30254,346557,91271,188911,117455,281142,511267,79764,674341,338733,80598,68752,198012,758169,276999,83061,623786
+662750,61576,173653,504295,560550,316013,548842,534918,186471,225648,369191,6890,505107,381805,379918,182988,525475,374700,248113,623869,278677,490442,562988,243142,302494,515870,439874,99350,31015,383843,93850,201883,137734,283851,511562,77525,630625,361495,83669,77877,201836,761256,284640,80197,671762
+661364,62090,188444,523575,571952,332517,566773,543827,198331,235578,368445,7344,515881,388579,396258,197375,539892,394452,261937,649384,283949,492358,590803,245894,295885,515712,446044,99840,32010,389768,94216,180934,144068,282390,508515,80521,681884,351715,82684,79668,207752,775111,286520,83636,671216
+665935,62624,188794,530466,573245,326004,569464,549186,194961,233762,358212,7232,510825,385439,392173,195898,541683,394597,268529,652259,286215,498127,592402,247905,299388,483871,475051,98957,31972,391454,97992,209648,156034,280367,514405,80519,687217,360669,84791,81647,207584,777624,280582,87706,668664
+667206,62395,186105,525343,572810,330504,568957,553485,193108,232450,363099,7380,513056,388407,396609,190748,537218,391439,265924,658517,289882,510062,587245,246730,299938,498797,466490,98678,32114,397314,95411,203958,137986,281659,506921,81868,724278,363076,84391,82323,205613,776896,281765,85419,659948
+660573,62220,187497,519649,573925,327763,567962,547972,191086,235530,353882,7134,514233,385134,399182,192675,542906,394335,262963,649912,289605,498580,584733,249370,295490,487448,460437,98502,31722,395838,95494,192613,135869,276790,499899,81622,712871,363736,86629,81148,207814,776967,284385,83462,655078
+642580,61472,184930,528011,560569,315108,571773,532197,189273,232408,332530,7222,507366,383449,379323,189735,531526,390465,265608,655689,282160,499833,581794,251479,297183,520190,419992,96347,31425,387094,92464,214706,137466,264676,509549,80488,707734,363016,83240,82375,203356,774799,274516,87475,675203
+650406,62190,185098,521580,555161,308796,542906,535238,187720,225513,352925,7017,497077,378623,382333,189042,522558,388007,261866,636844,278833,481402,569005,239209,309100,493594,415288,95945,30557,347304,95526,196676,121024,278591,514178,80647,715966,365105,78530,68744,199831,761372,277549,84931,637270
+647447,61960,176269,509203,561695,320541,571848,543489,183282,225922,356097,7012,509675,386581,392576,194268,547093,391277,252754,626661,282734,505079,568839,249179,313150,472986,430543,97501,31256,379964,99673,190448,134633,281178,508816,75218,619104,371445,80059,79459,204259,769208,280367,86100,697643
+654017,61789,185349,533036,566961,332646,580132,546734,193474,230133,355757,7218,518415,389583,395763,193851,557018,396477,267533,660355,287766,511454,586939,256437,311953,497511,433077,98860,31736,386474,92870,205875,141264,281970,514149,79939,696182,365469,82391,79941,206576,772817,283684,88709,699855
+651141,61659,190372,529894,570471,342837,583149,544620,200706,238419,366469,7512,529716,398634,398992,197050,580822,396121,269133,670364,290014,518328,591966,261556,282997,479052,412237,101135,32446,401773,98268,206939,133951,288446,511601,80135,702020,366366,83014,82899,210321,786174,283861,89974,688312
+650520,61647,192091,531379,563009,337607,580480,545964,201102,242454,361796,7440,522939,394914,394552,200023,576948,398753,272504,674073,290359,522513,591291,260344,285131,515100,439034,100444,32396,402161,93125,185555,141475,284271,495606,80081,714883,369249,82854,84919,208637,783947,279778,87125,670258
+650009,61260,189192,518598,556454,336172,575770,541447,194903,241787,358994,7335,527671,399832,389205,201148,560689,396085,272808,661280,285692,514552,595245,258042,295766,493275,452540,101580,32435,406763,92053,214433,146443,280073,500289,81589,705564,360950,86871,85181,211949,792303,279085,86023,683099
+646421,61858,187272,534959,560711,331714,572013,538871,198415,239849,336869,7388,517904,395874,384805,198594,552331,399223,266720,656333,284910,503483,584764,256402,294081,506630,449302,99831,32517,403104,95115,201650,152174,270761,512794,80158,714798,374180,84207,82954,207089,786551,276113,85985,666330
+658614,61469,188278,526370,561108,325271,558781,545975,197915,235275,369909,7283,515191,393818,392618,189466,541866,392010,263753,649990,288847,502519,579607,251814,300337,469141,422713,100894,31017,368971,96152,192700,127124,289477,524393,81461,694755,354657,81961,69775,206139,782941,282782,85386,661749
+650636,61838,180023,514133,560870,324259,565067,547130,192453,237489,369418,7047,521694,397102,393296,193410,570065,395969,256351,634971,288808,508375,594485,257238,309789,455446,403342,101481,31601,394875,93935,181731,133923,287228,506893,77373,630198,376521,83680,81872,209052,789235,283081,85162,690419
+623299,60561,192429,535120,560681,334083,569323,549818,204730,244736,363681,7332,521077,394903,396878,198422,563631,402926,274520,675864,290529,526002,600038,258624,292419,481044,430865,102114,32548,402858,94224,189770,149978,282502,509684,80394,693551,365546,88481,81499,208020,780545,270334,85891,666152
+596065,55512,193264,528625,498008,335859,574489,556886,199330,244500,369881,7624,533602,400714,400067,199200,557500,405742,273171,682456,293864,520092,597675,256216,292533,498363,451503,103516,32952,405549,92968,204492,147420,286772,503837,81392,715956,358593,85788,81781,210613,793209,241277,88806,676123
+629169,57673,189349,536227,529260,328282,571540,559963,200139,243128,360655,7355,531301,400914,400193,208862,567102,403645,272227,674324,296964,522496,589223,260944,300561,515113,430010,101743,32805,407919,92510,209920,143587,281063,492714,82745,698176,376324,86173,83357,210725,786956,261740,85819,688716
+636901,58307,190022,528402,537387,332748,575591,554953,200678,239296,352783,7757,531489,399992,390897,202953,559759,402029,274291,675450,295827,525014,605874,259395,287052,492719,442319,102681,32993,408902,91479,188279,139651,275195,505931,81353,703448,378953,87793,84888,209949,795138,263015,88595,674307
+637403,59262,192942,536959,535523,328774,572585,553383,200285,239504,336059,7355,525797,397438,390427,192761,554924,403384,271849,674845,294769,516035,591956,259634,302504,512730,465156,101714,32520,406440,89465,213079,152752,267111,511471,80933,708057,378013,84764,81473,208010,786335,264296,88201,664708
+650720,59383,191211,532806,539934,322099,550585,558679,191934,234992,363196,7280,519680,396454,388346,193035,544772,397459,269732,662106,293233,507485,582152,248782,305953,467864,401671,103627,31359,365484,92376,177957,130176,284974,518213,81446,721779,368678,79666,71304,208357,783745,269293,86700,650576
+647483,60078,183375,523360,542364,319614,562034,553983,191858,236289,365835,7181,529867,401951,392510,196314,568590,403193,262758,652705,292411,510451,596663,256850,307077,503855,421798,105738,31822,395422,95318,199353,135833,286992,498261,75274,623167,389933,84643,80411,211005,797056,273802,89164,686050
+655593,61280,157607,475093,552538,320972,564811,563687,205261,241141,361001,6338,533279,402267,397730,204309,555542,409446,276950,681248,292324,525208,544619,258813,298989,505736,439247,105547,32749,403487,91338,201657,139413,280336,505957,79819,687612,378686,84791,83095,208335,782779,280076,76337,565615
+649901,60989,140327,419994,547163,238178,471330,557457,203404,240672,352215,5686,532871,402231,398893,196585,563468,408369,275482,680304,293232,520819,497479,259414,299287,501872,446561,104807,32669,407265,93085,185010,138945,276275,497913,81323,695423,378106,82681,85211,162717,650110,273324,63553,533026
+648085,60300,157746,462367,543179,282160,513945,556691,201148,245218,357535,6302,535050,404092,395022,195754,561060,408892,275171,678856,294429,533552,539324,260146,295115,540182,413416,105014,33111,408241,87243,188630,149782,268054,486494,80631,693724,366861,86137,84929,182577,721865,275056,73571,594326
+645716,60017,162135,480452,548758,290093,528195,557147,199948,239785,348718,6367,525861,395652,395707,200578,553705,406158,273861,675490,294311,517626,538884,259702,294384,532728,433365,104765,32502,404686,92644,196235,144468,266400,486460,80535,723525,362108,80497,83870,184129,720710,276585,76251,616836
+647591,60487,172794,497184,548878,305612,549695,554985,205441,245887,326614,6871,533470,399760,391459,212377,581768,406445,286980,700891,294877,519326,575036,260939,299589,499672,425899,103096,32195,400030,92885,211235,147773,255156,501696,80631,709869,370453,86245,81823,184240,737247,272234,81686,667042
+656965,61050,181887,526162,551385,325387,556823,559671,205903,251267,344423,7133,538165,408685,395633,210402,581064,405281,291771,719416,295865,534443,595270,262398,300460,481020,405455,104713,30947,354227,91427,182786,122868,274829,500593,81889,703068,354762,78869,69467,195037,761402,277060,83396,665221
+648851,61480,186799,533623,552242,336167,590687,555437,210793,249512,348156,7199,547991,413393,395596,213786,597601,404734,285925,700321,295083,546264,603678,267064,306358,476431,397369,105882,31646,386946,96417,204749,139995,276494,501513,77592,629590,378828,80459,79594,205886,790223,278380,86586,709177
+651566,61745,195944,553300,558840,354778,596601,559949,216238,257738,347699,7657,555595,415041,401204,220563,598809,405409,296246,726544,297610,563090,618271,270561,301177,491557,392909,106896,32066,395266,94704,196539,142279,276910,499618,80212,689770,376360,87121,78866,213287,808454,278754,94207,702798
+647171,62189,198318,560982,564231,359483,606792,553528,215767,255873,317392,7506,555197,414131,397849,220043,611730,407749,300896,732517,295017,563390,616316,268592,300871,468800,419974,106304,32204,400959,94366,209842,154164,260120,499233,82276,701394,370619,86490,80795,212535,805519,275819,94315,715187
+643794,62058,199365,562913,564044,353552,601573,555725,218547,258324,283881,7678,557187,415898,393956,217770,598659,407542,298063,725584,298154,556070,617288,269914,294941,478279,423351,105481,32473,404544,90045,208301,150294,243858,488301,79747,713928,378133,86442,83842,213282,807751,274961,95168,719508
+642609,61860,197190,555325,558990,354041,616647,556831,213772,253451,272000,7781,561133,417914,394682,215481,601739,406301,294784,707505,298005,558581,621345,272385,297982,512403,422399,106738,32808,407150,90671,201363,160947,237119,499386,79659,678028,371017,87399,84487,216160,813907,269336,91484,695515
+652102,61310,200193,570214,555406,341607,598362,558424,217172,256104,343574,7651,546649,411280,391220,214341,594391,403465,296075,712033,300088,543618,619364,265530,300548,473031,462642,108411,31875,403702,94276,198552,152169,270202,503653,76845,665813,379834,89094,85526,209662,804118,272241,89209,708610
+656870,62522,205249,575931,555077,348778,585219,560523,210154,250695,342221,7573,536889,408017,391789,214397,584368,412238,296561,722941,299331,546536,613472,263682,297039,485309,387701,108820,30745,358880,88992,190298,124529,266560,498032,79071,694255,354096,80981,70850,208165,795737,273220,93655,702860
+655557,62312,201506,576576,556596,355372,608456,561802,210637,249224,339875,7595,533939,406136,398080,216289,596314,413523,298166,726004,299534,553493,622269,272092,299387,474445,402755,109530,31095,386895,96454,185257,145610,261292,495774,77650,642503,381543,84456,80677,208401,790908,277130,93658,742238
+654100,62116,208429,584122,558668,356475,605280,517040,217392,254497,342532,7840,550285,410604,351086,221513,598953,385385,306659,744734,288966,566015,622881,266775,297212,452464,444271,109403,32100,398321,95205,218351,143557,262959,489553,78190,691132,374066,81975,81993,213971,809293,275247,97524,734772
+653782,62311,208211,586373,563072,360852,629577,499828,215129,261410,318498,7778,558186,418235,336988,220139,611322,351540,307128,745385,250914,558443,643901,272352,301114,526522,474410,110370,32599,402079,88981,192802,154297,254323,497580,78930,708187,372654,86482,81922,219122,826358,277180,96230,771976
+655261,62528,214556,592448,559920,368077,622437,526290,212810,254908,298294,8014,560237,417433,362264,223431,597230,367687,287844,724506,266715,561561,643865,269962,287870,511976,444760,109070,32370,405358,93522,189997,146713,244959,490990,79912,703976,364661,86182,84158,217793,827259,278064,98777,744325
+653356,62037,209486,588312,551376,364552,626530,534619,163189,200694,335706,8091,426310,341818,366960,139975,434844,374447,220931,576875,276065,399631,647991,223561,292001,509046,463672,109199,31950,401783,90352,210996,152555,265046,500559,79762,727205,357698,83992,86296,218065,814138,277390,92933,746089
+651902,62434,210939,597400,550291,366600,622016,536750,184684,225112,321578,8276,458627,368525,364424,173182,533770,377957,249006,637717,278157,477607,629373,250612,292813,520721,463430,111176,31643,398581,92377,196631,149109,258562,499040,80487,730572,371207,83813,87078,213353,809793,277696,95604,725924
+659865,63027,210046,595647,561799,358213,598069,542049,191079,230793,318497,7905,479677,379728,373205,184895,536127,379024,263926,659180,282875,509190,632723,253972,299841,494858,394194,110851,30226,360912,88375,199042,124839,261925,503387,80559,728442,351878,80294,72178,209556,796356,281404,96837,748209
+654647,63449,207946,582684,567880,366406,624847,544583,198869,245922,326027,8102,509175,393645,381143,204031,575106,384854,278856,687304,288386,528987,654376,265327,307028,485753,397401,113428,30869,389487,97320,206201,139976,265885,496359,77176,639877,374255,81006,81850,214956,809245,282734,95940,754969
+656244,63124,211985,593422,562476,372336,629966,551494,207544,252833,323279,7956,526514,401009,384424,204930,593421,400744,299058,722018,287881,553913,646041,272165,303744,477985,409247,114590,32039,393601,92532,208434,145934,262973,509351,78426,700378,357713,85148,86221,216578,818367,276710,98962,777530
+647524,62902,214921,597764,548448,360112,629384,544861,208317,260905,292634,8032,534234,406967,385529,208108,597059,402147,302040,728955,286973,555734,636447,277446,292141,462761,461376,113462,31873,402833,91889,210957,140397,245892,496940,80179,722594,356577,87159,85370,220161,822676,273682,96113,735540
+649968,61783,212918,591223,550876,367967,636914,545438,208708,255638,250967,7988,532590,407808,380505,205530,598779,397650,301716,729124,286761,563179,640683,278233,296406,493008,435996,112221,31933,399895,91640,193174,153237,227586,498502,79716,705295,347663,87467,87636,217701,815653,272555,98345,736814
+647578,62125,214798,589541,559210,370168,632221,547808,216238,262938,231306,8195,537328,405852,382955,207995,596702,399154,305301,736820,286478,561483,631051,276632,292400,473949,451411,112506,31898,399137,92612,194074,136153,217468,497973,78970,681221,356997,82974,85079,218530,819288,274452,96330,727586
+643639,61823,215255,590848,556112,362606,628660,544930,214496,256681,230848,8233,531381,404228,381340,209236,593735,396964,304940,731660,288326,566151,631472,277371,296735,487852,449793,111819,30999,386779,93413,211514,144113,214857,505623,80517,683261,338959,83764,83463,215873,810131,273293,96684,729575
+656233,62053,214573,594535,541874,357787,597323,551027,212928,251802,304801,8246,515169,391583,384016,201773,578520,392628,300124,713459,284084,546731,626258,269179,301022,464586,433409,111548,29989,360179,91316,193150,125950,256300,499989,81546,693578,337466,81362,73916,209385,791803,279964,95942,719218
+650727,61609,208969,582986,543527,366235,609514,548403,213588,259524,310826,8129,531529,403845,384002,211660,597794,391560,298193,720587,284150,567813,627512,273311,301692,454532,441068,115204,30755,384465,93602,180091,138266,259703,475602,77434,652051,354780,81272,82357,214594,807678,276664,95638,763433
+653132,61652,213912,596950,547562,364390,607990,550507,219809,262219,311397,8132,536210,401233,390895,210942,615967,398362,313766,751557,284311,568909,625917,275917,296352,465825,423992,114783,30863,385486,92219,200462,137513,257159,490679,80576,687778,349441,85880,83941,211872,805930,275298,96352,717581
+643874,61465,213504,595000,542322,372523,612980,544918,221567,263301,313147,8098,541259,407336,384875,215479,607118,398031,314600,747939,284463,564533,634814,279787,297745,466095,449311,114879,31093,395670,89424,181373,146279,257538,496701,79452,707250,361543,84425,82026,216667,811295,271379,97342,741754
+640969,61432,214654,602115,536368,369224,607356,542018,221272,258775,316591,8126,549839,414211,388406,219018,620915,397397,314085,749606,278471,571830,634569,276634,301329,515472,398055,117979,31751,402434,90990,200749,146405,256020,495194,79318,714355,352639,84367,82340,220545,821050,275688,94919,748760
+652235,62224,222748,616726,516017,335666,574572,550675,222865,252032,310443,8139,530501,390867,393389,223831,610246,400438,315180,761189,267547,532573,627194,252843,285015,495301,363344,115259,30799,356830,87345,195055,117333,256896,506836,81458,688647,329807,78650,64580,211028,785989,276846,98698,747537
+644153,62294,216372,614997,514958,362983,592656,544186,224934,263376,301240,8378,530926,399745,390552,224215,634865,400896,310859,764849,269915,563223,631495,266938,284890,452408,386725,115674,30519,380438,92592,199632,140673,250140,486270,78391,656851,335997,78832,73451,212104,791775,274379,102435,741265
+653412,62675,224541,621720,522892,349023,586272,550788,219052,265384,302753,7990,522187,396560,390425,217732,627860,396807,316699,780090,275499,550583,641415,261281,289541,467091,406040,116784,29498,355934,86952,189287,126004,256161,495994,80028,719611,345696,76532,68414,207235,787636,280223,96645,752325
+649601,62983,217931,612542,532096,362069,603573,549609,223588,267497,306558,8018,537017,406426,391844,222519,640883,400415,313900,768021,277262,571869,642805,271154,293343,492196,412339,121107,30824,380828,97729,194705,138707,258302,492830,79062,660325,362061,81061,76398,213292,797810,279469,99404,771863
+645515,62370,223045,619421,535541,365374,609033,550093,226902,262126,305183,8342,545467,408220,392632,226523,625216,403621,321804,777147,281337,577252,635822,276693,288782,492462,421287,121483,31257,387215,92352,203662,133878,258403,491731,80774,708112,353777,84321,79955,216517,804472,274902,97485,754259
+644847,62607,224104,616144,534907,375306,611642,549702,236344,266667,270815,8364,556062,413234,387417,224673,605869,402322,323806,769093,282257,580269,636302,277008,294316,481689,477912,118531,31835,387642,91009,200805,146772,240210,495578,78941,727003,355972,86605,80659,219604,817937,271855,99677,751779
+641159,62120,224449,612685,533355,364195,603563,549774,228844,266417,235632,8294,566282,420403,392009,221157,621664,400664,320593,765430,282415,574410,629365,274364,301519,492567,467543,121538,32172,400364,93573,190670,136436,221965,501316,79301,726553,359432,84494,82467,225163,832620,276430,99064,776187
+644505,62153,228486,625487,532154,369789,607571,548593,231427,265092,244957,8467,562413,420903,380925,220332,622450,395107,323743,781597,280227,577460,636418,278722,314037,499355,448952,122577,31973,404288,94912,188366,149129,229428,519780,81038,725975,383277,83822,83184,222967,822232,267557,98505,747317
+646778,56247,212803,603814,535614,359314,596655,547902,226084,260992,300676,8209,564564,423109,395213,222791,618224,351716,307624,760199,279319,565358,632462,276966,294454,480455,412476,126506,31071,360770,90414,182199,126352,261070,422735,75529,653852,378100,76426,68284,223450,830723,276717,98838,762815
+654589,60014,221026,616935,540100,359383,591554,557020,227966,262395,288903,8258,547400,416133,397640,226031,621280,389348,319374,779888,285896,565273,627485,274255,301717,451837,386143,123531,30387,365012,89721,184635,132087,254872,449539,76607,690686,378198,77847,71023,216947,813546,277139,98822,742161
+653990,60961,219881,603633,541356,363332,614688,554948,224263,265831,280952,8051,559103,419938,398826,224771,621065,401021,317933,763006,285643,577304,637163,279945,309884,471921,413287,126016,30965,395457,92981,212650,141457,254265,469572,76424,646352,390293,80723,82377,220548,824589,279741,100301,748733
+656602,61789,224553,616540,539930,367156,612329,558426,227376,270241,250112,8485,562077,421632,399917,226809,623454,406987,326251,774168,287110,579644,647588,281161,304945,509235,447621,126842,31711,401039,93540,200383,148564,234222,472521,80624,704907,372439,83533,81388,220990,819488,278054,102843,747451
+660183,62903,225236,613523,545596,358059,616690,555899,231378,271806,222432,8282,566741,421557,398455,224409,603189,412639,329572,777485,288933,593328,637849,279934,296985,494745,449316,126030,31836,401506,93187,205320,149309,218262,478851,80965,712487,369253,85628,82986,223330,826183,278745,99787,770930
+653681,62592,226042,615689,544974,369342,614412,550847,229733,260392,204764,8356,571345,427872,394372,230151,611032,411500,331237,774165,286218,578955,619834,281383,301421,491156,499171,126626,31914,407267,90794,213771,151880,207038,488251,81340,720832,374918,84282,84140,225995,840567,278054,98945,755544
+651489,63005,230219,633947,540874,366684,621350,534583,226138,259381,239356,8433,568212,424433,390124,220447,615641,397174,318344,770051,287866,592005,626888,283142,311185,508133,458202,127478,31678,407720,94414,213795,151081,235226,492667,83108,719638,381711,86570,85667,225852,837500,286119,102351,774917
+658761,64017,228482,633836,544613,361155,603156,498508,185804,220971,287547,8278,471007,369293,352785,173645,513750,358659,259282,642200,266738,468234,621920,240867,311642,497631,406283,126435,31402,406553,94903,195206,140567,261179,503386,79530,682159,380848,74941,72364,223601,841527,292114,100898,802684
+654207,63070,231538,638260,544210,362496,596288,521197,197165,233683,285739,8271,496483,388518,371032,196333,575237,371053,286049,690159,263057,498297,623681,252946,297915,443636,394675,127399,30498,373201,93488,199653,133672,262319,496042,79370,698902,389155,78857,73486,224114,832686,287919,102737,771687
+655915,63173,224350,611872,551438,371898,622775,531722,199093,243056,282751,8096,519766,404641,381829,204220,586043,377852,286892,692801,273691,534044,628008,267700,308319,460522,425541,130591,31606,397253,94145,217309,147849,260164,489018,75994,651286,400599,83602,83424,226376,839901,285384,101123,775076
+658237,62254,226997,626751,551700,371174,622103,541244,203542,245135,242348,8633,536443,410168,385872,205734,589721,387999,298938,719587,276669,534546,642826,269408,299722,469574,418068,130785,32357,402161,97890,202912,147577,236432,498005,80982,708541,387601,84182,84205,227603,845203,284834,100989,776392
+656538,62334,225912,617311,544635,374320,628712,548178,211214,250190,211330,8445,537554,406753,387676,209313,588669,390050,305987,728964,278845,536162,653014,270497,294767,524442,469335,128798,32455,404760,92016,205619,148812,217154,495510,81599,724169,379251,85261,83462,225789,836197,280478,99368,754052
+659994,62184,225048,612902,550484,371274,626134,549762,212695,253997,181657,8533,544379,412943,384073,210839,602206,393346,306956,735679,279595,555332,644846,272138,297344,512393,442084,131038,32249,407153,88761,197024,150019,206771,494751,80268,730477,380178,81209,83520,227273,841182,280620,100223,776316
+658521,62332,222922,619769,552319,376177,624322,548395,213017,257451,165990,8644,550243,417282,389591,210228,598671,393856,309601,730660,279938,559235,651023,274900,298120,483944,455024,130809,32708,406638,86894,203278,165198,197506,492470,81341,739630,378760,85867,86313,227308,836324,278885,100713,757517
+661899,62233,232061,629267,546001,372175,625459,549078,217779,261120,201474,8528,545264,417962,391539,219603,618246,396496,318550,749292,282361,559301,644745,277757,298744,481154,441486,130667,31954,406489,91958,208940,148485,212412,506813,83335,741840,385871,84604,85123,225526,841250,281346,105632,777754
+667735,63076,233457,645608,548301,362895,602789,552706,215300,260644,341235,8419,542564,415410,394060,216699,628626,394089,315936,760834,287566,554415,655681,274328,300318,506447,409102,133812,30953,368762,91449,199166,124385,247546,495607,83942,732621,370414,81010,72682,224458,837032,288014,101478,780995
+656199,63792,229870,636104,546017,368168,617759,547112,218604,265950,340736,8421,554345,422042,398957,217417,635966,396703,306937,748848,283902,567543,655189,279328,301966,493453,456033,134781,31856,398577,93890,191608,144390,243336,493466,76268,657942,403064,83595,83767,226499,845604,284790,104160,797442
+651991,62261,230621,619697,546070,376365,620699,550637,217649,267201,309407,8315,567238,425825,395941,228246,627087,400497,318018,764750,283211,584521,648043,281921,298591,478087,429649,137040,32317,403188,94760,233066,139779,235271,499042,80757,701828,397974,86264,84368,229023,849092,280423,103102,767937
+648339,61559,231478,624537,542492,367577,623745,547886,217862,270160,266050,8300,562121,425715,390922,226361,646071,402882,322670,775554,283120,579335,656293,282344,301114,501166,465807,134945,32432,408618,91217,216498,147607,216890,503959,83768,726089,383693,84763,85268,226872,840383,277381,101010,776170
+647759,61378,230459,628197,539002,372169,605082,548772,226608,265374,337404,8542,564646,422528,395140,229133,639281,404462,325285,781049,288256,571730,645965,285378,302016,475781,463777,135846,32225,404676,92343,218574,156997,237082,506849,83278,734278,380127,89419,84516,226250,845284,273694,100279,768470
+641488,60647,228221,622268,533852,364632,618468,545012,225244,271177,329792,8419,563567,425054,385927,227965,643220,396762,323761,775295,284511,581502,653832,283625,302823,464657,445934,137114,32510,408143,89226,219629,156722,229061,501006,83342,741135,383641,87403,85537,226290,841691,269914,97689,757338
diff --git a/examples/data/seasonality.csv b/examples/data/seasonality.csv
new file mode 100644
index 0000000..fcd1d51
--- /dev/null
+++ b/examples/data/seasonality.csv
@@ -0,0 +1,722 @@
+Date,Visite
+11/20/13,32
+11/21/13,27
+11/22/13,30
+11/23/13,25
+11/24/13,14
+11/25/13,41
+11/26/13,32
+11/27/13,48
+11/28/13,22
+11/29/13,26
+11/30/13,23
+12/1/13,27
+12/2/13,40
+12/3/13,42
+12/4/13,46
+12/5/13,49
+12/6/13,26
+12/7/13,15
+12/8/13,20
+12/9/13,33
+12/10/13,32
+12/11/13,46
+12/12/13,32
+12/13/13,38
+12/14/13,27
+12/15/13,31
+12/16/13,65
+12/17/13,33
+12/18/13,42
+12/19/13,46
+12/20/13,37
+12/21/13,20
+12/22/13,23
+12/23/13,37
+12/24/13,30
+12/25/13,16
+12/26/13,33
+12/27/13,28
+12/28/13,37
+12/29/13,18
+12/30/13,38
+12/31/13,32
+1/1/14,16
+1/2/14,31
+1/3/14,34
+1/4/14,25
+1/5/14,27
+1/6/14,47
+1/7/14,48
+1/8/14,43
+1/9/14,44
+1/10/14,46
+1/11/14,25
+1/12/14,31
+1/13/14,40
+1/14/14,45
+1/15/14,46
+1/16/14,48
+1/17/14,33
+1/18/14,29
+1/19/14,26
+1/20/14,43
+1/21/14,71
+1/22/14,43
+1/23/14,51
+1/24/14,34
+1/25/14,25
+1/26/14,30
+1/27/14,47
+1/28/14,49
+1/29/14,49
+1/30/14,48
+1/31/14,40
+2/1/14,36
+2/2/14,33
+2/3/14,45
+2/4/14,53
+2/5/14,48
+2/6/14,30
+2/7/14,34
+2/8/14,20
+2/9/14,18
+2/10/14,37
+2/11/14,47
+2/12/14,35
+2/13/14,52
+2/14/14,50
+2/15/14,27
+2/16/14,27
+2/17/14,55
+2/18/14,58
+2/19/14,51
+2/20/14,51
+2/21/14,52
+2/22/14,37
+2/23/14,36
+2/24/14,44
+2/25/14,51
+2/26/14,55
+2/27/14,48
+2/28/14,54
+3/1/14,35
+3/2/14,37
+3/3/14,60
+3/4/14,54
+3/5/14,57
+3/6/14,40
+3/7/14,35
+3/8/14,22
+3/9/14,34
+3/10/14,50
+3/11/14,64
+3/12/14,45
+3/13/14,50
+3/14/14,59
+3/15/14,29
+3/16/14,23
+3/17/14,60
+3/18/14,56
+3/19/14,58
+3/20/14,53
+3/21/14,70
+3/22/14,37
+3/23/14,28
+3/24/14,61
+3/25/14,74
+3/26/14,36
+3/27/14,51
+3/28/14,52
+3/29/14,30
+3/30/14,31
+3/31/14,59
+4/1/14,73
+4/2/14,64
+4/3/14,82
+4/4/14,63
+4/5/14,37
+4/6/14,53
+4/7/14,89
+4/8/14,89
+4/9/14,84
+4/10/14,96
+4/11/14,71
+4/12/14,55
+4/13/14,63
+4/14/14,106
+4/15/14,76
+4/16/14,102
+4/17/14,113
+4/18/14,59
+4/19/14,49
+4/20/14,50
+4/21/14,71
+4/22/14,96
+4/23/14,99
+4/24/14,100
+4/25/14,71
+4/26/14,58
+4/27/14,46
+4/28/14,83
+4/29/14,66
+4/30/14,83
+5/1/14,61
+5/2/14,67
+5/3/14,58
+5/4/14,46
+5/5/14,83
+5/6/14,76
+5/7/14,83
+5/8/14,67
+5/9/14,74
+5/10/14,49
+5/11/14,48
+5/12/14,74
+5/13/14,89
+5/14/14,86
+5/15/14,65
+5/16/14,78
+5/17/14,49
+5/18/14,61
+5/19/14,81
+5/20/14,98
+5/21/14,93
+5/22/14,76
+5/23/14,65
+5/24/14,46
+5/25/14,37
+5/26/14,89
+5/27/14,105
+5/28/14,87
+5/29/14,77
+5/30/14,61
+5/31/14,47
+6/1/14,48
+6/2/14,81
+6/3/14,75
+6/4/14,91
+6/5/14,91
+6/6/14,77
+6/7/14,48
+6/8/14,29
+6/9/14,85
+6/10/14,102
+6/11/14,95
+6/12/14,94
+6/13/14,78
+6/14/14,46
+6/15/14,58
+6/16/14,88
+6/17/14,107
+6/18/14,114
+6/19/14,71
+6/20/14,82
+6/21/14,49
+6/22/14,45
+6/23/14,92
+6/24/14,99
+6/25/14,79
+6/26/14,76
+6/27/14,86
+6/28/14,49
+6/29/14,44
+6/30/14,77
+7/1/14,94
+7/2/14,100
+7/3/14,91
+7/4/14,70
+7/5/14,51
+7/6/14,37
+7/7/14,88
+7/8/14,90
+7/9/14,105
+7/10/14,89
+7/11/14,76
+7/12/14,48
+7/13/14,42
+7/14/14,91
+7/15/14,101
+7/16/14,101
+7/17/14,75
+7/18/14,93
+7/19/14,49
+7/20/14,36
+7/21/14,92
+7/22/14,75
+7/23/14,122
+7/24/14,85
+7/25/14,86
+7/26/14,61
+7/27/14,45
+7/28/14,90
+7/29/14,101
+7/30/14,86
+7/31/14,77
+8/1/14,94
+8/2/14,45
+8/3/14,45
+8/4/14,70
+8/5/14,105
+8/6/14,103
+8/7/14,105
+8/8/14,63
+8/9/14,26
+8/10/14,48
+8/11/14,86
+8/12/14,80
+8/13/14,86
+8/14/14,73
+8/15/14,71
+8/16/14,42
+8/17/14,58
+8/18/14,92
+8/19/14,86
+8/20/14,90
+8/21/14,81
+8/22/14,76
+8/23/14,74
+8/24/14,50
+8/25/14,77
+8/26/14,83
+8/27/14,79
+8/28/14,76
+8/29/14,57
+8/30/14,32
+8/31/14,46
+9/1/14,61
+9/2/14,72
+9/3/14,91
+9/4/14,79
+9/5/14,63
+9/6/14,38
+9/7/14,36
+9/8/14,74
+9/9/14,85
+9/10/14,64
+9/11/14,86
+9/12/14,75
+9/13/14,43
+9/14/14,43
+9/15/14,73
+9/16/14,84
+9/17/14,84
+9/18/14,71
+9/19/14,68
+9/20/14,39
+9/21/14,33
+9/22/14,74
+9/23/14,76
+9/24/14,73
+9/25/14,77
+9/26/14,70
+9/27/14,46
+9/28/14,44
+9/29/14,80
+9/30/14,81
+10/1/14,64
+10/2/14,62
+10/3/14,63
+10/4/14,38
+10/5/14,40
+10/6/14,80
+10/7/14,80
+10/8/14,73
+10/9/14,78
+10/10/14,67
+10/11/14,35
+10/12/14,51
+10/13/14,68
+10/14/14,67
+10/15/14,71
+10/16/14,63
+10/17/14,54
+10/18/14,54
+10/19/14,46
+10/20/14,90
+10/21/14,84
+10/22/14,61
+10/23/14,69
+10/24/14,48
+10/25/14,35
+10/26/14,47
+10/27/14,56
+10/28/14,82
+10/29/14,75
+10/30/14,64
+10/31/14,66
+11/1/14,43
+11/2/14,43
+11/3/14,84
+11/4/14,72
+11/5/14,80
+11/6/14,71
+11/7/14,61
+11/8/14,39
+11/9/14,54
+11/10/14,80
+11/11/14,73
+11/12/14,90
+11/13/14,69
+11/14/14,59
+11/15/14,44
+11/16/14,53
+11/17/14,84
+11/18/14,100
+11/19/14,94
+11/20/14,87
+11/21/14,86
+11/22/14,60
+11/23/14,54
+11/24/14,97
+11/25/14,86
+11/26/14,85
+11/27/14,78
+11/28/14,52
+11/29/14,67
+11/30/14,41
+12/1/14,75
+12/2/14,79
+12/3/14,68
+12/4/14,80
+12/5/14,75
+12/6/14,49
+12/7/14,42
+12/8/14,95
+12/9/14,67
+12/10/14,76
+12/11/14,103
+12/12/14,83
+12/13/14,50
+12/14/14,38
+12/15/14,82
+12/16/14,68
+12/17/14,76
+12/18/14,71
+12/19/14,52
+12/20/14,27
+12/21/14,36
+12/22/14,53
+12/23/14,53
+12/24/14,48
+12/25/14,35
+12/26/14,40
+12/27/14,28
+12/28/14,32
+12/29/14,60
+12/30/14,56
+12/31/14,49
+1/1/15,32
+1/2/15,61
+1/3/15,43
+1/4/15,45
+1/5/15,73
+1/6/15,59
+1/7/15,65
+1/8/15,76
+1/9/15,60
+1/10/15,42
+1/11/15,32
+1/12/15,64
+1/13/15,64
+1/14/15,63
+1/15/15,87
+1/16/15,75
+1/17/15,45
+1/18/15,49
+1/19/15,84
+1/20/15,99
+1/21/15,69
+1/22/15,72
+1/23/15,70
+1/24/15,45
+1/25/15,53
+1/26/15,81
+1/27/15,79
+1/28/15,94
+1/29/15,78
+1/30/15,85
+1/31/15,42
+2/1/15,40
+2/2/15,71
+2/3/15,77
+2/4/15,69
+2/5/15,60
+2/6/15,61
+2/7/15,45
+2/8/15,36
+2/9/15,57
+2/10/15,85
+2/11/15,84
+2/12/15,79
+2/13/15,55
+2/14/15,36
+2/15/15,42
+2/16/15,105
+2/17/15,56
+2/18/15,82
+2/19/15,68
+2/20/15,81
+2/21/15,36
+2/22/15,52
+2/23/15,88
+2/24/15,98
+2/25/15,91
+2/26/15,86
+2/27/15,76
+2/28/15,54
+3/1/15,39
+3/2/15,79
+3/3/15,75
+3/4/15,83
+3/5/15,76
+3/6/15,73
+3/7/15,35
+3/8/15,52
+3/9/15,58
+3/10/15,77
+3/11/15,82
+3/12/15,82
+3/13/15,62
+3/14/15,41
+3/15/15,48
+3/16/15,65
+3/17/15,80
+3/18/15,77
+3/19/15,87
+3/20/15,71
+3/21/15,38
+3/22/15,35
+3/23/15,79
+3/24/15,87
+3/25/15,89
+3/26/15,87
+3/27/15,57
+3/28/15,42
+3/29/15,40
+3/30/15,71
+3/31/15,82
+4/1/15,83
+4/2/15,82
+4/3/15,65
+4/4/15,49
+4/5/15,59
+4/6/15,74
+4/7/15,74
+4/8/15,84
+4/9/15,79
+4/10/15,72
+4/11/15,48
+4/12/15,36
+4/13/15,81
+4/14/15,98
+4/15/15,79
+4/16/15,71
+4/17/15,79
+4/18/15,47
+4/19/15,50
+4/20/15,81
+4/21/15,88
+4/22/15,96
+4/23/15,80
+4/24/15,88
+4/25/15,32
+4/26/15,46
+4/27/15,82
+4/28/15,101
+4/29/15,80
+4/30/15,69
+5/1/15,41
+5/2/15,40
+5/3/15,48
+5/4/15,90
+5/5/15,104
+5/6/15,91
+5/7/15,114
+5/8/15,110
+5/9/15,66
+5/10/15,59
+5/11/15,100
+5/12/15,100
+5/13/15,96
+5/14/15,92
+5/15/15,99
+5/16/15,53
+5/17/15,62
+5/18/15,66
+5/19/15,119
+5/20/15,107
+5/21/15,93
+5/22/15,102
+5/23/15,46
+5/24/15,49
+5/25/15,99
+5/26/15,117
+5/27/15,110
+5/28/15,107
+5/29/15,100
+5/30/15,42
+5/31/15,42
+6/1/15,107
+6/2/15,101
+6/3/15,109
+6/4/15,102
+6/5/15,125
+6/6/15,61
+6/7/15,52
+6/8/15,97
+6/9/15,108
+6/10/15,96
+6/11/15,100
+6/12/15,96
+6/13/15,46
+6/14/15,47
+6/15/15,80
+6/16/15,96
+6/17/15,115
+6/18/15,121
+6/19/15,114
+6/20/15,44
+6/21/15,43
+6/22/15,111
+6/23/15,92
+6/24/15,102
+6/25/15,99
+6/26/15,93
+6/27/15,42
+6/28/15,48
+6/29/15,91
+6/30/15,127
+7/1/15,96
+7/2/15,109
+7/3/15,81
+7/4/15,37
+7/5/15,44
+7/6/15,113
+7/7/15,127
+7/8/15,140
+7/9/15,127
+7/10/15,97
+7/11/15,44
+7/12/15,36
+7/13/15,84
+7/14/15,92
+7/15/15,90
+7/16/15,110
+7/17/15,88
+7/18/15,44
+7/19/15,44
+7/20/15,93
+7/21/15,100
+7/22/15,96
+7/23/15,101
+7/24/15,82
+7/25/15,51
+7/26/15,42
+7/27/15,107
+7/28/15,99
+7/29/15,79
+7/30/15,117
+7/31/15,103
+8/1/15,46
+8/2/15,36
+8/3/15,104
+8/4/15,120
+8/5/15,101
+8/6/15,97
+8/7/15,82
+8/8/15,43
+8/9/15,47
+8/10/15,95
+8/11/15,137
+8/12/15,134
+8/13/15,106
+8/14/15,84
+8/15/15,52
+8/16/15,50
+8/17/15,106
+8/18/15,132
+8/19/15,98
+8/20/15,97
+8/21/15,109
+8/22/15,64
+8/23/15,44
+8/24/15,103
+8/25/15,113
+8/26/15,111
+8/27/15,107
+8/28/15,95
+8/29/15,50
+8/30/15,53
+8/31/15,124
+9/1/15,136
+9/2/15,136
+9/3/15,144
+9/4/15,97
+9/5/15,59
+9/6/15,62
+9/7/15,100
+9/8/15,132
+9/9/15,123
+9/10/15,103
+9/11/15,86
+9/12/15,46
+9/13/15,48
+9/14/15,102
+9/15/15,132
+9/16/15,112
+9/17/15,125
+9/18/15,111
+9/19/15,51
+9/20/15,59
+9/21/15,116
+9/22/15,118
+9/23/15,146
+9/24/15,127
+9/25/15,109
+9/26/15,55
+9/27/15,40
+9/28/15,89
+9/29/15,99
+9/30/15,107
+10/1/15,105
+10/2/15,74
+10/3/15,39
+10/4/15,33
+10/5/15,113
+10/6/15,114
+10/7/15,102
+10/8/15,116
+10/9/15,105
+10/10/15,60
+10/11/15,70
+10/12/15,119
+10/13/15,120
+10/14/15,126
+10/15/15,138
+10/16/15,115
+10/17/15,84
+10/18/15,66
+10/19/15,132
+10/20/15,148
+10/21/15,114
+10/22/15,120
+10/23/15,122
+10/24/15,59
+10/25/15,65
+10/26/15,129
+10/27/15,133
+10/28/15,151
+10/29/15,141
+10/30/15,158
+10/31/15,68
+11/1/15,66
+11/2/15,171
+11/3/15,166
+11/4/15,171
+11/5/15,160
+11/6/15,138
+11/7/15,64
+11/8/15,40
+11/9/15,107
+11/10/15,138
\ No newline at end of file
diff --git a/examples/data/webTraffic.csv b/examples/data/webTraffic.csv
new file mode 100644
index 0000000..a5d8366
--- /dev/null
+++ b/examples/data/webTraffic.csv
@@ -0,0 +1,1 @@
+Date,Visite11/20/13,3211/21/13,2711/22/13,3011/23/13,2511/24/13,1411/25/13,4111/26/13,3211/27/13,4811/28/13,2211/29/13,2611/30/13,2312/1/13,2712/2/13,4012/3/13,4212/4/13,4612/5/13,4912/6/13,2612/7/13,1512/8/13,2012/9/13,3312/10/13,3212/11/13,4612/12/13,3212/13/13,3812/14/13,2712/15/13,3112/16/13,6512/17/13,3312/18/13,4212/19/13,4612/20/13,3712/21/13,2012/22/13,2312/23/13,3712/24/13,3012/25/13,1612/26/13,3312/27/13,2812/28/13,3712/29/13,1812/30/13,3812/31/13,321/1/14,161/2/14,311/3/14,341/4/14,251/5/14,271/6/14,471/7/14,481/8/14,431/9/14,441/10/14,461/11/14,251/12/14,311/13/14,401/14/14,451/15/14,461/16/14,481/17/14,331/18/14,291/19/14,261/20/14,431/21/14,711/22/14,431/23/14,511/24/14,341/25/14,251/26/14,301/27/14,471/28/14,491/29/14,491/30/14,481/31/14,402/1/14,362/2/14,332/3/14,452/4/14,532/5/14,482/6/14,302/7/14,342/8/14,202/9/14,182/10/14,372/11/14,472/12/14,352/13/14,522/14/14,502/15/14,272/16/14,272/17/14,552/18/14,582/19/14,512/20/14,512/21/14,522/22/14,372/23/14,362/24/14,442/25/14,512/26/14,552/27/14,482/28/14,543/1/14,353/2/14,373/3/14,603/4/14,543/5/14,573/6/14,403/7/14,353/8/14,223/9/14,343/10/14,503/11/14,643/12/14,453/13/14,503/14/14,593/15/14,293/16/14,233/17/14,603/18/14,563/19/14,583/20/14,533/21/14,703/22/14,373/23/14,283/24/14,613/25/14,743/26/14,363/27/14,513/28/14,523/29/14,303/30/14,313/31/14,594/1/14,734/2/14,644/3/14,824/4/14,634/5/14,374/6/14,534/7/14,894/8/14,894/9/14,844/10/14,964/11/14,714/12/14,554/13/14,634/14/14,1064/15/14,764/16/14,1024/17/14,1134/18/14,594/19/14,494/20/14,504/21/14,714/22/14,964/23/14,994/24/14,1004/25/14,714/26/14,584/27/14,464/28/14,834/29/14,664/30/14,835/1/14,615/2/14,675/3/14,585/4/14,465/5/14,835/6/14,765/7/14,835/8/14,675/9/14,745/10/14,495/11/14,485/12/14,745/13/14,895/14/14,865/15/14,655/16/14,785/17/14,495/18/14,615/19/14,815/20/14,985/21/14,935/22/14,765/23/14,655/24/14,465/25/14,375/26/14,895/27/14,1055/28/14,875/29/14,775/30/14,615/31/14,476/1/14,486/2/14,816/3/14,756/4/14,916/5/14,916/6/14,776/7/14,486/8/14,296/9/14,856/10/14,1026/11/14,956/12/14,946/13/14,786/14/14,466/15/14,586/16/14,886/17/14,1076/18/14,1146/19/14,716/20/14,826/21/14,496/22/14,456/23/14,926/24/14,996/25/14,796/26/14,766/27/14,866/28/14,496/29/14,446/30/14,777/1/14,947/2/14,1007/3/14,917/4/14,707/5/14,517/6/14,377/7/14,887/8/14,907/9/14,1057/10/14,897/11/14,767/12/14,487/13/14,427/14/14,917/15/14,1017/16/14,1017/17/14,757/18/14,937/19/14,497/20/14,367/21/14,927/22/14,757/23/14,1227/24/14,857/25/14,867/26/14,617/27/14,457/28/14,907/29/14,1017/30/14,867/31/14,778/1/14,948/2/14,458/3/14,458/4/14,708/5/14,1058/6/14,1038/7/14,1058/8/14,638/9/14,268/10/14,488/11/14,868/12/14,808/13/14,868/14/14,738/15/14,718/16/14,428/17/14,588/18/14,928/19/14,868/20/14,908/21/14,818/22/14,768/23/14,748/24/14,508/25/14,778/26/14,838/27/14,798/28/14,768/29/14,578/30/14,328/31/14,469/1/14,619/2/14,729/3/14,919/4/14,799/5/14,639/6/14,389/7/14,369/8/14,749/9/14,859/10/14,649/11/14,869/12/14,759/13/14,439/14/14,439/15/14,739/16/14,849/17/14,849/18/14,719/19/14,689/20/14,399/21/14,339/22/14,749/23/14,769/24/14,739/25/14,779/26/14,709/27/14,469/28/14,449/29/14,809/30/14,8110/1/14,6410/2/14,6210/3/14,6310/4/14,3810/5/14,4010/6/14,8010/7/14,8010/8/14,7310/9/14,7810/10/14,6710/11/14,3510/12/14,5110/13/14,6810/14/14,6710/15/14,7110/16/14,6310/17/14,5410/18/14,5410/19/14,4610/20/14,9010/21/14,8410/22/14,6110/23/14,6910/24/14,4810/25/14,3510/26/14,4710/27/14,5610/28/14,8210/29/14,7510/30/14,6410/31/14,6611/1/14,4311/2/14,4311/3/14,8411/4/14,7211/5/14,8011/6/14,7111/7/14,6111/8/14,3911/9/14,5411/10/14,8011/11/14,7311/12/14,9011/13/14,6911/14/14,5911/15/14,4411/16/14,5311/17/14,8411/18/14,10011/19/14,9411/20/14,8711/21/14,8611/22/14,6011/23/14,5411/24/14,9711/25/14,8611/26/14,8511/27/14,7811/28/14,5211/29/14,6711/30/14,4112/1/14,7512/2/14,7912/3/14,6812/4/14,8012/5/14,7512/6/14,4912/7/14,4212/8/14,9512/9/14,6712/10/14,7612/11/14,10312/12/14,8312/13/14,5012/14/14,3812/15/14,8212/16/14,6812/17/14,7612/18/14,7112/19/14,5212/20/14,2712/21/14,3612/22/14,5312/23/14,5312/24/14,4812/25/14,3512/26/14,4012/27/14,2812/28/14,3212/29/14,6012/30/14,5612/31/14,491/1/15,321/2/15,611/3/15,431/4/15,451/5/15,731/6/15,591/7/15,651/8/15,761/9/15,601/10/15,421/11/15,321/12/15,641/13/15,641/14/15,631/15/15,871/16/15,751/17/15,451/18/15,491/19/15,841/20/15,991/21/15,691/22/15,721/23/15,701/24/15,451/25/15,531/26/15,811/27/15,791/28/15,941/29/15,781/30/15,851/31/15,422/1/15,402/2/15,712/3/15,772/4/15,692/5/15,602/6/15,612/7/15,452/8/15,362/9/15,572/10/15,852/11/15,842/12/15,792/13/15,552/14/15,362/15/15,422/16/15,1052/17/15,562/18/15,822/19/15,682/20/15,812/21/15,362/22/15,522/23/15,882/24/15,982/25/15,912/26/15,862/27/15,762/28/15,543/1/15,393/2/15,793/3/15,753/4/15,833/5/15,763/6/15,733/7/15,353/8/15,523/9/15,583/10/15,773/11/15,823/12/15,823/13/15,623/14/15,413/15/15,483/16/15,653/17/15,803/18/15,773/19/15,873/20/15,713/21/15,383/22/15,353/23/15,793/24/15,873/25/15,893/26/15,873/27/15,573/28/15,423/29/15,403/30/15,713/31/15,824/1/15,834/2/15,824/3/15,654/4/15,494/5/15,594/6/15,744/7/15,744/8/15,844/9/15,794/10/15,724/11/15,484/12/15,364/13/15,814/14/15,984/15/15,794/16/15,714/17/15,794/18/15,474/19/15,504/20/15,814/21/15,884/22/15,964/23/15,804/24/15,884/25/15,324/26/15,464/27/15,824/28/15,1014/29/15,804/30/15,695/1/15,415/2/15,405/3/15,485/4/15,905/5/15,1045/6/15,915/7/15,1145/8/15,1105/9/15,665/10/15,595/11/15,1005/12/15,1005/13/15,965/14/15,925/15/15,995/16/15,535/17/15,625/18/15,665/19/15,1195/20/15,1075/21/15,935/22/15,1025/23/15,465/24/15,495/25/15,995/26/15,1175/27/15,1105/28/15,1075/29/15,1005/30/15,425/31/15,426/1/15,1076/2/15,1016/3/15,1096/4/15,1026/5/15,1256/6/15,616/7/15,526/8/15,976/9/15,1086/10/15,966/11/15,1006/12/15,966/13/15,466/14/15,476/15/15,806/16/15,966/17/15,1156/18/15,1216/19/15,1146/20/15,446/21/15,436/22/15,1116/23/15,926/24/15,1026/25/15,996/26/15,936/27/15,426/28/15,486/29/15,916/30/15,1277/1/15,967/2/15,1097/3/15,817/4/15,377/5/15,447/6/15,1137/7/15,1277/8/15,1407/9/15,1277/10/15,977/11/15,447/12/15,367/13/15,847/14/15,927/15/15,907/16/15,1107/17/15,887/18/15,447/19/15,447/20/15,937/21/15,1007/22/15,967/23/15,1017/24/15,827/25/15,517/26/15,427/27/15,1077/28/15,997/29/15,797/30/15,1177/31/15,1038/1/15,468/2/15,368/3/15,1048/4/15,1208/5/15,1018/6/15,978/7/15,828/8/15,438/9/15,478/10/15,958/11/15,1378/12/15,1348/13/15,1068/14/15,848/15/15,528/16/15,508/17/15,1068/18/15,1328/19/15,988/20/15,978/21/15,1098/22/15,648/23/15,448/24/15,1038/25/15,1138/26/15,1118/27/15,1078/28/15,958/29/15,508/30/15,538/31/15,1249/1/15,1369/2/15,1369/3/15,1449/4/15,979/5/15,599/6/15,629/7/15,1009/8/15,1329/9/15,1239/10/15,1039/11/15,869/12/15,469/13/15,489/14/15,1029/15/15,1329/16/15,1129/17/15,1259/18/15,1119/19/15,519/20/15,599/21/15,1169/22/15,1189/23/15,1469/24/15,1279/25/15,1099/26/15,559/27/15,409/28/15,899/29/15,999/30/15,10710/1/15,10510/2/15,7410/3/15,3910/4/15,3310/5/15,11310/6/15,11410/7/15,10210/8/15,11610/9/15,10510/10/15,6010/11/15,7010/12/15,11910/13/15,12010/14/15,12610/15/15,13810/16/15,11510/17/15,8410/18/15,6610/19/15,13210/20/15,14810/21/15,11410/22/15,12010/23/15,12210/24/15,5910/25/15,6510/26/15,12910/27/15,13310/28/15,15110/29/15,14110/30/15,15810/31/15,6811/1/15,6611/2/15,17111/3/15,16611/4/15,17111/5/15,16011/6/15,13811/7/15,6411/8/15,4011/9/15,10711/10/15,138
\ No newline at end of file
diff --git a/examples/decomposition_add.py b/examples/decomposition_add.py
new file mode 100644
index 0000000..962bab2
--- /dev/null
+++ b/examples/decomposition_add.py
@@ -0,0 +1,37 @@
+import pandas as pd
+import matplotlib.pyplot as plt
+
+from mathbox.app.signal.filter import moving_median, f_lowpass_filter
+
+
+if __name__ == '__main__':
+    src_data = pd.read_csv('./data/webTraffic.csv')
+
+    timeseries = src_data['Visite']
+
+    med_filtered = moving_median(timeseries, window=7)
+    #ave_filtered = moving_average(timeseries, window=5)
+
+    moved_trend = [x - y for x, y in zip(timeseries, med_filtered)]
+
+    f, seasonality = f_lowpass_filter(moved_trend, 86400, n=3, f_min=0.015/86400)
+
+    moved_seasonality = [x - y for x, y in zip(moved_trend, seasonality)]
+
+    fig, axs = plt.subplots(4, 1)
+    axs[0].plot(timeseries, 'b')
+    axs[0].set_title('Original')
+    fig.suptitle('Decomposition of Web traffic data', fontsize=16)
+
+    axs[1].plot(med_filtered, 'g')
+    axs[1].set_title('Trend')
+
+    axs[2].plot(seasonality, 'cyan')
+    axs[2].set_title('Seasonality')
+
+    axs[3].plot(moved_seasonality, 'r')
+    axs[3].set_title('Noise')
+
+    plt.show()
+
+    print("Frequency: ", f)
\ No newline at end of file
diff --git a/examples/decomposition_mul.py b/examples/decomposition_mul.py
new file mode 100644
index 0000000..e0af375
--- /dev/null
+++ b/examples/decomposition_mul.py
@@ -0,0 +1,37 @@
+import pandas as pd
+import matplotlib.pyplot as plt
+
+from mathbox.app.signal.filter import moving_median, f_lowpass_filter
+
+
+if __name__ == '__main__':
+    src_data = pd.read_csv('./data/webTraffic.csv')
+
+    timeseries = src_data['Visite']
+
+    med_filtered = moving_median(timeseries, window=7)
+    #ave_filtered = moving_average(timeseries, window=5)
+
+    moved_trend = [x / y for x, y in zip(timeseries, med_filtered)]
+
+    f, seasonality = f_lowpass_filter(moved_trend, 86400, n=3, f_min=0.015/86400)
+
+    moved_seasonality = [x / y for x, y in zip(moved_trend, seasonality)]
+
+    fig, axs = plt.subplots(4, 1)
+    axs[0].plot(timeseries, 'b')
+    axs[0].set_title('Original')
+    fig.suptitle('Decomposition of Web traffic data', fontsize=16)
+
+    axs[1].plot(med_filtered, 'g')
+    axs[1].set_title('Trend')
+
+    axs[2].plot(seasonality, 'cyan')
+    axs[2].set_title('Seasonality')
+
+    axs[3].plot(moved_seasonality, 'r')
+    axs[3].set_title('Noise')
+
+    plt.show()
+
+    print("Frequency: ", f)
\ No newline at end of file
diff --git a/examples/outlier_decomposition.py b/examples/outlier_decomposition.py
new file mode 100644
index 0000000..add410c
--- /dev/null
+++ b/examples/outlier_decomposition.py
@@ -0,0 +1,40 @@
+import pandas as pd
+import matplotlib.pyplot as plt
+
+from mathbox.app.signal.filter import moving_median, f_lowpass_filter
+from mathbox.app.signal.outlier import noise_outlier
+
+if __name__ == '__main__':
+    src_data = pd.read_csv('./data/webTraffic.csv')
+
+    timeseries = src_data['Visite']
+
+    med_filtered = moving_median(timeseries, window=7)
+    #ave_filtered = moving_average(timeseries, window=5)
+
+    moved_trend = [x / y for x, y in zip(timeseries, med_filtered)]
+
+    f, seasonality = f_lowpass_filter(moved_trend, 86400, n=3, f_min=0.015/86400)
+
+    moved_seasonality = [x / y for x, y in zip(moved_trend, seasonality)]
+
+    outlier = noise_outlier(moved_seasonality, 6)
+
+    fig, axs = plt.subplots(4, 1)
+    axs[0].plot(timeseries, 'b')
+    axs[0].set_title('Original')
+    fig.suptitle('Decomposition of Web traffic data', fontsize=16)
+
+    axs[1].plot(med_filtered, 'g')
+    axs[1].set_title('Trend')
+
+    axs[2].plot(seasonality, 'cyan')
+    axs[2].set_title('Seasonality')
+
+    axs[3].plot(moved_seasonality, 'r')
+    axs[3].plot([x[0] for x in outlier],[x[1] for x in outlier], 'bo')
+    axs[3].set_title('Noise')
+
+    plt.show()
+
+    print("Frequency: ", f)
\ No newline at end of file
diff --git a/examples/requirements.txt b/examples/requirements.txt
new file mode 100644
index 0000000..cd45ca8
--- /dev/null
+++ b/examples/requirements.txt
@@ -0,0 +1,2 @@
+pandas>=1.3.5
+matplotlib>=3.5.1
\ No newline at end of file
diff --git a/mathbox/__init__.py b/mathbox/__init__.py
index e69de29..28ca354 100644
--- a/mathbox/__init__.py
+++ b/mathbox/__init__.py
@@ -0,0 +1,3 @@
+"""
+mathbox
+"""
diff --git a/mathbox/app/__init__.py b/mathbox/app/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/app/signal/__init__.py b/mathbox/app/signal/__init__.py
new file mode 100644
index 0000000..7458fcc
--- /dev/null
+++ b/mathbox/app/signal/__init__.py
@@ -0,0 +1,3 @@
+"""
+Signal processing module
+"""
\ No newline at end of file
diff --git a/mathbox/app/signal/change_point.py b/mathbox/app/signal/change_point.py
new file mode 100644
index 0000000..658e6f1
--- /dev/null
+++ b/mathbox/app/signal/change_point.py
@@ -0,0 +1,58 @@
+from mathbox.statistics.estimator import energy_distance
+from mathbox.statistics.hypothesis_testing import permutation_test
+from mathbox.optimizer.utils import argmax
+from mathbox.utils import pairwise
+
+def t_stats(a, b):
+    e_distance = energy_distance(a,b)
+    return e_distance * len(a) * len(b) / (len(a) + len(b))
+
+def _calculate_t_stats(series, pvalue, permutations):
+    t_value = []
+    #t_value = [0] # magic
+    for i in range(len(series)-1):
+        a = series[:i+1]
+        b = series[i+1:]
+        t = t_stats(a,b)
+        t_value.append(t)
+    idx = int(argmax(t_value))
+    a = series[:idx+1]
+    b = series[idx+1:]
+    if permutation_test(a, b, t_stats, pvalue, permutations):
+        return (idx, t_value[idx])
+    else:
+        return None
+
+def _get_next_significant_change_point(series, change_points, memo, pvalue: float, permutations: int):
+    windows = [0] + sorted(change_points) + [len(series)]
+    candidates = []
+    for bounds in pairwise(windows):
+        if bounds in memo:
+            candidates.append(memo[bounds])
+        else:
+            a, b = bounds
+            candidate = _calculate_t_stats(series[a:b], pvalue, permutations)
+            if candidate is not None:
+                #idx = int(argmax(stats))    # 9,8,7 #idx = int(np.argmax(stats)) # 9,0,0
+                new = (candidate[0] + a, candidate[1]) # [a,b)里最大的t和它的位置
+                memo[bounds] = new
+                return new
+            else:
+                None
+
+def e_divisive(series, jump = 5, pvalue: float = 0.05, permutations: int = 100):
+    if jump != int(jump) or jump < 1:
+        raise ValueError("jump must be a positive integer")
+    change_points = []
+    memo = {}
+    while significant_change_point := _get_next_significant_change_point(
+        series, change_points, memo, pvalue, permutations
+    ):
+        if significant_change_point is not None:
+            if change_points == []:
+                change_points.append(significant_change_point[0])
+            else:
+                result = sorted([abs(significant_change_point[0] - x) for x in change_points])
+                if result[0] > jump and significant_change_point[0] > jump and significant_change_point[0] < len(series) - jump:
+                    change_points.append(significant_change_point[0])
+    return change_points
diff --git a/mathbox/app/signal/correlation.py b/mathbox/app/signal/correlation.py
new file mode 100644
index 0000000..b5b61a3
--- /dev/null
+++ b/mathbox/app/signal/correlation.py
@@ -0,0 +1,9 @@
+from mathbox.statistics.estimator import ncc
+
+
+def max_corr(obj, set, num):
+    ccfs = []
+    for i in range(len(set)):
+        ccfs.append((set[i][0],ncc(obj[1], set[i][1])))
+    sorted_res = sorted(ccfs, key=lambda d: d[1], reverse=True)
+    return sorted_res[1 : num + 1]
\ No newline at end of file
diff --git a/mathbox/app/signal/filter.py b/mathbox/app/signal/filter.py
new file mode 100644
index 0000000..83a64d4
--- /dev/null
+++ b/mathbox/app/signal/filter.py
@@ -0,0 +1,67 @@
+from mathbox.statistics.estimator import median
+from mathbox.app.signal.transform import dftfreq, rdft, irdft
+from mathbox.optimizer.utils import local_minmax
+
+def moving_average(signal, window=3) :
+    sum = 0
+    result = [0 for _ in signal]
+    for i in range(window):
+        sum += signal[i]
+        result[i] = sum / (i + 1)
+    for i in range(window, len(signal)):
+        sum += signal[i] - signal[i - window]
+        result[i] = sum / window
+    return result
+
+def moving_median(signal, window=3):
+    result = []
+    for i in range(len(signal)):
+        if i < window:
+            result.append(median(signal[:i + 1]))
+        else:
+            result.append(median(signal[i - window + 1:i + 1]))
+    return result
+
+# fourier lowpass filter
+# inputs:
+#   timeseries: 1D timeseries signal
+#   dt: sample period
+#   n: number of the maximum amplitude
+#   f_min: minimum frequency
+# outputs:
+#   freq: the frequencies whose amplitude is maximum
+#   f_timeseries: filtered timeseries
+def f_lowpass_filter(timeseries, dt, n=10, f_min=0.2):
+    sample_num = len(timeseries)
+    f = dftfreq(sample_num, dt)
+    f_half = f[:((sample_num - 1) // 2) + 1]
+    f_sig = rdft(timeseries)
+    if f_sig[-1].imag < 1e-10:
+        fix_flag = False
+    else:
+        fix_flag = True
+
+    f_sig_amp = [abs(x) for x in f_sig]
+
+    offset = f_sig_amp[0] / (sample_num)
+
+    amp_max_pos = [i[0] for i in local_minmax(f_sig_amp)[0]]
+    amp_max = [e for i, e in enumerate(f_sig_amp) if i in amp_max_pos]
+    amp_desc_pos = [i[0] for i in sorted(enumerate(amp_max), key=lambda x:x[1], reverse=True)]
+    
+    if len(amp_desc_pos) > n:
+        amp_desc_pos = amp_desc_pos[:n]
+    amp_max_n_pos = [amp_max_pos[i] for i in amp_desc_pos]
+
+    freq = [f_half[x] for x in amp_desc_pos]
+    for i in range(len(f_sig)):
+        if i not in amp_max_n_pos:
+            f_sig[i] = 0
+
+    for i in range(len(f_half)):
+        if f_half[i] < f_min:
+            f_sig[i] = 0
+    
+    f_timeseries = irdft(f_sig, fix_flag)
+    f_timeseries = [x + offset for x in f_timeseries]
+    return (freq, f_timeseries)
\ No newline at end of file
diff --git a/mathbox/app/signal/outlier.py b/mathbox/app/signal/outlier.py
new file mode 100644
index 0000000..6868e29
--- /dev/null
+++ b/mathbox/app/signal/outlier.py
@@ -0,0 +1,20 @@
+from mathbox.statistics.estimator import mean, std
+
+def noise_outlier(noise, bias=3):
+    noise_mean = mean(noise)
+    noise_std = std(noise)
+    return [(i,x) for i,x in enumerate(noise) if abs(x - noise_mean) > bias * noise_std]
+
+def simple_outlier(series, bias=3):
+    sorted_series = sorted(series)
+    length = len(series)
+    q3 = sorted_series[int(length * 0.75)]
+    q1 = sorted_series[int(length * 0.25)]
+    outlier_lo = [(i,x) for i,x in enumerate(series) if x < q1 - bias * (q3 - q1)]
+    outlier_hi = [(i,x) for i,x in enumerate(series) if x > q3 + bias * (q3 - q1)]
+    return outlier_lo, outlier_hi
+
+# Generalized ESD Test for Outliers
+# https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h3.htm
+def gesd():
+    pass
\ No newline at end of file
diff --git a/mathbox/app/signal/transform.py b/mathbox/app/signal/transform.py
new file mode 100644
index 0000000..927717a
--- /dev/null
+++ b/mathbox/app/signal/transform.py
@@ -0,0 +1,65 @@
+from math import pi, cos, sin
+
+# >> Discrete Fourier transform for sampled signals
+# x [in]: sampled signals, a list of magnitudes (real numbers)
+# y [out]: a list of complex numbers
+def dft(x):
+    N, y = len(x), []
+    for k in range(N):
+        real, imag = 0, 0
+        for n in range(N):
+            theta = -k * (2 * pi) * (float(n) / N)
+            real += x[n] * cos(theta)
+            imag += x[n] * sin(theta)
+        y.append(complex(real, imag))
+    return y # 第一个是直流分量
+
+def rdft(x):
+    return dft(x)[:(len(x)//2)+1]
+
+
+# >> Inverse discrete Fourier transform
+# yr [in]: real parts of the sinusoids
+# yi [in]: imaginary parts of the sinusoids
+# x [out]: sampled signals (real parts only), a list of magnitude
+def idft(yr, yi):
+    N, x = len(yr), []
+    for n in range(N):
+        real, imag = 0, 0
+        for k in range(N):
+            theta = k * (2 * pi) * (float(n) / N)
+            real += (yr[k] * cos(theta)) - (yi[k] * sin(theta))
+            # imag += (yr[k] * math.sin(theta)) + (yi[k] * math.cos(theta))
+        x.append(real / N)
+    return x
+
+def irdft(fourier, fix=False):
+    ext_f = []
+    if abs(fourier[-1].imag) and not fix < 1e-10:
+        for i in range(len(fourier)-2):
+            ext_f.append(fourier[-i-2].conjugate())
+    else:
+        for i in range(len(fourier)-1):
+            ext_f.append(fourier[-i-1].conjugate())
+    fourier.extend(ext_f)
+    N, x = len(fourier), []
+    for n in range(N):
+        real, imag = 0, 0
+        for k in range(N):
+            theta = k * (2 * pi) * (float(n) / N)
+            real += (fourier[k].real * cos(theta)) - (fourier[k].imag * sin(theta))
+            # imag += (fourier[k].real * math.sin(theta)) + (fourier[k].imag * math.cos(theta))
+        x.append(real / N)
+    return x
+
+def dftfreq(n, dt = 1.0):
+    if not isinstance(n, int):
+        raise ValueError("n should be an integer")
+    val = 1.0 / (n * dt)
+    results = []
+    N = (n-1)//2 + 1
+    p1 = [x for x in range(0, N)]
+    results[:N] = p1
+    p2 = [x for x in range(-(n//2), 0)]
+    results[N:] = p2
+    return [x * val for x in results]
\ No newline at end of file
diff --git a/mathbox/calculus/__init__.py b/mathbox/calculus/__init__.py
new file mode 100644
index 0000000..37cfe0f
--- /dev/null
+++ b/mathbox/calculus/__init__.py
@@ -0,0 +1,3 @@
+"""
+Calculus module
+"""
\ No newline at end of file
diff --git a/mathbox/calculus/differential.py b/mathbox/calculus/differential.py
new file mode 100644
index 0000000..dd3cedd
--- /dev/null
+++ b/mathbox/calculus/differential.py
@@ -0,0 +1,2 @@
+def diff(y):
+    return [y[i+1]-y[i] for i in range(len(y)-1)]
diff --git a/mathbox/calculus/integral.py b/mathbox/calculus/integral.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/la/__init__.py b/mathbox/la/__init__.py
new file mode 100644
index 0000000..c2efbd7
--- /dev/null
+++ b/mathbox/la/__init__.py
@@ -0,0 +1,3 @@
+"""
+Linear algebra module
+"""
\ No newline at end of file
diff --git a/mathbox/main.py b/mathbox/main.py
deleted file mode 100644
index babec57..0000000
--- a/mathbox/main.py
+++ /dev/null
@@ -1,2 +0,0 @@
-if __name__ == '__main__':
-    print('initilizing...')
\ No newline at end of file
diff --git a/mathbox/na/__init__.py b/mathbox/na/__init__.py
new file mode 100644
index 0000000..b5e704f
--- /dev/null
+++ b/mathbox/na/__init__.py
@@ -0,0 +1,3 @@
+"""
+Numerical analysis module
+"""
\ No newline at end of file
diff --git a/mathbox/na/interpolation.py b/mathbox/na/interpolation.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/optimizer/__init__.py b/mathbox/optimizer/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/optimizer/utils.py b/mathbox/optimizer/utils.py
new file mode 100644
index 0000000..618e4a4
--- /dev/null
+++ b/mathbox/optimizer/utils.py
@@ -0,0 +1,77 @@
+from mathbox.calculus.differential import diff
+
+def local_minmax(signal, closed=False):
+    threshold = (max(signal) - min(signal)) * 0.001 # avoid floating point errors
+    max_pos = []
+    min_pos = []
+    diff_x = diff(signal)
+    gradient = [x if abs(x) > threshold else 0.0 for x in diff_x]
+    
+    if closed == True:
+        if gradient[0] > 0:
+            min_pos.append(0)
+        elif gradient[0] < 0:
+            max_pos.append(0)
+        else:
+            for i in range(1, len(gradient)):
+                if gradient[i] < 0:
+                    max_pos.extend(range(0, i + 1))
+                    break
+                elif gradient[i] > 0:
+                    min_pos.extend(range(0, i + 1))
+                    break
+                else:
+                    continue
+
+    for i in range(len(gradient) - 1):
+        if gradient[i] > 0 and gradient[i + 1] < 0:
+            max_pos.append(i + 1)
+            continue
+        if gradient[i] < 0 and gradient[i + 1] > 0:
+            min_pos.append(i + 1)
+            continue
+        # > < or < > continue
+        if gradient[i] == 0:
+            continue
+        if gradient[i] > 0 and gradient[i + 1] == 0:
+            for j in range(i + 1, len(gradient)):
+                if gradient[j] < 0:
+                    max_pos.extend(range(i + 1, j + 1))
+                    break
+                if gradient[j] == 0:
+                    continue
+                if gradient[j] > 0:
+                    break
+        if gradient[i] < 0 and gradient[i + 1] == 0:
+            for j in range(i + 1, len(gradient)):
+                if gradient[j] > 0:
+                    min_pos.extend(range(i + 1, j + 1))
+                    break
+                if gradient[j] == 0:
+                    continue
+                if gradient[j] < 0:
+                    break
+
+    if closed == True:
+        if gradient[-1] < 0:
+            min_pos.append(len(gradient))
+        elif gradient[-1] > 0:
+            max_pos.append(len(gradient))
+        else:
+            for i in range(len(gradient) - 1, 0, -1):
+                if gradient[i] > 0:
+                    max_pos.extend(range(len(gradient), i, -1))
+                    break
+                elif gradient[i] < 0:
+                    min_pos.extend(range(len(gradient), i, -1))
+                    break
+                else:
+                    continue
+    
+    max_points = [(i,x) for i,x in enumerate(signal) if i in max_pos]
+    min_points = [(i,x) for i,x in enumerate(signal) if i in min_pos]
+    return max_points, min_points
+
+def argmax(alist):
+    # np.argmax output the 1st, this output the last
+    return max((x,i) for i,x in enumerate(alist))[1]
\ No newline at end of file
diff --git a/mathbox/statistics/__init__.py b/mathbox/statistics/__init__.py
new file mode 100644
index 0000000..fdeb492
--- /dev/null
+++ b/mathbox/statistics/__init__.py
@@ -0,0 +1,3 @@
+"""
+Statistics module
+"""
\ No newline at end of file
diff --git a/mathbox/statistics/estimator.py b/mathbox/statistics/estimator.py
new file mode 100644
index 0000000..ce26691
--- /dev/null
+++ b/mathbox/statistics/estimator.py
@@ -0,0 +1,62 @@
+
+
+def mean(samples):
+    return sum(samples) / len(samples)
+
+"""
+ddof == 1 provides an unbiased estimator of the variance of the infinite population.
+ddof == 0 provides a maximum likelihood estimate of the variance for normally distributed variables.
+"""
+def std(samples, ddof=1):
+    if ddof != 1 and ddof != 0:
+        raise ValueError("ddof must be 0 or 1")
+    x_bar = mean(samples)
+    return sum([(x - x_bar) ** 2 for x in samples]) / (len(samples) - ddof)
+
+def median(samples) :
+    samples = sorted(samples)
+    if len(samples) % 2 == 0:
+        return (samples[len(samples) // 2 - 1] + samples[len(samples) // 2]) / 2
+    else:
+        return samples[len(samples) // 2]
+
+# TODO:
+# Correlation with time shift
+# https://anomaly.io/understand-auto-cross-correlation-normalized-shift/index.html#/time_shift
+def ncc(x,y):
+    x_mean = mean(x)
+    y_mean = mean(y)
+    x_qsum  = 0
+    y_qsum  = 0
+    xy_sum  = 0
+    for i in range(len(x)):
+        x_qsum += (x[i] - x_mean) ** 2
+        y_qsum += (y[i] - y_mean) ** 2
+        xy_sum += (x[i] - x_mean) * (y[i] - y_mean)
+    return xy_sum / (x_qsum * y_qsum) ** 0.5
+
+def _operator_4_e_dist(a,b):
+    # distance[i * len_a + j(0~len_b)]
+    len_a = len(a)
+    len_b = len(b)
+    distance = []
+    sum = 0
+    for i in range(len_a):
+        row_distance = []
+        for j in range(len_b):
+            row_distance.append(abs(a[i]-b[j]))
+            sum += abs(a[i]-b[j])
+        distance.append(row_distance)
+    return distance, sum / (len_a * len_b)
+
+def energy_distance(a, b, normalize=False):
+    _,A = _operator_4_e_dist(a,b)
+    _,B = _operator_4_e_dist(a,a)
+    _,C = _operator_4_e_dist(b,b)
+    e_distance = (2* A - B - C)
+    normailized_e_distance = e_distance / (2 * A + 1e-10)
+    if normalize:
+        return normailized_e_distance
+    else:
+        return e_distance
+
diff --git a/mathbox/utils.py b/mathbox/utils.py
new file mode 100644
index 0000000..4d1b8fd
--- /dev/null
+++ b/mathbox/utils.py
@@ -0,0 +1,5 @@
+def pairwise(alist):
+    pair = []
+    for i in range(len(alist)-1):
+        pair.append((alist[i], alist[i+1]))
+    return pair
\ No newline at end of file


Test patch:
diff --git a/mathbox/app/signal/tests/__init__.py b/mathbox/app/signal/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/app/signal/tests/test_filter.py b/mathbox/app/signal/tests/test_filter.py
new file mode 100644
index 0000000..0f55e9e
--- /dev/null
+++ b/mathbox/app/signal/tests/test_filter.py
@@ -0,0 +1,8 @@
+import pytest
+from ..filter import *
+
+def test_moving_average():
+    assert moving_average([1,3,5,4,4],3) == [1.0,2.0,3.0,4.0,pytest.approx(4.3333,0.001)]
+    
+def test_moving_median():
+    assert moving_median([1,2,5,9,6],3) == [1.0,1.5,2.0,5.0,6.0]
\ No newline at end of file
diff --git a/mathbox/calculus/tests/__init__.py b/mathbox/calculus/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/calculus/tests/test_differential.py b/mathbox/calculus/tests/test_differential.py
new file mode 100644
index 0000000..9ffe19e
--- /dev/null
+++ b/mathbox/calculus/tests/test_differential.py
@@ -0,0 +1,4 @@
+from ..differential import *
+
+def test_diff():
+    assert diff([1,2,5,4,6]) == [1,3,-1,2]
\ No newline at end of file
diff --git a/mathbox/optimizer/tests/__init__.py b/mathbox/optimizer/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/optimizer/tests/test_utils.py b/mathbox/optimizer/tests/test_utils.py
new file mode 100644
index 0000000..672aa79
--- /dev/null
+++ b/mathbox/optimizer/tests/test_utils.py
@@ -0,0 +1,12 @@
+from ..utils import *
+
+def test_local_minmax():
+    case_1 = [1, 2, 3, 2, 1]
+    print(local_minmax(case_1,True))
+    print(local_minmax(case_1))
+    case_2 = [0,0,1,2,3,9,9.1,9,9,3,3,3,2,-1,0,0,0]
+    print("len_2: ",len(case_2))
+    print(local_minmax(case_2,True))
+    print(local_minmax(case_2))
+    assert local_minmax(case_2) == ([(6, 9.1)], [(13, -1)])
+    assert local_minmax(case_2,True) == ([(6, 9.1),(14,0),(15,0),(16,0)], [(0,0),(1,0),(13, -1)])
\ No newline at end of file
diff --git a/mathbox/statistics/hypothesis_testing.py b/mathbox/statistics/hypothesis_testing.py
new file mode 100644
index 0000000..10a392a
--- /dev/null
+++ b/mathbox/statistics/hypothesis_testing.py
@@ -0,0 +1,17 @@
+import random
+
+
+def permutation_test(alist, blist, estimator, p_value=0.05, times=100):
+    total = alist + blist
+    len_a = len(alist)
+    t_stats = estimator(alist, blist)
+    better_num = 0
+    for _ in range(times):
+        random.shuffle(total)
+        new_a = total[:len_a]
+        new_b = total[len_a:]
+        new_t_stats = estimator(new_a, new_b)
+        if new_t_stats >= t_stats:
+            better_num += 1
+    probability = better_num / (times + 1)
+    return True if probability <= p_value else False # false means reject H0
\ No newline at end of file
diff --git a/mathbox/statistics/tests/__init__.py b/mathbox/statistics/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mathbox/statistics/tests/test_estimator.py b/mathbox/statistics/tests/test_estimator.py
new file mode 100644
index 0000000..03f68c5
--- /dev/null
+++ b/mathbox/statistics/tests/test_estimator.py
@@ -0,0 +1,14 @@
+from ..estimator import *
+
+
+def test_mean():
+    assert mean([1,2,3,4,5]) == 3.0
+    assert mean([1.0,2.0,3.0,4.0,5.0]) == 3.0
+    
+def test_std():
+    assert std([1,2,3,4,5],ddof=1) == 2.5
+    assert std([1,2,3,4,5],ddof=0) == 2.0
+
+def test_median():
+    assert median([1,2,4,7,6]) == 4
+    assert median([1.0,2.0,3.5,4.0,5.0]) == 3.5
\ No newline at end of file
diff --git a/test_requirements.txt b/test_requirements.txt
new file mode 100644
index 0000000..bc65365
--- /dev/null
+++ b/test_requirements.txt
@@ -0,0 +1,5 @@
+pytest>=6.2.5
+pandas>=1.3.5
+#matplotlib>=3.5.1
+#scipy==1.7.3 # for test
+#numpy==1.21.4 # for test
\ No newline at end of file