├── AutoRegressionTest └── test.cpp ├── Compression ├── Compression.h ├── CompressionTestAuto.h ├── Compressor.cpp ├── HuffmanTree.h ├── LZW.h ├── README.txt ├── StaticCodes.h ├── Stream.h └── test.cpp ├── ComputationalGeometry ├── BuildingArea.h ├── ComputationalGeometryTestAuto.h ├── ConvexHull.h ├── KDTree.h ├── Point.h ├── testBuildingArea.cpp ├── testConvexHull.cpp └── testTrees.cpp ├── Cryptography ├── Cryptography.h ├── CryptographyTestAuto.h └── test.cpp ├── ErrorCorrectingCodes ├── CRC.h ├── ErrorCorrectingCodesTestAuto.h ├── LDPC.h ├── ReedSolomon.h └── test.cpp ├── ExternalMemoryAlgorithms ├── CSV.h ├── EMBTree.h ├── EMFreelist.h ├── EMVector.h ├── ExternalMemoryAlgorithmsTestAuto.h ├── File.h └── Test.cpp ├── FinancialCalculations ├── Annuity.h ├── CashFlows.h ├── FinancialCalculationsTestAuto.h ├── MeanVarianceOptimization.h ├── Misc.h ├── OptionPricing.h ├── PortfolioSimulation.h └── test.cpp ├── Graphs ├── Graph.h ├── GraphsTestAuto.h ├── NetworkFlow.h ├── NetworkFlowTestAuto.h ├── test.cpp └── testNetworkFlow.cpp ├── HashTable ├── BloomFilter.h ├── ChainingHashTable.h ├── HashFunction.h ├── HashTableTestAuto.h ├── LinearProbingHashTable.h ├── MapTestAutoHelper.h └── test.cpp ├── Heaps ├── Heap.h ├── HeapTestAuto.h ├── IndexedHeap.h └── test.cpp ├── LargeNumbers ├── LargeNumber.h ├── LargeNumberTestAuto.h ├── LargeRational.h └── test.cpp ├── MachineLearning ├── APriori.h ├── Classification.h ├── ClassificationCommon.h ├── ClusterResults.ods ├── ClusterResultsNew.ods ├── Clustering.h ├── CostClassification.h ├── Datasets │ ├── CNAE-9.data │ ├── SPECT.test │ ├── SPECT.train │ ├── arcene_train.data │ ├── arcene_train.labels │ ├── arcene_valid.data │ ├── arcene_valid.labels │ ├── data_banknote_authentication.txt │ ├── glass.data │ ├── ionosphere.data │ ├── iris.data │ ├── leaf.data │ ├── letter-recognition.data │ ├── madelon_train.data │ ├── madelon_train.labels │ ├── madelon_valid.data │ ├── madelon_valid.labels │ ├── pima-indians-diabetes.data │ ├── sat.trn │ ├── sat.tst │ ├── spambase.data │ ├── wdbc.data │ └── wine.data ├── DecisionTree.h ├── ImbalanceClassification.h ├── KNN.h ├── KNNRegression.h ├── KernelSVM.h ├── LSVM.h ├── Lasso.h ├── LearningCommon.h ├── NaiveBayes.h ├── NeuralNetwork.h ├── NeuralNetworkRegression.h ├── RandomForest.h ├── RandomForestRegression.h ├── ReadClassificationData.h ├── RegDatasets │ ├── CASP.data │ ├── Concrete_Data.data │ ├── ENB2012_dataConverted.data │ ├── Folds5x2_ppConverted.data │ ├── SkillCraft1Converted.data │ ├── airfoil_self_noise.data │ ├── machine.data │ ├── winequality-whiteConverted.data │ └── yacht_hydrodynamics.data ├── RegResults.ods ├── Regression.h ├── RegressionCommon.h ├── RegressionTree.h ├── ReinforcementLearning.h ├── TestClustering.cpp ├── optdigits.tes ├── optdigits.tra ├── results.ods ├── testAPriori.cpp ├── testClassification.cpp ├── testReg.cpp └── testReinforcementLearning.cpp ├── MiscAlgs ├── CombinatorialGeneration.h ├── IntervalSetUnion.h ├── KBitWordVector.h ├── LRUCache.h ├── MiscAlgsTestAuto.h ├── PrimeTable.h ├── test.cpp └── testIntervalSetUnion.cpp ├── NumericalMethods ├── AllRootsFinder.h ├── CubicSpline.h ├── Differentiation.h ├── EquationSolving.h ├── FFT.h ├── Integration.h ├── Interpolation.h ├── IntervalNumber.h ├── Matrix.h ├── NumericalCommon.h ├── NumericalMethods.h ├── NumericalMethodsTestAuto.h ├── ODESolving.h ├── SparseMatrix.h ├── TestFunctions1D.h ├── testCubicSpline.cpp ├── testDeriv.cpp ├── testEquationSolving.cpp ├── testFFT.cpp ├── testIntegrators.cpp ├── testInterpolation.cpp ├── testInterval.cpp ├── testMatrix.cpp ├── testNum.cpp ├── testODE.cpp └── testRootSolvers.cpp ├── NumericalOptimization ├── CoordinateDescent.h ├── DifferentialEvolution.h ├── DiscreteGlobalOptimization.h ├── GlobalNumericalOptimization.h ├── GoldenSection.h ├── LBFGS.h ├── LinearProgramming.h ├── MetaheuristicWrappers.h ├── NelderMead.h ├── NumericalOptimization.h ├── SPSA.h ├── testLinearProgramming.cpp ├── testOpt.cpp ├── testOpt1D.cpp ├── testOptCommon.h └── testOptGlobal.cpp ├── Optimization ├── BinPacking.h ├── ContraintProcessing.h ├── Knapsack.h ├── MetaHeuristics.h ├── OptTestAuto.h ├── Satisfiability3.h ├── SearchAlgorithms.h ├── TSP.h ├── TestConstraint.cpp └── test.cpp ├── README.md ├── RandomNumberGeneration ├── Bootstrap.h ├── CircleArea.py ├── Correlation.h ├── DistributionTests.h ├── Generators.h ├── MCMC.h ├── MultipleComparison.h ├── OCBA.h ├── PermutationTests.h ├── Random.h ├── SensitivityAnalysis.h ├── Sobol.h ├── Statistics.h ├── TimeSeries.h ├── test.cpp ├── testBootstrap.cpp ├── testCommon.h ├── testCorrelation.cpp ├── testDistribution.cpp ├── testMCMC.cpp ├── testMultipleComparison.cpp ├── testOCBA.cpp ├── testPermutationTests.cpp ├── testRandom.cpp ├── testSensitivityAnalysis.cpp ├── testSobol.cpp └── testTimeSeries.cpp ├── RandomTreap ├── DynamicSortedSequenceTestAuto.h ├── LCPTreap.h ├── SkipList.h ├── Treap.h ├── Trie.h └── test.cpp ├── Scrap ├── ArithmeticCoding.h ├── BFGS.h ├── ConjugateGradientOptimization.h ├── CuckooHashTable.h ├── DSRS.h ├── Datasets │ └── iris.data ├── EMLinearHashing.h ├── FriedmanTest.h ├── IncrementalSort.h ├── IntervalTree.h ├── L2Boost.h ├── LSH.h ├── LSHLearner.h ├── LeftLeaningRedBlackTree.h ├── MRMR.h ├── PairingHeap.h ├── RMQ.h ├── SAMME.h ├── ScrapClustering.h ├── ScrapHeap.h ├── ScrapTrie.h ├── SortedLinkedList.h ├── SymmetricMinMaxHeap.h ├── TestEMHashing.cpp ├── WilcoxonSignedRankTest.h ├── testArithmeticCoding.cpp ├── testClassification.cpp ├── testClustering.cpp ├── testCuckoo.cpp ├── testFriedmanTest.cpp ├── testHeap.cpp ├── testIncrementalSort.cpp ├── testIntervalTree.cpp ├── testL2Boost.cpp ├── testLSH.cpp ├── testLinkedListSort.cpp ├── testOptScrap.cpp ├── testRMQ.cpp ├── testTrie.cpp └── testWilcoxonSignedRankTest.cpp ├── Slides ├── IntroMachineLearning.pdf └── MonteCarloAlgorithms.pdf ├── Sorting ├── Sort.h ├── SortTestAuto.h └── testSort.cpp ├── StringAlgorithms ├── Diff.h ├── RankSelect.h ├── RegEx.h ├── StringAlgorithmsTestAuto.h ├── SubstringSearch.h ├── SuffixArray.h ├── test.cpp └── testRankSelect.cpp └── Utils ├── Bits.h ├── Bitset.h ├── Debug.h ├── GCFreeList.h ├── Queue.h ├── Stack.h ├── UnionFind.h ├── Utils.h ├── UtilsTestAuto.h ├── Vector.h ├── testBasics.cpp ├── testBits.cpp └── testUF.cpp /AutoRegressionTest/test.cpp: -------------------------------------------------------------------------------- 1 | #include "../Utils/UtilsTestAuto.h" 2 | #include "../Sorting/SortTestAuto.h" 3 | #include "../RandomTreap/DynamicSortedSequenceTestAuto.h" 4 | #include "../HashTable/HashTableTestAuto.h" 5 | #include "../Heaps/HeapTestAuto.h" 6 | #include "../Graphs/GraphsTestAuto.h" 7 | #include "../ExternalMemoryAlgorithms/ExternalMemoryAlgorithmsTestAuto.h" 8 | #include "../StringAlgorithms/StringAlgorithmsTestAuto.h" 9 | #include "../Compression/CompressionTestAuto.h" 10 | #include "../MiscAlgs/MiscAlgsTestAuto.h" 11 | #include "../Optimization/OptTestAuto.h" 12 | #include "../LargeNumbers/LargeNumberTestAuto.h" 13 | #include "../ComputationalGeometry/ComputationalGeometryTestAuto.h" 14 | #include "../ErrorCorrectingCodes/ErrorCorrectingCodesTestAuto.h" 15 | #include "../Cryptography/CryptographyTestAuto.h" 16 | #include "../NumericalMethods/NumericalMethodsTestAuto.h" 17 | #include "../FinancialCalculations/FinancialCalculationsTestAuto.h" 18 | 19 | using namespace igmdk; 20 | 21 | int main() 22 | { 23 | DEBUG("All Tests Auto"); 24 | testAllAutoUtils(); 25 | testAllAutoSort(); 26 | testAllAutoDynamicSortedSequence(); 27 | testAllAutoHashTable(); 28 | testAllAutoHeaps(); 29 | testAllAutoGraphs(); 30 | testAllAutoExternalMemoryAlgorithms(); 31 | testAllAutoStringAlgorithms(); 32 | testAllAutoCompression(); 33 | testAllAutoMiscAlgorithms(); 34 | testAllAutoOpt(); 35 | testAllAutoComputationalGeometry(); 36 | testAllAutoErrorCorrectingCodes(); 37 | testAllAutoCryptography(); 38 | testAllAutoNumericalMethods(); 39 | testAllAutoFinancialCalculations(); 40 | DEBUG("All Tests Auto passed"); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Compression/CompressionTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_COMPRESSION_TEST_AUTO_H 2 | #define IGMDK_COMPRESSION_TEST_AUTO_H 3 | #include 4 | using namespace std; 5 | #include "Compression.h" 6 | 7 | namespace igmdk{ 8 | 9 | void testGammaCodeAuto() 10 | { 11 | DEBUG("testGammaCodeAuto"); 12 | BitStream result; 13 | for(int i = 1; i < 1000; ++i) GammaEncode(i, result); 14 | for(int i = 1; i < 1000; ++i) assert(GammaDecode(result) == i); 15 | DEBUG("testGammaCodeAuto passed"); 16 | } 17 | 18 | void testFibonacciCodeAuto() 19 | { 20 | DEBUG("testFibonacciCodeAuto"); 21 | BitStream result; 22 | for(int i = 1; i < 1000; ++i) FibonacciEncode(i, result); 23 | for(int i = 1; i < 1000; ++i) assert(FibonacciDecode(result) == i); 24 | DEBUG("testFibonacciCodeAuto passed"); 25 | } 26 | 27 | void testByteCodeAuto() 28 | { 29 | DEBUG("testGammaCodeAuto"); 30 | BitStream result; 31 | for(int i = 0; i < 1000; ++i) byteEncode(i, result); 32 | for(int i = 0; i < 1000; ++i) assert(byteDecode(result) == i); 33 | DEBUG("testGammaCodeAuto passed"); 34 | } 35 | 36 | Vector getRandomBytes(int n = 10000) 37 | { 38 | Vector w(n, 0); 39 | for(int i = 0; i < n; ++i) w[i] = GlobalRNG().next(); 40 | return w; 41 | } 42 | void testBWTCompressAuto() 43 | { 44 | DEBUG("testBWTCompressAuto"); 45 | Vector byteArray = getRandomBytes(); 46 | assert(byteArray == BWTUncompress(BWTCompress(byteArray))); 47 | DEBUG("testBWTCompressAuto passed"); 48 | } 49 | 50 | void testLZWAuto() 51 | { 52 | DEBUG("testLZWAuto"); 53 | Vector byteArray = getRandomBytes(), code; 54 | { 55 | BitStream in(byteArray); 56 | BitStream out; 57 | LZWCompress(in, out); 58 | code = ExtraBitsCompress(out.bitset); 59 | } 60 | { 61 | BitStream in(ExtraBitsUncompress(code)); 62 | BitStream out; 63 | LZWUncompress(in, out); 64 | assert(byteArray == out.bitset.getStorage()); 65 | } 66 | DEBUG("testLZWAuto passed"); 67 | } 68 | 69 | void testAllAutoCompression() 70 | { 71 | DEBUG("testAllAutoCompression"); 72 | testGammaCodeAuto(); 73 | testFibonacciCodeAuto(); 74 | testByteCodeAuto(); 75 | testBWTCompressAuto(); 76 | testLZWAuto(); 77 | } 78 | 79 | }//end namespace 80 | #endif 81 | -------------------------------------------------------------------------------- /Compression/LZW.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_LZW_H 2 | #define IGMDK_LZW_H 3 | #include "../RandomTreap/Trie.h" 4 | #include "Stream.h" 5 | #include 6 | namespace igmdk{ 7 | 8 | void LZWCompress(BitStream& in, BitStream& out, int maxBits = 16) 9 | { 10 | assert(in.bytesLeft()); 11 | byteEncode(maxBits, out);//store as config 12 | TernaryTreapTrie dictionary; 13 | TernaryTreapTrie::Handle h; 14 | int n = 0; 15 | while(n < (1 << numeric_limits::digits)) 16 | {//initialize with all bytes 17 | unsigned char letter = n; 18 | dictionary.insert(&letter, 1, n++); 19 | } 20 | Vector word; 21 | while(in.bytesLeft()) 22 | { 23 | unsigned char c = in.readByte(); 24 | word.append(c); 25 | //if found keep appending 26 | if(!dictionary.findIncremental(word.getArray(), word.getSize(), h)) 27 | {//word without the last byte guaranteed to be in the dictionary 28 | out.writeValue(*dictionary.find(word.getArray(), 29 | word.getSize() - 1), lgCeiling(n)); 30 | if(n < twoPower(maxBits))//add new word if have space 31 | dictionary.insert(word.getArray(), word.getSize(), n++); 32 | word = Vector(1, c);//set to read byte 33 | } 34 | } 35 | out.writeValue(*dictionary.find(word.getArray(), word.getSize()), 36 | lgCeiling(n)); 37 | } 38 | 39 | void LZWUncompress(BitStream& in, BitStream& out) 40 | { 41 | int maxBits = byteDecode(in), size = twoPower(maxBits), n = 0, 42 | lastIndex = -1; 43 | assert(maxBits >= numeric_limits::digits); 44 | Vector > dictionary(size); 45 | for(; n < (1 << numeric_limits::digits); ++n) 46 | dictionary[n].append(n); 47 | while(in.bitsLeft()) 48 | { 49 | int index = in.readValue(lastIndex == -1 ? 8 : 50 | min(maxBits, lgCeiling(n + 1))); 51 | if(lastIndex != -1 && n < size) 52 | { 53 | Vector word = dictionary[lastIndex]; 54 | word.append((index == n ? word : dictionary[index])[0]); 55 | dictionary[n++] = word; 56 | } 57 | for(int i = 0; i < dictionary[index].getSize(); ++i) 58 | out.writeByte(dictionary[index][i]); 59 | lastIndex = index; 60 | } 61 | } 62 | 63 | }//end namespace 64 | #endif 65 | -------------------------------------------------------------------------------- /Compression/README.txt: -------------------------------------------------------------------------------- 1 | Please download test files into this directory from http://introcs.cs.princeton.edu/java/data/ 2 | 3 | bible.txt 4 | dickens.txt 5 | ecoli.txt 6 | mobydick.txt 7 | pi10mm.txt 8 | world192.txt 9 | 10 | These are for use with Compressor.cpp. Other files can be used as well. -------------------------------------------------------------------------------- /Compression/Stream.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_STREAM_H 2 | #define IGMDK_STREAM_H 3 | #include "../Utils/Bitset.h" 4 | #include "../Utils/Vector.h" 5 | namespace igmdk{ 6 | 7 | Vector ReinterpretEncode(unsigned long long n, int size) 8 | { 9 | assert(size > 0); 10 | enum{M = 1 << numeric_limits::digits}; 11 | Vector result; 12 | while(size-- > 0) 13 | { 14 | result.append(n % M); 15 | n /= M; 16 | } 17 | return result; 18 | } 19 | unsigned long long ReinterpretDecode(Vector const& code) 20 | { 21 | assert(code.getSize() > 0); 22 | unsigned long long n = 0, base = 1; 23 | enum{M = 1 << numeric_limits::digits}; 24 | for(int i = 0; i < code.getSize(); ++i) 25 | { 26 | n += base * code[i]; 27 | base *= M; 28 | } 29 | return n; 30 | } 31 | 32 | struct Stream 33 | { 34 | unsigned long long position; 35 | Stream(): position(0) {} 36 | }; 37 | struct BitStream : public Stream 38 | { 39 | Bitset bitset;//unsigned char for portability 40 | enum{B = numeric_limits::digits}; 41 | BitStream() {} 42 | BitStream(Bitset const& aBitset): bitset(aBitset) {} 43 | BitStream(Vector const& vector): bitset(vector) {} 44 | void writeBit(bool value){bitset.append(value);} 45 | bool readBit() 46 | { 47 | assert(bitsLeft()); 48 | return bitset[position++]; 49 | } 50 | void writeByte(unsigned char byte){writeValue(byte, B);} 51 | void writeBytes(Vector const& bytes) 52 | {for(int i = 0; i < bytes.getSize(); ++i) writeByte(bytes[i]);} 53 | unsigned char readByte(){return readValue(B);} 54 | Vector readBytes(int n) 55 | { 56 | assert(n <= bytesLeft()); 57 | Vector result(n); 58 | for(int i = 0; i < n; ++i) result[i] = readByte(); 59 | return result; 60 | } 61 | void debug()const{bitset.debug();} 62 | void writeValue(unsigned long long value, int bits) 63 | {bitset.appendValue(value, bits);} 64 | unsigned long long readValue(int bits) 65 | { 66 | assert(bits <= bitsLeft()); 67 | position += bits; 68 | return bitset.getValue(position - bits, bits); 69 | } 70 | unsigned long long bitsLeft()const{return bitset.getSize() - position;} 71 | unsigned long long bytesLeft()const{return bitsLeft()/B;} 72 | }; 73 | 74 | }//end namespace 75 | #endif 76 | -------------------------------------------------------------------------------- /Compression/test.cpp: -------------------------------------------------------------------------------- 1 | #include "Compression.h" 2 | #include "CompressionTestAuto.h" 3 | #include 4 | using namespace igmdk; 5 | 6 | void compress(Vector const& byteArray) 7 | { 8 | BitStream result; 9 | FibonacciEncode(1597, result);//first large value that loses to byte code 10 | result.bitset.debug(); 11 | DEBUG(FibonacciDecode(result)); 12 | 13 | GammaEncode(32, result); 14 | result.bitset.debug(); 15 | DEBUG(GammaDecode(result)); 16 | 17 | byteEncode(128 * 128, result); 18 | result.bitset.debug(); 19 | DEBUG(byteDecode(result)); 20 | 21 | HuffmanTree HuffTree(byteArray); 22 | Vector MTF_Mississippi = MoveToFrontTransform(true, byteArray); 23 | 24 | cout << "breakpoint" << endl;//if have to recompute HUFFMAN do MISSISSIPPI not "large ascii text" 25 | } 26 | 27 | void timeRT() 28 | { 29 | char text[] = //"abbabab"; 30 | "mississippi"; 31 | Vector uncompressed; 32 | for(int i = 0; i < sizeof(text)-1; ++i) uncompressed.append(text[i]); 33 | 34 | cout << "uncompressed.size" << uncompressed.getSize() << endl; 35 | compress(uncompressed); 36 | } 37 | 38 | int main() 39 | { 40 | timeRT();//fail Huffman has bug??? 41 | testAllAutoCompression(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /ComputationalGeometry/BuildingArea.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_BUILDING_AREA_H 2 | #define IGMDK_BUILDING_AREA_H 3 | 4 | #include 5 | #include 6 | #include //sort 7 | #include 8 | namespace igmdk{ 9 | 10 | using namespace std; 11 | 12 | struct RoofCorner 13 | { 14 | double x, y; 15 | bool isLeft; 16 | RoofCorner(double theX, double theY, bool theIsLeft): x(theX), y(theY), 17 | isLeft(theIsLeft){}//comparison on x + give priority to left over right 18 | bool operator<(RoofCorner const& rhs)const 19 | {return x == rhs.x ? isLeft > rhs.isLeft : x < rhs.x;} 20 | }; 21 | double buildingArea(vector corners) 22 | { 23 | sort(corners.begin(), corners.end()); 24 | double result = 0, currentHeight = 0, lastX = corners[0].x; 25 | map openBuildings;//indexed and sorted by height, note that 26 | //don't have numerical issues with double key as no calculations are done 27 | for(unsigned int i = 0; i < corners.size(); ++i) 28 | { 29 | double x = corners[i].x, y = corners[i].y; 30 | result += currentHeight * (x - lastX); 31 | lastX = x; 32 | //manage count of open buildings 33 | openBuildings[y] += corners[i].isLeft ? 1 : -1; 34 | if(openBuildings[y] == 0) openBuildings.erase(y); 35 | //current height is that of tallest open building 36 | currentHeight = openBuildings.size() > 0 ? 37 | openBuildings.rbegin()->first : 0; 38 | } 39 | return result; 40 | } 41 | void testBuildingArea() 42 | { 43 | vector points; 44 | points.push_back(RoofCorner(0, 1, true)); 45 | points.push_back(RoofCorner(2, 1, false)); 46 | points.push_back(RoofCorner(1, 2, true)); 47 | points.push_back(RoofCorner(3, 2, false)); 48 | assert(buildingArea(points) == 5); 49 | } 50 | 51 | }//end namespace 52 | #endif 53 | -------------------------------------------------------------------------------- /ComputationalGeometry/ComputationalGeometryTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_COMPUTATIONAL_GEOMETRY_TEST_AUTO_H 2 | #define IGMDK_COMPUTATIONAL_GEOMETRY_TEST_AUTO_H 3 | #include "KDTree.h" 4 | #include "Point.h" 5 | #include 6 | using namespace std; 7 | 8 | namespace igmdk{ 9 | 10 | 11 | template void testPointMapAutoHelper(MAP2D& trie) 12 | { 13 | int n = 100000; 14 | Vector permutation(n); 15 | for(int i = 0; i < n; ++i) permutation[i] = i; 16 | GlobalRNG().randomPermutation(permutation.getArray(), n); 17 | for(int j = 0; j < n; ++j) 18 | { 19 | int i = permutation[j]; 20 | Vector key(2, i); 21 | trie.insert(key, -i); 22 | assert(trie.find(key)); 23 | assert(*trie.find(key) == -i); 24 | } 25 | } 26 | template void testAutoCheckRange(Vector const& v, int from, 27 | int to) 28 | { 29 | for(int i = from; i < to; ++i) 30 | { 31 | bool found = false; 32 | for(int j = 0; j < v.getSize(); ++j) 33 | if(v[j]->key[0] == i) 34 | { 35 | found = true; 36 | break; 37 | } 38 | assert(found); 39 | } 40 | } 41 | void testKDTreeAuto() 42 | { 43 | DEBUG("testKDTreeAuto"); 44 | typedef KDTree, int> TREE; 45 | TREE tree(2); 46 | testPointMapAutoHelper(tree); 47 | EuclideanDistance >::DistanceIncremental di; 48 | Vector p1(2, 100); 49 | //radius test; 7 * 7 + 7 * 7 = 98, so just makes it in 10^2 50 | testAutoCheckRange(tree.distanceQuery(p1, 100, di), 93, 107); 51 | //nn tests 52 | typename TREE::NodeType* nn = tree.nearestNeighbor(p1, di); 53 | assert(nn && nn->key == p1); 54 | testAutoCheckRange(tree.kNN(p1, 5, di), 98, 102); 55 | //range test 56 | testAutoCheckRange(tree.rangeQuery(Vector(2, 97), Vector(2, 103), 57 | Vector(2, true)), 97, 103); 58 | DEBUG("testKDTreeAuto passed"); 59 | } 60 | 61 | void testVPTreeAuto() 62 | { 63 | DEBUG("testVPTreeAuto"); 64 | typedef VpTree, int, EuclideanDistance >::Distance> 65 | TREE; 66 | TREE tree; 67 | testPointMapAutoHelper(tree); 68 | Vector p1(2, 100); 69 | //radius test; 7 * 7 + 7 * 7 = 98, so just makes it in 10^2 70 | testAutoCheckRange(tree.distanceQuery(p1, 10), 93, 107); 71 | //nn tests 72 | typename TREE::NodeType* nn = tree.nearestNeighbor(p1); 73 | assert(nn && nn->key == p1); 74 | testAutoCheckRange(tree.kNN(p1, 5), 98, 102); 75 | DEBUG("testVPTreeAuto passed"); 76 | } 77 | 78 | void testAllAutoComputationalGeometry() 79 | { 80 | DEBUG("testAllAutoComputationalGeometry"); 81 | testKDTreeAuto(); 82 | testVPTreeAuto(); 83 | } 84 | 85 | }//end namespace 86 | #endif 87 | -------------------------------------------------------------------------------- /ComputationalGeometry/ConvexHull.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CONVEXHULL_H 2 | #define IGMDK_CONVEXHULL_H 3 | #include "Point.h" 4 | #include "../Utils/Utils.h" 5 | #include "../Utils/Vector.h" 6 | #include "../Sorting/Sort.h" 7 | #include "../LargeNumbers/LargeRational.h" 8 | namespace igmdk{ 9 | 10 | double triangleArea(Point2 const& a, Point2 const& b, Point2 const& c) 11 | {return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);} 12 | bool ccw(Point2 const& a, Point2 const& b, Point2 const& c) 13 | {return triangleArea(a, b, c) >= 0;}//true if the points turn left 14 | 15 | Rational robustTriangleArea(Point2 const&a, Point2 const&b, Point2 const&c) 16 | { 17 | return (Rational(b[0]) - Rational(a[0])) * (Rational(c[1]) - 18 | Rational(a[1])) - (Rational(b[1]) - Rational(a[1])) * (Rational(c[0]) 19 | - Rational(a[0])); 20 | } 21 | bool robustCcw(Point2 const& a, Point2 const& b, Point2 const& c) 22 | {return !robustTriangleArea(a, b, c).isMinus();} 23 | 24 | void processPoint(Vector& hull, Point2 const& point) 25 | { 26 | hull.append(point); 27 | while(hull.getSize() > 2 && ccw(hull[hull.getSize() - 3], 28 | hull[hull.getSize() - 2], hull[hull.getSize() - 1])) 29 | { 30 | hull[hull.getSize() - 2] = hull[hull.getSize() - 1]; 31 | hull.removeLast(); 32 | } 33 | } 34 | Vector convexHull(Vector& points) 35 | { 36 | assert(points.getSize() > 2); 37 | quickSort(points.getArray(), 0, points.getSize() - 1, 38 | LexicographicComparator()); 39 | //upper hull 40 | Vector result; 41 | result.append(points[0]);//initialize with the first two points 42 | result.append(points[1]); 43 | for(int i = 2; i < points.getSize(); ++i) processPoint(result, points[i]); 44 | //lower hull, remove leftmost point which is added twice 45 | for(int i = points.getSize() - 2; i >= 0; --i) 46 | processPoint(result, points[i]); 47 | result.removeLast(); 48 | return result; 49 | } 50 | 51 | }//end namespace 52 | #endif 53 | -------------------------------------------------------------------------------- /ComputationalGeometry/Point.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_POINT_H 2 | #define IGMDK_POINT_H 3 | #include "../Utils/Utils.h" 4 | #include 5 | #include //int version of abs 6 | namespace igmdk{ 7 | 8 | template 9 | class Point: public ArithmeticType > 10 | { 11 | KEY x[D]; 12 | public: 13 | static int const d = D; 14 | KEY& operator[](int i){assert(i >= 0 && i < D); return x[i];} 15 | KEY const& operator[](int i)const{assert(i >= 0 && i < D); return x[i];} 16 | int getSize()const{return D;} 17 | Point(){for(int i = 0; i < D; ++i) x[i] = 0;} 18 | Point(KEY const& x0, KEY const& x1) 19 | { 20 | assert(D == 2);//to prevent accidents for D > 2 21 | x[0] = x0; 22 | x[1] = x1; 23 | } 24 | bool operator==(Point const& rhs)const 25 | { 26 | for(int i = 0; i < D; ++i) if(x[i] != rhs.x[i]) return false; 27 | return true; 28 | } 29 | Point& operator+=(Point const& rhs) 30 | { 31 | for(int i = 0; i < D; ++i) x[i] += rhs.x[i]; 32 | return *this; 33 | } 34 | Point& operator*=(double scalar) 35 | { 36 | for(int i = 0; i < D; ++i) x[i] *= scalar; 37 | return *this; 38 | } 39 | friend Point operator*(Point const& point, double scalar) 40 | { 41 | Point result = point; 42 | return result *= scalar; 43 | } 44 | Point& operator-=(Point const& rhs){return *this += rhs * -1;} 45 | Point operator-(){return *this * -1;} 46 | double friend dotProduct(Point const& a, Point const& b) 47 | { 48 | double dp = 0; 49 | for(int i = 0; i < D; ++i) dp += a[i] * b[i]; 50 | return dp; 51 | } 52 | }; 53 | typedef Point Point2; 54 | 55 | template class EuclideanDistance 56 | { 57 | static double iDistanceIncremental(VECTOR const& lhs, VECTOR const& rhs, 58 | int i)//add on a component 59 | { 60 | double x = lhs[i] - rhs[i]; 61 | return x * x; 62 | } 63 | static double distanceIncremental(VECTOR const& lhs, VECTOR const& rhs, 64 | double bound = numeric_limits::infinity()) 65 | {//compute distance up to a bound 66 | assert(lhs.getSize() == rhs.getSize()); 67 | double sum = 0; 68 | for(int i = 0; i < lhs.getSize() && sum < bound; ++i) 69 | sum += iDistanceIncremental(lhs, rhs, i); 70 | return sum; 71 | } 72 | public: 73 | struct Distance 74 | {//metric functor 75 | double operator()(VECTOR const& lhs, VECTOR const& rhs)const 76 | {return sqrt(distanceIncremental(lhs, rhs));} 77 | }; 78 | struct DistanceIncremental 79 | {//incremental functor that returns distance squared 80 | double operator()(VECTOR const& lhs, VECTOR const& rhs)const 81 | {return distanceIncremental(lhs, rhs);} 82 | double operator()(VECTOR const& lhs, VECTOR const& rhs, int i)const 83 | {return iDistanceIncremental(lhs, rhs, i);} 84 | double operator()(double bound, VECTOR const& lhs, VECTOR const& rhs) 85 | const{return distanceIncremental(lhs, rhs, bound);} 86 | }; 87 | }; 88 | 89 | }//end namespace 90 | #endif 91 | -------------------------------------------------------------------------------- /ComputationalGeometry/testBuildingArea.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "BuildingArea.h" 3 | using namespace igmdk; 4 | 5 | int main() 6 | { 7 | testBuildingArea(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ComputationalGeometry/testConvexHull.cpp: -------------------------------------------------------------------------------- 1 | #include "ConvexHull.h" 2 | #include "../Utils/Debug.h" 3 | #include 4 | using namespace igmdk; 5 | 6 | void testConvexHull() 7 | { 8 | Vector points, result; 9 | int N = 5; 10 | for(int i = 0; i < N; ++i) 11 | { 12 | points.append(Point2(GlobalRNG().uniform01(), GlobalRNG().uniform01())); 13 | DEBUG(points[i][0]); 14 | DEBUG(points[i][1]); 15 | } 16 | result = convexHull(points); 17 | DEBUG(result.getSize()); 18 | for(int i = 0; i < result.getSize(); ++i) 19 | { 20 | DEBUG(result[i][0]); 21 | DEBUG(result[i][1]); 22 | } 23 | } 24 | 25 | int main() 26 | { 27 | testConvexHull(); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Cryptography/Cryptography.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CRYPTOGRAPHY_H 2 | #define IGMDK_CRYPTOGRAPHY_H 3 | #include "../RandomNumberGeneration/Random.h" 4 | #include "../Utils/Utils.h" 5 | #include "../ErrorCorrectingCodes/CRC.h" 6 | #include "../Compression/Compression.h" 7 | using namespace std; 8 | 9 | namespace igmdk{ 10 | 11 | void applyARC4(uint32_t seed, Vector temp, 12 | Vector& data) 13 | { 14 | for(int i = 0; i < temp.getSize(); ++i) 15 | temp[i] ^= (seed = xorshiftTransform(seed)); 16 | ARC4 arc4(temp.getArray(), temp.getSize()); 17 | for(int i = 0; i < data.getSize(); ++i) data[i] ^= arc4.nextByte(); 18 | } 19 | Vector simpleEncrypt(Vector data, 20 | Vector const& key) 21 | { 22 | uint32_t seed = time(0), s = sizeof(int); 23 | CRC32 crc32; 24 | Vector theSeed = ReinterpretEncode(seed, s), crc = 25 | ReinterpretEncode(crc32.hash(data.getArray(), data.getSize()), s); 26 | for(int i = 0; i < s; ++i) data.append(crc[i]); 27 | applyARC4(seed, key, data); 28 | for(int i = 0; i < s; ++i) data.append(theSeed[i]); 29 | return data; 30 | } 31 | pair, bool> simpleDecrypt(Vector code, 32 | Vector const& key) 33 | { 34 | assert(code.getSize() >= 8); 35 | enum{s = sizeof(uint32_t)}; 36 | Vector seed, crc; 37 | for(int i = 0; i < s; ++i) seed.append(code[code.getSize() + i - 4]); 38 | for(int i = 0; i < s; ++i) code.removeLast(); 39 | applyARC4(ReinterpretDecode(seed), key, code); 40 | for(int i = 0; i < s; ++i) crc.append(code[code.getSize() + i - 4]); 41 | for(int i = 0; i < s; ++i) code.removeLast(); 42 | CRC32 crc32; 43 | return make_pair(code, crc32.hash(code.getArray(), code.getSize()) == 44 | ReinterpretDecode(crc)); 45 | } 46 | 47 | }//end namespace 48 | #endif 49 | -------------------------------------------------------------------------------- /Cryptography/CryptographyTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CRYPTOGRAPHY_TEST_AUTO_H 2 | #define IGMDK_CRYPTOGRAPHY_TEST_AUTO_H 3 | #include "Cryptography.h" 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | namespace igmdk{ 9 | 10 | void testSimpleEncryptAuto() 11 | { 12 | DEBUG("testSimpleEncryptAuto"); 13 | string s = "top secret info", key = "123456", sDecrypted; 14 | enum{B = 128}; 15 | Vector data, password; 16 | for(int i = 0; i < B; ++i) 17 | { 18 | data.append(i < s.length() ? s[i] : 0); 19 | password.append(i < key.length() ? key[i] : 0); 20 | } 21 | assert(data == simpleDecrypt(simpleEncrypt(data, password), 22 | password).first); 23 | DEBUG("testSimpleEncryptAuto passed"); 24 | } 25 | 26 | void testAllAutoCryptography() 27 | { 28 | DEBUG("testAllAutoCryptography"); 29 | testSimpleEncryptAuto(); 30 | } 31 | 32 | }//end namespace 33 | #endif 34 | -------------------------------------------------------------------------------- /Cryptography/test.cpp: -------------------------------------------------------------------------------- 1 | #include "Cryptography.h" 2 | #include "CryptographyTestAuto.h" 3 | using namespace igmdk; 4 | 5 | int main() 6 | { 7 | testAllAutoCryptography(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /ErrorCorrectingCodes/CRC.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CRC_H 2 | #define IGMDK_CRC_H 3 | #include 4 | 5 | namespace igmdk{ 6 | 7 | using namespace std; 8 | 9 | class CRC32 10 | { 11 | uint32_t polynomial, constant[256]; 12 | public: 13 | CRC32(uint32_t thePolynomial = 0xFA567D89u):polynomial(thePolynomial) 14 | { 15 | for(int i = 0; i < 256; ++i) 16 | { 17 | constant[i] = i << 24;//make extended c 18 | for(int j = 0; j < 8; ++j) constant[i] = 19 | (constant[i] << 1) ^ (constant[i] >> 31 ? polynomial : 0); 20 | } 21 | } 22 | uint32_t hash(unsigned char* array, int size, uint32_t crc = 0) 23 | { 24 | assert(numeric_limits::digits == 8); 25 | for(int i = 0; i < size; ++i) 26 | crc = (crc << 8) ^ constant[(crc >> 24) ^ array[i]]; 27 | return crc; 28 | } 29 | }; 30 | 31 | }//end namespace 32 | #endif 33 | -------------------------------------------------------------------------------- /ErrorCorrectingCodes/ErrorCorrectingCodesTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_ERROR_CORRECTING_CODES_TEST_AUTO_H 2 | #define IGMDK_ERROR_CORRECTING_CODES_TEST_AUTO_H 3 | #include "CRC.h" 4 | #include "ReedSolomon.h" 5 | #include "LDPC.h" 6 | #include 7 | using namespace std; 8 | 9 | namespace igmdk{ 10 | 11 | void testReedSolomonAuto() 12 | { 13 | DEBUG("testReedSolomonAuto"); 14 | Vector message; 15 | string text = "Four score and seven years ago our fathers brought forth" 16 | " on this continent a new nation ..."; 17 | for(int i = 0; i < text.size(); ++i) message.append(text[i]); 18 | int n = 255, p = (n - 223)/2; 19 | for(int j = 0; j < 1000; ++j) 20 | { 21 | ReedSolomon rs; 22 | Vector code = rs.encodeBlock(rs.lengthPadBlock(message)); 23 | for(int i = 0; i < p; ++i)//introduce upto p random errors 24 | { 25 | int location = GlobalRNG().mod(n); 26 | code[location] = GlobalRNG().mod(256); 27 | } 28 | pair, bool> result = rs.decodeBlock(code); 29 | assert(result.second); 30 | result = rs.lengthUnpadBlock(result.first); 31 | assert(result.second); 32 | Vector messageDecoded = result.first; 33 | assert(message == messageDecoded); 34 | } 35 | DEBUG("testReedSolomonAuto passed"); 36 | } 37 | 38 | void testAllAutoErrorCorrectingCodes() 39 | { 40 | DEBUG("testAllAutoErrorCorrectingCodes"); 41 | testReedSolomonAuto(); 42 | } 43 | 44 | }//end namespace 45 | #endif 46 | -------------------------------------------------------------------------------- /ErrorCorrectingCodes/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "ErrorCorrectingCodesTestAuto.h" 4 | using namespace std; 5 | using namespace igmdk; 6 | 7 | void testLDPCAuto()//takes ~100 seconds on my pc 8 | {//not quite auto need better statistical tests here 9 | int n = 20, k = 5; 10 | int nFailed = 0, nFalseSuccess = 0, nCodes = 100, nTests = 100; 11 | for(int m = 0; m < nCodes; ++m) 12 | { 13 | LDPC l(n, k); 14 | Bitset<> message(l.getNewK()); 15 | for(int i = 0; i < message.getSize(); ++i) 16 | message.set(i, GlobalRNG().mod(2));//random message 17 | for(int j = 0; j < nTests; ++j) 18 | { 19 | Bitset<> code = l.encode(message); 20 | //below use the worst-case bound but need to try other values 21 | for(int i = 0; i < (n - l.getNewK())/2; ++i) 22 | code.set(GlobalRNG().mod(code.getSize()), GlobalRNG().mod(2)); 23 | 24 | pair, bool> result = l.decode(code); 25 | if(!result.second) ++nFailed; 26 | else if(message != result.first) ++nFalseSuccess; 27 | } 28 | } 29 | DEBUG(nFailed * 1.0/nTests/nCodes);//0.34 particular run 30 | DEBUG(nFalseSuccess * 1.0/nTests/nCodes);//0.09 particular run 31 | } 32 | 33 | void testLDPC() 34 | { 35 | LDPC l(20, 5); 36 | Bitset<> message(l.getNewK()); 37 | message.setAll(); 38 | message.set(1, 0); 39 | message.set(0, 0); 40 | DEBUG("message"); 41 | message.debug(); 42 | Bitset<> code = l.encode(message); 43 | DEBUG("code"); 44 | code.debug(); 45 | for(int i = 0; i < 3; ++i) 46 | code.set(GlobalRNG().mod(code.getSize()), GlobalRNG().mod(2)); 47 | DEBUG("code"); 48 | code.debug(); 49 | pair, bool> result = l.decode(code); 50 | message = result.first; 51 | DEBUG(result.second); 52 | DEBUG("message"); 53 | message.debug();//fails very occasionally 54 | } 55 | 56 | int main() 57 | { 58 | testAllAutoErrorCorrectingCodes(); 59 | testLDPC(); 60 | testLDPCAuto(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /ExternalMemoryAlgorithms/EMFreelist.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_EMFREELIST_H 2 | #define IGMDK_EMFREELIST_H 3 | 4 | #include "EMVector.h" 5 | 6 | namespace igmdk{ 7 | 8 | template > 9 | class EMFreelist 10 | { 11 | EMVector nodes; 12 | EMVector > returned; 13 | //disallow copying 14 | EMFreelist(EMFreelist const&); 15 | EMFreelist& operator=(EMFreelist const&); 16 | public: 17 | EMFreelist(string const& filenameSuffix, int cacheSize = 2): 18 | nodes("Nodes" + filenameSuffix, cacheSize), 19 | returned("Returned" + filenameSuffix){} 20 | long long allocate(POD const& item = POD()) 21 | { 22 | if(returned.getSize() > 0) 23 | {//reuse the last deallocated node 24 | long long result = returned[returned.getSize() - 1]; 25 | returned.removeLast(); 26 | nodes.set(item, result); 27 | return result; 28 | } 29 | else 30 | { 31 | nodes.append(item); 32 | return nodes.getSize() - 1; 33 | } 34 | } 35 | void deallocate(long long i) 36 | {//no efficient way to check if already deallocated 37 | assert(i >= 0 && i < nodes.getSize()); 38 | returned.append(i); 39 | } 40 | POD operator[](long long i) 41 | {//no efficient way to check if already deallocated 42 | assert(i >= 0 && i < nodes.getSize()); 43 | return nodes[i]; 44 | } 45 | void set(POD const& item, long long i) 46 | {//no efficient way to check if already deallocated 47 | assert(i >= 0 && i < nodes.getSize()); 48 | nodes.set(item, i); 49 | } 50 | }; 51 | 52 | }//end namespace 53 | #endif 54 | -------------------------------------------------------------------------------- /FinancialCalculations/OptionPricing.h: -------------------------------------------------------------------------------- 1 | #ifndef OPTION_PRICING_H 2 | #define OPTION_PRICING_H 3 | #include "../RandomNumberGeneration/Statistics.h" 4 | namespace igmdk{ 5 | 6 | double priceEuropeanCall(double price, double r, double q, 7 | double strikePrice, double strikeTime, double t0 = 0) 8 | {//Black-Scholes formula 9 | //r, q, and time have same period unit, usually annual 10 | assert(price > 0 && isfinite(r) && r > 0 && q > 0 && strikePrice > 0 && 11 | strikeTime > 0 && t0 <= strikeTime); 12 | double t = strikeTime - t0, temp = q * sqrt(t), 13 | d1 = (log(price/strikePrice) + (r + q * q/2) * t)/temp, 14 | d2 = d1 - temp, discountedStrike = strikePrice * exp(-r * t); 15 | return price * approxNormalCDF(d1) - discountedStrike * approxNormalCDF(d2); 16 | } 17 | 18 | double priceEuropeanPut(double price, double riskFreeRate, double r, double q, 19 | double strikePrice, double strikeTime, double t0 = 0) 20 | {//price call, then use put-call parity with continuous compounding discounting 21 | assert(price > 0 && isfinite(r) && r > 0 && q > 0 && strikePrice > 0 && 22 | strikeTime > 0 && t0 <= strikeTime); 23 | double callPrice = priceEuropeanCall(price, r, q, strikePrice, strikeTime, 24 | t0), discountedStrike = strikePrice * exp(-riskFreeRate * strikeTime); 25 | return callPrice + discountedStrike - price; 26 | } 27 | 28 | }//end namespace 29 | #endif 30 | -------------------------------------------------------------------------------- /Graphs/test.cpp: -------------------------------------------------------------------------------- 1 | #include "Graph.h" 2 | #include "GraphsTestAuto.h" 3 | #include "../Utils/Debug.h" 4 | using namespace igmdk; 5 | 6 | void DDDGraph() 7 | { 8 | typedef GraphAA G; 9 | G Graph05; 10 | for(int i = 0; i < 6; ++i) 11 | { 12 | Graph05.addVertex(); 13 | } 14 | Graph05.addEdge(0,1,6); 15 | Graph05.addEdge(0,2,8); 16 | Graph05.addEdge(0,3,18); 17 | Graph05.addEdge(1,4,11); 18 | Graph05.addEdge(2,3,9); 19 | Graph05.addEdge(4,5,3); 20 | Graph05.addEdge(5,2,7); 21 | Graph05.addEdge(5,3,4); 22 | 23 | cout << "breakpoint" << endl; 24 | } 25 | 26 | int main() 27 | { 28 | testAllAutoGraphs(); 29 | DDDGraph(); 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Graphs/testNetworkFlow.cpp: -------------------------------------------------------------------------------- 1 | #include "NetworkFlowTestAuto.h" 2 | #include "../Utils/Debug.h" 3 | using namespace igmdk; 4 | 5 | int main() 6 | { 7 | testAllAutoNetworkFlow(); 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /HashTable/BloomFilter.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_BLOOM_FILTER_H 2 | #define IGMDK_BLOOM_FILTER_H 3 | 4 | #include 5 | #include "../Utils/Bitset.h" 6 | #include "HashFunction.h" 7 | using namespace std; 8 | 9 | namespace igmdk{ 10 | 11 | template > 12 | class BloomFilter 13 | { 14 | Bitset items;//must be before h1, h2 15 | HASHER h1, h2; 16 | int nHashes; 17 | int hash(int hash1, int hash2, int i) 18 | { 19 | if(i == 0) return hash1; 20 | if(i == 1) return hash2; 21 | return (hash1 + i * hash2) % items.getSize(); 22 | } 23 | public: 24 | BloomFilter(int m, int theNHashes = 7): nHashes(theNHashes), items( 25 | nextPowerOfTwo(m)), h1(items.getSize()), h2(items.getSize()) 26 | {assert(m > 0 && theNHashes > 0);} 27 | void insert(KEY const& key) 28 | { 29 | int hash1 = h1(key), hash2 = h2(key); 30 | for(int i = 0; i < nHashes; ++i) items.set(hash(hash1, hash2, i)); 31 | } 32 | bool isInserted(KEY const& key) 33 | { 34 | int hash1 = h1.hash(key), hash2 = h2.hash(key); 35 | for(int i = 0; i < nHashes; ++i) 36 | if(!items[hash(hash1, hash2, i)]) return false; 37 | return true; 38 | } 39 | }; 40 | 41 | }//end namespace 42 | #endif 43 | -------------------------------------------------------------------------------- /HashTable/HashTableTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_HASH_TABLE_TEST_AUTO_H 2 | #define IGMDK_HASH_TABLE_TEST_AUTO_H 3 | 4 | #include "MapTestAutoHelper.h" 5 | #include "ChainingHashTable.h" 6 | #include "LinearProbingHashTable.h" 7 | 8 | namespace igmdk{ 9 | 10 | void testChainingHashTableAuto() 11 | { 12 | DEBUG("testChainingHashTableAuto"); 13 | testMapAutoHelper >(); 14 | DEBUG("testChainingHashTableAuto passed"); 15 | } 16 | 17 | void testLinearProbingHashTableAuto() 18 | { 19 | DEBUG("testLinearProbingHashTableAuto"); 20 | testMapAutoHelper >(); 21 | DEBUG("testLinearProbingHashTableAuto passed"); 22 | } 23 | 24 | void testAllAutoHashTable() 25 | { 26 | DEBUG("testAllAutoHashTable"); 27 | testChainingHashTableAuto(); 28 | testLinearProbingHashTableAuto(); 29 | } 30 | 31 | }//end namespace 32 | #endif 33 | -------------------------------------------------------------------------------- /HashTable/MapTestAutoHelper.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_MAP_TEST_AUTO_HELPER_H 2 | #define IGMDK_MAP_TEST_AUTO_HELPER_H 3 | 4 | #include "../Utils/Bitset.h" 5 | 6 | namespace igmdk{ 7 | 8 | struct Struct10_2 9 | { 10 | enum{SIZE = 10}; 11 | int array[SIZE]; 12 | Struct10_2(int last) 13 | { 14 | for(int i = 1; i < SIZE; ++i) 15 | { 16 | array[i] = i; 17 | } 18 | array[0] = last; 19 | } 20 | bool operator==(Struct10_2 const& rhs)const 21 | { 22 | for(int i = 0; i < SIZE; ++i) 23 | { 24 | if(array[i] != rhs.array[i]) return false; 25 | } 26 | return true; 27 | } 28 | bool operator<(Struct10_2 const& rhs)const 29 | { 30 | for(int i = 0; i < SIZE; ++i) 31 | { 32 | if(array[i] < rhs.array[i]) return true; 33 | if(array[i] > rhs.array[i]) return false; 34 | } 35 | return false; 36 | } 37 | int getSize()const{return SIZE;} 38 | int const operator[](int i)const{return array[i];} 39 | }; 40 | 41 | template void testMapAutoHelper(int n = 100000) 42 | { 43 | MAP_II m; 44 | for(int i = 0; i < n; ++i) m.insert(i, -i); 45 | Bitset<> seen(n), allSet(n); 46 | seen.setAll(false); 47 | allSet.setAll(true); 48 | for(typename MAP_II::Iterator e = m.end(), i = m.begin(); i != e; ++i) 49 | { 50 | assert(!seen[i->key]); 51 | seen.set(i->key, true); 52 | assert(i->value == -i->key); 53 | } 54 | assert(seen == allSet); 55 | for(int i = 0; i < n; ++i) 56 | { 57 | assert(m.find(i)); 58 | assert(*m.find(i) == -i); 59 | m.remove(i); 60 | assert(!m.find(i)); 61 | } 62 | } 63 | 64 | }//end namespace 65 | #endif 66 | -------------------------------------------------------------------------------- /Heaps/Heap.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_HEAP_H 2 | #define IGMDK_HEAP_H 3 | #include "../Utils/Vector.h" 4 | namespace igmdk{ 5 | 6 | template 7 | struct ReportDefault{void operator()(ITEM& item, int i){}}; 8 | template, 9 | typename REPORTER = ReportDefault > class Heap 10 | { 11 | REPORTER r; 12 | int getParent(int i)const{return (i - 1)/2;} 13 | int getLeftChild(int i)const{return 2 * i + 1;} 14 | Vector items; 15 | void moveUp(int i) 16 | { 17 | ITEM temp = items[i]; 18 | for(int parent; i > 0 && c(temp, items[parent = getParent(i)]); 19 | i = parent) r(items[i] = items[parent], i); 20 | r(items[i] = temp, i); 21 | } 22 | void moveDown(int i) 23 | { 24 | ITEM temp = items[i]; 25 | for(int child; (child = getLeftChild(i)) < items.getSize(); i = child) 26 | {//find smaller child 27 | int rightChild = child + 1; 28 | if(rightChild < items.getSize() && c(items 29 | [rightChild], items[child])) child = rightChild; 30 | //replace with the smaller child if any 31 | if(!c(items[child], temp)) break; 32 | r(items[i] = items[child], i); 33 | } 34 | r(items[i] = temp, i); 35 | } 36 | public: 37 | COMPARATOR c; 38 | Heap(COMPARATOR const& theC = COMPARATOR(), REPORTER const& 39 | theReporter = REPORTER()): r(theReporter), c(theC) {} 40 | bool isEmpty()const{return items.getSize() == 0;} 41 | int getSize()const{return items.getSize();} 42 | ITEM const& getMin()const 43 | { 44 | assert(!isEmpty()); 45 | return items[0]; 46 | } 47 | void insert(ITEM const& item) 48 | { 49 | items.append(item); 50 | moveUp(items.getSize() - 1); 51 | } 52 | ITEM const& operator[](int i)const 53 | {//random access is useful with item handles 54 | assert(i >= 0 && i < items.getSize()); 55 | return items[i]; 56 | } 57 | void changeKey(int i, ITEM const& item) 58 | { 59 | assert(i >= 0 && i < items.getSize()); 60 | bool decrease = c(item, items[i]); 61 | items[i] = item; 62 | decrease ? moveUp(i) : moveDown(i); 63 | } 64 | ITEM deleteMin(){return remove(0);} 65 | ITEM remove(int i) 66 | { 67 | assert(i >= 0 && i < items.getSize()); 68 | ITEM result = items[i]; 69 | r(result, -1); 70 | if(items.getSize() > i) 71 | {//not last item 72 | items[i] = items.lastItem(); 73 | r(items[i], i);//report move 74 | moveDown(i);//won't touch the last item 75 | } 76 | items.removeLast(); 77 | return result; 78 | } 79 | }; 80 | 81 | }//end namespace 82 | #endif 83 | -------------------------------------------------------------------------------- /Heaps/HeapTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_HEAP_TEST_AUTO_H 2 | #define IGMDK_HEAP_TEST_AUTO_H 3 | #include 4 | using namespace std; 5 | #include "Heap.h" 6 | #include "IndexedHeap.h" 7 | #include "../Sorting/Sort.h" 8 | 9 | namespace igmdk{ 10 | 11 | void testHeapAuto() 12 | { 13 | DEBUG("testHeapAuto"); 14 | int N = 1000000; 15 | Heap heap; 16 | for(int i = 0; i < N; ++i) 17 | { 18 | heap.insert(i); 19 | } 20 | Vector nums; 21 | for(int i = 0; i < N; ++i) 22 | { 23 | nums.append(heap.deleteMin()); 24 | } 25 | assert(isSorted(nums.getArray(), 0, N - 1, DefaultComparator())); 26 | DEBUG("testHeapAuto passed"); 27 | } 28 | 29 | void testAllAutoHeaps() 30 | { 31 | DEBUG("testAllAutoHeaps"); 32 | testHeapAuto(); 33 | } 34 | 35 | }//end namespace 36 | #endif 37 | -------------------------------------------------------------------------------- /Heaps/test.cpp: -------------------------------------------------------------------------------- 1 | #include "HeapTestAuto.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace igmdk; 7 | 8 | void timeSRT() 9 | { 10 | IndexedHeap heap; 11 | int N = 1500000; 12 | //IndexedArrayHeap heap; 13 | for(int i = 0; i < N; ++i) 14 | { 15 | heap.insert(rand()%10, i); 16 | } 17 | for(int i = 0; i < N; ++i) 18 | { 19 | heap.deleteMin(); 20 | } 21 | } 22 | 23 | void DDDIndexedHeap() 24 | { 25 | IndexedHeap IndexedHeap0to3; 26 | for(int i = 0; i < 4; ++i) 27 | { 28 | IndexedHeap0to3.insert(rand(), i); 29 | } 30 | cout << "breakpoint" << endl; 31 | } 32 | 33 | void DDDIndexedArrayHeap() 34 | { 35 | IndexedArrayHeap IndexedArrayHeap0to3; 36 | for(int i = 0; i < 4; ++i) 37 | { 38 | IndexedArrayHeap0to3.insert(rand(), i); 39 | } 40 | cout << "breakpoint" << endl; 41 | } 42 | 43 | int main() 44 | { 45 | testAllAutoHeaps(); 46 | DDDIndexedHeap(); 47 | DDDIndexedArrayHeap(); 48 | timeSRT(); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /LargeNumbers/LargeNumberTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_LARGE_NUMBER_TEST_AUTO_H 2 | #define IGMDK_LARGE_NUMBER_TEST_AUTO_H 3 | #include "LargeNumber.h" 4 | #include "LargeRational.h" 5 | 6 | namespace igmdk{ 7 | 8 | void testNumberAuto() 9 | { 10 | assert((-Number(0) - Number(2)) == (Number(0) - Number(2))); 11 | assert((Number(2) - Number(0)) == (Number(2) - -Number(0))); 12 | 13 | Number m = power(Number(2), Number(128)); 14 | m >>= 125; 15 | assert(m == Number(8)); 16 | m <<= 125; 17 | assert(power(Number(2), Number(2)) == Number(4)); 18 | assert(Number(4) % Number(3) == Number(1)); 19 | assert(modInverse(Number(4), Number(7)) == Number(2)); 20 | 21 | assert((Number(-11) % Number(103)) == Number(-11)); 22 | assert(gcd(m, Number(3)) == Number(1)); 23 | assert(sqrtInt(Number(99)) == Number(9)); 24 | assert(modPower(Number(2), Number(2), Number(3)) == Number(1)); 25 | assert(isPrime(Number((3)))); 26 | assert(isPrime(Number((53)))); 27 | assert(!isPrime(Number((616460792)))); 28 | assert(Number(-23).toDecimalString() == "-23"); 29 | assert(Number("-23") == Number(-23)); 30 | } 31 | 32 | void testAllAutoLargeNumber() 33 | { 34 | DEBUG("testAllAutoLargeNumber"); 35 | testNumberAuto(); 36 | } 37 | 38 | }//end namespace 39 | #endif 40 | -------------------------------------------------------------------------------- /LargeNumbers/LargeRational.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_LARGE_RATIONAL_H 2 | #define IGMDK_LARGE_RATIONAL_H 3 | #include "LargeNumber.h" 4 | #include "../Utils/Utils.h" 5 | #include "../Utils/Debug.h" 6 | #include "../Utils/Vector.h" 7 | using namespace std; 8 | namespace igmdk{ 9 | 10 | pair rationalize(double x) 11 | {//only support the usual binary (not decimal) 12 | assert(numeric_limits::radix == 2 && 13 | numeric_limits::digits <= numeric_limits::digits); 14 | int w = numeric_limits::digits, e; 15 | x = frexp(x, &e);//normalize x into [0.5, 1) 16 | long long mantissa = ldexp(x, w);//find x^53 17 | return make_pair(mantissa, e - w); 18 | } 19 | 20 | struct Rational: public ArithmeticType 21 | { 22 | Number numerator, denominator; 23 | Rational(Number const& theNumerator = Number(0), 24 | Number const& theDenominator = Number(1)): numerator(theNumerator), 25 | denominator(theDenominator) 26 | { 27 | assert(!denominator.isZero()); 28 | reduce(); 29 | } 30 | Rational(double x): denominator(1), numerator(1) 31 | { 32 | pair mantissaExponent = rationalize(x); 33 | numerator = Number(mantissaExponent.first); 34 | int e = mantissaExponent.second; 35 | if(e < 0) denominator <<= -e; 36 | else if(e > 0) numerator <<= e; 37 | } 38 | void reduce() 39 | { 40 | Number g = gcd(numerator, denominator); 41 | numerator /= g; 42 | denominator /= g; 43 | } 44 | bool isZero()const{return numerator.isZero();} 45 | bool isMinus()const 46 | {return numerator.isNegative() != denominator.isNegative();} 47 | 48 | Rational operator-()const 49 | { 50 | Rational result = *this; 51 | result.numerator.negate(); 52 | return result; 53 | } 54 | Rational& operator+=(Rational const& rhs) 55 | { 56 | numerator = numerator * rhs.denominator + rhs.numerator * 57 | denominator; 58 | denominator *= rhs.denominator; 59 | reduce(); 60 | return *this; 61 | } 62 | Rational& operator-=(Rational const& rhs){return *this += -rhs;} 63 | 64 | Rational& operator*=(Rational const& rhs) 65 | { 66 | numerator *= rhs.numerator; 67 | denominator *= rhs.denominator; 68 | reduce(); 69 | return *this; 70 | } 71 | Rational& operator/=(Rational const& rhs) 72 | { 73 | assert(!rhs.isZero()); 74 | numerator *= rhs.denominator; 75 | denominator * rhs.numerator; 76 | reduce(); 77 | return *this; 78 | } 79 | 80 | int lg()const{return numerator.lg() - denominator.lg();} 81 | Number evaluate(Number const& scale = Number(1)) 82 | {return numerator * scale / denominator;} 83 | }; 84 | 85 | }//end namespace 86 | #endif 87 | -------------------------------------------------------------------------------- /LargeNumbers/test.cpp: -------------------------------------------------------------------------------- 1 | #include "LargeNumberTestAuto.h" 2 | #include "../Utils/Debug.h" 3 | using namespace igmdk; 4 | 5 | void DDDNumber() 6 | { 7 | Number n(2); 8 | Number TwoPow100 = power(n, Number(100)); 9 | 10 | cout << "breakpoint" << endl; 11 | } 12 | 13 | void testRationalizeHelper(double x) 14 | { 15 | DEBUG(numeric_limits::digits); 16 | pair me = rationalize(x); 17 | DEBUG(me.first); 18 | DEBUG(me.second); 19 | DEBUG(me.first * pow(2, me.second)); 20 | } 21 | 22 | void testRationalize() 23 | { 24 | testRationalizeHelper(10); 25 | testRationalizeHelper(0); 26 | testRationalizeHelper(1.0/3); 27 | } 28 | 29 | int main() 30 | { 31 | testAllAutoLargeNumber(); 32 | testRationalize(); 33 | //return 0; 34 | DDDNumber(); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /MachineLearning/APriori.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_APRIORI_H 2 | #define IGMDK_APRIORI_H 3 | 4 | #include "../Sorting/Sort.h" 5 | #include "../RandomTreap/LCPTreap.h" 6 | #include "../MiscAlgs/CombinatorialGeneration.h" 7 | namespace igmdk{ 8 | 9 | struct APriori 10 | { 11 | LCPTreap, int> counts; 12 | int processBasket(Vector const& basket, int round, 13 | int rPrevMinCount = 0, int r1MinCount = 0) 14 | { 15 | int addedCount = 0; 16 | if(basket.getSize() > round) 17 | { 18 | Combinator c(round, basket.getSize()); 19 | do//prepare the current combination of ids, needn't sort if each 20 | {//basket is already sorted 21 | Vector key, single; 22 | for(int i = 0; i < round; ++i) key.append(basket[c.c[i]]); 23 | quickSort(key.getArray(), key.getSize()); 24 | int* count = counts.find(key); 25 | if(count) ++*count;//combination is frequent if already 26 | else if(round == 1)//frequent or round is 1 27 | { 28 | counts.insert(key, 1); 29 | ++addedCount; 30 | } 31 | else//combination is frequent if the last item and 32 | {//combination without the last item are both frequent 33 | single.append(key.lastItem()); 34 | if(*counts.find(single) >= r1MinCount) 35 | { 36 | key.removeLast(); 37 | if(*counts.find(key) >= rPrevMinCount) 38 | { 39 | key.append(single[0]); 40 | counts.insert(key, 1); 41 | ++addedCount; 42 | } 43 | } 44 | } 45 | }while(!c.next()); 46 | } 47 | return addedCount; 48 | } 49 | void noCutProcess(Vector >const& baskets, int nRounds) 50 | { 51 | for(int k = 1; k <= nRounds; ++k) 52 | for(int i = 0; i < baskets.getSize(); ++i) 53 | processBasket(baskets[i], k); 54 | } 55 | }; 56 | 57 | }//end namespace 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /MachineLearning/Classification.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_MACHINELEARNING_H 2 | #define IGMDK_MACHINELEARNING_H 3 | #include "ClassificationCommon.h" 4 | #include "RandomForest.h" 5 | #include "KernelSVM.h" 6 | namespace igmdk{ 7 | 8 | template struct SmartFSLearner 9 | { 10 | typedef FeatureSubsetLearner MODEL; 11 | MODEL model; 12 | public: 13 | template SmartFSLearner(DATA const& data, int limit = 20): 14 | model(data, selectFeaturesSmart(SCVRiskFunctor,DATA>( 15 | data), getD(data), limit)) {} 16 | int predict(NUMERIC_X const& x)const{return model.predict(x);} 17 | }; 18 | 19 | class SimpleBestCombiner 20 | { 21 | BestCombiner c; 22 | public: 23 | template SimpleBestCombiner(DATA const& data) 24 | { 25 | c.addNoParamsClassifier(data, SCVRiskFunctor< 26 | NoParamsLearner, EMPTY, DATA>(data)); 27 | c.addNoParamsClassifier(data, SCVRiskFunctor< 28 | NoParamsLearner, EMPTY, DATA>(data)); 29 | } 30 | int predict(NUMERIC_X const& x)const{return c.predict(x);} 31 | }; 32 | 33 | }//end namespace 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /MachineLearning/ClusterResults.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/MachineLearning/ClusterResults.ods -------------------------------------------------------------------------------- /MachineLearning/ClusterResultsNew.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/MachineLearning/ClusterResultsNew.ods -------------------------------------------------------------------------------- /MachineLearning/Datasets/arcene_train.labels: -------------------------------------------------------------------------------- 1 | 1 2 | -1 3 | 1 4 | 1 5 | -1 6 | -1 7 | 1 8 | -1 9 | -1 10 | -1 11 | -1 12 | 1 13 | -1 14 | 1 15 | -1 16 | 1 17 | -1 18 | -1 19 | -1 20 | -1 21 | -1 22 | -1 23 | -1 24 | 1 25 | -1 26 | -1 27 | 1 28 | -1 29 | 1 30 | -1 31 | 1 32 | 1 33 | 1 34 | -1 35 | -1 36 | 1 37 | -1 38 | -1 39 | 1 40 | -1 41 | 1 42 | -1 43 | -1 44 | 1 45 | -1 46 | -1 47 | -1 48 | -1 49 | 1 50 | 1 51 | -1 52 | 1 53 | -1 54 | -1 55 | 1 56 | -1 57 | 1 58 | 1 59 | 1 60 | -1 61 | 1 62 | 1 63 | -1 64 | 1 65 | -1 66 | -1 67 | -1 68 | -1 69 | 1 70 | 1 71 | -1 72 | 1 73 | -1 74 | -1 75 | 1 76 | -1 77 | -1 78 | 1 79 | -1 80 | 1 81 | 1 82 | 1 83 | -1 84 | 1 85 | 1 86 | -1 87 | 1 88 | 1 89 | -1 90 | -1 91 | 1 92 | -1 93 | 1 94 | 1 95 | -1 96 | -1 97 | -1 98 | 1 99 | -1 100 | 1 101 | -------------------------------------------------------------------------------- /MachineLearning/Datasets/arcene_valid.labels: -------------------------------------------------------------------------------- 1 | -1 2 | -1 3 | -1 4 | 1 5 | 1 6 | 1 7 | -1 8 | 1 9 | -1 10 | -1 11 | 1 12 | -1 13 | -1 14 | 1 15 | -1 16 | -1 17 | 1 18 | 1 19 | 1 20 | 1 21 | 1 22 | -1 23 | 1 24 | -1 25 | 1 26 | -1 27 | -1 28 | -1 29 | -1 30 | -1 31 | -1 32 | -1 33 | 1 34 | 1 35 | 1 36 | -1 37 | -1 38 | -1 39 | 1 40 | -1 41 | -1 42 | 1 43 | -1 44 | -1 45 | 1 46 | -1 47 | -1 48 | 1 49 | 1 50 | -1 51 | -1 52 | 1 53 | 1 54 | -1 55 | -1 56 | -1 57 | -1 58 | 1 59 | 1 60 | 1 61 | -1 62 | 1 63 | 1 64 | -1 65 | -1 66 | -1 67 | -1 68 | 1 69 | -1 70 | -1 71 | 1 72 | -1 73 | 1 74 | -1 75 | -1 76 | 1 77 | -1 78 | -1 79 | 1 80 | 1 81 | 1 82 | -1 83 | -1 84 | 1 85 | 1 86 | -1 87 | 1 88 | 1 89 | -1 90 | -1 91 | 1 92 | -1 93 | 1 94 | 1 95 | -1 96 | -1 97 | -1 98 | 1 99 | 1 100 | -1 101 | -------------------------------------------------------------------------------- /MachineLearning/ImbalanceClassification.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_IMBALANCE_CLASSIFICATION_H 2 | #define IGMDK_IMBALANCE_CLASSIFICATION_H 3 | #include "ClassificationCommon.h" 4 | #include "RandomForest.h" 5 | #include "KernelSVM.h" 6 | #include "../Utils/Vector.h" 7 | #include "../RandomNumberGeneration/Statistics.h" 8 | #include 9 | namespace igmdk{ 10 | 11 | class WeightedRF 12 | { 13 | Vector forest; 14 | int nClasses; 15 | public: 16 | template WeightedRF(DATA const& data, Vector const 17 | & weights, int nTrees = 300): nClasses(findNClasses(data)) 18 | { 19 | assert(data.getSize() > 1); 20 | AliasMethod sampler(weights); 21 | for(int i = 0; i < nTrees; ++i) 22 | { 23 | PermutedData resample(data); 24 | for(int j = 0; j < data.getSize(); ++j) 25 | resample.addIndex(sampler.next()); 26 | forest.append(DecisionTree(resample, 0, true)); 27 | } 28 | } 29 | int predict(NUMERIC_X const& x)const 30 | {return RandomForest::classifyWork(x, forest, nClasses);} 31 | }; 32 | 33 | template 34 | Vector findImbalanceWeights(DATA const& data) 35 | { 36 | int n = data.getSize(), properK = 0, nClasses = findNClasses(data); 37 | Vector counts(nClasses); 38 | for(int i = 0; i < n; ++i) ++counts[data.getY(i)]; 39 | for(int i = 0; i < nClasses; ++i) if(counts[i] > 0) ++properK; 40 | Vector dataWeights(n, 0); 41 | for(int i = 0; i < data.getSize(); ++i) 42 | dataWeights[i] = 1.0/properK/counts[data.getY(i)]; 43 | return dataWeights; 44 | } 45 | class ImbalanceRF 46 | { 47 | WeightedRF model; 48 | public: 49 | template ImbalanceRF(DATA const& data, int nTrees = 300): 50 | model(data, findImbalanceWeights(data), nTrees) {} 51 | int predict(NUMERIC_X const& x)const{return model.predict(x);} 52 | }; 53 | 54 | template 55 | class WeightedBaggedLearner 56 | { 57 | Vector models; 58 | int nClasses; 59 | public: 60 | template WeightedBaggedLearner(DATA const& data, 61 | Vector weights, PARAMS const& p = PARAMS(), int nBags = 15): 62 | nClasses(findNClasses(data)) 63 | { 64 | assert(data.getSize() > 1); 65 | AliasMethod sampler(weights); 66 | for(int i = 0; i < nBags; ++i) 67 | { 68 | PermutedData resample(data); 69 | for(int j = 0; j < data.getSize(); ++j) 70 | resample.addIndex(sampler.next()); 71 | models.append(LEARNER(resample, p)); 72 | } 73 | } 74 | int predict(NUMERIC_X const& x)const 75 | {return RandomForest::classifyWork(x, models, nClasses);} 76 | }; 77 | 78 | class ImbalanceSVM 79 | { 80 | WeightedBaggedLearner, 81 | pair > model; 82 | public: 83 | template ImbalanceSVM(DATA const& data): model(data, 84 | findImbalanceWeights(data), NoParamsSVM::gaussianMultiClassSVM(data)) 85 | {} 86 | int predict(NUMERIC_X const& x)const{return model.predict(x);} 87 | }; 88 | typedef ScaledLearner, int> SImbSVM; 89 | 90 | }//end namespace 91 | #endif 92 | 93 | -------------------------------------------------------------------------------- /MachineLearning/KNN.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_KNN_H 2 | #define IGMDK_KNN_H 3 | #include "ClassificationCommon.h" 4 | #include "../ComputationalGeometry/KDTree.h" 5 | #include 6 | namespace igmdk{ 7 | 8 | template::Distance> > class KNNClassifier 10 | { 11 | mutable INDEX instances; 12 | int n, nClasses; 13 | public: 14 | KNNClassifier(int theNClasses): nClasses(theNClasses), n(0) {} 15 | template KNNClassifier(DATA const& data): n(0), 16 | nClasses(findNClasses(data)) 17 | { 18 | for(int i = 0; i < data.getSize(); ++i) 19 | learn(data.getY(i), data.getX(i)); 20 | } 21 | void learn(int label, X const& x){instances.insert(x, label); ++n;} 22 | int predict(X const& x)const 23 | { 24 | Vector neighbors = 25 | instances.kNN(x, 2 * int(log(n))/2 + 1); 26 | Vector votes(nClasses); 27 | for(int i = 0; i < neighbors.getSize(); ++i) 28 | ++votes[neighbors[i]->value]; 29 | return argMax(votes.getArray(), votes.getSize()); 30 | } 31 | }; 32 | 33 | }//end namespace 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /MachineLearning/KNNRegression.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_KNN_REGRESSION_H 2 | #define IGMDK_KNN_REGRESSION_H 3 | #include "LearningCommon.h" 4 | #include "../ComputationalGeometry/KDTree.h" 5 | #include "../RandomNumberGeneration/Statistics.h" 6 | #include 7 | 8 | namespace igmdk{ 9 | 10 | template::Distance> > class KNNReg 12 | { 13 | mutable INDEX instances; 14 | int k; 15 | public: 16 | template KNNReg(DATA const& data, int theK = -1): k(theK) 17 | { 18 | assert(data.getSize() > 0); 19 | if(k == -1) k = 2 * int(log(data.getSize())/2) + 1; 20 | for(int i = 0; i < data.getSize(); ++i) 21 | learn(data.getY(i), data.getX(i)); 22 | } 23 | void learn(double label, X const& x){instances.insert(x, label);} 24 | double predict(X const& x)const 25 | { 26 | Vector neighbors = instances.kNN(x, k); 27 | IncrementalStatistics s; 28 | for(int i = 0; i < neighbors.getSize(); ++i) 29 | s.addValue(neighbors[i]->value); 30 | return s.getMean(); 31 | } 32 | }; 33 | typedef ScaledLearner, double>, double> SKNNReg; 34 | 35 | }//end namespace 36 | #endif 37 | 38 | -------------------------------------------------------------------------------- /MachineLearning/NaiveBayes.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_NAIVE_BAYES_H 2 | #define IGMDK_NAIVE_BAYES_H 3 | #include "ClassificationCommon.h" 4 | #include "../Utils/Vector.h" 5 | #include "../HashTable/ChainingHashTable.h" 6 | #include 7 | namespace igmdk{ 8 | 9 | class NaiveBayes 10 | { 11 | struct Feature 12 | { 13 | int count; 14 | LinearProbingHashTable valueCounts; 15 | Feature(): count(0) {} 16 | void add(int value) 17 | { 18 | ++count; 19 | int* valueCount = valueCounts.find(value); 20 | if(valueCount) ++*valueCount; 21 | else valueCounts.insert(value, 1); 22 | } 23 | double prob(int value) 24 | { 25 | int* valueCount = valueCounts.find(value); 26 | return (valueCount ? 1 + *valueCount : 1)/(1.0 + count); 27 | } 28 | }; 29 | typedef ChainingHashTable FEATURE_COUNTS; 30 | typedef ChainingHashTable CLASS_COUNTS; 31 | mutable CLASS_COUNTS counts; 32 | public: 33 | typedef Vector > SPARSE_CATEGORICAL_X; 34 | static SPARSE_CATEGORICAL_X convertToSparse(CATEGORICAL_X const& x) 35 | { 36 | SPARSE_CATEGORICAL_X result; 37 | for(int i = 0 ; i < x.getSize(); ++i) 38 | result.append(make_pair(i, x[i])); 39 | return result; 40 | } 41 | void learn(SPARSE_CATEGORICAL_X const& x, int label) 42 | { 43 | for(int i = 0; i < x.getSize(); ++i) 44 | { 45 | FEATURE_COUNTS* classCounts = counts.find(label); 46 | if(!classCounts) classCounts = &counts.insert(label, 47 | FEATURE_COUNTS())->value; 48 | Feature* f = classCounts->find(x[i].first); 49 | if(!f) f = &classCounts->insert(x[i].first, Feature())->value; 50 | f->add(x[i].second); 51 | } 52 | } 53 | int predict(SPARSE_CATEGORICAL_X const& x)const 54 | { 55 | double maxLL; 56 | int bestClass = -1; 57 | for(CLASS_COUNTS::Iterator i = counts.begin(); i != counts.end(); 58 | ++i) 59 | { 60 | double ll = 0; 61 | for(int j = 0; j < x.getSize(); j++) 62 | { 63 | Feature* f = i->value.find(x[j].first); 64 | if(f) ll += log(f->prob(x[j].second)); 65 | } 66 | if(bestClass == -1 || maxLL < ll) 67 | { 68 | maxLL = ll; 69 | bestClass = i->key; 70 | } 71 | } 72 | return bestClass; 73 | } 74 | }; 75 | 76 | struct NumericalBayes 77 | { 78 | NaiveBayes model; 79 | DiscretizerEqualWidth disc; 80 | template NumericalBayes(DATA const& data): disc(data) 81 | { 82 | for(int i = 0; i < data.getSize(); ++i) model.learn(NaiveBayes:: 83 | convertToSparse(disc(data.getX(i))), data.getY(i)); 84 | } 85 | int predict(NUMERIC_X const& x)const 86 | {return model.predict(NaiveBayes::convertToSparse(disc(x)));} 87 | }; 88 | 89 | }//end namespace 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /MachineLearning/NeuralNetworkRegression.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_NEURAL_NETWORK_REGRESSION_H 2 | #define IGMDK_NEURAL_NETWORK_REGRESSION_H 3 | #include "RegressionCommon.h" 4 | #include "../Utils/Utils.h" 5 | #include "../NumericalOptimization/NumericalOptimization.h" 6 | #include "../NumericalOptimization/DiscreteGlobalOptimization.h" 7 | #include "../RandomNumberGeneration/Statistics.h" 8 | #include 9 | 10 | namespace igmdk{ 11 | 12 | class HiddenLayerNNReg 13 | { 14 | Vector nns; 15 | public: 16 | template HiddenLayerNNReg(DATA const& data, 17 | Vectorconst& p, int nGoal = 100000, int nNns = 5): 18 | nns(nNns, NeuralNetwork(getD(data), true, p[0])) 19 | {//structure 20 | int nHidden = p[1], D = getD(data), 21 | nRepeats = ceiling(nGoal, data.getSize()); 22 | double a = sqrt(3.0/D); 23 | for(int l = 0; l < nns.getSize(); ++l) 24 | { 25 | NeuralNetwork& nn = nns[l]; 26 | nn.addLayer(nHidden); 27 | for(int j = 0; j < nHidden; ++j) 28 | for(int k = -1; k < D; ++k) 29 | nn.addConnection(0, j, k, k == -1 ? 0 : 30 | GlobalRNG().uniform(-a, a)); 31 | nn.addLayer(1); 32 | for(int k = -1; k < nHidden; ++k) 33 | nn.addConnection(1, 0, k, 0); 34 | } 35 | //training 36 | for(int j = 0; j < nRepeats; ++j) 37 | for(int i = 0; i < data.getSize(); ++i) 38 | learn(data.getX(i), data.getY(i)); 39 | } 40 | void learn(NUMERIC_X const& x, double label) 41 | { 42 | for(int l = 0; l < nns.getSize(); ++l) 43 | nns[l].learn(x, Vector(1, label)); 44 | } 45 | double evaluate(NUMERIC_X const& x)const 46 | { 47 | double result = 0; 48 | for(int l = 0; l < nns.getSize(); ++l) 49 | result += nns[l].evaluate(x)[0]; 50 | return result/nns.getSize(); 51 | } 52 | int predict(NUMERIC_X const& x)const{return evaluate(x);} 53 | }; 54 | struct NoParamsNNReg 55 | { 56 | HiddenLayerNNReg model; 57 | template static Vector findParams(DATA const& 58 | data, int rLow = -15, int rHigh = 5, int hLow = 0, int hHigh = 6) 59 | { 60 | Vector > sets(2); 61 | for(int i = rLow; i <= rHigh; i += 2) sets[0].append(pow(2, i)); 62 | for(int i = hLow; i <= hHigh; i += 2) sets[1].append(pow(2, i)); 63 | return gridMinimize(sets, 64 | RRiskFunctor, DATA>(data)); 65 | } 66 | template NoParamsNNReg(DATA const& data): 67 | model(data, findParams(data)) {} 68 | double predict(NUMERIC_X const& x)const{return model.predict(x);} 69 | }; 70 | typedef ScaledLearner, double, EMPTY, 71 | ScalerMQ> SNNReg; 72 | 73 | }//end namespace 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /MachineLearning/RandomForest.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_RANDOM_FOREST_H 2 | #define IGMDK_RANDOM_FOREST_H 3 | #include "ClassificationCommon.h" 4 | #include "DecisionTree.h" 5 | #include "../Utils/Vector.h" 6 | #include "../RandomNumberGeneration/Random.h" 7 | #include 8 | namespace igmdk{ 9 | 10 | class RandomForest 11 | { 12 | Vector forest; 13 | int nClasses; 14 | public: 15 | template RandomForest(DATA const& data, int nTrees = 300): 16 | nClasses(findNClasses(data)) 17 | { 18 | assert(data.getSize() > 1); 19 | for(int i = 0; i < nTrees; ++i) 20 | { 21 | PermutedData resample(data); 22 | for(int j = 0; j < data.getSize(); ++j) 23 | resample.addIndex(GlobalRNG().mod(data.getSize())); 24 | forest.append(DecisionTree(resample, 0, true)); 25 | } 26 | } 27 | template static int classifyWork(NUMERIC_X const& x, 28 | ENSEMBLE const& e, int nClasses) 29 | { 30 | Vector counts(nClasses, 0); 31 | for(int i = 0; i < e.getSize(); ++i) ++counts[e[i].predict(x)]; 32 | return argMax(counts.getArray(), counts.getSize()); 33 | } 34 | int predict(NUMERIC_X const& x)const 35 | {return classifyWork(x, forest, nClasses);} 36 | Vector classifyProbs(NUMERIC_X const& x)const 37 | { 38 | Vector counts(nClasses, 0); 39 | for(int i = 0; i < forest.getSize(); ++i) 40 | ++counts[forest[i].predict(x)]; 41 | normalizeProbs(counts); 42 | return counts; 43 | } 44 | }; 45 | 46 | }//end namespace 47 | #endif 48 | 49 | -------------------------------------------------------------------------------- /MachineLearning/RandomForestRegression.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_RANDOM_FOREST_REGRESSION_H 2 | #define IGMDK_RANDOM_FOREST_REGRESSION_H 3 | #include "LearningCommon.h" 4 | #include "../Utils/Vector.h" 5 | #include "../RandomNumberGeneration/Statistics.h" 6 | #include "RegressionTree.h" 7 | 8 | namespace igmdk{ 9 | 10 | class RandomForestReg 11 | { 12 | Vector forest; 13 | public: 14 | template RandomForestReg(DATA const& data, 15 | int nTrees = 300){addTrees(data, nTrees);} 16 | template void addTrees(DATA const& data, int nTrees) 17 | { 18 | assert(data.getSize() > 1); 19 | for(int i = 0, D = getD(data); i < nTrees; ++i) 20 | { 21 | PermutedData resample(data); 22 | for(int j = 0; j < data.getSize(); ++j) 23 | resample.addIndex(GlobalRNG().mod(data.getSize())); 24 | forest.append(RegressionTree(resample, 0, 50, true)); 25 | } 26 | } 27 | double predict(NUMERIC_X const& x)const 28 | { 29 | IncrementalStatistics s; 30 | for(int i = 0; i < forest.getSize(); ++i) 31 | s.addValue(forest[i].predict(x)); 32 | return s.getMean(); 33 | } 34 | }; 35 | 36 | }//end namespace 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /MachineLearning/RegResults.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/MachineLearning/RegResults.ods -------------------------------------------------------------------------------- /MachineLearning/Regression.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_REGRESSION_H 2 | #define IGMDK_REGRESSION_H 3 | #include "LearningCommon.h" 4 | #include "RandomForestRegression.h" 5 | #include "Lasso.h" 6 | #include 7 | 8 | namespace igmdk{ 9 | 10 | template struct SmartFSLearnerReg 11 | { 12 | typedef FeatureSubsetLearner MODEL; 13 | MODEL model; 14 | public: 15 | template SmartFSLearnerReg(DATA const& data, 16 | int subsampleLimit = 20): model(data, selectFeaturesSmart( 17 | RRiskFunctor, DATA>(data), getD(data), 18 | subsampleLimit)) {} 19 | double predict(NUMERIC_X const& x)const{return model.predict(x);} 20 | }; 21 | 22 | class SimpleBestCombinerReg 23 | { 24 | BestCombiner c; 25 | public: 26 | template SimpleBestCombinerReg(DATA const& data) 27 | { 28 | c.addNoParamsClassifier(data, RRiskFunctor< 29 | NoParamsLearner, EMPTY, DATA>(data)); 30 | c.addNoParamsClassifier(data, RRiskFunctor< 31 | NoParamsLearner, EMPTY, DATA>(data)); 32 | } 33 | double predict(NUMERIC_X const& x)const{return c.predict(x);} 34 | }; 35 | 36 | }//end namespace 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /MachineLearning/RegressionCommon.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_REGRESSION_COMMON_H 2 | #define IGMDK_REGRESSION_COMMON_H 3 | #include "LearningCommon.h" 4 | #include "../Utils/Vector.h" 5 | #include "../RandomNumberGeneration/Random.h" 6 | #include 7 | 8 | namespace igmdk{ 9 | 10 | struct RegressionStats 11 | { 12 | double expStd, rmse, l1Err, lInfErr; 13 | void debug()const 14 | { 15 | DEBUG(expStd); 16 | DEBUG(rmse); 17 | DEBUG(l1Err); 18 | DEBUG(lInfErr); 19 | } 20 | }; 21 | RegressionStats evaluateRegressor( 22 | Vector > const& testResult) 23 | { 24 | IncrementalStatistics yStats, l2Stats, l1Stats; 25 | for(int i = 0; i < testResult.getSize(); ++i) 26 | { 27 | yStats.addValue(testResult[i].first); 28 | double diff = testResult[i].second - testResult[i].first; 29 | l1Stats.addValue(abs(diff)); 30 | l2Stats.addValue(diff * diff); 31 | } 32 | RegressionStats result; 33 | result.lInfErr = l1Stats.maximum; 34 | result.l1Err = l1Stats.getMean(); 35 | result.rmse = sqrt(l2Stats.getMean()); 36 | result.expStd = 1 - result.rmse/yStats.stdev(); 37 | return result; 38 | } 39 | template double 40 | crossValidateReg(PARAMS const& p, DATA const& data, int nFolds = 5) 41 | { 42 | return evaluateRegressor(crossValidateGeneral(p, data, nFolds)).rmse; 44 | } 45 | template 46 | struct RRiskFunctor 47 | { 48 | DATA const& data; 49 | RRiskFunctor(DATA const& theData): data(theData) {} 50 | double operator()(PARAM const& p)const 51 | {return crossValidateReg(p, data);} 52 | }; 53 | 54 | template double 55 | repeatedCVReg(PARAMS const& p, DATA const& data, int nFolds = 5, 56 | int nRepeats = 5) 57 | { 58 | return evaluateRegressor(repeatedCVGeneral( 59 | LEARNER(data, p), data, nFolds, nRepeats)).rmse; 60 | } 61 | template 62 | struct RRCVRiskFunctor 63 | { 64 | DATA const& data; 65 | RRCVRiskFunctor(DATA const& theData): data(theData) {} 66 | double operator()(PARAM const& p)const 67 | {return repeatedCVReg(p, data);} 68 | }; 69 | 70 | }//end namespace 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /MachineLearning/ReinforcementLearning.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_REINFORCEMENT_LEARNING_H 2 | #define IGMDK_REINFORCEMENT_LEARNING_H 3 | 4 | #include "../Utils/Vector.h" 5 | #include 6 | namespace igmdk{ 7 | 8 | double UCB1(double averageValue, int nTries, int totalTries) 9 | {return averageValue + sqrt(2 * log(totalTries)/nTries);} 10 | 11 | template void TDLearning(PROBLEM& p) 12 | { 13 | while(p.hasMoreEpisodes()) 14 | { 15 | double valueCurrent = p.startEpisode(); 16 | while(!p.isInFinalState()) 17 | { 18 | double valueNext = p.pickNextState(); 19 | p.updateCurrentStateValue(p.learningRate() * (p.reward() + 20 | p.discountRate() * valueNext - valueCurrent)); 21 | p.goToNextState(); 22 | valueCurrent = valueNext; 23 | } 24 | p.updateCurrentStateValue(p.learningRate() * 25 | (p.reward() - valueCurrent)); 26 | } 27 | } 28 | 29 | struct DiscreteValueFunction 30 | { 31 | Vector > values; 32 | double learningRate(int state){return 1.0/values[state].second;} 33 | void updateValue(int state, double delta) 34 | { 35 | ++values[state].second; 36 | values[state].first += delta; 37 | } 38 | DiscreteValueFunction(int n): values(n, make_pair(0.0, 1)){} 39 | }; 40 | 41 | struct LinearCombinationValueFunction 42 | { 43 | Vector weights; 44 | int n; 45 | double learningRate(){return 1.0/n;} 46 | void updateWeights(Vector const& stateFeatures, double delta) 47 | {//set one of the state features to 1 to have a bias weight 48 | assert(stateFeatures.getSize() == weights.getSize()); 49 | for(int i = 0; i < weights.getSize(); ++i) 50 | weights[i] += delta * stateFeatures[i]; 51 | ++n; 52 | } 53 | LinearCombinationValueFunction(int theN): weights(theN, 0), n(1) {} 54 | }; 55 | 56 | }//end namespace 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /MachineLearning/results.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/MachineLearning/results.ods -------------------------------------------------------------------------------- /MachineLearning/testAPriori.cpp: -------------------------------------------------------------------------------- 1 | #include "APriori.h" 2 | #include "../Utils/Debug.h" 3 | using namespace igmdk; 4 | 5 | void testAPriori() 6 | { 7 | Vector > baskets; 8 | Vector b1, b2, b3, b4; 9 | b1.append(0); 10 | b1.append(1); 11 | b1.append(2); 12 | b1.append(3); 13 | baskets.append(b1); 14 | b2.append(5); 15 | b2.append(1); 16 | b2.append(2); 17 | b2.append(4); 18 | baskets.append(b2); 19 | b3.append(7); 20 | b3.append(1); 21 | b3.append(2); 22 | b3.append(6); 23 | baskets.append(b3); 24 | b4.append(1); 25 | b4.append(0); 26 | b4.append(4); 27 | b4.append(6); 28 | baskets.append(b4); 29 | APriori ap; 30 | ap.noCutProcess(baskets, 3); 31 | for(LCPTreap, int>::Iterator i(ap.counts.begin()); i != ap.counts.end(); ++i) 32 | { 33 | for(int j = 0; j < i->key.getSize(); ++j) 34 | { 35 | DEBUG(i->key[j]); 36 | } 37 | DEBUG(i->value); 38 | } 39 | } 40 | 41 | int main(int argc, char *argv[]) 42 | { 43 | testAPriori(); 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /MachineLearning/testReinforcementLearning.cpp: -------------------------------------------------------------------------------- 1 | #include "ReinforcementLearning.h" 2 | #include "../RandomNumberGeneration/Random.h" 3 | using namespace igmdk; 4 | 5 | struct GridWorld 6 | { 7 | DiscreteValueFunction u; 8 | int state, nEpisodes, nextState; 9 | double reward() 10 | { 11 | if(state == 3) return 1; 12 | if(state == 7) return -1; 13 | return -0.04; 14 | } 15 | double discountRate(){return 1;} 16 | double goToNextState(){state = nextState;} 17 | double pickNextState() 18 | { 19 | int row = state % 4, column = state / 4; 20 | int rows[4] = {row+1,row,row,row-1}; 21 | int columns[4] = {column,column+1,column-1,column}; 22 | bool set = false; 23 | for(int i = 0; i < 4; ++i) 24 | { 25 | if(rows[i] >= 0 && rows[i] <= 3 && columns[i] >= 0 && columns[i] <= 2 && !(rows[i] == 1 && columns[i] == 1)) 26 | { 27 | int newState = rows[i] + columns[i] * 4; 28 | assert(state !=newState); 29 | if(!set || u.values[newState].first > u.values[nextState].first) {nextState = newState; set = true;} 30 | } 31 | } 32 | assert(set); 33 | return u.values[nextState].first; 34 | } 35 | bool isInFinalState(){return state == 3 || state == 7;} 36 | double learningRate(){return u.learningRate(state);} 37 | bool hasMoreEpisodes(){return nEpisodes;} 38 | double startEpisode() 39 | { 40 | do{state = GlobalRNG().mod(12);} while(state == 5); 41 | --nEpisodes; 42 | return u.values[state].first;} 43 | void updateCurrentStateValue(double delta){u.updateValue(state, delta);} 44 | GridWorld():nEpisodes(100), u(12){} 45 | void debug() 46 | { 47 | for(int i = 0; i < 3; ++i) 48 | { 49 | for(int j = 0; j < 4; ++j) 50 | { 51 | cout << " " << u.values[j + i * 4].first; 52 | } 53 | cout << endl; 54 | } 55 | } 56 | }; 57 | 58 | void testReinforcement() 59 | { 60 | GridWorld g; 61 | TDLearning(g); 62 | g.debug(); 63 | } 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | testReinforcement(); 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /MiscAlgs/CombinatorialGeneration.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_COMBINATORIAL_GENERATION_H 2 | #define IGMDK_COMBINATORIAL_GENERATION_H 3 | #include "../Sorting/Sort.h" 4 | 5 | namespace igmdk{ 6 | 7 | struct Permutator 8 | { 9 | Vector p; 10 | Permutator(int size){for(int i = 0; i < size; ++i) p.append(i);} 11 | bool next() 12 | {//find largest i such that p[i] < p[i + 1] 13 | int j = p.getSize() - 1, i = j - 1;//start with one-before-last 14 | while(i >= 0 && p[i] >= p[i + 1]) --i; 15 | bool backToIdentity = i == -1; 16 | if(!backToIdentity) 17 | {//find j such that p[j] is next largest element after p[i] 18 | while(i < j && p[i] >= p[j]) --j; 19 | swap(p[i], p[j]); 20 | } 21 | p.reverse(i + 1, p.getSize() - 1); 22 | return backToIdentity;//true if returned to smallest permutation 23 | } 24 | bool advance(int i) 25 | { 26 | assert(i >= 0 && i < p.getSize()); 27 | quickSort(p.getArray(), i + 1, p.getSize() - 1, 28 | ReverseComparator()); 29 | return next(); 30 | } 31 | }; 32 | 33 | struct Combinator 34 | { 35 | int n; 36 | Vector c; 37 | Combinator(int m, int theN): n(theN), c(m, -1) 38 | { 39 | assert(m <= n && m > 0); 40 | skipAfter(0); 41 | } 42 | void skipAfter(int i) 43 | {//increment c[i], and reset all c[j] for j > i 44 | assert(i >= 0 && i < c.getSize()); 45 | ++c[i]; 46 | for(int j = i + 1; j < c.getSize(); ++j) c[j] = c[j - 1] + 1; 47 | } 48 | bool next() 49 | {//find rightmost c[i] which can be increased 50 | int i = c.getSize() - 1; 51 | while(i >= 0 && c[i] == n - c.getSize() + i) --i; 52 | bool finished = i == -1; 53 | if(!finished) skipAfter(i); 54 | return finished; 55 | } 56 | }; 57 | 58 | struct Partitioner 59 | { 60 | Vector p; 61 | Partitioner(int n): p(n, 0) {assert(n > 0);} 62 | bool skipAfter(int k) 63 | {//set trailing elements to maximum values and call next 64 | assert(k >= 0 && k < p.getSize()); 65 | for(int i = k; i < p.getSize(); ++i) p[i] = i; 66 | return next(); 67 | } 68 | bool next() 69 | {//find rightmost p[j] which can be increased 70 | int m = 0, j = -1; 71 | for(int i = 0; i < p.getSize(); ++i) 72 | { 73 | if(p[i] < m) j = i; 74 | m = max(m, p[i] + 1); 75 | } 76 | bool finished = j == -1; 77 | if(!finished) 78 | {//increase it and reset the tail 79 | ++p[j]; 80 | for(int i = j + 1; i < p.getSize(); ++i) p[i] = 0; 81 | } 82 | return finished; 83 | } 84 | }; 85 | 86 | }//end namespace 87 | #endif 88 | -------------------------------------------------------------------------------- /MiscAlgs/IntervalSetUnion.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SCRAP_UNION_FIND_H 2 | #define IGMDK_SCRAP_UNION_FIND_H 3 | 4 | #include "../Utils/Utils.h" 5 | #include "../Utils/Vector.h" 6 | #include "../RandomTreap/Treap.h" 7 | 8 | namespace igmdk{ 9 | 10 | class IntervalSetUnion 11 | { 12 | Treap treap; 13 | public: 14 | int find(int i){return treap.getSize() == 0 ? -1: treap.successor(i)->key;} 15 | void merge(int i){return treap.remove(i);} 16 | void split(int i){treap.insert(i, 0);} 17 | }; 18 | 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /MiscAlgs/KBitWordVector.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_K_BIT_VECTOR_H 2 | #define IGMDK_K_BIT_VECTOR_H 3 | #include "../Utils/Bitset.h" 4 | using namespace std; 5 | namespace igmdk{ 6 | 7 | template class KBitWordVector 8 | { 9 | Bitset b; 10 | public: 11 | unsigned long long getSize()const{return b.getSize()/N;} 12 | KBitWordVector(){}; 13 | KBitWordVector(int n, WORD item = 0): b(n * N) 14 | { 15 | if(Bits::getValue(item, 0, N) == 0) b.setAll(0); 16 | else for(unsigned long long i = 0; i < getSize(); ++i) set(item, i); 17 | } 18 | WORD operator[](unsigned long long i)const 19 | {assert(i < getSize()); return b.getValue(i * N, N);} 20 | void set(WORD value, unsigned long long i) 21 | {assert(i < getSize()); b.setValue(value, i * N, N);} 22 | void append(WORD value){b.appendValue(value, N);} 23 | }; 24 | 25 | }//end namespace 26 | #endif 27 | -------------------------------------------------------------------------------- /MiscAlgs/LRUCache.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_LRU_CACHE_H 2 | #define IGMDK_LRU_CACHE_H 3 | #include "../Utils/GCFreeList.h" 4 | #include "../HashTable/LinearProbingHashTable.h" 5 | 6 | namespace igmdk{ 7 | 8 | template > class LRUCache 10 | { 11 | typedef KVPair ITEM; 12 | typedef SimpleDoublyLinkedList LIST; 13 | typedef typename LIST::Iterator I; 14 | LIST l; 15 | int size, capacity; 16 | LinearProbingHashTable h; 17 | public: 18 | LRUCache(int theCapacity): size(0), capacity(theCapacity) 19 | {assert(capacity > 0);} 20 | VALUE* read(KEY const& k) 21 | { 22 | I* np = h.find(k); 23 | if(np) 24 | {//put in front on access 25 | l.moveBefore(*np, l.begin()); 26 | return &(*np)->value; 27 | } 28 | return 0; 29 | } 30 | typedef I Iterator; 31 | Iterator begin(){return l.begin();} 32 | Iterator end(){return l.end();} 33 | Iterator evicteeOnWrite(KEY const& k)//none if not full or item in cache 34 | {return size < capacity || h.find(k) ? end() : l.rBegin();} 35 | void write(KEY const& k, VALUE const& v) 36 | { 37 | VALUE* oldV = read(k);//first check if already inserted 38 | if(oldV) *oldV = v;//found, update 39 | else 40 | { 41 | Iterator evictee = evicteeOnWrite(k); 42 | if(evictee != end()) 43 | { 44 | h.remove(evictee->key); 45 | l.moveBefore(evictee, l.begin());//recycle evictee 46 | evictee->key = k; 47 | evictee->value = v; 48 | } 49 | else 50 | { 51 | ++size; 52 | l.prepend(ITEM(k, v)); 53 | } 54 | h.insert(k, l.begin()); 55 | } 56 | } 57 | }; 58 | 59 | template > class DelayedCommitLRUCache 61 | { 62 | RESOURCE& r; 63 | typedef LRUCache, HASHER> LRU; 64 | typedef typename LRU::Iterator I; 65 | LRU c; 66 | void commit(I i) 67 | { 68 | if(i->value.second) r.write(i->key, i->value.first); 69 | i->value.second = false; 70 | } 71 | void writeHelper(KEY const& k, VALUE const& v, bool fromWrite) 72 | {//first commit evictee if any 73 | I i = c.evicteeOnWrite(k); 74 | if(i != c.end()) commit(i); 75 | c.write(k, pair(v, fromWrite)); 76 | } 77 | DelayedCommitLRUCache(DelayedCommitLRUCache const&);//no copying allowed 78 | DelayedCommitLRUCache& operator=(DelayedCommitLRUCache const&); 79 | public: 80 | DelayedCommitLRUCache(RESOURCE& theR, int capacity): r(theR), c(capacity) 81 | {assert(capacity > 0);} 82 | VALUE const& read(KEY const& k) 83 | {//first check if in cache 84 | pair* mv = c.read(k); 85 | if(!mv) 86 | {//if not then read from resource and put in cache 87 | writeHelper(k, r.read(k), false); 88 | mv = c.read(k); 89 | } 90 | return mv->first; 91 | } 92 | void write(KEY const& k, VALUE const& v){writeHelper(k, v, true);} 93 | void flush(){for(I i = c.begin(); i != c.end(); ++i) commit(i);} 94 | ~DelayedCommitLRUCache(){flush();} 95 | }; 96 | 97 | }//end namespace 98 | #endif 99 | -------------------------------------------------------------------------------- /MiscAlgs/MiscAlgsTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_MISC_ALGORITHMS_TEST_AUTO_H 2 | #define IGMDK_MISC_ALGORITHMS_TEST_AUTO_H 3 | #include "LRUCache.h" 4 | #include "PrimeTable.h" 5 | #include "CombinatorialGeneration.h" 6 | #include "KBitWordVector.h" 7 | 8 | using namespace std; 9 | 10 | namespace igmdk{ 11 | 12 | void testLRUAuto() 13 | { 14 | DEBUG("testLRUAuto"); 15 | int n = 1000; int k = 5; 16 | LRUCache c(k); 17 | for(int i = 0; i < n; ++i) c.write(i, i); 18 | for(LRUCache::Iterator i = c.begin(); i != c.end(); ++i) 19 | assert(i->value >= n - k && i->value < n); 20 | for(int i = n - k; i < n; ++i) 21 | { 22 | assert(c.read(i)); 23 | assert(*c.read(i) == i); 24 | } 25 | for(int i = 0; i < n - k; ++i) 26 | { 27 | assert(!c.read(i)); 28 | } 29 | DEBUG("testLRUAuto passed"); 30 | } 31 | 32 | void testPrimeTableAuto() 33 | { 34 | DEBUG("testPrimeTableAuto"); 35 | int smallPrimes[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}; 36 | Vector primality(50, false); 37 | for(int i = 0; i < sizeof(smallPrimes)/sizeof(smallPrimes[0]); ++i) 38 | primality[smallPrimes[i]] = true; 39 | PrimeTable pt(primality.getSize()); 40 | for(int i = 1; i < primality.getSize(); ++i) 41 | assert(pt.isPrime(i) == primality[i]); 42 | DEBUG("testPrimeTableAuto passed"); 43 | } 44 | 45 | void testKBitVectorAuto() 46 | { 47 | DEBUG("testKBitWordVectorAuto"); 48 | KBitWordVector<5> x; 49 | int N = 100000; 50 | for(int i = 0; i < N; ++i) x.append(i); 51 | for(int i = 0; i < N; ++i) x.set(i, i); 52 | for(int i = 0; i < N; ++i) assert(x[i] == i % 32); 53 | DEBUG("testKBitVectorAuto passed"); 54 | } 55 | 56 | void testAllAutoMiscAlgorithms() 57 | { 58 | DEBUG("testAllAutoMicAlgorithms"); 59 | testLRUAuto(); 60 | testPrimeTableAuto(); 61 | testKBitVectorAuto(); 62 | } 63 | 64 | }//end namespace 65 | #endif 66 | -------------------------------------------------------------------------------- /MiscAlgs/PrimeTable.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_PRIME_TABLE_H 2 | #define IGMDK_PRIME_TABLE_H 3 | #include "../Utils/Bitset.h" 4 | 5 | namespace igmdk{ 6 | 7 | class PrimeTable 8 | { 9 | long long maxN; 10 | Bitset<> table;//marks odd numbers starting from 3 11 | long long nToI(long long n)const{return (n - 3)/2;} 12 | public: 13 | PrimeTable(long long primesUpto): maxN(primesUpto - 1), 14 | table(nToI(maxN) + 1) 15 | { 16 | assert(primesUpto > 1); 17 | table.setAll(true); 18 | for(long long i = 3; i <= sqrt(maxN); i += 2) 19 | if(isPrime(i))//set every odd multiple i <= k <= maxN/i to false 20 | for(long long k = i; i * k <= maxN; k += 2) 21 | table.set(nToI(i * k), false); 22 | } 23 | bool isPrime(long long n)const 24 | { 25 | assert(n > 0 && n <= maxN); 26 | return n == 2 || (n > 2 && n % 2 && table[nToI(n)]); 27 | } 28 | }; 29 | 30 | }//end namespace 31 | #endif 32 | -------------------------------------------------------------------------------- /MiscAlgs/test.cpp: -------------------------------------------------------------------------------- 1 | #include "MiscAlgsTestAuto.h" 2 | #include "KBitWordVector.h" 3 | #include 4 | #include 5 | using namespace std; 6 | using namespace igmdk; 7 | 8 | void DDDLRU() 9 | { 10 | LRUCache LRU4_0to9(4); 11 | for(int i = 0; i < 10; ++i) LRU4_0to9.write(i, i); 12 | 13 | cout << "breakpoint" << endl; 14 | } 15 | 16 | void DDDNBitVector() 17 | { 18 | KBitWordVector<4, unsigned char> Vector4BitChar8to12; 19 | for(int i = 0; i < 5; i += 1) 20 | { 21 | Vector4BitChar8to12.append(i + 8); 22 | } 23 | cout << "breakpoint" << endl; 24 | } 25 | 26 | int main() 27 | { 28 | testAllAutoMiscAlgorithms(); 29 | 30 | DDDLRU(); 31 | 32 | DDDNBitVector(); 33 | 34 | Permutator perm(4); 35 | for(int j = 0; j < 7; ++j) 36 | { 37 | cout << "P" << endl; 38 | for(int i = 0; i < perm.p.getSize(); ++i) cout << perm.p[i] << " "; 39 | cout << endl; 40 | if(perm.next()) break; 41 | } 42 | DEBUG("done1"); 43 | perm.advance(0); 44 | perm.advance(1); 45 | for(;;) 46 | { 47 | cout << "P" << endl; 48 | for(int i = 0; i < perm.p.getSize(); ++i) cout << perm.p[i] << " "; 49 | cout << endl; 50 | if(perm.next()) break; 51 | } 52 | 53 | 54 | DEBUG("done2"); 55 | 56 | Combinator comb(4, 6); 57 | 58 | for(int j = 0; j < 7; ++j) 59 | { 60 | cout << "C" << endl; 61 | for(int i = 0; i < comb.c.getSize(); ++i) cout << comb.c[i] << " "; 62 | cout << endl; 63 | if(comb.next()) break; 64 | } 65 | DEBUG("done3"); 66 | comb.skipAfter(1); 67 | for(;;) 68 | { 69 | cout << "C" << endl; 70 | for(int i = 0; i < comb.c.getSize(); ++i) cout << comb.c[i] << " "; 71 | cout << endl; 72 | if(comb.next()) break; 73 | } 74 | DEBUG("done4"); 75 | Partitioner part(4); 76 | 77 | for(;;) 78 | { 79 | cout << "Pa" << endl; 80 | for(int i = 0; i < part.p.getSize(); ++i) cout << part.p[i] << " "; 81 | cout << endl; 82 | if(part.next()) break; 83 | } 84 | 85 | 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /MiscAlgs/testIntervalSetUnion.cpp: -------------------------------------------------------------------------------- 1 | #include "IntervalSetUnion.h" 2 | #include 3 | using namespace igmdk; 4 | 5 | int main() 6 | { 7 | IntervalSetUnion iu; 8 | 9 | iu.split(5); 10 | DEBUG(iu.find(2)); 11 | iu.split(3); 12 | DEBUG(iu.find(2)); 13 | iu.merge(3); 14 | DEBUG(iu.find(2)); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /NumericalMethods/AllRootsFinder.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_ALL_ROOTS_FINDER_H 2 | #define IGMDK_ALL_ROOTS_FINDER_H 3 | #include 4 | #include "Matrix.h" 5 | #include "Interpolation.h" 6 | #include "EquationSolving.h" 7 | namespace igmdk{ 8 | 9 | Vector > findAllRoots(Vector const& lowerCoefs) 10 | { 11 | int n = lowerCoefs.getSize(); 12 | Matrix companion(n, n); 13 | for(int r = 0; r < n; ++r) 14 | { 15 | if(r > 0) companion(r, r - 1) = 1; 16 | companion(r, n - 1) = -lowerCoefs[r]; 17 | } 18 | return QREigenHessenberg(companion); 19 | } 20 | 21 | template Vector findAllRealRootsCheb( 22 | FUNCTION const& f, double a, double b, int maxDegree = 32, 23 | double duplicateXEps = highPrecEps) 24 | { 25 | Vector, ScaledChebAB> > pieces = 26 | interpolateAdaptiveHeap(f, a, b, maxDegree).first. 27 | getPieces(); 28 | PiecewiseData resultFilter(duplicateXEps); 29 | for(int i = 0; i < pieces.getSize(); ++i) 30 | { 31 | Vector rootsI = pieces[i].second.findAllRealRoots(); 32 | for(int j = 0; j < rootsI.getSize(); ++j) 33 | {//range and finiteness check 34 | double polishedRoot = 35 | solveSecant(f, rootsI[j], duplicateXEps).first; 36 | if(isfinite(polishedRoot) && a <= polishedRoot && 37 | polishedRoot <= b) resultFilter.insert(polishedRoot, EMPTY()); 38 | } 39 | } 40 | Vector > tempResult = resultFilter.getPieces(); 41 | Vector result(tempResult.getSize()); 42 | for(int i = 0; i < tempResult.getSize(); ++i) 43 | result[i] = tempResult[i].first; 44 | return result; 45 | } 46 | 47 | }//end namespace 48 | #endif 49 | -------------------------------------------------------------------------------- /NumericalMethods/IntervalNumber.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_INTERVAL_NUMBER_H 2 | #define IGMDK_INTERVAL_NUMBER_H 3 | #include 4 | #include "../Utils/Utils.h" 5 | namespace igmdk{ 6 | //beware below, though part of C99 standard, not supported by some compilers 7 | //such as clang 8 | #pragma STDC FENV_ACCESS ON 9 | template 10 | class IntervalNumber: public ArithmeticType > 11 | {//all operations must restore nearest rounding for other calculations 12 | ITEM left, right; 13 | public: 14 | IntervalNumber(ITEM rounded) 15 | {//epsilon addition exact; change this to ulp? 16 | std::fesetround(FE_DOWNWARD); 17 | left = rounded * (1 + numeric_limits::epsilon()); 18 | std::fesetround(FE_UPWARD); 19 | right = rounded * (1 - numeric_limits::epsilon()); 20 | std::fesetround(FE_TONEAREST); 21 | } 22 | IntervalNumber(long long numerator, long long denominator) 23 | { 24 | std::fesetround(FE_DOWNWARD); 25 | left = numerator/denominator; 26 | std::fesetround(FE_UPWARD); 27 | right = numerator/denominator; 28 | std::fesetround(FE_TONEAREST); 29 | } 30 | bool isfinite()const{return std::isfinite(left) && std::isfinite(right);} 31 | bool isnan()const{return std::isnan(left) && std::isnan(right);} 32 | IntervalNumber& operator+=(IntervalNumber const& rhs) 33 | { 34 | std::fesetround(FE_DOWNWARD); 35 | left += rhs.left; 36 | std::fesetround(FE_UPWARD); 37 | right += rhs.right; 38 | std::fesetround(FE_TONEAREST); 39 | return *this; 40 | } 41 | IntervalNumber operator-()const//minus exact in floating represenation 42 | {return IntervalNumber(-right, -left);} 43 | IntervalNumber& operator-=(IntervalNumber const& rhs) 44 | {return *this += -rhs;} 45 | IntervalNumber& operator*=(IntervalNumber const& rhs) 46 | { 47 | std::fesetround(FE_DOWNWARD); 48 | ITEM temp1 = min(left * rhs.left, left * rhs.right); 49 | ITEM temp2 = min(right * rhs.left, right * rhs.right); 50 | ITEM newLeft = min(temp1, temp2); 51 | std::fesetround(FE_UPWARD); 52 | temp1 = max(left * rhs.left, left * rhs.right); 53 | temp2 = max(right * rhs.left, right * rhs.right); 54 | ITEM newRight = max(temp1, temp2); 55 | std::fesetround(FE_TONEAREST); 56 | left = newLeft; 57 | right = newRight; 58 | return *this; 59 | } 60 | IntervalNumber& operator*=(long long a) 61 | {//exact constant multiplication 62 | std::fesetround(FE_DOWNWARD); 63 | left *= a; 64 | std::fesetround(FE_UPWARD); 65 | right *= a; 66 | std::fesetround(FE_TONEAREST); 67 | return *this; 68 | } 69 | bool contains(ITEM a)const{return left <= a && a <= right;} 70 | IntervalNumber& operator/=(IntervalNumber rhs) 71 | { 72 | if(rhs.contains(ITEM(0))) 73 | { 74 | rhs.left = -numeric_limits::infinity(); 75 | rhs.right = numeric_limits::infinity(); 76 | } 77 | else 78 | { 79 | std::fesetround(FE_DOWNWARD); 80 | rhs.left = ITEM(1)/rhs.right; 81 | std::fesetround(FE_UPWARD); 82 | rhs.right = ITEM(1)/rhs.left; 83 | } 84 | return (*this) *= rhs; 85 | } 86 | void debug()const 87 | { 88 | cout << left << " "; 89 | cout << right << " "; 90 | cout << endl; 91 | } 92 | }; 93 | 94 | }// end namespace 95 | #endif 96 | -------------------------------------------------------------------------------- /NumericalMethods/Matrix.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/NumericalMethods/Matrix.h -------------------------------------------------------------------------------- /NumericalMethods/NumericalCommon.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_NUMERICAL_COMMON_H 2 | #define IGMDK_NUMERICAL_COMMON_H 3 | 4 | #include 5 | namespace igmdk{ 6 | 7 | double defaultPrecEps = sqrt(numeric_limits::epsilon()); 8 | double highPrecEps = 100 * numeric_limits::epsilon(); 9 | 10 | bool isELess(double a, double b, 11 | double eRelAbs = numeric_limits::epsilon()) 12 | {return a < b && b - a >= eRelAbs * max(1.0, max(abs(a), abs(b)));} 13 | bool isEEqual(double a, double b, 14 | double eRelAbs = numeric_limits::epsilon()) 15 | {return !isELess(a, b, eRelAbs) && !isELess(b, a, eRelAbs);} 16 | 17 | template double normInf(Vector const& x) 18 | {//works for complex vector too 19 | double xInf = 0; 20 | for(int i = 0; i < x.getSize(); ++i) 21 | { 22 | double ax = abs(x[i]); 23 | if(isnan(ax)) return ax;//check for NaN before max 24 | xInf = max(xInf, ax); 25 | } 26 | return xInf; 27 | } 28 | 29 | }//end namespace 30 | #endif 31 | -------------------------------------------------------------------------------- /NumericalMethods/NumericalMethods.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_NUMERICAL_METHODS_H 2 | #define IGMDK_NUMERICAL_METHODS_H 3 | 4 | #include "Matrix.h" 5 | #include "EquationSolving.h" 6 | #include "Differentiation.h" 7 | #include "FFT.h" 8 | #include "Interpolation.h" 9 | #include "Integration.h" 10 | #include "ODESolving.h" 11 | #include "AllRootsFinder.h" 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /NumericalMethods/testFFT.cpp: -------------------------------------------------------------------------------- 1 | #include "FFT.h" 2 | #include "../RandomNumberGeneration/Random.h" 3 | #include "NumericalMethodsTestAuto.h" 4 | using namespace std; 5 | using namespace igmdk; 6 | 7 | void FFTTestReal() 8 | { 9 | int n = 4; 10 | Vector x(n); 11 | for(int i = 0; i < n; ++i) x[i] = i; 12 | Vector > z(n); 13 | for(int i = 0; i < n; ++i) z[i] = complex(x[i], 0); 14 | double normYDiff = normInf(FFTRealEven(x) - FFTGeneral(z)); 15 | DEBUG(normYDiff); 16 | DEBUG("FFTRealEven(x)"); 17 | FFTRealEven(x).debug(); 18 | DEBUG("FFTGeneral(z))"); 19 | FFTGeneral(z).debug(); 20 | } 21 | 22 | Vector slowDCTI(Vector const& x) 23 | { 24 | int n = x.getSize() - 1; 25 | Vector result(n + 1); 26 | for(int i = 0; i <= n; ++i) 27 | { 28 | double ci = 0; 29 | for(int j = 0; j <= n; ++j) ci += cos(i * j * PI()/n) 30 | * x[j] * (j == 0 || j == n ? 0.5 : 1.0); 31 | result[i] = ci; 32 | } 33 | return result; 34 | } 35 | void DCTTestHelper(Vector const& x, double eps = defaultPrecEps) 36 | { 37 | double normXDiff = normInf(x - IDCTI(DCTI(x))), 38 | normYDiff = normInf(slowDCTI(x) - DCTI(x)); 39 | if(normXDiff >= eps || normYDiff >= eps) 40 | { 41 | DEBUG("failed for x="); 42 | DEBUG(x.getSize()); 43 | x.debug(); 44 | DEBUG(normXDiff); 45 | DEBUG(normYDiff); 46 | DEBUG("IDCTI(DCTI(x))"); 47 | IDCTI(DCTI(x)).debug(); 48 | DEBUG("DCTI(x)"); 49 | DCTI(x).debug(); 50 | DEBUG("slowDCTI(x)"); 51 | slowDCTI(x).debug(); 52 | assert(false); 53 | } 54 | } 55 | void DCTTestAuto() 56 | { 57 | int nMax = 100, nn = 1000; 58 | for(int n = 3; n <= nMax; ++n)//fails for 2 in bits 59 | { 60 | for(int j = 0; j < nn; ++j) 61 | { 62 | Vector x(n); 63 | for(int i = 0; i < n; ++i) x[i] = GlobalRNG().uniform(-1, 1); 64 | DCTTestHelper(x); 65 | } 66 | } 67 | DEBUG("DCTTestAuto passed"); 68 | } 69 | 70 | int main() 71 | { 72 | FFTTestReal(); 73 | FFTTestAuto(); 74 | DCTTestAuto(); 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /NumericalMethods/testInterval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include //for shared ptr 7 | #include "IntervalNumber.h" 8 | using namespace std; 9 | using namespace igmdk; 10 | 11 | int main() 12 | { 13 | IntervalNumber<> iv1(2.0), iv2(3.14); 14 | DEBUG("+"); 15 | (iv1 + iv2).debug(); 16 | DEBUG("-"); 17 | (iv1 - iv2).debug(); 18 | DEBUG("*"); 19 | (iv1 * iv2).debug(); 20 | DEBUG("/"); 21 | (iv1 / iv2).debug(); 22 | DEBUG(iv1.isfinite()); 23 | DEBUG(iv1.isnan()); 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /NumericalMethods/testNum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include //for shared ptr 7 | #include "NumericalMethods.h" 8 | #include "../NumericalOptimization/GlobalNumericalOptimization.h" 9 | #include "../RandomNumberGeneration/Statistics.h" 10 | #include "../Utils/DEBUG.h" 11 | #include "../ExternalMemoryAlgorithms/CSV.h" 12 | #include "NumericalMethodsTestAuto.h" 13 | #include "TestFunctions1D.h" 14 | using namespace std; 15 | using namespace igmdk; 16 | 17 | int main() 18 | { 19 | testELessAuto(); 20 | return 0; 21 | 22 | DEBUG(numeric_limits::min()); 23 | DEBUG(numeric_limits::max()); 24 | DEBUG(numeric_limits::epsilon()); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /NumericalMethods/testRootSolvers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include //for shared ptr 7 | #include "AllRootsFinder.h" 8 | #include "../NumericalOptimization/GlobalNumericalOptimization.h" 9 | #include "../RandomNumberGeneration/Statistics.h" 10 | #include "../Utils/DEBUG.h" 11 | #include "../ExternalMemoryAlgorithms/CSV.h" 12 | #include "NumericalMethodsTestAuto.h" 13 | #include "TestFunctions1D.h" 14 | using namespace std; 15 | using namespace igmdk; 16 | 17 | void testAllRootSolver() 18 | { 19 | Vector coefs(2);//x^2 - 1 = 0, roots: 1, -1 20 | coefs[0] = -1; 21 | coefs[1] = 0; 22 | Vector > roots = findAllRoots(coefs); 23 | DEBUG("roots"); 24 | roots.debug(); 25 | Vector coefs2(3);//MATLAB EXAMPLE x^3 -7x + 6 = 0, roots = 1, 2, 3 26 | coefs2[0] = 6; 27 | coefs2[1] = -7; 28 | coefs2[2] = 0; 29 | Vector > roots2 = findAllRoots(coefs2); 30 | DEBUG("roots2"); 31 | roots2.debug(); 32 | Vector coefs3(3);//0 EXAMPLE x^3 = 0 33 | coefs3[0] = 0; 34 | coefs3[1] = 0; 35 | coefs3[2] = 0; 36 | Vector > roots3 = findAllRoots(coefs3); 37 | DEBUG("roots3"); 38 | roots3.debug(); 39 | } 40 | 41 | struct SQUARE2 42 | { 43 | double operator()(double x)const{return x * x - 0.25;} 44 | }; 45 | void testChebRoots() 46 | { 47 | ChebFunction cf(SQUARE2(), 16); 48 | Vector rroots = cf.findAllRealRoots(); 49 | DEBUG("roots"); 50 | rroots.debug();//expect 0.5 and -0.5 51 | rroots = findAllRealRootsCheb(SQUARE2(), -1, 1); 52 | DEBUG("roots adaptive"); 53 | rroots.debug();//expect 0.5 and -0.5 54 | rroots = findAllRealRootsCheb(TestFunctions1D::Sin(), -10, 10); 55 | DEBUG("sin roots adaptive"); 56 | rroots.debug();//expect 0 and +- iPi for i 1 to 3 57 | } 58 | 59 | int main() 60 | { 61 | testChebRoots(); 62 | return 0; 63 | testAllRootSolver(); 64 | return 0; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /NumericalOptimization/CoordinateDescent.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_COORDINATE_DESCENT_H 2 | #define IGMDK_COORDINATE_DESCENT_H 3 | #include 4 | #include "../Utils/Vector.h" 5 | #include "../RandomNumberGeneration/Random.h" 6 | #include "GoldenSection.h" 7 | namespace igmdk{ 8 | 9 | template struct IncrementalWrapper 10 | { 11 | FUNCTION f; 12 | mutable Vector xBound; 13 | int i; 14 | mutable int evalCount; 15 | public: 16 | IncrementalWrapper(FUNCTION const& theF, Vector const& x0): 17 | f(theF), xBound(x0), i(0), evalCount(0) {} 18 | void setCurrentDimension(double theI) 19 | { 20 | assert(theI >= 0 && theI < xBound.getSize()); 21 | i = theI; 22 | } 23 | int getEvalCount()const{return evalCount;} 24 | int getSize()const{return xBound.getSize();} 25 | Vector const& getX()const{return xBound;} 26 | double getXi()const{return xBound[i];} 27 | double operator()(double xi)const 28 | { 29 | double oldXi = xBound[i]; 30 | xBound[i] = xi; 31 | double result = f(xBound); 32 | ++evalCount; 33 | xBound[i] = oldXi; 34 | return result; 35 | } 36 | void bind(double xi)const{xBound[i] = xi;} 37 | }; 38 | 39 | template double unimodalCoordinateDescent( 40 | INCREMENTAL_FUNCTION &f, int maxEvals = 1000000, 41 | double xPrecision = highPrecEps) 42 | { 43 | int D = f.getSize(); 44 | Vector order(D); 45 | for(int i = 0; i < D; ++i) order[i] = i; 46 | double y = f(f.getXi()), relStep = 0.1; 47 | while(f.getEvalCount() < maxEvals)//may be exceeded but ok 48 | {//use random order full cycles 49 | GlobalRNG().randomPermutation(order.getArray(), D); 50 | double yPrev = y, maxRelXStep = 0; 51 | for(int i = 0; i < D && f.getEvalCount() < maxEvals; ++i) 52 | { 53 | int j = order[i]; 54 | f.setCurrentDimension(j); 55 | pair resultJ = minimizeGSBracket(f, f.getXi(), 56 | y, true, relStep, xPrecision); 57 | maxRelXStep = max(maxRelXStep, abs(resultJ.first - f.getXi())/ 58 | max(1.0, abs(f.getXi()))); 59 | f.bind(resultJ.first); 60 | y = resultJ.second; 61 | }//done if no improvement in x or y 62 | if(maxRelXStep < xPrecision || !isELess(y, yPrev)) break; 63 | relStep = min(0.1, maxRelXStep);//take smaller first steps as converge 64 | } 65 | return y; 66 | } 67 | template pair, double> 68 | unimodalCoordinateDescentGeneral(FUNCTION const& f, Vector const& 69 | x0, int maxEvals = 1000000, double xPrecision = highPrecEps) 70 | { 71 | IncrementalWrapper iw(f, x0); 72 | double y = unimodalCoordinateDescent(iw, maxEvals, xPrecision); 73 | return make_pair(iw.xBound, y); 74 | } 75 | 76 | }//end namespace igmdk 77 | #endif 78 | -------------------------------------------------------------------------------- /NumericalOptimization/DifferentialEvolution.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_DIFFERENTIAL_EVOLUTION_H 2 | #define IGMDK_DIFFERENTIAL_EVOLUTION_H 3 | #include 4 | #include "../Utils/Vector.h" 5 | #include "../RandomNumberGeneration/Random.h" 6 | namespace igmdk{ 7 | 8 | Vector boxTrim(Vector x, 9 | Vector > const& box) 10 | { 11 | for(int i = 0; i < x.getSize(); ++i) 12 | { 13 | if(x[i] < box[i].first) x[i] = box[i].first; 14 | else if(isnan(x[i]) || x[i] > box[i].second) x[i] = box[i].second; 15 | } 16 | return x; 17 | } 18 | 19 | template pair, double> 20 | differentialEvolutionMinimize(FUNCTION const& f, SAMPLER const& s, 21 | Vector > const& box, int maxEvals = 1000000) 22 | { 23 | assert(maxEvals > 0); 24 | int n = pow(maxEvals, 1.0/3); 25 | Vector, double> > population(n); 26 | for(int i = 0; i < n; ++i) 27 | { 28 | population[i].first = s(); 29 | population[i].second = f(population[i].first); 30 | } 31 | maxEvals -= n; 32 | while(maxEvals > 0) 33 | { 34 | for(int i = 0; i < n && maxEvals-- > 0; ++i) 35 | {//mutate new point 36 | Vector jkl = GlobalRNG().randomCombination(3, n); 37 | Vector xiNew = population[i].first, xiMutated = 38 | boxTrim(population[jkl[0]].first + (population[jkl[1]].first - 39 | population[jkl[2]].first) * 0.9, box); 40 | //crossover with mutated point 41 | int D = xiNew.getSize(), randK = GlobalRNG().mod(D); 42 | for(int k = 0; k < D; ++k) if(GlobalRNG().mod(2) || k == randK) 43 | xiNew[k] = xiMutated[k]; 44 | if(!isfinite(norm(xiNew))) 45 | {//enforce finite samples 46 | ++maxEvals; 47 | continue; 48 | } 49 | //select best of original and mutated 50 | double yiNew = f(xiNew); 51 | if(yiNew < population[i].second) 52 | { 53 | population[i].first = xiNew; 54 | population[i].second = yiNew; 55 | } 56 | } 57 | } 58 | pair, double>& best = population[0]; 59 | for(int i = 1; i < n; ++i) 60 | if(best.second < population[i].second) best = population[i]; 61 | return best; 62 | } 63 | 64 | }//end namespace igmdk 65 | #endif 66 | -------------------------------------------------------------------------------- /NumericalOptimization/LinearProgramming.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_LINEAR_PROGRAMMING_H 2 | #define IGMDK_LINEAR_PROGRAMMING_H 3 | #include "../Utils/Utils.h" 4 | #include "../NumericalMethods/Matrix.h" 5 | namespace igmdk{ 6 | 7 | struct LinearProgrammingSimplex 8 | { 9 | Matrix B, N; 10 | Vector b, cB, cN, x; 11 | Vector p; 12 | bool isUnbounded; 13 | bool performIteration() 14 | { 15 | LUP lup(B), lupT(B.transpose()); 16 | x = lup.solve(b); 17 | //check if x is optimal or find entering variable 18 | Vector y = cN - lupT.solve(cB) * N; 19 | int entering = 0; 20 | double bestValue = y[0]; 21 | for(int i = 1; i < y.getSize(); ++i) if(y[i] < bestValue) 22 | { 23 | bestValue = y[i]; 24 | entering = i; 25 | } 26 | if(bestValue >= 0) return false; 27 | //find leaving variable 28 | Vector a; 29 | for(int i = 0; i < N.rows; ++i) a.append(N(i, entering)); 30 | a = lup.solve(a); 31 | int leaving = -1; 32 | double minRatio, maxA = -1; 33 | for(int i = 0; i < x.getSize(); ++i) if(a[i] > 0) 34 | { 35 | double newRatio = x[i]/a[i]; 36 | if(leaving == -1 || minRatio > newRatio) 37 | { 38 | leaving = i; 39 | maxA = max(maxA, a[i]); 40 | minRatio = newRatio; 41 | } 42 | } 43 | if(maxA <= 0){isUnbounded = true; return false;} 44 | //swap variables 45 | for(int i = 0; i < N.rows; ++i){swap(B(i, leaving), N(i, entering));} 46 | swap(p[leaving], p[entering]); 47 | swap(cB[leaving], cN[entering]); 48 | return true; 49 | } 50 | LinearProgrammingSimplex(Matrixconst&B0, Matrix 51 | const& N0, Vectorconst& cB0, Vectorconst& cN0, 52 | Vector const& b0): isUnbounded(false), B(B0), N(N0), cB(cB0), 53 | cN(cN0), b(b0), x(b) 54 | {for(int i = 0; i < cB.getSize() + cN.getSize(); ++i) p.append(i);} 55 | Vector > solve() 56 | { 57 | while(performIteration()); 58 | Vector > result; 59 | if(!isUnbounded) 60 | for(int i = 0; i < x.getSize(); ++i) 61 | result.append(make_pair(p[i], x[i])); 62 | return result; 63 | } 64 | }; 65 | 66 | }//end namespace igmdk 67 | #endif 68 | -------------------------------------------------------------------------------- /NumericalOptimization/NumericalOptimization.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_NUMERICAL_OPTIMIZATION_H 2 | #define IGMDK_NUMERICAL_OPTIMIZATION_H 3 | #include 4 | #include "../Utils/Vector.h" 5 | #include "GoldenSection.h" 6 | #include "NelderMead.h" 7 | #include "CoordinateDescent.h" 8 | #include "LBFGS.h" 9 | namespace igmdk{ 10 | 11 | double RMRate(int i){return 1/pow(i + 1, 0.501);} 12 | 13 | template pair, double> hybridLocalMinimize( 14 | Vector const& x0, FUNCTION const& f, int maxEvals = 1000000, 15 | double yPrecision = highPrecEps) 16 | { 17 | GradientFunctor g(f); 18 | DirectionalDerivativeFunctor dd(f); 19 | int D = x0.getSize(), LBFGSevals = D < 200 ? maxEvals/2 : maxEvals; 20 | pair, double> result = LBFGSMinimize(x0, f, g, dd, 21 | LBFGSevals, yPrecision); 22 | if(D > 1 && D < 200) 23 | { 24 | int nRestarts = 30; 25 | NelderMead nm(x0.getSize(), f); 26 | result = nm.restartedMinimize(result.first, 27 | (maxEvals - LBFGSevals)/nRestarts, highPrecEps, nRestarts); 28 | } 29 | return result; 30 | } 31 | 32 | }//end namespace igmdk 33 | #endif 34 | -------------------------------------------------------------------------------- /NumericalOptimization/SPSA.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SPSA_H 2 | #define IGMDK_SPSA_H 3 | #include "../RandomNumberGeneration/Random.h" 4 | #include "NumericalOptimization.h" 5 | namespace igmdk{ 6 | 7 | template POINT SPSA(POINT x, 8 | FUNCTION const& f, int maxEvals = 10000, double initialStep = 1) 9 | { 10 | POINT direction = x; 11 | for(int i = 0, D = x.getSize(); i < maxEvals/2; ++i) 12 | { 13 | for(int j = 0; j < D; ++j) direction[j] = 14 | GlobalRNG().next() % 2 ? 1 : -1; 15 | double step = initialStep/pow(i + 1, 0.101), temp = RMRate(i) * 16 | (f(x + direction * step) - f(x - direction * step))/2; 17 | if(!isfinite(temp)) break; 18 | for(int j = 0; j < D; ++j) x[j] -= temp/direction[j]; 19 | } 20 | return x; 21 | } 22 | template pair metaSPSA( 23 | POINT x, FUNCTION const& f, int spsaEvals = 100000, int estimateEvals = 24 | 100, double step = pow(2, 10), double minStep = pow(2, -20)) 25 | { 26 | pair xy(x, numeric_limits::infinity()); 27 | for(; step > minStep; step /= 2) 28 | { 29 | if(isfinite(xy.second)) x = SPSA(xy.first, f, spsaEvals, step); 30 | double sum = 0; 31 | for(int i = 0; i < estimateEvals; ++i) sum += f(x); 32 | if(sum/estimateEvals < xy.second) 33 | { 34 | xy.first = x; 35 | xy.second = sum/estimateEvals; 36 | } 37 | } 38 | return xy; 39 | } 40 | 41 | }//end namespace igmdk 42 | #endif 43 | -------------------------------------------------------------------------------- /NumericalOptimization/testLinearProgramming.cpp: -------------------------------------------------------------------------------- 1 | #include "LinearProgramming.h" 2 | #include "../Utils/DEBUG.h" 3 | using namespace std; 4 | using namespace igmdk; 5 | 6 | void testSimplex() 7 | { 8 | Matrix B = Matrix::identity(3), N(3, 2); 9 | N(0, 0) = -2; 10 | N(0, 1) = 1; 11 | N(1, 0) = -1; 12 | N(1, 1) = 2; 13 | N(2, 0) = 1; 14 | N(2, 1) = 0; 15 | Vector b, cB(3, 0), cN; 16 | b.append(2); 17 | b.append(7); 18 | b.append(3); 19 | cN.append(-1); 20 | cN.append(-2); 21 | LinearProgrammingSimplex s(B, N, cB, cN, b); 22 | Vector > result = s.solve(), expectedResult; 23 | expectedResult.append(make_pair(0, 5.0)); 24 | expectedResult.append(make_pair(2, 3.0)); 25 | expectedResult.append(make_pair(1, 3.0)); 26 | for(int i = 0; i < result.getSize(); ++i) 27 | { 28 | DEBUG(result[i].first); 29 | DEBUG(result[i].second); 30 | assert(result[i] == expectedResult[i]); 31 | } 32 | } 33 | 34 | int main() 35 | { 36 | testSimplex(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /NumericalOptimization/testOptCommon.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_TEST_OPT_COMMON_H 2 | #define IGMDK_TEST_OPT_COMMON_H 3 | #include "../Utils/DEBUG.h" 4 | #include "../ExternalMemoryAlgorithms/CSV.h" 5 | using namespace std; 6 | namespace igmdk{ 7 | 8 | template void debugResultHelperBatch( 9 | Vector, double> > const& results, 10 | FUNCTION const& f, Vector > & matrix, int start) 11 | { 12 | int k = results.getSize(); 13 | double timediff = 1.0 * (clock() - start)/CLOCKS_PER_SEC/k; 14 | pair, double> answer = f.getAnswer(); 15 | double cap = -4;//"solved" if got few digits or more 16 | IncrementalStatistics xe, ye, gn, se; 17 | for(int i = 0; i < k; ++i) 18 | {//cap change at eps and digits at 0, digits negative for smaller is better 19 | pair, double> const& result = results[i]; 20 | double eps = numeric_limits::epsilon(), 21 | relAbsXDigits = min(0.0, log10(max(eps, normInf(result.first - answer.first)/ 22 | max(1.0, normInf(answer.first))))), 23 | relAbsYDigits = min(0.0, log10(max(eps, abs(result.second - answer.second)/ 24 | max(1.0, abs(answer.second))))); 25 | xe.addValue(relAbsXDigits); 26 | ye.addValue(relAbsYDigits); 27 | se.addValue(relAbsYDigits <= cap); 28 | double gradNorm = norm(estimateGradientCD(result.first, f)), 29 | normalizedGradNorm = gradNorm/max(1.0, abs(result.second)); 30 | gn.addValue(normalizedGradNorm); 31 | } 32 | double relAbsXDigits = xe.getMean(), relAbsYDigits = ye.getMean(), 33 | sePercentage = -se.getMean(); 34 | DEBUG(relAbsXDigits); 35 | DEBUG(relAbsYDigits); 36 | DEBUG(sePercentage); 37 | DEBUG(TEST_SET::evalCount/k);//ok to round down 38 | matrix.lastItem().append(to_string(relAbsXDigits)); 39 | matrix.lastItem().append(to_string(relAbsYDigits)); 40 | matrix.lastItem().append(to_string(sePercentage)); 41 | matrix.lastItem().append(to_string(TEST_SET::evalCount/k)); 42 | TEST_SET::evalCount = 0; 43 | double normalizedGradNorm = gn.getMean(); 44 | TEST_SET::evalCount = 0; 45 | DEBUG(normalizedGradNorm); 46 | matrix.lastItem().append(to_string(normalizedGradNorm)); 47 | DEBUG(timediff); 48 | matrix.lastItem().append(to_string(timediff)); 49 | } 50 | 51 | void createMinReport(string const& prefix, 52 | Vector > const& matrix) 53 | { 54 | int reportNumber = time(0); 55 | string filename = prefix + to_string(reportNumber) + ".csv"; 56 | createCSV(matrix, filename.c_str()); 57 | Vector names; 58 | names.append("XError"); 59 | names.append("YError"); 60 | names.append("SEP"); 61 | names.append("NEvals"); 62 | names.append("ScaledGradNorm"); 63 | names.append("TimeSeconds"); 64 | createAugmentedCSVFiles(matrix, names, filename, 1); 65 | } 66 | 67 | }//end namespace igmdk 68 | #endif 69 | -------------------------------------------------------------------------------- /Optimization/OptTestAuto.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_OPT_TEST_AUTO_H 2 | #define IGMDK_OPT_TEST_AUTO_H 3 | #include 4 | using namespace std; 5 | #include "SearchAlgorithms.h" 6 | #include "../Graphs/Graph.h" 7 | 8 | namespace igmdk{ 9 | 10 | struct GraphProblem 11 | { 12 | typedef int STATE_ID; 13 | int nullState()const{return -1;} 14 | typedef EHash HASHER; 15 | GraphAA graph; 16 | int from, to; 17 | int start()const{return from;} 18 | template 19 | bool isGoal(int i, DUMMY const& d)const{return i == to;} 20 | template 21 | Vector nextStates(int j, DUMMY const& d)const 22 | { 23 | Vector result; 24 | for(GraphAA::AdjacencyIterator i = graph.begin(j); 25 | i != graph.end(j); ++i) result.append(i.to()); 26 | return result; 27 | } 28 | template 29 | double remainderLowerBound(int dummy, int i, DUMMY const& d)const{return 0;} 30 | template 31 | double distance(int k, int j, DUMMY const& d)const 32 | { 33 | for(GraphAA::AdjacencyIterator i = graph.begin(j); 34 | i != graph.end(j); ++i) if(i.to() == k) return i.data(); 35 | return 0; 36 | } 37 | }; 38 | 39 | void testAStarAuto() 40 | { 41 | typedef GraphAA G; 42 | G sp; 43 | GraphProblem Gp; 44 | for(int i = 0; i < 6; ++i) 45 | { 46 | Gp.graph.addVertex(); 47 | } 48 | Gp.graph.addEdge(0,1,6); 49 | Gp.graph.addEdge(0,2,8); 50 | Gp.graph.addEdge(0,3,18); 51 | Gp.graph.addEdge(1,4,11); 52 | Gp.graph.addEdge(2,3,9); 53 | Gp.graph.addEdge(4,5,3); 54 | Gp.graph.addEdge(5,2,7); 55 | Gp.graph.addEdge(5,3,4); 56 | Gp.from = 0; 57 | Gp.to = 5; 58 | 59 | pair, bool> result = AStar::solve(Gp); 60 | assert(result.second); 61 | Vector expected; 62 | expected.append(0); 63 | expected.append(1); 64 | expected.append(4); 65 | expected.append(5); 66 | assert(result.first == expected); 67 | DEBUG("testAStartAuto passed"); 68 | } 69 | 70 | void testRBFSAuto() 71 | { 72 | typedef GraphAA G; 73 | G sp; 74 | GraphProblem Gp; 75 | for(int i = 0; i < 6; ++i) 76 | { 77 | Gp.graph.addVertex(); 78 | } 79 | Gp.graph.addEdge(0,1,6); 80 | Gp.graph.addEdge(0,2,8); 81 | Gp.graph.addEdge(0,3,18); 82 | Gp.graph.addEdge(1,4,11); 83 | Gp.graph.addEdge(2,3,9); 84 | Gp.graph.addEdge(4,5,3); 85 | Gp.graph.addEdge(5,2,7); 86 | Gp.graph.addEdge(5,3,4); 87 | Gp.from = 0; 88 | Gp.to = 5; 89 | 90 | RecursiveBestFirstSearch dk(Gp); 91 | assert(dk.foundGoal); 92 | assert(dk.pred.pop() == 5); 93 | assert(dk.pred.pop() == 4); 94 | assert(dk.pred.pop() == 1); 95 | assert(dk.pred.pop() == 0); 96 | assert(dk.pred.isEmpty()); 97 | DEBUG("testRBFSAuto passed"); 98 | } 99 | 100 | void testAllAutoOpt() 101 | { 102 | DEBUG("testAllAutoOpt"); 103 | testAStarAuto(); 104 | testRBFSAuto(); 105 | } 106 | 107 | }//end namespace 108 | #endif 109 | -------------------------------------------------------------------------------- /Optimization/TestConstraint.cpp: -------------------------------------------------------------------------------- 1 | #include "ContraintProcessing.h" 2 | #include "../Utils/Debug.h" 3 | using namespace igmdk; 4 | using namespace std; 5 | 6 | void testAC3() 7 | { 8 | //Example: trace execution on (0)<->(0,1)<->(0,1,2)<->(0,1,2,3) with <-> 9 | //denoting alldiff constraint 10 | AllDifferent ad; 11 | 12 | ConstraintGraph cg; 13 | for(int i = 0; i < 4; ++i) 14 | { 15 | cg.addVariable(i+1); 16 | cg.variables[i].setAll(true); 17 | ad.addVariable(i); 18 | } 19 | for(int i = 0; i < 4; ++i) cg.variables[i].debug(); 20 | for(int i = 0; i < 3; ++i) cg.addConstraint(i, i+1, ad.handle); 21 | //for(int j = i + 1; j < 4; ++j) 22 | // cg.addConstraint(i, j, AllDifferent()); 23 | DEBUG(cg.SAC3()); 24 | for(int i = 0; i < 4; ++i) cg.variables[i].debug(); 25 | //Vector result; 26 | //backtrackFind(cg.variables, result, AllDifferent()); 27 | //for(int i = 0; i < result.getSize(); ++i) DEBUG(result[i]); 28 | } 29 | 30 | 31 | void testSudoku() 32 | { 33 | int easy[] = 34 | { 35 | 2,0,1,7,9,5,0,0,0, 36 | 0,0,9,0,0,8,0,1,0, 37 | 0,0,0,3,0,1,0,0,7, 38 | 0,2,0,5,0,0,1,7,8, 39 | 0,8,0,0,0,0,0,9,0, 40 | 1,5,7,0,0,4,0,3,0, 41 | 6,0,0,8,0,2,0,0,0, 42 | 0,9,0,6,0,0,5,0,0, 43 | 0,0,0,1,7,9,3,0,6 44 | }; 45 | int medium[] = 46 | { 47 | 0,0,5,0,0,3,2,9,0, 48 | 9,0,0,2,0,0,0,3,4, 49 | 0,0,0,0,1,0,8,0,0, 50 | 0,0,0,0,9,0,0,7,1, 51 | 0,0,0,6,0,5,0,0,0, 52 | 7,3,0,0,2,0,0,0,0, 53 | 0,0,7,0,6,0,0,0,0, 54 | 6,8,0,0,0,9,0,0,2, 55 | 0,5,2,8,0,0,6,0,0 56 | }; 57 | int hard[] = 58 | { 59 | 0,1,2,0,6,0,8,0,0, 60 | 0,0,0,0,3,0,0,5,0, 61 | 6,0,0,4,0,0,0,0,7, 62 | 0,0,6,0,0,0,0,1,0, 63 | 0,9,7,0,0,0,6,4,0, 64 | 0,8,0,0,0,0,7,0,0, 65 | 8,0,0,0,0,1,0,0,3, 66 | 0,4,0,0,5,0,0,0,0, 67 | 0,0,1,0,2,0,9,7,0 68 | }; 69 | { 70 | Sudoku sd(easy); 71 | DEBUG("Easy Solution"); 72 | sd.printSolution(); 73 | } 74 | { 75 | Sudoku sd(medium); 76 | DEBUG("Medium Solution"); 77 | sd.printSolution(); 78 | } 79 | { 80 | Sudoku sd(hard); 81 | DEBUG("Hard Solution"); 82 | sd.printSolution(); 83 | } 84 | 85 | } 86 | 87 | 88 | int main() 89 | { 90 | //testAC3(); 91 | testSudoku(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This code is for the readers of the book (see https://www.amazon.com/dp/B08PXHJCXY), and for personal use only. For commercial use please reach out (my email is in the book's preface and back cover). 2 | 3 | I ask that you please post an honest review of the book on Amazon.com in return. The feedback I got so far for the previous editions has been limited, and I need it to improve the book further. This is hobby project that is worked on weekends/evenings, so any assistance is greatly appreciated. 4 | 5 | All reusable code is in .h files, and test*.cpp files allow testing various parts of it. 6 | 7 | The code has been reasonably tested, but no guarantees are made about its quality or behavior. I.e. the code is provided "as is", without any implicit warranty of merchantability. So don't use it in pacemakers, nuclear reactors, etc. 8 | 9 | Github seems to have a bug in downloading the slides--the best way to get them is to download the entire repository. 10 | -------------------------------------------------------------------------------- /RandomNumberGeneration/CircleArea.py: -------------------------------------------------------------------------------- 1 | import math 2 | class Point: 3 | def __init__(self, x, y): 4 | self.x = x 5 | self.y = y 6 | class Circle: 7 | def __init__(self, p, r): 8 | self.p = p 9 | self.r = r 10 | def distance(p1, p2): 11 | return math.sqrt((p1.x - p2.x)**2 + (p1.y - p2.y)**2) 12 | def isInCircle(p, circles): 13 | for c in circles: 14 | if distance(p, c.p) <= c.r: 15 | return True 16 | return False 17 | def findBoundingBox(circles): 18 | inf = math.inf 19 | left = inf 20 | right = -inf 21 | down = inf 22 | up = -inf 23 | for c in circles: 24 | if c.p.x - c.r < left: 25 | left = c.p.x - c.r 26 | if c.p.x + c.r > right: 27 | right = c.p.x + c.r 28 | if c.p.y - c.r < down: 29 | down = c.p.y - c.r 30 | if c.p.y + c.r > up: 31 | up = c.p.y + c.r 32 | return [Point(left, up), Point(right, down)] 33 | import random 34 | def findCoveredArea(circles, nSimulations): 35 | box = findBoundingBox(circles) 36 | left = box[0].x 37 | right = box[1].x 38 | down = box[1].y 39 | up = box[0].y 40 | inCount = 0 41 | for _ in range(0, nSimulations): 42 | if isInCircle(Point(random.uniform(left, right), 43 | random.uniform(down, up)), circles): 44 | inCount += 1 45 | return float(inCount)/nSimulations * (up - down) * (right - left) 46 | print(findCoveredArea([Circle(Point(0, 0), 1)], 1000000))#expect Pi 47 | -------------------------------------------------------------------------------- /RandomNumberGeneration/Correlation.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CORRELATION_H 2 | #define IGMDK_CORRELATION_H 3 | #include "Statistics.h" 4 | #include 5 | namespace igmdk{ 6 | 7 | double PearsonCorrelation(Vector > const& a) 8 | { 9 | int n = a.getSize(); 10 | assert(n > 1); 11 | IncrementalStatistics x, y; 12 | for(int i = 0; i < n; ++i) 13 | { 14 | x.addValue(a[i].first); 15 | y.addValue(a[i].second); 16 | } 17 | double covSum = 0; 18 | for(int i = 0; i < a.getSize(); ++i) 19 | covSum += (a[i].first - x.getMean()) * (a[i].second - y.getMean()); 20 | covSum /= n - 1; 21 | double result = covSum/sqrt(x.getVariance() * y.getVariance()); 22 | return isfinite(result) ? result : 0;//check for div by 0 23 | } 24 | pair PearsonCorrelationConf(double corr, int n, double z = 2) 25 | { 26 | assert(0 <= corr && corr <= 1 && n > 3); 27 | double stat = atanh(corr), std = 1/sqrt(n - 3); 28 | return make_pair(tanh(stat - z * std), tanh(stat + z * std)); 29 | } 30 | 31 | double SpearmanCorrelation(Vector > a) 32 | { 33 | Vector x, y; 34 | for(int i = 0; i < a.getSize(); ++i) 35 | { 36 | x.append(a[i].first); 37 | y.append(a[i].second); 38 | } 39 | x = convertToRanks(x), y = convertToRanks(y); 40 | for(int i = 0; i < a.getSize(); ++i) 41 | { 42 | a[i].first = x[i]; 43 | a[i].second = y[i]; 44 | } 45 | return PearsonCorrelation(a); 46 | } 47 | pair SpearmanCorrelationConf(double corr, int n, double z = 2) 48 | { 49 | assert(0 <= corr && corr <= 1 && n > 1); 50 | double std = 1/sqrt(n - 1); 51 | return make_pair(corr - z * std, corr + z * std); 52 | } 53 | 54 | }//end namespace 55 | #endif 56 | -------------------------------------------------------------------------------- /RandomNumberGeneration/DistributionTests.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_DISTRIBUTION_TESTS_H 2 | #define IGMDK_DISTRIBUTION_TESTS_H 3 | #include "Statistics.h" 4 | #include "../Sorting/Sort.h" 5 | #include 6 | namespace igmdk{ 7 | 8 | double evaluateChiSquaredCdf(double chi, int n) 9 | { 10 | assert(chi >= 0 && n > 0); 11 | double m = 5.0/6 - 1.0/9/n - 7.0/648/n/n + 25.0/2187/n/n/n, 12 | q2 = 1.0/18/n + 1.0/162/n/n - 37.0/11664/n/n/n, temp = chi/n, 13 | x = pow(temp, 1.0/6) - pow(temp, 1.0/3)/2 + pow(temp, 1.0/2)/3; 14 | return approxNormalCDF((x - m)/sqrt(q2)); 15 | } 16 | double chiSquaredP(Vector const& counts, 17 | Vector const& means, int degreesOfFreedomRemoved = 0) 18 | { 19 | double chiStat = 0; 20 | for(int i = 0; i < counts.getSize(); ++i) 21 | {//enforce 5 in each bin for good approximation 22 | assert(means[i] >= 5); 23 | chiStat += (counts[i] - means[i]) * (counts[i] - means[i])/means[i]; 24 | } 25 | return 1 - evaluateChiSquaredCdf(chiStat, 26 | counts.getSize() - degreesOfFreedomRemoved); 27 | } 28 | 29 | template double findMaxKDiff(Vector x, CDF const& cdf) 30 | {//helper to calculate max diff 31 | quickSort(x.getArray(), x.getSize()); 32 | double level = 0, maxDiff = 0, del = 1.0/x.getSize(); 33 | for(int i = 0; i < x.getSize(); ++i) 34 | { 35 | double cdfValue = cdf(x[i]); 36 | maxDiff = max(maxDiff, abs(cdfValue - level)); 37 | level += del; 38 | while(i + 1 < x.getSize() && x[i] == x[i + 1]) 39 | { 40 | level += del; 41 | ++i; 42 | } 43 | maxDiff = max(maxDiff, abs(cdfValue - level)); 44 | } 45 | return maxDiff; 46 | } 47 | template double DKWPValue(Vector const& x, 48 | CDF const& cdf) 49 | {//DKW invalid for p-value < 0.5 50 | double delta = findMaxKDiff(x, cdf); 51 | //DEBUG(delta); 52 | return min(0.5, 2 * exp(-2 * x.getSize() * delta * delta)); 53 | } 54 | 55 | double findMaxKSDiff(Vector a, Vector b) 56 | {//helper to calculate max diff 57 | quickSort(a.getArray(), a.getSize()); 58 | quickSort(b.getArray(), b.getSize()); 59 | double aLevel = 0, bLevel = 0, maxDiff = 0, delA = 1.0/a.getSize(), 60 | delB = 1.0/b.getSize(); 61 | for(int i = 0, j = 0; i < a.getSize() || j < b.getSize();) 62 | { 63 | double x, nextX = numeric_limits::infinity(); 64 | bool useB = i >= a.getSize() || (j < b.getSize() && b[j] < a[i]); 65 | if(useB) 66 | { 67 | x = b[j++]; 68 | bLevel += delB; 69 | } 70 | else 71 | { 72 | aLevel += delA; 73 | x = a[i++]; 74 | }//handle equal values--process all before diff update 75 | if(i < a.getSize() || j < b.getSize()) 76 | { 77 | useB = i >= a.getSize() || (j < b.getSize() && b[j] < a[i]); 78 | nextX = useB ? b[j] : a[i]; 79 | } 80 | if(x != nextX) maxDiff = max(maxDiff, abs(aLevel - bLevel)); 81 | } 82 | return maxDiff; 83 | } 84 | double KS2SamplePValue(Vector const& a, Vector const& b) 85 | {//calculate the adjustment first, then find p-value of d 86 | double stddev = sqrt(1.0 * (a.getSize() + b.getSize())/ 87 | (a.getSize() * b.getSize())), 88 | delta = findMaxKSDiff(a, b)/stddev; 89 | return 2 * exp(-2 * delta * delta); 90 | } 91 | 92 | }//end namespace 93 | #endif 94 | -------------------------------------------------------------------------------- /RandomNumberGeneration/MCMC.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_MCMC_H 2 | #define IGMDK_MCMC_H 3 | #include "Random.h" 4 | #include "../Utils/Vector.h" 5 | #include 6 | namespace igmdk{ 7 | 8 | template class GridRWM 9 | { 10 | PDF f; 11 | double x, fx, aFrom, aTo; 12 | int from, to; 13 | double sampleHelper(double a) 14 | { 15 | double xNew = x + GlobalRNG().uniform(-a, a), fxNew = f(xNew); 16 | if(fx * GlobalRNG().uniform01() <= fxNew) 17 | { 18 | x = xNew; 19 | fx = fxNew; 20 | } 21 | return x; 22 | } 23 | public: 24 | GridRWM(double x0 = 0, PDF const& theF = PDF(), int from = -10, 25 | int to = 20): x(x0), f(theF), fx(f(x)), aFrom(pow(2, from)), 26 | aTo(pow(2, to)) {} 27 | double sample() 28 | { 29 | for(double a = aFrom; a < aTo; a *= 2) sampleHelper(a); 30 | return x; 31 | } 32 | }; 33 | 34 | template class MultidimGridRWM 35 | { 36 | PDF f; 37 | Vector x; 38 | double fx, aFrom, aTo, factor; 39 | Vector sampleHelper(double a) 40 | { 41 | Vector xNew = x; 42 | for(int i = 0; i < xNew.getSize(); ++i) 43 | xNew[i] += GlobalRNG().uniform(-a, a); 44 | double fxNew = f(xNew); 45 | if(fx * GlobalRNG().uniform01() <= fxNew) 46 | { 47 | x = xNew; 48 | fx = fxNew; 49 | } 50 | return x; 51 | } 52 | public: 53 | MultidimGridRWM(Vector const& x0, PDF const& theF = PDF(), 54 | int from = -10, int to = 20): x(x0), f(theF), fx(f(x)), aFrom(pow(2, 55 | from)), aTo(pow(2, to)), factor(pow(2, 1.0/x.getSize())) {} 56 | Vector sample() 57 | { 58 | for(double a = aFrom; a < aTo; a *= factor) sampleHelper(a); 59 | return x; 60 | } 61 | }; 62 | 63 | }//end namespace 64 | #endif 65 | -------------------------------------------------------------------------------- /RandomNumberGeneration/MultipleComparison.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_MULTIPLE_COMPARISON_H 2 | #define IGMDK_MULTIPLE_COMPARISON_H 3 | #include "Statistics.h" 4 | #include "../Sorting/Sort.h" 5 | #include "../NumericalMethods/Matrix.h" 6 | #include 7 | namespace igmdk{ 8 | 9 | double find2SidedConfZBonf(int k, double conf = 0.95) 10 | { 11 | assert(k > 0); 12 | return find2SidedConfZ(1 - (1 - conf)/k); 13 | } 14 | 15 | double findNemenyiSignificantAveRankDiff(int k, int n, bool forControl = false, 16 | double conf = 0.95) 17 | {//invert rank sum formula 18 | int nPairs = k * (k + 1)/2; 19 | double q = sqrt(nPairs/(3.0 * n)), 20 | z = find2SidedConfZBonf(forControl ? k : nPairs, conf); 21 | return q * z/n;//for rank average, not sum 22 | } 23 | 24 | void HolmAdjust(Vector& pValues) 25 | { 26 | int k = pValues.getSize(); 27 | Vector indices(k); 28 | for(int i = 0; i < k; ++i) indices[i] = i; 29 | IndexComparator c(pValues.getArray()); 30 | quickSort(indices.getArray(), 0, k - 1, c); 31 | for(int i = 0; i < k; ++i) pValues[indices[i]] = min(1.0, max(i > 0 ? 32 | pValues[indices[i - 1]] : 0, (k - i) * pValues[indices[i]])); 33 | } 34 | 35 | void FDRAdjust(Vector& pValues) 36 | { 37 | int k = pValues.getSize(); 38 | Vector indices(k); 39 | for(int i = 0; i < k; ++i) indices[i] = i; 40 | IndexComparator c(pValues.getArray()); 41 | quickSort(indices.getArray(), 0, k - 1, c); 42 | for(int i = k - 1; i >= 0; --i) pValues[indices[i]] = min(i < k - 1 ? 43 | pValues[indices[i + 1]] : 1, pValues[indices[i]] * k/(i + 1)); 44 | } 45 | 46 | Vector FriedmanRankSums(Vector > const& a) 47 | {//a[i] is vector of responses on domain i 48 | assert(a.getSize() > 0 && a[0].getSize() > 1); 49 | int n = a.getSize(), k = a[0].getSize(); 50 | Vector alternativeRankSums(k); 51 | for(int i = 0; i < n; ++i) 52 | { 53 | assert(a[i].getSize() == k); 54 | Vector ri = convertToRanks(a[i]); 55 | for(int j = 0; j < k; ++j) alternativeRankSums[j] += ri[j]; 56 | } 57 | return alternativeRankSums; 58 | } 59 | 60 | double NemenyiAllPairsPValueUnadjusted(double r1, double r2, int n, int k) 61 | {return 1 - approxNormalCDF(abs(r1 - r2)/sqrt(n * k * (k + 1)/6.0));} 62 | Matrix RankTestAllPairs(Vector > const& a, 63 | double NemenyiALevel = 0.05, bool useFDR = false) 64 | { 65 | Vector rankSums = FriedmanRankSums(a); 66 | int n = a.getSize(), k = rankSums.getSize(); 67 | Vector temp(k * (k - 1)/2); 68 | for(int i = 1, index = 0; i < k; ++i) for(int j = 0; j < i; ++j) 69 | temp[index++] = NemenyiAllPairsPValueUnadjusted(rankSums[i], 70 | rankSums[j], n, k); 71 | if(useFDR) FDRAdjust(temp); 72 | else HolmAdjust(temp); 73 | Matrix result = Matrix::identity(k); 74 | for(int i = 1, index = 0; i < k; ++i) for(int j = 0; j < i; ++j) 75 | result(i, j) = result(j, i) = temp[index++]; 76 | return result; 77 | } 78 | 79 | }//end namespace 80 | #endif 81 | -------------------------------------------------------------------------------- /RandomNumberGeneration/OCBA.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_OCBA_H 2 | #define IGMDK_OCBA_H 3 | 4 | #include "../Utils/Vector.h" 5 | #include "Statistics.h" 6 | #include "MultipleComparison.h" 7 | #include 8 | namespace igmdk{ 9 | 10 | bool isNormal0BestBonf(Vector const& data, double aLevel) 11 | {//smallest is best with precision meanPrecision 12 | int k = data.getSize(); 13 | assert(k > 1); 14 | double z = find2SidedConfZBonf(k, 1 - aLevel), 15 | upper = data[0].mean + z * data[0].stddev(); 16 | for(int i = 1; i < k; ++i) 17 | { 18 | double lower = data[i].mean - z * data[i].stddev(); 19 | if(lower <= upper) return false; 20 | } 21 | return true; 22 | } 23 | 24 | template struct OCBA 25 | { 26 | MULTI_FUNCTION const& f; 27 | Vector data; 28 | int nDone; 29 | OCBA(MULTI_FUNCTION const& theF = MULTI_FUNCTION(), int initialSims = 30): 30 | f(theF), data(theF.getSize()) 31 | { 32 | int k = f.getSize(); 33 | for(int i = 0; i < k; ++i) 34 | for(int j = 0; j < initialSims; ++j) data[i].addValue(f(i)); 35 | nDone = k * initialSims; 36 | } 37 | pair, int> findBest() 38 | { 39 | int k = f.getSize(); 40 | Vector s; 41 | for(int i = 0; i < k; ++i) s.append(data[i].getStandardErrorSummary()); 42 | int bestI = 0, bestRatioI = -1; 43 | double bestMean = s[0].mean, ratioSum = 0, bestRatio; 44 | for(int i = 1; i < k; ++i) 45 | if(s[i].mean < bestMean) bestMean = s[bestI = i].mean; 46 | swap(s[0], s[bestI]); 47 | return make_pair(s, bestI); 48 | } 49 | void simulateNext() 50 | { 51 | pair, int> best = findBest(); 52 | int k = f.getSize(), bestI = best.second, bestRatioI = -1;; 53 | Vector s = best.first; 54 | //compute the largest OCBA ratio 55 | double bestMean = s[0].mean, ratioSum = 0, bestRatio; 56 | for(int i = 1; i < k; ++i) 57 | { 58 | double meanDiff = s[i].mean - bestMean, ratio = 59 | s[i].variance/(meanDiff * meanDiff); 60 | ratioSum += ratio * ratio/s[i].variance; 61 | if(bestRatioI == -1 || ratio > bestRatio) 62 | { 63 | bestRatio = ratio; 64 | bestRatioI = i; 65 | } 66 | } 67 | double ratioBest = sqrt(ratioSum * s[0].variance); 68 | if(ratioBest > bestRatio) bestRatioI = bestI; 69 | else if(bestRatioI == bestI) bestRatioI = 0; 70 | //simulate the largest ratio alternative 71 | data[bestRatioI].addValue(f(bestRatioI)); 72 | ++nDone; 73 | } 74 | int simulateTillBest(int simBudget = 100000, double aLevel = 0.05) 75 | { 76 | assert(nDone < simBudget); 77 | int k = f.getSize(), nTests = lgCeiling(simBudget) - lgFloor(nDone); 78 | while(nDone < simBudget) 79 | { 80 | simulateNext(); 81 | if(isPowerOfTwo(nDone) || nDone == simBudget - 1) 82 | { 83 | Vector s = findBest().first; 84 | if(isNormal0BestBonf(s, aLevel/nTests)) break; 85 | } 86 | } 87 | return nTests; 88 | } 89 | }; 90 | 91 | }//end namespace 92 | #endif 93 | -------------------------------------------------------------------------------- /RandomNumberGeneration/PermutationTests.h: -------------------------------------------------------------------------------- 1 | #ifndef PERMUTATION_TESTS_H 2 | #define PERMUTATION_TESTS_H 3 | 4 | #include "Random.h" 5 | #include "../Utils/Vector.h" 6 | #include "../NumericalMethods/EquationSolving.h" 7 | 8 | namespace igmdk{ 9 | 10 | template double permutationTest(PERM_TESTER& p, 11 | int b = 10000, int side = 0, Random<>& rng = GlobalRNG()) 12 | {//"more extreme" means larger for 1-sided, side -1 for smaller, 1 for larger 13 | assert(b > 1 && abs(side) <= 1); 14 | double f = p(); 15 | int nLeft = 1, nRight = 1;//start with 1 not 0 16 | for(int i = 0; i < b; ++i) 17 | { 18 | p.exchange(rng); 19 | double fr = p(); 20 | nLeft += (f <= fr); 21 | nRight += (f >= fr); 22 | } 23 | double leftP = nLeft * 1.0/(b + 1), rightP = nRight * 1.0/(b + 1); 24 | return side == 0 ? min(1.0, 2 * min(leftP, rightP)) : 25 | side == -1 ? leftP : rightP; 26 | } 27 | 28 | template struct PairedTestLocationPermuter 29 | { 30 | Vector diffs; 31 | LOCATION_F f; 32 | PairedTestLocationPermuter(Vector const& data): diffs(data){} 33 | PairedTestLocationPermuter(Vector > const& data) 34 | { 35 | for(int i = 0; i < data.getSize(); ++i) 36 | diffs.append(data[i].first - data[i].second); 37 | } 38 | double operator()()const{return f(diffs);} 39 | void exchange(Random<>& r) 40 | {for(int i = 0; i < diffs.getSize(); ++i)if(r.mod(2))diffs[i] *= -1;} 41 | void setShift(double shift)//must not be called after exchange 42 | {for(int i = 0; i < diffs.getSize(); ++i) diffs[i] += shift;} 43 | }; 44 | 45 | template struct permConfHelper 46 | { 47 | PERM_TESTER const& p; 48 | double a; 49 | int seed, b; 50 | permConfHelper(PERM_TESTER const& theP, double theA, int theSeed, 51 | int theB): p(theP), a(theA), seed(theSeed), b(theB) {} 52 | double operator()(double shift)const 53 | { 54 | Random<> rng(seed); 55 | PERM_TESTER p2 = p; 56 | p2.setShift(shift); 57 | return permutationTest(p2, b, 0, rng) - a; 58 | } 59 | }; 60 | template pair permutationConf( 61 | PERM_TESTER& p, double a = 0.05, int b = 10000)//assume two-sided 62 | { 63 | double stat = p(); 64 | permConfHelper f(p, a, time(0), b); 65 | double left = exponentialSearch1Sided(f, -stat, -0.001).first, 66 | right = exponentialSearch1Sided(f, -stat).first; 67 | left = isfinite(left) ? left : -stat; 68 | right = isfinite(right) ? right : -stat; 69 | return make_pair(2 * stat + left, 2 * stat + right); 70 | } 71 | 72 | template pair permutationLocationConf( 73 | Vector const& data, double a = 0.05, int b = 10000) 74 | { 75 | PairedTestLocationPermuter p = {data}; 76 | return permutationConf(p, a, b); 77 | } 78 | 79 | }//end namespace 80 | #endif 81 | -------------------------------------------------------------------------------- /RandomNumberGeneration/SensitivityAnalysis.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SENSITIVITY_ANALYSIS_H 2 | #define IGMDK_SENSITIVITY_ANALYSIS_H 3 | #include "Statistics.h" 4 | #include "Bootstrap.h" 5 | #include "../Utils/Vector.h" 6 | #include 7 | namespace igmdk{ 8 | 9 | Vector findSobolIndicesHelper(Vector const& ya, 10 | Vector > const& yc) 11 | {//calculate S from YA and YC 12 | int n = ya.getSize(), D = yc.getSize(); 13 | Vector result(D); 14 | IncrementalStatistics s; 15 | for(int i = 0; i < n; ++i) s.addValue(ya[i]); 16 | double f02 = s.getMean() * s.getMean(), tempa = dotProduct(ya, ya)/n; 17 | for(int j = 0; j < D; ++j) 18 | result[j] = max(0.0, (dotProduct(ya, yc[j])/n - f02)/(tempa - f02)); 19 | return result; 20 | } 21 | template pair, Vector>> 22 | findSobolIndicesSaltelli(Vector, double> > const& 23 | data, FUNCTOR const& f, int nBoots = 200, double a = 0.05) 24 | {//calculate ya and yb 25 | int D = data[0].first.getSize(), n = data.getSize()/2; 26 | Vector ya(n), yb(n), yaR(n); 27 | for(int i = 0; i < 2 * n; ++i) 28 | if(i < n) ya[i] = data[i].second; 29 | else yb[i - n] = data[i].second; 30 | //calculate yc 31 | Vector > yc(D, Vector(n)), ycR = yc; 32 | for(int j = 0; j < D; ++j) 33 | for(int i = 0; i < n; ++i) 34 | { 35 | Vector x = data[n + i].first; 36 | x[j] = data[i].first[j]; 37 | yc[j][i] = f(x); 38 | } 39 | //bootstrap to find standard deviations 40 | Vector s(D); 41 | for(int k = 0; k < nBoots; ++k) 42 | {//resample data rows 43 | for(int i = 0; i < n; ++i) 44 | { 45 | int index = GlobalRNG().mod(n); 46 | yaR[i] = ya[index]; 47 | for(int j = 0; j < D; ++j) ycR[j][i] = yc[j][index]; 48 | } 49 | //evaluate 50 | Vector indicesR = findSobolIndicesHelper(yaR, ycR); 51 | for(int j = 0; j < D; ++j) s[j].addValue(indicesR[j]); 52 | } 53 | Vector indices = findSobolIndicesHelper(ya, yc); 54 | Vector > confs; 55 | double z = getMixedZ(a/D); 56 | for(int j = 0; j < D; ++j) 57 | { 58 | double delta = s[j].stdev() * z; 59 | confs.append(make_pair(indices[j] - delta, indices[j] + delta)); 60 | } 61 | return make_pair(indices, confs); 62 | } 63 | 64 | }//end namespace 65 | #endif 66 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testCorrelation.cpp: -------------------------------------------------------------------------------- 1 | #include "Correlation.h" 2 | #include "Bootstrap.h" 3 | #include "../NumericalMethods/NumericalMethods.h" 4 | #include "../NumericalMethods/Matrix.h" 5 | #include "../Utils/Debug.h" 6 | #include "../ExternalMemoryAlgorithms/CSV.h" 7 | #include "testCommon.h" 8 | using namespace igmdk; 9 | 10 | template 11 | void testPearsonConfs(Vector >& matrix) 12 | { 13 | int n = 30; 14 | typedef pair X; 15 | typedef correr F; 16 | F f; 17 | pair > target = testBootstrapHelper(f, n); 18 | DEBUG("Exact Simulation"); 19 | DEBUG(target.first); 20 | DEBUG(target.second.first); 21 | DEBUG(target.second.second); 22 | SAMPLER s; 23 | BootstrapSimulationResult p("Normal"), 24 | bt("Bootstrap-t-capped"); 25 | for(int i = 0; i < 10000; ++i) 26 | { 27 | Vector samples(n); 28 | for(int j = 0; j < n; ++j) samples[j] = s(); 29 | double stat = f(samples); 30 | double left = target.first + stat - target.second.second; 31 | double right = target.first + stat - target.second.first; 32 | pair exact(left, right); 33 | BasicBooter booter(samples); 34 | p.addValue(PearsonCorrelationConf(PearsonCorrelation(samples), samples.getSize()), target.first, exact, stat); 35 | //p.addValue(PearsonCorrelationConf(PearsonCorrelation(samples), samples.getSize()), target.first, exact, stat); 36 | booter.resample = booter.data;//reset 37 | bt.addValue(bootstrapTIntervalCapped(booter), target.first, exact, stat); 38 | } 39 | p.print(matrix); 40 | //bc.print(matrix); 41 | //bmr.print(matrix); 42 | //bm.print(matrix); 43 | bt.print(matrix); 44 | //br.print(matrix); 45 | } 46 | 47 | void testPearsonConfsDriver() 48 | { 49 | Vector > matrix; 50 | DEBUG("Normal Error Spearman"); 51 | matrix.append(Vector()); 52 | matrix.lastItem().append("Normal Error Almost Line"); 53 | testPearsonConfs(matrix); 54 | matrix.append(Vector()); 55 | matrix.lastItem().append("Normal Error Cubic"); 56 | testPearsonConfs(matrix); 57 | 58 | makeConfsReport("Pearson", matrix); 59 | } 60 | 61 | int main(int argc, char *argv[]) 62 | { 63 | testPearsonConfsDriver(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testMCMC.cpp: -------------------------------------------------------------------------------- 1 | #include "MCMC.h" 2 | #include "Statistics.h" 3 | #include "../NumericalMethods/Matrix.h" 4 | using namespace igmdk; 5 | 6 | struct Normal01SemiPDF 7 | { 8 | double mean, variance; 9 | Normal01SemiPDF(double theMean = 100, double theVariance = 10000): 10 | mean(theMean), variance(theVariance){} 11 | double operator()(double x)const{x -= mean; return exp(-x * x/2/variance);} 12 | }; 13 | 14 | struct MultivarNormalSemiPDF 15 | { 16 | double operator()(Vector x)const 17 | { 18 | Matrix b2(3, 3); 19 | b2(0, 0) = 1; 20 | b2(0, 1) = 4; 21 | b2(0, 2) = 5; 22 | b2(1, 0) = 4; 23 | b2(1, 1) = 20; 24 | b2(1, 2) = 32; 25 | b2(2, 0) = 5; 26 | b2(2, 1) = 32; 27 | b2(2, 2) = 64; 28 | LUP lup(b2); 29 | Matrix inv = inverse(lup, 3); 30 | //inv.debug(); 31 | //for(int i = 0; i < x.getSize(); ++i) x[i] -= 100; 32 | //for(int i = 0; i < x.getSize(); ++i) DEBUG(x[i]); 33 | //DEBUG(inv * x * x/(-2)); 34 | //DEBUG(exp(inv * x * x/(-2))); 35 | //system("PAUSE"); 36 | return exp(dotProduct(inv * x, x)/(-2)); 37 | } 38 | }; 39 | 40 | void testVectorMagicMCMC2() 41 | { 42 | MultidimGridRWM g(Vector(3, 0.5)); 43 | int n = 10000; 44 | for(int i = 0; i < n; ++i) g.sample(); 45 | 46 | Vector sum(3, 0); 47 | Matrix outerSum(3, 3); 48 | for(int i = 0; i < n; ++i) 49 | { 50 | Vector x = g.sample(); 51 | sum += x; 52 | outerSum += outerProduct(x, x); 53 | } 54 | Vector mean = sum * (1.0/n); 55 | for(int i = 0; i < 3; ++i) DEBUG(mean[i]); 56 | Matrix cov = (outerSum - outerProduct(mean, sum)) * (1.0/(n - 1)); 57 | cov.debug(); 58 | } 59 | 60 | void testMCMCMagic() 61 | { 62 | GridRWM s; 63 | int n = 10; 64 | for(int i = 0; i < n; ++i) s.sample(); 65 | IncrementalStatistics z; 66 | 67 | for(int i = 0; i < n; ++i) z.addValue(s.sample()); 68 | DEBUG(z.getMean()); 69 | DEBUG(z.getVariance()); 70 | 71 | } 72 | 73 | int main(int argc, char *argv[]) 74 | { 75 | testVectorMagicMCMC2(); 76 | return 0; 77 | testMCMCMagic(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testMultipleComparison.cpp: -------------------------------------------------------------------------------- 1 | #include "Random.h" 2 | #include "Statistics.h" 3 | #include "PermutationTests.h" 4 | #include "Bootstrap.h" 5 | #include "DistributionTests.h" 6 | #include "../NumericalMethods/NumericalMethods.h" 7 | #include "../NumericalMethods/Matrix.h" 8 | #include "../Utils/Debug.h" 9 | #include "../ExternalMemoryAlgorithms/CSV.h" 10 | #include "testCommon.h" 11 | using namespace igmdk; 12 | 13 | void testFriedman() 14 | { 15 | Vector > responses; 16 | Vector r1; 17 | r1.append(14); 18 | r1.append(23); 19 | r1.append(26); 20 | r1.append(30); 21 | responses.append(r1); 22 | Vector r2; 23 | r2.append(19); 24 | r2.append(25); 25 | r2.append(25); 26 | r2.append(33); 27 | responses.append(r2); 28 | Vector r3; 29 | r3.append(17); 30 | r3.append(22); 31 | r3.append(29); 32 | r3.append(28); 33 | responses.append(r3); 34 | Vector r4; 35 | r4.append(17); 36 | r4.append(21); 37 | r4.append(28); 38 | r4.append(27); 39 | responses.append(r4); 40 | Vector r5; 41 | r5.append(16); 42 | r5.append(24); 43 | r5.append(28); 44 | r5.append(32); 45 | responses.append(r5); 46 | Vector r6; 47 | r6.append(15); 48 | r6.append(23); 49 | r6.append(27); 50 | r6.append(36); 51 | responses.append(r6); 52 | Vector r7; 53 | r7.append(18); 54 | r7.append(26); 55 | r7.append(27); 56 | r7.append(26); 57 | responses.append(r7); 58 | Vector r8; 59 | r8.append(16); 60 | r8.append(22); 61 | r8.append(30); 62 | r8.append(32); 63 | responses.append(r8); 64 | double k = 4; 65 | DEBUG("Holm"); 66 | Matrix all = RankTestAllPairs(responses, 0.05, false); 67 | for(int i = 0; i < k; ++i) 68 | { 69 | cout << "-"; 70 | for(int j = 0; j < k; ++j) 71 | { 72 | cout << ":" << std::fixed << std::setprecision(4) << all(i, j) << "|"; 73 | } 74 | cout << endl; 75 | } 76 | DEBUG("FDR"); 77 | all = RankTestAllPairs(responses, 0.05, true); 78 | for(int i = 0; i < k; ++i) 79 | { 80 | cout << "-"; 81 | for(int j = 0; j < k; ++j) 82 | { 83 | cout << ":" << std::fixed << std::setprecision(4) << all(i, j) << "|"; 84 | } 85 | cout << endl; 86 | } 87 | } 88 | 89 | void testNemenyi() 90 | { 91 | int k = 10, n = 10; 92 | DEBUG(findNemenyiSignificantAveRankDiff(1, 1)); 93 | DEBUG(findNemenyiSignificantAveRankDiff(k, n)); 94 | } 95 | 96 | int main(int argc, char *argv[]) 97 | { 98 | testNemenyi(); 99 | return 0; 100 | testFriedman(); 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testOCBA.cpp: -------------------------------------------------------------------------------- 1 | #include "OCBA.h" 2 | #include "Statistics.h" 3 | #include "../NumericalMethods/NumericalMethods.h" 4 | #include "../NumericalMethods/Matrix.h" 5 | #include "../Utils/Debug.h" 6 | #include "../ExternalMemoryAlgorithms/CSV.h" 7 | using namespace igmdk; 8 | 9 | void testNormalSummary() 10 | { 11 | 12 | Vector hha; 13 | NormalSummary n1(10, 100.0/8); 14 | NormalSummary n2(20, 81.0/8); 15 | NormalSummary n3(22, 144.0/8); 16 | hha.append(n1); 17 | hha.append(n2); 18 | hha.append(n3); 19 | DEBUG(isNormal0BestBonf(hha, 0.05));//wont match Chen book - k adjustment 20 | 21 | Vector hha2; 22 | NormalSummary n4(1, 0.1); 23 | NormalSummary n5(2, 0.2); 24 | NormalSummary n6(3, 0.3); 25 | hha2.append(n4); 26 | hha2.append(n5); 27 | hha2.append(n6); 28 | DEBUG(isNormal0BestBonf(hha2, 0.05)); 29 | } 30 | 31 | struct OCBATest 32 | { 33 | mutable int nEvals; 34 | OCBATest(): nEvals(0){} 35 | int getSize()const{return 6;} 36 | double operator()(int i)const 37 | { 38 | ++nEvals; 39 | if(i == 0) return GlobalRNG().normal(1, 9); 40 | if(i == 1) return GlobalRNG().normal(2, 8); 41 | if(i == 2) return GlobalRNG().normal(3, 7); 42 | if(i == 3) return GlobalRNG().normal(4, 6); 43 | if(i == 4) return GlobalRNG().normal(5, 5); 44 | else return GlobalRNG().normal(6, 4); 45 | } 46 | }; 47 | 48 | template int 49 | simulateSelectBest(MULTI_FUNCTION& f, int n0 = 30, int T = 100000, 50 | double meanPrecision = 0, double aLevel = 0.05) 51 | { 52 | int D = f.getSize(), winner = -1; 53 | assert(D > 1 && n0 > 1 && T > n0 * D); 54 | Vector data(D); 55 | for(int i = 0; i < D; ++i) 56 | for(int j = 0; j < n0; ++j) data[i].addValue(f(i)); 57 | int k = n0 * D; 58 | for(; k < T;) 59 | { 60 | Vector s; 61 | for(int i = 0; i < D; ++i) s.append(data[i].getStandardErrorSummary()); 62 | int bestIndex = 0; 63 | double bestMean = s[0].mean; 64 | for(int i = 1; i < D; ++i) 65 | if(s[i].mean < bestMean) bestMean = s[bestIndex = i].mean; 66 | swap(s[0], s[bestIndex]); 67 | for(int i = 0; i < D; ++i) 68 | if(isPowerOfTwo(++k) && isNormal0BestBonf(s, aLevel/lgCeiling(T))) 69 | { 70 | return lgCeiling(T); 71 | } 72 | for(int i = 0; i < D; ++i) data[i].addValue(f(i)); 73 | } 74 | return lgCeiling(T); 75 | } 76 | void testOCBA() 77 | { 78 | IncrementalStatistics sO, sN; 79 | for(int i = 0; i < 100; ++i) 80 | { 81 | OCBATest to; 82 | OCBA o(to); 83 | int nTests = o.simulateTillBest(); 84 | sO.addValue(to.nEvals); 85 | pair, int> best = o.findBest(); 86 | DEBUG(isNormal0BestBonf(best.first, 0.05/nTests)); 87 | DEBUG(best.second); 88 | OCBATest t; 89 | simulateSelectBest(t); 90 | sN.addValue(t.nEvals); 91 | } 92 | DEBUG(sO.getMean()); 93 | DEBUG(sO.getStandardErrorSummary().error95()); 94 | DEBUG(sN.getMean()); 95 | DEBUG(sN.getStandardErrorSummary().error95()); 96 | } 97 | 98 | int main(int argc, char *argv[]) 99 | { 100 | testOCBA(); 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testPermutationTests.cpp: -------------------------------------------------------------------------------- 1 | #include "PermutationTests.h" 2 | #include "Statistics.h" 3 | #include "../NumericalMethods/NumericalMethods.h" 4 | #include "../NumericalMethods/Matrix.h" 5 | #include "../Utils/Debug.h" 6 | #include "../ExternalMemoryAlgorithms/CSV.h" 7 | using namespace igmdk; 8 | 9 | struct meaner 10 | { 11 | double operator()(Vector const& observations)const 12 | { 13 | double result = observations[0]; 14 | for(int i = 1; i < observations.getSize(); ++i) 15 | { 16 | result += observations[i]; 17 | } 18 | return result / observations.getSize(); 19 | } 20 | }; 21 | //duplicated 22 | double permutationPairedTest(Vector > const& data, 23 | int b = 10000) 24 | { 25 | PairedTestLocationPermuter p = {data}; 26 | return permutationTest(p, b); 27 | } 28 | 29 | void testPermPair() 30 | { 31 | Vector > a; 32 | a.append(pair(51.2, 45.8)); 33 | a.append(pair(46.5, 41.3)); 34 | a.append(pair(24.1, 15.8)); 35 | a.append(pair(10.2, 11.1)); 36 | a.append(pair(65.3, 58.5)); 37 | a.append(pair(92.1, 70.3)); 38 | a.append(pair(30.3, 31.6)); 39 | a.append(pair(49.2, 35.4)); 40 | DEBUG(permutationPairedTest(a, 10000000));//seems to converge to 0.0236, t-test gives 0.0283 41 | } 42 | 43 | template pair permutationPairedConf( 44 | Vector > const& data, double a = 0.05, int b = 10000) 45 | { 46 | PairedTestLocationPermuter p = {data}; 47 | return permutationConf(p, a, b); 48 | } 49 | 50 | void testPermConf() 51 | { 52 | Vector > a; 53 | a.append(pair(51.2, 45.8)); 54 | a.append(pair(46.5, 41.3)); 55 | a.append(pair(24.1, 15.8)); 56 | a.append(pair(10.2, 11.1)); 57 | a.append(pair(65.3, 58.5)); 58 | a.append(pair(92.1, 70.3)); 59 | a.append(pair(30.3, 31.6)); 60 | a.append(pair(49.2, 35.4)); 61 | pair conf = permutationPairedConf(a); 62 | DEBUG(conf.first); 63 | DEBUG(conf.second); 64 | //DEBUG(permutationPairedTest(a, 10000000));//seems to converge to 0.0236 65 | } 66 | 67 | int main(int argc, char *argv[]) 68 | { 69 | testPermPair(); 70 | return 0; 71 | testPermConf(); 72 | return 0; 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testSensitivityAnalysis.cpp: -------------------------------------------------------------------------------- 1 | #include "SensitivityAnalysis.h" 2 | #include "Statistics.h" 3 | using namespace igmdk; 4 | 5 | struct SobolIndexFunctor 6 | { 7 | double operator()(Vector const& x)const 8 | { 9 | double sum = 0; 10 | for(int j = 0; j < x.getSize(); ++j) sum += x[j]; 11 | return sum; 12 | } 13 | }; 14 | void testSobolIndex() 15 | { 16 | int n = 10000, D = 5; 17 | Vector, double> > data(n); 18 | SobolIndexFunctor f; 19 | for(int i = 0; i < n; ++i) 20 | { 21 | Vector x(D); 22 | double y = 0; 23 | for(int j = 0; j < D; ++j) x[j] = GlobalRNG().normal01() * j; 24 | data[i] = make_pair(x, f(x)); 25 | } 26 | pair, Vector>> result = findSobolIndicesSaltelli(data, f); 27 | Vector indices = result.first; 28 | for(int j = 0; j < D; ++j) DEBUG(indices[j]); 29 | for(int j = 0; j < D; ++j) 30 | { 31 | DEBUG(result.second[j].first); 32 | DEBUG(result.second[j].second); 33 | } 34 | 35 | Vector correct(D); 36 | for(int j = 0; j < D; ++j) correct[j] = 1.0 * j * j; 37 | normalizeProbs(correct); 38 | double mse = 0; 39 | for(int j = 0; j < D; ++j) mse += pow(correct[j] - indices[j], 2); 40 | DEBUG(sqrt(mse)); 41 | } 42 | 43 | int main(int argc, char *argv[]) 44 | { 45 | testSobolIndex(); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /RandomNumberGeneration/testSobol.cpp: -------------------------------------------------------------------------------- 1 | #include "Sobol.h" 2 | using namespace igmdk; 3 | 4 | void testSobol() 5 | { 6 | DEBUG(Sobol::maxD()); 7 | Sobol so(2); 8 | //estimate Pi 9 | double n = 0, nTotal = pow(10, 8); 10 | for(int i = 0; i < nTotal; ++i) 11 | { 12 | double x = so.getU01Value(0), y = so.getU01Value(1); 13 | if(x * x + y * y <= 1) ++n; 14 | so.next(); 15 | } 16 | double pi = 4 * n/nTotal; 17 | DEBUG(pi); 18 | double error = 4 * 2 * PI() * log(nTotal) * log(nTotal)/nTotal; 19 | DEBUG(error); 20 | } 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | testSobol(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /RandomTreap/SkipList.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/RandomTreap/SkipList.h -------------------------------------------------------------------------------- /Scrap/ConjugateGradientOptimization.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_CONJUGATE_GRADIENT_OPTIMIZATION_H 2 | #define IGMDK_CONJUGATE_GRADIENT_OPTIMIZATION_H 3 | #include 4 | #include "../Utils/Vector.h" 5 | #include "../Utils/Utils.h" 6 | #include "../NumericalOptimization/LBFGS.h" 7 | namespace igmdk{ 8 | 9 | double steepestStepScale(Vector const& x, double y, 10 | Vector const& grad) 11 | { 12 | return max(1/max(1.0, abs(y)), max(1.0, norm(x)) * 13 | sqrt(numeric_limits::epsilon())/norm(grad)); 14 | } 15 | template 16 | pair, double> conjugateGradient(Vector const& x0, 17 | FUNCTION const& f, GRADIENT const& g, DIRECTIONAL_DERIVATIVE const& dd, 18 | int maxEvals = 1000000, double yPrecision = highPrecEps, 19 | string const& formula = "PRP+", bool useExact = true) 20 | { 21 | pair, double> xy(x0, f(x0)); 22 | Vector grad = g(xy.first), d; 23 | int D = xy.first.getSize(), gEvals = g.fEvals(D), 24 | restartDelta = 100, restartCountdown = 0; 25 | maxEvals -= gEvals; 26 | double a; 27 | while(maxEvals > 0) 28 | { 29 | if(restartCountdown <= 0) 30 | { 31 | restartCountdown = restartDelta; 32 | d = -grad; 33 | a = steepestStepScale(xy.first, xy.second, grad); 34 | } 35 | Vector xOld = xy.first; 36 | if(goldenSectionLineSearch(f, grad, dd, xy.first, xy.second, maxEvals, 37 | d * a, yPrecision, useExact)) 38 | {//failed case 39 | if(restartCountdown == restartDelta) break;//failed after restart 40 | else 41 | {//force restart 42 | restartCountdown = 0; 43 | continue; 44 | } 45 | } 46 | else --restartCountdown; 47 | if((maxEvals -= gEvals) < 1) break; 48 | Vector gradNew = g(xy.first); 49 | double b = 0; 50 | if(formula == "PRP+") b = max(0.0, dotProduct(gradNew, 51 | (gradNew - grad))/dotProduct(grad, grad)); 52 | else if(formula == "HZ") 53 | { 54 | Vector y = gradNew - grad; 55 | double temp = dotProduct(y, d), b = dotProduct(y - d * 56 | (dotProduct(y, y) * 2/temp), gradNew)/temp; 57 | } 58 | else 59 | { 60 | DEBUG("bad formula specification"); 61 | assert(false); 62 | } 63 | double temp = dotProduct(grad, (xy.first - xOld)); 64 | d = -gradNew + d * b; 65 | grad = gradNew; 66 | a = dotProduct(grad, d)/temp; 67 | } 68 | return xy; 69 | } 70 | 71 | }//end namespace igmdk 72 | #endif 73 | -------------------------------------------------------------------------------- /Scrap/DSRS.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_DSRS_H 2 | #define IGMDK_DSRS_H 3 | #include 4 | #include "../Utils/Vector.h" 5 | #include "../NumericalMethods/NumericalCommon.h" 6 | #include "../RandomNumberGeneration/Random.h" 7 | namespace igmdk{ 8 | 9 | template pair, double> 10 | DSRS(Vector const& x0, FUNCTION const& f, 11 | double step = 1, double factor = 0.8, int maxFEvals = 10000000, 12 | double yPrecision = numeric_limits::epsilon()) 13 | { 14 | pair, double> xy(x0, f(x0)); 15 | for(double dd = 0; --maxFEvals && step * (dd + step) > yPrecision;) 16 | { 17 | Vector direction = x0;//ensure non-zero direction 18 | for(int j = 0; j < direction.getSize(); ++j) direction[j] = 19 | GlobalRNG().uniform01() * GlobalRNG().sign(); 20 | direction *= 1/norm(direction); 21 | double yNew = f(xy.first + direction * step); 22 | if(isELess(yNew, xy.second, yPrecision)) 23 | { 24 | dd = (xy.second - yNew)/step; 25 | xy.first += direction * step; 26 | xy.second = yNew; 27 | step *= 2; 28 | } 29 | else step *= factor; 30 | } 31 | return xy; 32 | } 33 | 34 | }//end namespace igmdk 35 | #endif 36 | -------------------------------------------------------------------------------- /Scrap/FriedmanTest.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_FRIEDMAN_TEST_H 2 | #define IGMDK_FRIEDMAN_TEST_H 3 | #include "../RandomNumberGeneration/Statistics.h" 4 | #include "../RandomNumberGeneration/DistributionTests.h" 5 | #include "../Utils/Vector.h" 6 | namespace igmdk{ 7 | 8 | pair > FriedmanPValue(Vector > const& a) 9 | {//a[i] is vector of responses on domain i 10 | assert(a.getSize() > 0 && a[0].getSize() > 1); 11 | int n = a.getSize(), k = a[0].getSize(); 12 | double aveRank = (k + 1)/2.0, SSAlternative = 0, SSTotal = 0; 13 | Vector alternativeRankSums(k); 14 | for(int i = 0; i < n; ++i) 15 | { 16 | assert(a[i].getSize() == k); 17 | Vector ri = convertToRanks(a[i]); 18 | for(int j = 0; j < k; ++j) 19 | { 20 | alternativeRankSums[j] += ri[j]; 21 | SSTotal += (ri[j] - aveRank) * (ri[j] - aveRank); 22 | } 23 | } 24 | for(int j = 0; j < k; ++j) 25 | { 26 | double temp = alternativeRankSums[j] - n * aveRank; 27 | SSAlternative += temp * temp; 28 | } 29 | double p = 30 | 1 - evaluateChiSquaredCdf(SSAlternative * (k - 1)/SSTotal, k - 1); 31 | return make_pair(p, alternativeRankSums); 32 | } 33 | 34 | } 35 | #endif 36 | -------------------------------------------------------------------------------- /Scrap/IncrementalSort.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_INCREMENTAL_SORT_H 2 | #define IGMDK_INCREMENTAL_SORT_H 3 | #include "../Utils/Stack.h" 4 | #include "../Sorting/Sort.h" 5 | namespace igmdk{ 6 | 7 | template ITEM incrementalQuickSelect( 8 | ITEM* vector, int left, Stack& s, COMPARATOR const& c) 9 | { 10 | for(int right, i, j; left < (right = s.getTop()); s.push(j)) 11 | partition3(vector, left, right, i, j, c); 12 | s.pop(); 13 | return vector[left]; 14 | } 15 | template void incrementalSort( 16 | ITEM* vector, int n, COMPARATOR const& c) 17 | { 18 | Stack s; 19 | s.push(n - 1); 20 | for(int i = 0; i < n; ++i) incrementalQuickSelect(vector, i, s, c); 21 | } 22 | 23 | }//end namespace 24 | #endif 25 | -------------------------------------------------------------------------------- /Scrap/IntervalTree.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_INTERVAL_TREE_H 2 | #define IGMDK_INTERVAL_TREE_H 3 | 4 | #include "../Sorting/Sort.h" 5 | #include "../ComputationalGeometry/Point.h" 6 | 7 | namespace igmdk{ 8 | 9 | class IntervalTree 10 | { 11 | Vector& points; 12 | struct Node{int median, point, left, right;}; 13 | int root; 14 | Vector nodes; 15 | int findRemoveMin(Vector& indices) 16 | { 17 | int result = 0; 18 | for(int i = 1; i < indices.getSize(); ++i) 19 | if(points[indices[i]][0] < points[indices[result]][0]) result = i; 20 | int point = indices[result]; 21 | //remove at result and keep order 22 | for(int j = result; j < indices.getSize() - 1; ++j) 23 | indices[j] = indices[j + 1]; 24 | indices.removeLast(); 25 | return point; 26 | } 27 | void construct(int node, Vector& indices) 28 | { 29 | if(indices.getSize() == 1) 30 | { 31 | nodes[node].left = nodes[node].right = -1; 32 | nodes[node].point = indices[0]; 33 | return; 34 | } 35 | nodes[node].point = findRemoveMin(indices); 36 | nodes[node].median = indices[indices.getSize()/2]; 37 | Vector left, right; 38 | for(int i = 0; i < indices.getSize(); ++i) 39 | { 40 | if(i <= indices.getSize()/2) 41 | left.append(indices[i]); 42 | else right.append(indices[i]); 43 | } 44 | nodes[node].left = nodes.getSize(); 45 | nodes.append(Node()); 46 | construct(nodes[node].left, left); 47 | if(right.getSize() > 0) 48 | { 49 | nodes[node].right = nodes.getSize(); 50 | nodes.append(Node()); 51 | construct(nodes[node].right, right); 52 | } 53 | else nodes[node].right = -1; 54 | } 55 | struct DComparator 56 | { 57 | Vector& points; 58 | DComparator(Vector& thePoints): points(thePoints){} 59 | bool operator()(int lhs, int rhs)const 60 | {return points[lhs][1] < points[rhs][1];} 61 | bool isEqual(int lhs, int rhs)const 62 | {return points[lhs][1] == points[rhs][1];} 63 | }; 64 | public: 65 | IntervalTree(Vector& thePoints):points(thePoints), root(0) 66 | { 67 | assert(points.getSize() > 0); 68 | nodes.append(Node()); 69 | Vector indices; 70 | for(int i = 0; i < points.getSize(); ++i) indices.append(i); 71 | quickSort(indices.getArray(), 0, indices.getSize()-1, 72 | DComparator(points)); 73 | construct(root, indices); 74 | } 75 | void containingIntervals(int x, Vector& result, int node = 0) 76 | { 77 | if(points[nodes[node].point][0] <= x) 78 | { 79 | if(points[nodes[node].point][1] >= x) 80 | result.append(nodes[node].point); 81 | if(nodes[node].left != -1) 82 | { 83 | if(x <= points[nodes[node].median][1]) 84 | containingIntervals(x, result, nodes[node].left); 85 | if(nodes[node].right != -1) 86 | containingIntervals(x, result, nodes[node].right); 87 | } 88 | } 89 | } 90 | }; 91 | 92 | } 93 | #endif 94 | -------------------------------------------------------------------------------- /Scrap/L2Boost.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_L2_BOOST_H 2 | #define IGMDK_L2_BOOST_H 3 | #include "../MachineLearning/Regression.h" 4 | #include 5 | 6 | namespace igmdk{ 7 | 8 | template, 9 | typename PARAMS = EMPTY, typename X = NUMERIC_X> class L2Boost 10 | { 11 | Vector classifiers; 12 | Vector weights; 13 | double getWeight(int i)const{return 1/pow(i + 1, 0.501);} 14 | struct L2Loss 15 | { 16 | Vector F; 17 | L2Loss(int n): F(n, 0) {} 18 | double getNegGrad(int i, double y){return 2 * (y - F[i]);} 19 | double loss(int i, double y){return (F[i] - y) * (F[i] - y);} 20 | }; 21 | public: 22 | template L2Boost(DATA const& data, 23 | PARAMS const& p = PARAMS(), int nClassifiers = 300) 24 | { 25 | int n = data.getSize(); 26 | assert(n > 0 && nClassifiers > 0); 27 | L2Loss l(n); 28 | RelabeledData regData(data); 29 | for(int j = 0; j < n; ++j) regData.addLabel(data.getY(j)); 30 | for(int i = 0; i < nClassifiers; ++i) 31 | {//find gradients of relabel data and fit learner 32 | for(int j = 0; j < n; ++j) 33 | regData.labels[j] = l.getNegGrad(j, data.getY(j)); 34 | classifiers.append(LEARNER(regData, p)); 35 | Vector h; 36 | for(int j = 0; j < n; ++j) 37 | h.append(classifiers.lastItem().predict(data.getX(j))); 38 | //calculate weights and update F 39 | double sumH2 = 0, weight = 0; 40 | for(int j = 0; j < n; ++j) 41 | { 42 | sumH2 += h[j] * h[j]; 43 | weight += (data.getY(j) - l.F[j]) * h[j]; 44 | } 45 | if(weight > 0 && isfinite(weight/sumH2)) 46 | { 47 | weights.append(weight/sumH2); 48 | for(int j = 0; j < n; ++j) 49 | l.F[j] += weights.lastItem() * h[j]; 50 | } 51 | else 52 | { 53 | classifiers.removeLast(); 54 | break; 55 | } 56 | } 57 | } 58 | double predict(X const& x)const 59 | { 60 | double sum = 0; 61 | for(int i = 0; i < classifiers.getSize(); ++i) 62 | sum += classifiers[i].predict(x) * weights[i]; 63 | return sum; 64 | } 65 | }; 66 | 67 | }//end namespace 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /Scrap/RMQ.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_RMQ_H 2 | #define IGMDK_RMQ_H 3 | 4 | #include "../Utils/Vector.h" 5 | namespace igmdk{ 6 | 7 | template int LCA(ITEM* array, int i, int j) 8 | {//O(h) performance 9 | int hDiff = 0; 10 | for(int k = i; array[k] != -1; k = array[k]) --hDiff; 11 | for(int k = j; array[k] != -1; k = array[k]) ++hDiff; 12 | if (hDiff < 0) {swap(i, j); hDiff = -hDiff;} 13 | while(hDiff--) j = array[j]; 14 | while(i != j) {i = array[i]; j = array[j];} 15 | return i; 16 | } 17 | 18 | template struct LRMTree 19 | {//previous smaller value tree 20 | Vector parents; 21 | LRMTree(ITEM* array, int size): parents(size, -1) 22 | { 23 | for(int i = 1; i < size; ++i) 24 | {//expand the rightmost branch unless a smaller value causes another 25 | //rightmost branch to be created 26 | parents[i] = i - 1; 27 | while(parents[i] != -1 && array[parents[i]] >= array[i]) 28 | parents[i] = parents[parents[i]]; 29 | } 30 | } 31 | int RMQ(int left, int right) 32 | { 33 | int l = LCA(parents.getArray(), left, right); 34 | if(l == left) return l; 35 | while(parents[right] != l) right = parents[right]; 36 | return right; 37 | } 38 | }; 39 | 40 | } 41 | #endif 42 | -------------------------------------------------------------------------------- /Scrap/SAMME.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SAMME_H 2 | #define IGMDK_SAMME_H 3 | 4 | #include "../MachineLearning/Classification.h" 5 | 6 | namespace igmdk{ 7 | 8 | template, 9 | typename PARAMS = EMPTY, typename X = NUMERIC_X> class AdaBoostSamme 10 | { 11 | Vector classifiers; 12 | Vector weights; 13 | int nClasses; 14 | public: 15 | template AdaBoostSamme(DATA const& data, PARAMS const& 16 | p = PARAMS(), int nClassifiers = 300): nClasses(findNClasses(data)) 17 | { 18 | int n = data.getSize(); 19 | assert(n > 0 && nClassifiers > 0 && nClasses > 0); 20 | Vector dataWeights(n, 1.0/n); 21 | for(int i = 0; i < nClassifiers; ++i) 22 | { 23 | AliasMethod sampler(dataWeights); 24 | PermutedData resample(data); 25 | for(int j = 0; j < n; ++j) resample.addIndex(sampler.next()); 26 | classifiers.append(LEARNER(resample, p)); 27 | double error = 0; 28 | Bitset<> isWrong(n); 29 | for(int j = 0; j < n; ++j) if(classifiers.lastItem().predict( 30 | data.getX(j)) != data.getY(j)) 31 | { 32 | isWrong.set(j); 33 | error += dataWeights[j]; 34 | } 35 | if(error >= 1 - 1.0/nClasses) classifiers.removeLast(); 36 | else if(error == 0) 37 | {//replace ensemble by classifier 38 | Vector temp; 39 | temp.append(classifiers.lastItem()); 40 | classifiers = temp; 41 | weights = Vector(1, 1); 42 | break; 43 | } 44 | else 45 | { 46 | double expWeight = (nClasses - 1) * (1 - error)/error; 47 | weights.append(log(expWeight)); 48 | for(int j = 0; j < n; ++j) 49 | if(isWrong[j]) dataWeights[j] *= expWeight; 50 | normalizeProbs(dataWeights); 51 | } 52 | } 53 | } 54 | int predict(X const& x)const 55 | { 56 | Vector counts(nClasses, 0); 57 | for(int i = 0; i < classifiers.getSize(); ++i) 58 | counts[classifiers[i].predict(x)] += weights[i]; 59 | return argMax(counts.getArray(), counts.getSize()); 60 | } 61 | }; 62 | 63 | }//end namespace 64 | #endif 65 | 66 | -------------------------------------------------------------------------------- /Scrap/SortedLinkedList.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SORTED_LINKED_LIST_H 2 | #define IGMDK_SORTED_LINKED_LIST_H 3 | 4 | #include "../Utils/GCFreeList.h" 5 | #include "../Utils/Utils.h" 6 | namespace igmdk{ 7 | 8 | template > 9 | struct LinkedList 10 | { 11 | struct Node 12 | { 13 | ITEM item; 14 | Node* next; 15 | Node(ITEM const& theItem, Node* theNext) 16 | : item(theItem), next(theNext) {} 17 | }*root; 18 | int size; 19 | Freelist freelist; 20 | COMPARATOR c; 21 | LinkedList(COMPARATOR theC = COMPARATOR()): root(0), size(0), c(theC) {} 22 | void prepend(ITEM const& item) 23 | { 24 | root = new(freelist.allocate())Node(item, root); 25 | ++size; 26 | } 27 | Node* advanceSmaller(Node*& a, Node*& b) 28 | { 29 | Node*& smaller = c(b->item, a->item) ? b : a; 30 | Node* nodeToAppend = smaller; 31 | smaller = smaller->next; 32 | return nodeToAppend; 33 | } 34 | Node* merge(Node* a, Node* b) 35 | {//pick head 36 | Node* head = advanceSmaller(a, b), *tail = head; 37 | //append from smaller until one runs out 38 | while(a && b) tail = tail->next = advanceSmaller(a, b); 39 | //append the rest of the remaining list 40 | tail->next = a ? a : b; 41 | return head; 42 | } 43 | Node* mergesort(Node* list, int n, Node*& nextAfterLast) 44 | { 45 | if(n==1) 46 | { 47 | nextAfterLast = list->next; 48 | list->next = 0; 49 | return list; 50 | } 51 | int middle = n/2; 52 | Node *secondHalf, *m1 = mergesort(list, middle, secondHalf); 53 | return merge(m1, mergesort(secondHalf, n - middle, nextAfterLast)); 54 | } 55 | void sort() 56 | { 57 | if(size > 1) 58 | { 59 | Node* dummy; 60 | root = mergesort(root, size, dummy); 61 | } 62 | } 63 | }; 64 | 65 | }//end namespace 66 | #endif 67 | -------------------------------------------------------------------------------- /Scrap/SymmetricMinMaxHeap.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_SYMMETRIC_MIN_MAX_HEAP_H 2 | #define IGMDK_SYMMETRIC_MIN_MAX_HEAP_H 3 | 4 | #include "../Utils/Vector.h" 5 | 6 | namespace igmdk{ 7 | 8 | template > 9 | class SymmetricMinMaxHeap 10 | { 11 | Vector items; 12 | COMPARATOR c; 13 | int getParent(int i){return i/2 - 1;} 14 | int getLeftChild(int i){return 2*i+2;} 15 | int getRightChild(int i){return 2*i+3;} 16 | int getLeftSibling(int i){return getLeftChild(getParent(i));} 17 | void moveUp(int i) 18 | { 19 | for(;;) 20 | { 21 | int next = getParent(getParent(i)), ppl, ppr, 22 | pl = getLeftSibling(i); 23 | if(c(items[i], items[pl])) next = pl;//p1 24 | else if(c(items[i], items[ppl = getLeftChild(next)])) 25 | next = ppl;//p2 26 | else if(c(items[ppr = getRightChild(next)], items[i])) 27 | next = ppr;//p3 28 | else return; 29 | swap(items[next], items[i]); 30 | i = next; 31 | } 32 | } 33 | void moveDownMin(int i) 34 | { 35 | for(;;) 36 | { 37 | int next = getParent(i), l = getLeftChild(i), 38 | pr = getRightChild(next); 39 | if(l < items.getSize()) 40 | { 41 | int prl = getLeftChild(pr); 42 | next = prl < items.getSize() && c(items[prl], items[l]) ? 43 | prl : l; 44 | if(c(items[i], items[next])) return; 45 | } 46 | else if(pr < items.getSize() && c(items[pr], items[i])) next = pr; 47 | else return; 48 | swap(items[next], items[i]); 49 | i = next; 50 | } 51 | } 52 | void moveDownMax(int i) 53 | { 54 | for(;;) 55 | { 56 | int next, pl = getLeftChild(getParent(i)), plr = getRightChild(pl); 57 | if(plr < items.getSize()) 58 | { 59 | int r = getRightChild(i), 60 | child = r < items.getSize() ? r : getLeftChild(i); 61 | next = child < items.getSize() && c(items[plr], items[child]) ? 62 | child : plr; 63 | if(c(items[next], items[i])) return; 64 | } 65 | else if(c(items[i], items[pl])) next = pl; 66 | else return; 67 | swap(items[next], items[i]); 68 | i = next; 69 | } 70 | } 71 | public: 72 | bool isEmpty(){return items.getSize() <= 0;} 73 | ITEM const& getMin(){assert(!isEmpty());return items[0];} 74 | ITEM const& getMax(){assert(!isEmpty());return items[items.getSize()!= 1];} 75 | void insert(ITEM const& item) 76 | { 77 | items.append(item); 78 | if(items.getSize() > 1) moveUp(items.getSize()-1); 79 | } 80 | void deleteMin() 81 | { 82 | assert(!isEmpty()); 83 | items[0] = items.lastItem(); 84 | moveDownMin(0); 85 | items.removeLast(); 86 | } 87 | void deleteMax() 88 | { 89 | assert(!isEmpty()); 90 | int index = items.getSize() != 1; 91 | items[index] = items[items.getSize()-1]; 92 | moveDownMax(index); 93 | items.remove(items.getSize()-1); 94 | } 95 | }; 96 | 97 | } 98 | #endif 99 | -------------------------------------------------------------------------------- /Scrap/TestEMHashing.cpp: -------------------------------------------------------------------------------- 1 | #include "EMLinearHashing.h" 2 | #include "../Utils/Debug.h" 3 | #include 4 | using namespace std; 5 | 6 | using namespace igmdk; 7 | 8 | template 9 | struct EMGraph 10 | { 11 | struct Vertex 12 | { 13 | long long upto; 14 | VERTEX_DATA data; 15 | }; 16 | EMVector vertices; 17 | struct Edge 18 | { 19 | long long to; 20 | EDGE_DATA data; 21 | }; 22 | EMVector edges; 23 | void addVertex(VERTEX_DATA const& data) 24 | { 25 | Vertex entry = vertices.lastItem(); 26 | entry.data = data; 27 | vertices.append(entry); 28 | } 29 | void addEdgeToLastVertex(long long to, EDGE_DATA data) 30 | { 31 | Edge entry = {to, data}; 32 | edges.append(entry); 33 | Vertex lastVertex = vertices.lastItem(); 34 | ++lastVertex.upto; 35 | vertices[vertices.getLast()] = lastVertex; 36 | } 37 | long long edgeStart(long long v) 38 | { 39 | assert(v >= 0 && v < vertices.getSize()); 40 | return v ? vertices[v-1].upto : 0; 41 | } 42 | }; 43 | 44 | int main() 45 | { 46 | EMLinearHashTable trie; 47 | //EMLinearProbingHashTable trie; 48 | int N = 150000; 49 | for(int i = 0; i < N; ++i) 50 | { 51 | trie.insert(i, i); 52 | } 53 | DEBUG("Done inserting"); 54 | for(int j = 0; j < 1; ++j) 55 | { 56 | for(int i = 0; i < N; ++i) 57 | { 58 | bool status; 59 | int item = trie.find(i, status); 60 | assert(status); 61 | //trie.remove(i); 62 | //if(status) DEBUG(item); 63 | } 64 | } 65 | /*DEBUG((EMLinearHashTable::N)); 66 | DEBUG(trie.ioFindCount); 67 | DEBUG(trie.listCount); 68 | DEBUG(trie.maxLength); 69 | DEBUG(trie.bitSize); 70 | DEBUG(trie.table.getSize());*/ 71 | /*for(int i = 0; i < 30; ++i) 72 | { 73 | DEBUG(i); 74 | DEBUG(trie.counts[i]); 75 | }*/ 76 | 77 | 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /Scrap/WilcoxonSignedRankTest.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_WILCOXON_SIGNED_RANK_TEST_H 2 | #define IGMDK_WILCOXON_SIGNED_RANK_TEST_H 3 | #include "../Sorting/Sort.h" 4 | namespace igmdk{ 5 | 6 | struct SignedRankComparator 7 | { 8 | typedef pair P; 9 | int sign(P const& p)const{return p.first - p.second > 0 ? 1 : -1;} 10 | double diff(P const& p)const{return abs(p.first - p.second);} 11 | bool operator()(P const& lhs, P const& rhs)const 12 | {return diff(lhs) < diff(rhs);} 13 | bool isEqual(P const& lhs, P const& rhs)const 14 | {return diff(lhs) == diff(rhs);} 15 | }; 16 | double signedRankZ(Vector > a) 17 | {//same test, use Conover version! 18 | SignedRankComparator c; 19 | quickSort(a.getArray(), 0, a.getSize() - 1, c); 20 | int nP = a.getSize(), i = 0; 21 | //if odd number of 0's, drop first, distribute rest evenly 22 | while(i < a.getSize() && c.diff(a[i]) == 0) ++i; 23 | if(i % 2) --nP; 24 | double signedRankSum = 0, rank2Sum = 0; 25 | for(i = i % 2; i < a.getSize(); ++i) 26 | {//rank lookahead to scan for ties, then sum computation 27 | int j = i; 28 | while(i + 1 < a.getSize() && c.isEqual(a[i], a[i + 1])) ++i; 29 | double rank = (i + j)/2.0 + 1 + nP - a.getSize(); 30 | while(j <= i) 31 | { 32 | signedRankSum += c.sign(a[j++]) * rank; 33 | rank2Sum += rank * rank; 34 | } 35 | } 36 | return rank2Sum == 0 ? 0 : abs(signedRankSum)/sqrt(rank2Sum); 37 | } 38 | 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /Scrap/testArithmeticCoding.cpp: -------------------------------------------------------------------------------- 1 | #include "ArithmeticCoding.h" 2 | #include 3 | #include 4 | using namespace igmdk; 5 | 6 | struct ugly 7 | { 8 | unsigned char a:4; 9 | unsigned char b:4; 10 | unsigned char c; 11 | }; 12 | 13 | Vector compress(Vector const& byteArray) 14 | { 15 | return Arithmetic::AdaptiveCompress(byteArray); 16 | } 17 | 18 | Vector uncompress(Vector const& byteArray) 19 | { 20 | return Arithmetic::AdaptiveUncompress(byteArray); 21 | } 22 | 23 | void timeRT() 24 | { 25 | char text[] = "hello arithmetic coding"; 26 | Vector uncompressed0; 27 | for(int i = 0; i < sizeof(text)-1; ++i) uncompressed0.append(text[i]); 28 | Vector uncompressed(uncompressed0); 29 | 30 | cout << "uncompressed.size" << uncompressed.getSize() << endl; 31 | Vector compressed(compress(uncompressed)); 32 | cout << "compressed.size" << compressed.getSize() << endl; 33 | Vector uncompressed2(uncompress(compressed)); 34 | cout << "uncompressed2.size" << uncompressed2.getSize() << endl; 35 | assert(uncompressed.getSize() == uncompressed2.getSize()); 36 | for(int i = 0; i < uncompressed2.getSize(); ++i) assert(uncompressed2[i] == uncompressed[i]); 37 | } 38 | 39 | int main() 40 | { 41 | clock_t start = clock(); 42 | //for(;;) 43 | for(int i =0; i < 1; ++i) 44 | { 45 | timeRT(); 46 | } 47 | 48 | int tFL = (clock() - start); 49 | cout << "FL: "< 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "../RandomNumberGeneration/Statistics.h" 11 | #include "../ExternalMemoryAlgorithms/File.h" 12 | using namespace igmdk; 13 | 14 | template int testNumericalClassifier() 15 | { 16 | DEBUG("Started Reading"); 17 | typedef InMemoryData T; 18 | Vector dataM(50);//make many enough to avoid ref realloc 19 | Vector, PermutedData > > data; 20 | 21 | dataM.append(T()); 22 | readIrisData(dataM.lastItem()); 23 | data.append(makeData(dataM)); 24 | for(int i = 0; i < data.getSize(); ++i) 25 | { 26 | if(false)//cost 27 | { 28 | /*int start = clock(); 29 | int k = findNClasses(data[i].first); 30 | Matrix c = sampleCostDeterministic(k); 31 | for(int z = 0; z < k; ++z) 32 | { 33 | for(int j = 0; j < k; ++j) 34 | cout << c(z, j) << " "; 35 | cout << endl; 36 | } 37 | //LEARNER s(T(data[i].first).data); 38 | LEARNER s(T(data[i].first).data, c); 39 | Matrix confusion = evaluateConfusion(evaluateLearner(s, T(data[i].second).data)); 40 | for(int z = 0; z < k; ++z) 41 | { 42 | for(int j = 0; j < k; ++j) 43 | cout << confusion(z, j) << " "; 44 | cout << endl; 45 | } 46 | ClassifierStats cs(confusion); 47 | double timediff = 1.0 * (clock() - start)/CLOCKS_PER_SEC; 48 | double cost = evalConfusionCost(confusion, c); 49 | DEBUG(cost); 50 | cs.debug(); 51 | addToCSV(Vector(1, toStringDouble(cost)), fCost.c_str()); 52 | addToCSV(Vector(1, toStringDouble(timediff)), fTimer.c_str());*/ 53 | } 54 | else 55 | { 56 | int start = clock(); 57 | LEARNER NeuralNetworkIris(data[i].first); 58 | ClassifierStats cs(evaluateConfusion(evaluateLearner(NeuralNetworkIris, data[i].second))); 59 | double timediff = 1.0 * (clock() - start)/CLOCKS_PER_SEC; 60 | cs.debug(); 61 | } 62 | //system("PAUSE"); 63 | } 64 | return 0; 65 | } 66 | 67 | int main(int argc, char *argv[]) 68 | { 69 | testNumericalClassifier >(); 70 | testNumericalClassifier >(); 71 | testNumericalClassifier(); 72 | return 0; 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /Scrap/testClustering.cpp: -------------------------------------------------------------------------------- 1 | #include "../MachineLearning/Classification.h" 2 | #include "ScrapClustering.h" 3 | #include "../MachineLearning/ReadClassificationData.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "../RandomNumberGeneration/Statistics.h" 10 | #include "../ExternalMemoryAlgorithms/File.h" 11 | using namespace igmdk; 12 | 13 | 14 | 15 | template int testNumericalClusterer() 16 | { 17 | DEBUG("Started Reading"); 18 | typedef InMemoryData T; 19 | Vector dataM(50);//make many enough to avoid ref realloc 20 | Vector, PermutedData > > data; 21 | 22 | dataM.append(T()); 23 | readIrisData(dataM.lastItem());//iris data duplicated here from ML directory to use same code 24 | data.append(makeData(dataM)); 25 | 26 | DEBUG("Done Reading"); 27 | for(int i = 0; i < data.getSize(); ++i) 28 | { 29 | int start = clock(); 30 | CLUSTERER c; 31 | //Vector result = c(data[i].first, findNClasses(data[i].first)); 32 | //ScalerMinMax s(data[i].first); 33 | //ScalerMQ s(data[i].first); 34 | //ScaledData, ScalerMQ> sd(data[i].first, s); 35 | ScalerMinMax s(data[i].first); 36 | ScaledData, ScalerMinMax> sd(data[i].first, s); 37 | //Vector result = c(sd).assignments; 38 | Vector result = c(sd, findNClasses(sd)).assignments; 39 | 40 | Matrix counts = clusterContingencyMatrix(result, sd); 41 | double purity = clusterPurity(counts); 42 | double aRand = AdjustedRandIndex(counts); 43 | double relkDiff = (counts.rows - counts.columns)*1.0/counts.columns; 44 | double cAcc = clusterClassificationAccuracy(counts); 45 | 46 | DEBUG(purity); 47 | DEBUG(aRand); 48 | DEBUG(relkDiff); 49 | DEBUG(cAcc); 50 | 51 | double timediff = 1.0 * (clock() - start)/CLOCKS_PER_SEC; 52 | DEBUG(timediff); 53 | } 54 | return 0; 55 | } 56 | 57 | int main(int argc, char *argv[]) 58 | { 59 | testNumericalClusterer(); 60 | testNumericalClusterer >(); 61 | //testNumericalClusterer::Functor>(); 62 | return 0; 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /Scrap/testCuckoo.cpp: -------------------------------------------------------------------------------- 1 | #include "CuckooHashTable.h" 2 | #include "../RandomNumberGeneration/Statistics.h" 3 | using namespace igmdk; 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Xorshift64HashSeeded 9 | { 10 | unsigned long long seed; 11 | public: 12 | Xorshift64HashSeeded():seed(GlobalRNG().next()){} 13 | unsigned int hash(unsigned long long x) 14 | {return QualityXorshift64::transform(seed+x);} 15 | template unsigned int hash(NUMBER* array, int size) 16 | { 17 | unsigned long long sum = seed; 18 | for(int i = 0; i < size; ++i) sum = 19 | QualityXorshift64::transform(sum + array[i]); 20 | return sum; 21 | } 22 | }; 23 | 24 | struct Fat2 25 | { 26 | enum{SIZE = 10}; 27 | int array[SIZE]; 28 | Fat2(int last) 29 | { 30 | for(int i = 1; i < SIZE; ++i) 31 | { 32 | array[i] = i; 33 | } 34 | array[0] = last; 35 | } 36 | bool operator==(Fat2 const& rhs)const 37 | { 38 | for(int i = 0; i < SIZE; ++i) 39 | { 40 | if(array[i] != rhs.array[i]) return false; 41 | } 42 | return true; 43 | } 44 | bool operator<(Fat2 const& rhs)const 45 | { 46 | for(int i = 0; i < SIZE; ++i) 47 | { 48 | if(array[i] < rhs.array[i]) return true; 49 | if(array[i] > rhs.array[i]) return false; 50 | } 51 | return false; 52 | } 53 | int getSize()const{return SIZE;} 54 | int const operator[](int i)const{return array[i];} 55 | }; 56 | 57 | struct Action 58 | { 59 | void operator()(int const& key, int const& item) 60 | { 61 | cout << key << endl; 62 | } 63 | }; 64 | 65 | void timeRT() 66 | { 67 | CuckooHashTable t; 68 | int N = 1500000; 69 | for(int i = 0; i < N; ++i) 70 | { 71 | t.insert(i,i); 72 | } 73 | /*CuckooHashTable::Iterator iter(t); 74 | while(iter.hasNext()) 75 | { 76 | cout << iter.next()->key << endl; 77 | } 78 | 79 | Action action; 80 | t.forEach(action);*/ 81 | for(int j = 0; j < 1; ++j) 82 | { 83 | for(int i = 0; i < N; ++i) 84 | { 85 | assert(t.find(i)); 86 | //cout << *t.find(i) << endl; 87 | assert(*t.find(i) == i); 88 | t.remove(i); 89 | } 90 | } 91 | DEBUG("done"); 92 | /*for(int i = 0; i < 1500000; ++i) 93 | { 94 | t.remove(i); 95 | }*/ 96 | } 97 | 98 | int main() 99 | { 100 | timeRT(); 101 | return 0; 102 | } 103 | -------------------------------------------------------------------------------- /Scrap/testFriedmanTest.cpp: -------------------------------------------------------------------------------- 1 | #include "FriedmanTest.h" 2 | #include "../Utils/Debug.h" 3 | using namespace igmdk; 4 | 5 | void testFriedman() 6 | { 7 | Vector > responses; 8 | Vector r1; 9 | r1.append(14); 10 | r1.append(23); 11 | r1.append(26); 12 | r1.append(30); 13 | responses.append(r1); 14 | Vector r2; 15 | r2.append(19); 16 | r2.append(25); 17 | r2.append(25); 18 | r2.append(33); 19 | responses.append(r2); 20 | Vector r3; 21 | r3.append(17); 22 | r3.append(22); 23 | r3.append(29); 24 | r3.append(28); 25 | responses.append(r3); 26 | Vector r4; 27 | r4.append(17); 28 | r4.append(21); 29 | r4.append(28); 30 | r4.append(27); 31 | responses.append(r4); 32 | Vector r5; 33 | r5.append(16); 34 | r5.append(24); 35 | r5.append(28); 36 | r5.append(32); 37 | responses.append(r5); 38 | Vector r6; 39 | r6.append(15); 40 | r6.append(23); 41 | r6.append(27); 42 | r6.append(36); 43 | responses.append(r6); 44 | Vector r7; 45 | r7.append(18); 46 | r7.append(26); 47 | r7.append(27); 48 | r7.append(26); 49 | responses.append(r7); 50 | Vector r8; 51 | r8.append(16); 52 | r8.append(22); 53 | r8.append(30); 54 | r8.append(32); 55 | responses.append(r8); 56 | pair > result = FriedmanPValue(responses); 57 | DEBUG(result.first); 58 | } 59 | 60 | int main(int argc, char *argv[]) 61 | { 62 | testFriedman(); 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /Scrap/testHeap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "PairingHeap.h" 8 | #include "ScrapHeap.h" 9 | #include "SymmetricMinMaxHeap.h" 10 | using namespace igmdk; 11 | 12 | void timeSRT() 13 | { 14 | IndexedPaHeap heap; 15 | //IndexedPointerHeap heap; 16 | //BucketQueue heap(9); 17 | //SymmetricMinMaxHeap heap; 18 | //PairingHeap heap; 19 | int N = 15000000; 20 | //PairingHeap::PairingHandle a[500000]; 21 | for(int i = 0; i < N; ++i) 22 | { 23 | heap.insert(rand()%10, i); 24 | //heap.insert(i); 25 | //a[i] = rand(); 26 | //heap.insert(a[i]); 27 | } 28 | //system("PAUSE"); 29 | for(int i = 0; i < N; ++i) 30 | { 31 | //heap.decreaseKey(p[i], a[i]->element - i); 32 | //heap.changeKey(i, a[i] - i); 33 | } 34 | for(int i = 0; i < N; ++i) 35 | { 36 | //cout <<"&&&"<< heap.getMax() << endl; 37 | //heap.deleteMax(); 38 | //if(heap.isEmpty())break; 39 | //cout <<"&&&"<< heap.getMin() << endl; 40 | heap.deleteMin(); 41 | //heap.map.remove(i); 42 | } 43 | //cout << "next" << endl; 44 | /*for(int i = 0; i < 10; ++i) 45 | { 46 | heap.insert(rand()); 47 | } 48 | for(int i = 0; i < 10; ++i) 49 | { 50 | cout << heap.getMin() << endl; 51 | heap.deleteMin(); 52 | }*/ 53 | /*int a[10]; 54 | for(int i = 0; i < 10; ++i) 55 | { 56 | a[i] = rand(); 57 | } 58 | Heap heap(a,10,10); 59 | for(int i = 0; i < 10; ++i) 60 | { 61 | cout << a[i] << endl; 62 | } 63 | for(int i = 0; i < 10; ++i) 64 | { 65 | heap.changeKey(i, rand()); 66 | } 67 | //heap.changeKey(5, -10); 68 | for(int i = 0; i < 10; ++i) 69 | { 70 | //cout << a[i] << endl; 71 | } 72 | //heap.changeKey(5, 100000000); 73 | for(int i = 0; i < 10; ++i) 74 | { 75 | cout << a[i] << endl; 76 | } 77 | for(int i = 0; i < 10; ++i) 78 | { 79 | cout << heap.getMin() << endl; 80 | heap.deleteMin(); 81 | }*/ 82 | } 83 | 84 | int main() 85 | { 86 | clock_t start = clock(); 87 | timeSRT(); 88 | int tFL = (clock() - start); 89 | cout << "FL: "< 3 | #include 4 | using namespace igmdk; 5 | 6 | void testIncremental() 7 | { 8 | int simple[] = {5, 1, 3 ,0,4,2}; 9 | incrementalSort(simple, 6, DefaultComparator()); 10 | for(int i = 0; i < 6; ++i) 11 | { 12 | DEBUG(simple[i]); 13 | } 14 | } 15 | 16 | int main() 17 | { 18 | testIncremental(); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Scrap/testIntervalTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "IntervalTree.h" 4 | using namespace igmdk; 5 | 6 | void testIntervalTree() 7 | { 8 | int N = 15000; 9 | Vector points; 10 | for(int i = 0; i < N; ++i) 11 | { 12 | double p1 = (GlobalRNG().next() % 1000), p2 = i; 13 | points.append(Point2(min(p1, p2), max(p1, p2))); 14 | //DEBUG(min(p1, p2)); 15 | //DEBUG(max(p1, p2)); 16 | } 17 | DEBUG(clock()); 18 | 19 | 20 | 21 | IntervalTree it(points); 22 | for(int k = 0; k < 10000; ++k) 23 | { 24 | Vector result; 25 | int point = (GlobalRNG().next() % 1000);//GlobalRNG.next() % 10; 26 | //DEBUG(point); 27 | it.containingIntervals(point, result); 28 | for(int i = 0; i < result.getSize(); ++i) 29 | { 30 | //DEBUG(result[i].key.x[0]); 31 | //DEBUG(result[i].key.x[1]); 32 | //DEBUG(result[i]); 33 | } 34 | //DEBUG(result.getSize()); 35 | } 36 | DEBUG(clock()); 37 | } 38 | 39 | int main() 40 | { 41 | testIntervalTree(); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Scrap/testL2Boost.cpp: -------------------------------------------------------------------------------- 1 | #include "L2Boost.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../RandomNumberGeneration/Statistics.h" 8 | #include "../ExternalMemoryAlgorithms/File.h" 9 | using namespace igmdk; 10 | 11 | template void readEnergyHeatData(DATA& result) 12 | { 13 | //the data format is 5 space-separated values per line 14 | //the last value is y 15 | ifstream fin("../MachineLearning/RegDatasets/ENB2012_dataConverted.data"); 16 | while(!fin.eof()) 17 | { 18 | string line; 19 | getline(fin, line, '\n'); 20 | stringstream data; 21 | data << line; 22 | NUMERIC_X x; 23 | for(int i = 0; i < 8; i++) 24 | { 25 | double currentDigit; 26 | data >> currentDigit; 27 | x.append( currentDigit ); 28 | } 29 | double label; 30 | data >> label; 31 | result.addZ(x, label); 32 | } 33 | } 34 | 35 | template int testRegressor() 36 | { 37 | DEBUG("Started Reading"); 38 | typedef InMemoryData T; 39 | Vector data; 40 | data.append(T()); 41 | readEnergyHeatData(data.lastItem()); 42 | DEBUG("Done Reading"); 43 | for(int i = 0; i < data.getSize(); ++i) 44 | { 45 | pair, PermutedData > tt(createTrainingTestSetsDetPerm(data[i])); 46 | int start = clock(); 47 | LEARNER NeuralNet(tt.first); 48 | RegressionStats cs = evaluateRegressor(evaluateLearner(NeuralNet, tt.second)); 49 | double timediff = 1.0 * (clock() - start)/CLOCKS_PER_SEC; 50 | cs.debug(); 51 | } 52 | return 0; 53 | } 54 | 55 | void testRegressors() 56 | { 57 | DEBUG("L2Boost"); 58 | testRegressor >(); 59 | } 60 | 61 | int main(int argc, char *argv[]) 62 | { 63 | for(int i = 0; i < 1; ++i) testRegressors(); 64 | return 0; 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /Scrap/testLSH.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "LSH.h" 4 | #include "../ComputationalGeometry/Point.h" 5 | #include "../RandomNumberGeneration/Random.h" 6 | #include "../NumericalMethods/NumericalMethods.h" 7 | using namespace igmdk; 8 | 9 | void testLSH() 10 | { 11 | //DEBUG(1/exp(1)); 12 | //DEBUG(E2LSHHasher::p(1, 1)); 13 | int D = 2; 14 | LSH tree = buildE2LSH(D, 1, 1, D * 5); 15 | int N = 1000000; 16 | for(int i = 0; i < N; ++i) 17 | { 18 | tree.insert(Vector(2, i)); 19 | } 20 | for(int i = 0; i < 1; ++i) 21 | { 22 | Vector > neighbors = tree.cNeighbors(Vector(2, i)); 23 | DEBUG(neighbors.getSize()); 24 | for(int j = 0; j < neighbors.getSize(); ++j) 25 | { 26 | DEBUG(j); 27 | for(int k = 0; k < neighbors[j].getSize(); ++k) DEBUG(neighbors[j][k]); 28 | } 29 | } 30 | } 31 | 32 | void testLSH2() 33 | { 34 | //DEBUG(1/exp(1)); 35 | //DEBUG(E2LSHHasher::p(1, 1)); 36 | int D = 2; 37 | NearestNeighborLSH tree = buildE2NNLSH(D, 1, 10, D * 5); 38 | int N = 100000; 39 | for(int i = 0; i < N; ++i) 40 | { 41 | tree.insert(Vector(2, i)); 42 | } 43 | int noneCount = 0; 44 | for(int i = 0; i < N; ++i) 45 | { 46 | pair, bool> neighbor = tree.cNeighbor(Vector(2, i)); 47 | //DEBUG(neighbor.second); 48 | if(neighbor.second) 49 | { 50 | //for(int k = 0; k < neighbor.first.getSize(); ++k) DEBUG(neighbor.first[k]); 51 | } 52 | else ++noneCount; 53 | } 54 | DEBUG(noneCount); 55 | } 56 | 57 | void testLSH3() 58 | { 59 | //DEBUG(1/exp(1)); 60 | //DEBUG(E2LSHHasher::p(1, 1)); 61 | int D = 100; 62 | NearestNeighborLSH tree = buildE2NNLSH(D, 1, 10, D * 0.5); 63 | int N = 100000; 64 | for(int i = 0; i < N; ++i) 65 | { 66 | Vector x; 67 | for(int j = 0; j < D; ++j) x.append(i); 68 | tree.insert(x); 69 | } 70 | int noneCount = 0; 71 | for(int i = 0; i < N; ++i) 72 | { 73 | Vector x; 74 | for(int j = 0; j < D; ++j) x.append(i); 75 | pair, bool> neighbor = tree.cNeighbor(x); 76 | //DEBUG(neighbor.second); 77 | if(neighbor.second) 78 | { 79 | //for(int k = 0; k < neighbor.first.getSize(); ++k) DEBUG(neighbor.first[k]); 80 | } 81 | else ++noneCount; 82 | }//20 secs 83 | DEBUG(noneCount); 84 | } 85 | 86 | int main() 87 | { 88 | testLSH(); 89 | testLSH2(); 90 | testLSH3(); 91 | return 0; 92 | } 93 | -------------------------------------------------------------------------------- /Scrap/testLinkedListSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "SortedLinkedList.h" 8 | using namespace std; 9 | using namespace igmdk; 10 | 11 | void timeSRT() 12 | { 13 | typedef pair Item; 14 | LinkedList ll; 15 | for(int i = 100; i>=0; --i) 16 | { 17 | ll.prepend(Item(i, i)); 18 | } 19 | ll.sort(); 20 | for(LinkedList::Node* iter = ll.root;iter; iter = iter->next) 21 | cout << "key" <item.first<< endl; 22 | } 23 | 24 | int main() 25 | { 26 | clock_t start = clock(); 27 | 28 | 29 | timeSRT(); 30 | int tFL = (clock() - start); 31 | cout << "FL: "< 2 | #include 3 | #include "../Utils/Debug.h" 4 | #include "RMQ.h" 5 | using namespace std; 6 | using namespace igmdk; 7 | 8 | void testLRMTree() 9 | { 10 | int array[] = {15,8,13,7,11,16,1,10,9,14,2,12,3,6,5,4}, 11 | size = sizeof(array)/sizeof(*array); 12 | LRMTree lrm(array, size); 13 | for(int i = 0; i < size; ++i) DEBUG(lrm.parents[i]); 14 | DEBUG(lrm.RMQ(4,8)); 15 | DEBUG(lrm.RMQ(0,5)); 16 | DEBUG(lrm.RMQ(0,size-1)); 17 | DEBUG(lrm.RMQ(11,size-1)); 18 | } 19 | 20 | int main() 21 | { 22 | testLRMTree(); 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /Scrap/testTrie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "ScrapTrie.h" 6 | #include "LeftLeaningRedBlackTree.h" 7 | #include "../RandomNumberGeneration/Random.h" 8 | using namespace std; 9 | using namespace igmdk; 10 | 11 | void timeRT() 12 | { 13 | LeftLeaningRedBlackTree trie; 14 | //PatriciaTrie trie; 15 | int N = 1500000; 16 | for(int i = 0; i < N; ++i) 17 | { 18 | //DEBUG("BEGIN"); 19 | //DEBUG(i); 20 | trie.insert(i, i); 21 | //DEBUG("END"); 22 | } 23 | //system("PAUSE"); 24 | for(int j = 0; j < 1; ++j) 25 | { 26 | for(int i = 0; i < N; ++i) 27 | { 28 | assert(trie.find(i)); 29 | //DEBUG(*trie.find(i)); 30 | //cout << *trie.find(i) << endl; 31 | assert(*trie.find(i) == i); 32 | trie.remove(i); 33 | /*for(int k = 0; k <=i; ++k) 34 | { 35 | assert(!trie.find(k)); 36 | } 37 | for(int k = i+1; k < 1500; ++k) 38 | { 39 | assert(trie.find(k)); 40 | }*/ 41 | } 42 | } 43 | } 44 | 45 | void timeRT2() 46 | { 47 | enum{N = 10000}; 48 | int data[N]; 49 | for(int i = 0; i < N; ++i) data[i] = GlobalRNG().next(); 50 | LeftLeaningRedBlackTree trie; 51 | //PatriciaTrie trie; 52 | for(int i = 0; i < N; ++i) 53 | { 54 | trie.insert(data[i], i); 55 | 56 | } 57 | for(int j = 0; j < 10000; ++j) 58 | { 59 | for(int i = 0; i < N; ++i) 60 | { 61 | assert(trie.find(data[i])); 62 | //cout << *trie.find(i) << endl; 63 | assert(*trie.find(data[i]) == i); 64 | //trie.remove(i); 65 | /*for(int k = 0; k <=i; ++k) 66 | { 67 | assert(!trie.find(k)); 68 | } 69 | for(int k = i+1; k < 1500; ++k) 70 | { 71 | assert(trie.find(k)); 72 | }*/ 73 | } 74 | } 75 | } 76 | 77 | int main() 78 | { 79 | clock_t start = clock(); 80 | 81 | timeRT(); 82 | int tFL = (clock() - start); 83 | cout << "FL: "< > a; 9 | a.append(pair(51.2, 45.8)); 10 | a.append(pair(46.5, 41.3)); 11 | a.append(pair(24.1, 15.8)); 12 | a.append(pair(10.2, 11.1)); 13 | a.append(pair(65.3, 58.5)); 14 | a.append(pair(92.1, 70.3)); 15 | a.append(pair(30.3, 31.6)); 16 | a.append(pair(49.2, 35.4)); 17 | double z = signedRankZ(a); 18 | DEBUG(z); 19 | DEBUG(1 - approxNormal2SidedConf(z)); 20 | } 21 | 22 | void testWilcoxon2() 23 | { 24 | Vector > a; 25 | a.append(pair(125, 110)); 26 | a.append(pair(115, 122)); 27 | a.append(pair(130, 125)); 28 | a.append(pair(140, 120)); 29 | a.append(pair(140, 140)); 30 | a.append(pair(115, 124)); 31 | a.append(pair(140, 123)); 32 | a.append(pair(125, 137)); 33 | a.append(pair(140, 135)); 34 | a.append(pair(135, 145)); 35 | DEBUG(signedRankZ(a)); 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | testWilcoxon(); 41 | return 0; 42 | testWilcoxon2(); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Slides/IntroMachineLearning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/Slides/IntroMachineLearning.pdf -------------------------------------------------------------------------------- /Slides/MonteCarloAlgorithms.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/Slides/MonteCarloAlgorithms.pdf -------------------------------------------------------------------------------- /Sorting/testSort.cpp: -------------------------------------------------------------------------------- 1 | #include "Sort.h" 2 | #include "SortTestAuto.h" 3 | #include "../Utils/Vector.h" 4 | #include 5 | #include 6 | using namespace igmdk; 7 | 8 | int main() 9 | { 10 | testAllAutoSort(); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /StringAlgorithms/test.cpp: -------------------------------------------------------------------------------- 1 | #include "StringAlgorithmsTestAuto.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | using namespace igmdk; 9 | 10 | void DDDLCS() 11 | { 12 | Vector x, y; 13 | x.append('s'); 14 | x.append('i'); 15 | x.append('n'); 16 | x.append('k'); 17 | 18 | y.append('t'); 19 | y.append('h'); 20 | y.append('i'); 21 | y.append('n'); 22 | y.append('k'); 23 | typedef Diff D; 24 | Vector SinkIntoThink = D::diff(x, y); 25 | 26 | cout << "breakpoint" << endl; 27 | 28 | } 29 | 30 | void DDDSuffixIndex() 31 | { 32 | string test = "mississippi"; 33 | Vector temp; 34 | for(int i = 0; i < test.length(); ++i) temp.append(test[i]); 35 | SuffixIndex Mississippi(temp); 36 | cout << "breakpoint" << endl; 37 | } 38 | 39 | int main() 40 | { 41 | testAllAutoStringAlgorithms(); 42 | 43 | DDDLCS(); 44 | DDDSuffixIndex(); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Utils/Debug.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_DEBUG_H 2 | #define IGMDK_DEBUG_H 3 | #include 4 | #include 5 | using namespace std; 6 | namespace igmdk{ 7 | //print the expression, a space, and a new line 8 | #define DEBUG(var) cout << #var " "<< setprecision(17) << (var) << endl; 9 | 10 | }//end namespace 11 | #endif 12 | -------------------------------------------------------------------------------- /Utils/GCFreeList.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dkedyk/ImplementingUsefulAlgorithms/0acf5d17e2d946fe3cff3b4569cbfce61f85b924/Utils/GCFreeList.h -------------------------------------------------------------------------------- /Utils/Queue.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_QUEUE_H 2 | #define IGMDK_QUEUE_H 3 | #include "Utils.h" 4 | namespace igmdk{ 5 | 6 | template class Queue 7 | { 8 | enum{MIN_CAPACITY = 8};//same as for vector 9 | int capacity, front, size; 10 | ITEM* items;//must be declared after capacity 11 | int offset(int i)const{return (front + i) % capacity;} 12 | void resize() 13 | { 14 | ITEM* oldArray = items; 15 | int newCapacity = max(int(MIN_CAPACITY), size * 2); 16 | items = rawMemory(newCapacity); 17 | for(int i = 0; i < size; ++i) new(&items[i])ITEM(oldArray[offset(i)]); 18 | deleteArray(oldArray); 19 | front = 0; 20 | capacity = newCapacity; 21 | } 22 | void deleteArray(ITEM* array) 23 | {//desctruct only allocated items 24 | for(int i = 0; i < size; ++i) array[offset(i)].~ITEM(); 25 | rawDelete(array); 26 | } 27 | public: 28 | bool isEmpty()const{return size == 0;} 29 | int getSize()const{return size;} 30 | ITEM& operator[](int i) 31 | { 32 | assert(i >= 0 && i < size); 33 | return items[offset(i)]; 34 | } 35 | ITEM const& operator[](int i)const 36 | { 37 | assert(i >= 0 && i < size); 38 | return items[offset(i)]; 39 | } 40 | Queue(int theCapacity = MIN_CAPACITY): capacity(max(int(MIN_CAPACITY), 41 | theCapacity)), front(0), size(0), items(rawMemory(capacity)) {} 42 | Queue(Queue const& rhs): capacity(max(int(MIN_CAPACITY), rhs.size)), 43 | size(rhs.size), front(0), items(rawMemory(capacity)) 44 | {for(int i = 0; i < size; ++i) push(rhs[i]);} 45 | Queue& operator=(Queue const& rhs){return genericAssign(*this, rhs);} 46 | ~Queue(){deleteArray(items);} 47 | void push(ITEM const& item) 48 | { 49 | if(size == capacity) resize(); 50 | new(&items[offset(size++)])ITEM(item); 51 | } 52 | ITEM pop() 53 | { 54 | assert(!isEmpty()); 55 | ITEM result = items[front]; 56 | items[front].~ITEM(); 57 | front = offset(1); 58 | if(capacity > 4 * --size && capacity > MIN_CAPACITY) resize(); 59 | return result; 60 | } 61 | ITEM& top()const 62 | { 63 | assert(!isEmpty()); 64 | return items[front]; 65 | } 66 | void debug()const 67 | { 68 | for(int i = 0; i < getSize(); ++i) cout << operator[](i) << ", "; 69 | cout << endl; 70 | } 71 | }; 72 | 73 | }//end namespace 74 | #endif 75 | -------------------------------------------------------------------------------- /Utils/Stack.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_STACK_H 2 | #define IGMDK_STACK_H 3 | #include "Utils.h" 4 | #include "Vector.h" 5 | namespace igmdk{ 6 | 7 | template > struct Stack 8 | { 9 | VECTOR storage; 10 | void push(ITEM const& item){storage.append(item);} 11 | ITEM pop() 12 | { 13 | assert(!isEmpty()); 14 | ITEM result = storage.lastItem(); 15 | storage.removeLast(); 16 | return result; 17 | } 18 | ITEM& getTop() 19 | { 20 | assert(!isEmpty()); 21 | return storage.lastItem(); 22 | } 23 | bool isEmpty(){return !storage.getSize();} 24 | }; 25 | 26 | }//end namespace 27 | #endif 28 | -------------------------------------------------------------------------------- /Utils/UnionFind.h: -------------------------------------------------------------------------------- 1 | #ifndef IGMDK_UNION_FIND_H 2 | #define IGMDK_UNION_FIND_H 3 | 4 | #include "../Utils/Utils.h" 5 | #include "../Utils/Vector.h" 6 | 7 | namespace igmdk{ 8 | 9 | class UnionFind 10 | { 11 | mutable Vector parent;//parent or negated size of the tree 12 | public: 13 | UnionFind(int size): parent(size, -1){} 14 | bool isRoot(int n)const{return parent[n] < 0;}; 15 | int find(int n)const 16 | {return isRoot(n) ? n : (parent[n] = find(parent[n]));} 17 | void join(int i, int j) 18 | { 19 | int parentI = find(i), parentJ = find(j); 20 | if(parentI != parentJ) 21 | {//parent[parentI] and parent[parentJ] are negative sizes 22 | if(parent[parentI] > parent[parentJ]) swap(parentI, parentJ); 23 | parent[parentI] += parent[parentJ]; 24 | parent[parentJ] = parentI; 25 | } 26 | } 27 | bool areEquivalent(int i, int j)const{return find(i) == find(j);} 28 | int subsetSize(int i)const{return -parent[find(i)];} 29 | void addSubset(){parent.append(-1);} 30 | }; 31 | 32 | }//end namespace 33 | #endif 34 | -------------------------------------------------------------------------------- /Utils/testBasics.cpp: -------------------------------------------------------------------------------- 1 | #include "Stack.h" 2 | #include "Queue.h" 3 | #include "GCFreeList.h" 4 | #include "UtilsTestAuto.h" 5 | using namespace igmdk; 6 | 7 | void DDDVector() 8 | { 9 | Vector Vector0to4; 10 | for(int i = 0; i < 5; ++i ) Vector0to4.append(i); 11 | 12 | cout << "breakpoint" << endl; 13 | } 14 | 15 | void DDDStack() 16 | { 17 | Stack Stack0to4; 18 | for(int i = 0; i < 5; ++i ) Stack0to4.push(i); 19 | 20 | cout << "breakpoint" << endl; 21 | } 22 | 23 | void DDDQueue() 24 | { 25 | Queue Queue1to4; 26 | for(int i = 0; i < 5; ++i ) Queue1to4.push(i); 27 | Queue1to4.pop(); 28 | 29 | cout << "breakpoint" << endl; 30 | } 31 | 32 | void DDDList() 33 | { 34 | SimpleDoublyLinkedList List0to2; 35 | for(int i = 2; i >= 0; --i ) List0to2.prepend(i); 36 | 37 | cout << "breakpoint" << endl; 38 | } 39 | 40 | void DDDFreelist() 41 | { 42 | Freelist Freelist0to14R5(8); 43 | int* items[15]; 44 | DEBUG("a"); 45 | for(int i = 0; i < 15; ++i ) items[i] = new(Freelist0to14R5.allocate())int(i); 46 | DEBUG("r"); 47 | for(int i = 0; i < 5; ++i ) Freelist0to14R5.remove(items[i]); 48 | 49 | cout << "breakpoint" << endl; 50 | } 51 | 52 | 53 | 54 | int main() 55 | { 56 | testAllAutoUtils(); 57 | //return 0; 58 | DDDVector(); 59 | //DDDDeque(); 60 | DDDStack(); 61 | DDDQueue(); 62 | DDDList(); 63 | DDDFreelist(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Utils/testBits.cpp: -------------------------------------------------------------------------------- 1 | #include "Bitset.h" 2 | using namespace igmdk; 3 | #include 4 | 5 | template void printBits(WORD x) 6 | { 7 | bitset b(x); 8 | cout << b << endl; 9 | } 10 | 11 | void testBits() 12 | { 13 | printBits<8>(Bits::upperMask(4));//expect 11110000 14 | } 15 | 16 | int popCountWord2(unsigned long long x) 17 | { 18 | int n = 0; 19 | while(x) 20 | { 21 | ++n; 22 | x &= x - 1; 23 | } 24 | return n; 25 | } 26 | void timePopCount() 27 | { 28 | unsigned long long x = 3435345355555ull; 29 | clock_t start = clock(); 30 | int p = popCountWord(x); 31 | for(int i = 0; i < 1000000000; ++i) p += popCountWord(x) + 1; 32 | //timeRT(); 33 | int tFL = (clock() - start); 34 | cout << p << "PC: "< BitsetChar19Every4(19); 46 | for(int i = 0; i < 19; i += 4) 47 | { 48 | BitsetChar19Every4.set(i, true); 49 | } 50 | cout << "breakpoint" << endl; 51 | } 52 | 53 | int main() 54 | { 55 | DDDBitset(); 56 | //timePopCount(); 57 | testBits(); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Utils/testUF.cpp: -------------------------------------------------------------------------------- 1 | #include "UnionFind.h" 2 | #include 3 | #include "DEBUG.h" 4 | #include "../RandomTreap/Treap.h"//for set union 5 | using namespace igmdk; 6 | 7 | //NOT MENTIONED IN TEXT 8 | class IntervalSetUnion 9 | { 10 | Treap treap; 11 | public: 12 | int find(int i) 13 | {return treap.getSize() == 0 ? -1 : treap.successor(i)->key;} 14 | void merge(int i){return treap.remove(i);} 15 | void split(int i){treap.insert(i, 0);} 16 | }; 17 | int main() 18 | { 19 | IntervalSetUnion iu; 20 | 21 | iu.split(5); 22 | DEBUG(iu.find(2)); 23 | iu.split(3); 24 | DEBUG(iu.find(2)); 25 | iu.merge(3); 26 | DEBUG(iu.find(2)); 27 | return 0; 28 | } 29 | --------------------------------------------------------------------------------