├── .gitattributes ├── .github └── issue_template.md ├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── asm_x86_64 ├── libmath.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── main.c ├── powers.asm ├── rdtsc.asm └── vector.asm ├── c ├── Distance.c ├── Distance.h ├── KMeans.c ├── KMeans.h ├── Powers.c ├── Powers.h ├── Signals.c ├── Signals.h ├── SquareMatrix.c ├── SquareMatrix.h ├── Statistics.c ├── Statistics.h ├── Vector.c ├── Vector.h ├── libmath.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── main.c ├── cpp ├── BigInt.cpp ├── BigInt.h ├── CMakeLists.txt ├── Calculus.cpp ├── Calculus.h ├── Distance.cpp ├── Distance.h ├── Double.cpp ├── Double.h ├── Graphics.cpp ├── Graphics.h ├── KMeans.cpp ├── KMeans.h ├── Matrix.cpp ├── Matrix.h ├── Peaks.cpp ├── Peaks.h ├── Powers.cpp ├── Powers.h ├── Prime.cpp ├── Prime.h ├── Signals.cpp ├── Signals.h ├── SquareMatrix.cpp ├── SquareMatrix.h ├── Statistics.cpp ├── Statistics.h ├── Vector.cpp ├── Vector.h ├── libmath.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── main.cpp ├── data ├── 10_pullups.csv └── florida.csv ├── java ├── pom.xml └── src │ └── main │ └── java │ ├── CsvReader.java │ ├── GraphPeak.java │ ├── GraphPoint.java │ ├── LibMathTests.java │ ├── Peaks.java │ └── Statistics.java ├── julia ├── Distance.jl ├── LibMathTests.jl ├── Peaks.jl ├── Powers.jl └── Signals.jl ├── python ├── distance.py ├── graphics.py ├── kmeans.py ├── main.py ├── peaks.py ├── signals.py └── statistics.py └── rust ├── Cargo.toml └── src ├── distance.rs ├── graphics.rs ├── kmeans.rs ├── lib.rs ├── peaks.rs ├── powers.rs ├── signals.rs ├── square_matrix.rs ├── statistics.rs └── vector.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | # C++ 2 | 3 | # Sources 4 | *.c text 5 | *.cc text 6 | *.cxx text 7 | *.cpp text 8 | *.c++ text 9 | *.hpp text 10 | *.h text 11 | *.h++ text 12 | *.hh text 13 | 14 | # Compiled Object files 15 | *.slo binary 16 | *.lo binary 17 | *.o binary 18 | *.obj binary 19 | 20 | # Precompiled Headers 21 | *.gch binary 22 | *.pch binary 23 | 24 | # Compiled Dynamic libraries 25 | *.so binary 26 | *.dylib binary 27 | *.dll binary 28 | 29 | # Compiled Static libraries 30 | *.lai binary 31 | *.la binary 32 | *.a binary 33 | *.lib binary 34 | 35 | # Executables 36 | *.exe binary 37 | *.out binary 38 | *.app binary 39 | 40 | # Python 41 | 42 | # Source files 43 | # ============ 44 | *.pxd text 45 | *.py text 46 | *.py3 text 47 | *.pyw text 48 | *.pyx text 49 | 50 | # Binary files 51 | # ============ 52 | *.db binary 53 | *.p binary 54 | *.pkl binary 55 | *.pyc binary 56 | *.pyd binary 57 | *.pyo binary 58 | 59 | # Note: .db, .p, and .pkl files are associated 60 | # with the python modules ``pickle``, ``dbm.*``, 61 | # ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` 62 | # (among others). -------------------------------------------------------------------------------- /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Steps to reproduce the issue: 2 | 1. 3 | 2. 4 | 3. 5 | 6 | ### Expected behavior: 7 | What did you expect to happen? 8 | 9 | ### Observed behavior: 10 | What actually happened? 11 | 12 | ### OS and Machine Specifications: 13 | - OS name and version: 14 | - CPU: 15 | - RAM: 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## User settings 2 | xcuserdata/ 3 | 4 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 5 | *.xcscmblueprint 6 | *.xccheckout 7 | 8 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 9 | build/ 10 | DerivedData/ 11 | *.moved-aside 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | 21 | # Rust 22 | rust/target/ 23 | rust/Cargo.lock 24 | 25 | # Python 26 | *.pyc 27 | 28 | # Java # 29 | *.class 30 | 31 | # Mobile Tools for Java (J2ME) 32 | .mtj.tmp/ 33 | 34 | # Package Files # 35 | *.jar 36 | *.war 37 | *.ear 38 | 39 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 40 | hs_err_pid* 41 | target 42 | 43 | # Eclipse 44 | .settings/ 45 | 46 | # VSCode 47 | .vscode/ipch/ 48 | 49 | # Eclipse Core 50 | .project 51 | 52 | # JDT-specific (Eclipse Java Development Tools) 53 | .classpath 54 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "type": "java", 10 | "name": "CodeLens (Launch) - LibMathTests", 11 | "request": "launch", 12 | "mainClass": "LibMathTests", 13 | "args": [ 14 | "--csv", "data/10_pullups.csv" 15 | ], 16 | }, 17 | { 18 | "type": "java", 19 | "name": "Debug (Launch) - Current File", 20 | "request": "launch", 21 | "mainClass": "${file}", 22 | "args": [ 23 | "--csv", "data/10_pullups.csv" 24 | ] 25 | }, 26 | { 27 | "type": "julia", 28 | "name": "Debug (Launch) - Julia Tests", 29 | "request": "launch", 30 | "mainClass": "LibMathTests.jl", 31 | "args": [ 32 | "--csv", "data/10_pullups.csv" 33 | ] 34 | } 35 | ] 36 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael J. Simms 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![asm_x86-64](https://img.shields.io/badge/asm-x86_64-brightgreen.svg)]() [![C](https://img.shields.io/badge/c-brightgreen.svg)]() [![C++](https://img.shields.io/badge/cpp-brightgreen.svg)]() [![Rust](https://img.shields.io/badge/rust-brightgreen.svg)](https://www.rust-lang.org) [![Python 2.7|3.7](https://img.shields.io/badge/python-2.7%2F3.7-brightgreen.svg)](https://www.python.org/) [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) 2 | 3 | # LibMath 4 | A collection of commonly used math routines, in C, C++, Python, Rust, and Julia programming languages. 5 | 6 | ## Rationale 7 | This is a collection of small, and quick, math routines I've written for other hobby projects over the years. I decided to organize them and place them in one library so they would be easier to reuse in the future. They're also available for anyone else that wants to use this code, instead of a larger, heaveyweight math library. **There are no production project files in this library. It is just a loose collection of code. Include the files you need and ignore the ones you don't.** The project files and main files are included just for testing. 8 | 9 | ## Features 10 | This library is primarily focused on C and C++. However, I have started adding Python and Rust implementations where appropriate, or when needed. As python already has a large collection of libraries, there simply isn't as much need for python implementations for many of these algorithms. 11 | 12 | ### Distance Calculations 13 | * Hamming Distance (C, C++, Rust, Python, Julia) 14 | * Levenshtein Distance (C, C++, Rust, Julia) 15 | * Basic Euclidian Distances (C, C++, Rust, Python, Julia) 16 | * Haversine Distance (C, C++, Rust, Python) - Distance between points on the Earth's surface. 17 | 18 | ### Graphics 19 | * Quadratic Bezier Curve (C++) 20 | 21 | ### Linear Algebra 22 | * Basic Matrix Operations - with optimizations for square matrices (C, C++, Rust) 23 | * Basic Vector Operations (C, C++, Rust) 24 | 25 | ### Statistical Functions 26 | * Mean, Standard Deviation, and Variance (C, C++, Rust, Python2 - unnecesary in Python3) 27 | * Min, Max (C, C++, Rust) 28 | 29 | ### Signals Functions 30 | * Simple Signal Smoothing (C, C++, Python, Julia) 31 | 32 | ### K-Means 33 | * One dimensional K-Means (C, C++, Rust, Python) 34 | 35 | ### Peak Finding 36 | * Find peaks that rise more than one standard deviation above the mean for at least three consecutive points on the x axis. (C++, Rust, Python) 37 | 38 | ### Power 39 | * Find the nearest power of two (C, C++, Julia) 40 | 41 | ### Graphics 42 | * Ray Casting (Python, Rust) - Determines if a point is within a polygon. 43 | 44 | ## Using 45 | Add this respository as a submodule to your own project and then add the file you want directly to your build, or just copy the source files directly into your project. This library is just meant to be a loose collection of files that you can do whatever you want with. This way you don't have to add code for algorithms you don't need to your project. 46 | 47 | ## License 48 | This library is released under the MIT license, see LICENSE for details. 49 | -------------------------------------------------------------------------------- /asm_x86_64/libmath.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /asm_x86_64/libmath.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /asm_x86_64/main.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | extern double vectorMultiply(const double* A, const double* B, size_t vecLen); 27 | extern void vectorSubtract(const double* A, const double* B, double* C, size_t vecLen); 28 | extern double vectorDot(const double* A, const double* B, size_t vecLen); 29 | extern double vectorLength(const double* A, size_t vecLen); 30 | extern void vectorNormalize(double* A, size_t vecLen); 31 | extern void vectorCross(const double* A, const double* B, double* C, size_t vecLen); 32 | 33 | extern long long GetRDTSC(void); 34 | extern unsigned long NearestPowerOf2(unsigned long num); 35 | 36 | int main(int argc, const char * argv[]) 37 | { 38 | printf("Vector Tests:\n"); 39 | printf("-------------\n"); 40 | double* v1 = (double*)malloc(sizeof(double) * 3); 41 | double* v2 = (double*)malloc(sizeof(double) * 3); 42 | v1[0] = 1; v1[1] = 2; v1[2] = 3; 43 | v2[0] = 1; v2[1] = 2; v2[2] = 3; 44 | long long startTime = GetRDTSC(); 45 | long long endTime = GetRDTSC(); 46 | printf("Execution Time: %lld\n\n", endTime - startTime); 47 | free((void*)v1); 48 | free((void*)v2); 49 | 50 | printf("Square Matrix Tests:\n"); 51 | printf("--------------------\n"); 52 | startTime = GetRDTSC(); 53 | endTime = GetRDTSC(); 54 | printf("Execution Time: %lld\n\n", endTime - startTime); 55 | 56 | printf("Statistics Tests:\n"); 57 | printf("-----------------\n"); 58 | startTime = GetRDTSC(); 59 | endTime = GetRDTSC(); 60 | printf("Execution Time: %lld\n\n", endTime - startTime); 61 | 62 | printf("Power Tests:\n"); 63 | printf("------------\n"); 64 | startTime = GetRDTSC(); 65 | unsigned long nearest = NearestPowerOf2(63); 66 | endTime = GetRDTSC(); 67 | printf("Nearest power of 2 for 63 is %ld.\n\n", nearest); 68 | assert(nearest == 64); 69 | printf("Execution Time: %lld\n\n", endTime - startTime); 70 | 71 | printf("Distance Tests:\n"); 72 | printf("---------------\n"); 73 | startTime = GetRDTSC(); 74 | endTime = GetRDTSC(); 75 | printf("Execution Time: %lld\n\n", endTime - startTime); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /asm_x86_64/powers.asm: -------------------------------------------------------------------------------- 1 | ; by Michael J. Simms 2 | ; Copyright (c) 2018 Michael J. Simms 3 | 4 | ; Permission is hereby granted, free of charge, to any person obtaining a copy 5 | ; of this software and associated documentation files (the "Software"), to deal 6 | ; in the Software without restriction, including without limitation the rights 7 | ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | ; copies of the Software, and to permit persons to whom the Software is 9 | ; furnished to do so, subject to the following conditions: 10 | ; 11 | ; The above copyright notice and this permission notice shall be included in all 12 | ; copies or substantial portions of the Software. 13 | ; 14 | ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | ; SOFTWARE. 21 | 22 | global _NearestPowerOf2 23 | 24 | section .text 25 | 26 | ; unsigned long NearestPowerOf2(unsigned long num) 27 | _NearestPowerOf2: 28 | push rbp 29 | mov rbp, rsp 30 | 31 | ; n = num > 0 ? num - 1 : 0 32 | xor rbx, rbx 33 | ; if rcx == 0 then jump to doing the shifts, rcx is the first parameter (i.e. num) 34 | cmp rcx, $0 35 | je shifts 36 | ; rbx = rcx - 1 37 | mov rbx, rcx 38 | sub rbx, $1 39 | 40 | shifts: 41 | ; n |= n >> 1 42 | mov rax, rbx 43 | shr rax, $1 44 | or rbx, rax 45 | 46 | ; n |= n >> 2 47 | mov rax, rbx 48 | shr rax, $2 49 | or rbx, rax 50 | 51 | ; n |= n >> 4 52 | mov rax, rbx 53 | shr rax, $4 54 | or rbx, rax 55 | 56 | ; n |= n >> 8 57 | mov rax, rbx 58 | shr rax, $8 59 | or rbx, rax 60 | 61 | ; n |= n >> 16 62 | mov rax, rbx 63 | shr rax, $16 64 | or rax, rbx 65 | 66 | ; n++ 67 | add rax, $1 68 | 69 | pop rbp 70 | ret 71 | -------------------------------------------------------------------------------- /asm_x86_64/rdtsc.asm: -------------------------------------------------------------------------------- 1 | global _GetRDTSC 2 | 3 | section .text 4 | 5 | _GetRDTSC: 6 | cpuid 7 | rdtsc 8 | shl rdx, 32 9 | or rax, rdx 10 | ret 11 | -------------------------------------------------------------------------------- /asm_x86_64/vector.asm: -------------------------------------------------------------------------------- 1 | ; by Michael J. Simms 2 | ; Copyright (c) 2018 Michael J. Simms 3 | 4 | ; Permission is hereby granted, free of charge, to any person obtaining a copy 5 | ; of this software and associated documentation files (the "Software"), to deal 6 | ; in the Software without restriction, including without limitation the rights 7 | ; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | ; copies of the Software, and to permit persons to whom the Software is 9 | ; furnished to do so, subject to the following conditions: 10 | ; 11 | ; The above copyright notice and this permission notice shall be included in all 12 | ; copies or substantial portions of the Software. 13 | ; 14 | ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | ; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | ; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | ; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | ; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | ; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | ; SOFTWARE. 21 | 22 | global _VectorMultiply 23 | global _VectorSubtract 24 | global _VectorDot 25 | global _VectorLength 26 | global _VectorNormalize 27 | global _VectorCross 28 | 29 | section .text 30 | 31 | ; double vectorMultiply(const double* A, const double* B, size_t vecLen) 32 | _VectorMultiply: 33 | push rbp 34 | mov rbp, rsp 35 | mov rax, $0 36 | ret 37 | 38 | ; void vectorSubtract(const double* A, const double* B, double* C, size_t vecLen) 39 | _VectorSubtract: 40 | push rbp 41 | mov rbp, rsp 42 | ret 43 | 44 | ; double vectorDot(const double* A, const double* B, size_t vecLen) 45 | _VectorDot: 46 | push rbp 47 | mov rbp, rsp 48 | mov rax, $0 49 | ret 50 | 51 | ; double vectorLength(const double* A, size_t vecLen) 52 | _VectorLength: 53 | push rbp 54 | mov rbp, rsp 55 | mov rax, $0 56 | ret 57 | 58 | ; void vectorNormalize(double* A, size_t vecLen) 59 | _VectorNormalize: 60 | push rbp 61 | mov rbp, rsp 62 | ret 63 | 64 | ; void vectorCross(const double* A, const double* B, double* C, size_t vecLen) 65 | _VectorCross: 66 | push rbp 67 | mov rbp, rsp 68 | ret 69 | -------------------------------------------------------------------------------- /c/Distance.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Distance.h" 23 | #include "Statistics.h" 24 | 25 | #include 26 | #include 27 | 28 | // Hamming Distance 29 | size_t hammingDistance(const char* str1, const char* str2) 30 | { 31 | size_t len1 = strlen(str1); 32 | 33 | // The strings must be the same length. 34 | if (len1 != strlen(str2)) 35 | return (size_t)-1; 36 | 37 | size_t distance = 0; 38 | 39 | for (size_t i = 0; i < len1; ++i) 40 | { 41 | if (str1[i] != str2[i]) 42 | ++distance; 43 | } 44 | return distance; 45 | } 46 | 47 | // Levenshtein Distance 48 | size_t levenshteinDistance(const char* str1, const char* str2) 49 | { 50 | size_t m = strlen(str1); 51 | size_t n = strlen(str2); 52 | 53 | // Test for empty strings. 54 | if (m == 0) 55 | return n; 56 | if (n == 0) 57 | return m; 58 | 59 | // Temp vectors. 60 | size_t vecSize = sizeof(size_t) * n; 61 | size_t* v0 = (size_t*)malloc(vecSize); 62 | if (!v0) 63 | { 64 | return (size_t)-1; 65 | } 66 | size_t* v1 = (size_t*)malloc(vecSize); 67 | if (!v1) 68 | { 69 | free((void*)v0); 70 | return (size_t)-1; 71 | } 72 | size_t* tempV = (size_t*)malloc(vecSize); 73 | if (!tempV) 74 | { 75 | free((void*)v0); 76 | free((void*)v1); 77 | return (size_t)-1; 78 | } 79 | 80 | for (size_t i = 0; i < n; ++i) 81 | { 82 | v0[i] = i; 83 | } 84 | for (size_t i = 0; i < m - 1; ++i) 85 | { 86 | v1[0] = i + 1; 87 | 88 | for (size_t j = 0; j < n - 1; ++j) 89 | { 90 | size_t costs[3]; // deletion, insertion, and substitution costs (in that order) 91 | costs[0] = v0[j + 1] + 1; 92 | costs[1] = v1[j] + 1; 93 | if (str1[i] == str2[j]) 94 | costs[2] = v0[j]; 95 | else 96 | costs[2] = v0[j] + 1; 97 | v1[j + 1] = statisticsMinInt(costs, 3); 98 | } 99 | 100 | // Copy v1 to v0. 101 | memcpy(tempV, v0, vecSize); 102 | memcpy(v0, v1, vecSize); 103 | memcpy(v1, tempV, vecSize); 104 | } 105 | 106 | // Save the final distance calculation, before freeing the vector. 107 | size_t distance = v0[n - 1]; 108 | 109 | // Clean up. 110 | free((void*)v0); 111 | free((void*)v1); 112 | free((void*)tempV); 113 | 114 | return distance; 115 | } 116 | 117 | // 1 dimensional Euclidian distance 118 | double euclidianDistance1D(double pt1, double pt2) 119 | { 120 | return fabs(pt1 - pt2); 121 | } 122 | 123 | // 2 dimensional Euclidian distance 124 | double euclidianDistance2D(double pt1X, double pt1Y, double pt2X, double pt2Y) 125 | { 126 | double tempX = pt2X - pt1X; 127 | double tempY = pt2Y - pt1Y; 128 | return sqrt((tempX * tempX) + (tempY * tempY)); 129 | } 130 | -------------------------------------------------------------------------------- /c/Distance.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _DISTANCE_ 25 | #define _DISTANCE_ 26 | 27 | #include 28 | 29 | /** 30 | * Computes the Hamming distance of the strings. 31 | */ 32 | size_t hammingDistance(const char* str1, const char* str2); 33 | 34 | /** 35 | * Computes the Levenshtein distance of str2 relative to str1. 36 | */ 37 | size_t levenshteinDistance(const char* str1, const char* str2); 38 | 39 | /** 40 | * Computes the Euclidian distance between two points in a 1D space. 41 | */ 42 | double euclidianDistance1D(double pt1, double pt2); 43 | 44 | /** 45 | * Computes the Euclidian distance between two points in a 2D space. 46 | */ 47 | double euclidianDistance2D(double pt1X, double pt1Y, double pt2X, double pt2Y); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /c/KMeans.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "KMeans.h" 23 | #include "Distance.h" 24 | #include "Statistics.h" 25 | 26 | #include 27 | 28 | size_t* kMeans1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters, double* centroids) 29 | { 30 | // Sanity check. 31 | if (k == 0) 32 | { 33 | return NULL; 34 | } 35 | 36 | // Create the output error array; describes the error for each data point. 37 | double* errors = (double*)malloc(sizeof(double) * dataLen); 38 | if (!errors) 39 | { 40 | return NULL; 41 | } 42 | 43 | // Create the cluster means array; describes the error for each data point. 44 | size_t* clusterSizes = (size_t*)malloc(sizeof(size_t) * k); 45 | if (!clusterSizes) 46 | { 47 | free((void*)errors); 48 | return NULL; 49 | } 50 | 51 | // Create the output tag array. 52 | size_t* tags = (size_t*)malloc(sizeof(size_t) * dataLen); 53 | if (!tags) 54 | { 55 | free((void*)clusterSizes); 56 | free((void*)errors); 57 | return NULL; 58 | } 59 | 60 | // Assignment step. Find the closest centroid for each data point. 61 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 62 | { 63 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 64 | { 65 | double distance = euclidianDistance1D(data[dataIndex], centroids[clusterIndex]); 66 | if ((clusterIndex == 0) || (distance < errors[dataIndex])) 67 | { 68 | tags[dataIndex] = clusterIndex; 69 | errors[dataIndex] = distance; 70 | } 71 | } 72 | } 73 | 74 | // Update step. 75 | double avgError = (double)0.0; 76 | size_t iterCount = 0; 77 | size_t numRelocations = 0; 78 | do { 79 | // Recompute cluster means. 80 | memset(centroids, 0, sizeof(double) * k); 81 | memset(clusterSizes, 0, sizeof(size_t) * k); 82 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 83 | { 84 | size_t clusterIndex = tags[dataIndex]; 85 | centroids[clusterIndex] += data[dataIndex]; 86 | clusterSizes[clusterIndex]++; 87 | } 88 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 89 | { 90 | centroids[clusterIndex] /= clusterSizes[clusterIndex]; 91 | } 92 | 93 | // Measure each data point against it's own cluster mean, and all other cluster means. 94 | // Relocate the data point to the cluster that matches best. 95 | numRelocations = 0; 96 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 97 | { 98 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 99 | { 100 | double distance = euclidianDistance1D(data[dataIndex], centroids[clusterIndex]); 101 | if (distance < errors[dataIndex]) 102 | { 103 | tags[dataIndex] = clusterIndex; 104 | errors[dataIndex] = distance; 105 | ++numRelocations; 106 | } 107 | } 108 | } 109 | 110 | // Compute the average error. 111 | avgError = statisticsAverageDouble(errors, dataLen); 112 | 113 | ++iterCount; 114 | } while ((avgError > maxError) && (iterCount < maxIters) && (numRelocations > 0)); 115 | 116 | // Free memory. 117 | free((void*)clusterSizes); 118 | free((void*)errors); 119 | 120 | return tags; 121 | } 122 | 123 | size_t* kMeansEquallySpacedCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters) 124 | { 125 | // Sanity check. 126 | if (dataLen <= 1) 127 | { 128 | return NULL; 129 | } 130 | 131 | size_t* tags = NULL; 132 | 133 | double* centroids = (double*)malloc(sizeof(double) * k); 134 | if (centroids) 135 | { 136 | // Select the k data points that are farthest apart from each other. 137 | double min = statisticsMin(data, dataLen); 138 | centroids[0] = min; 139 | double max = statisticsMax(data, dataLen); 140 | centroids[k - 1] = max; 141 | double increment = (max - min) / (double)(k - 1); 142 | for (size_t i = 1; i < k - 1; ++i) 143 | { 144 | centroids[i] = min + (increment * (double)i); 145 | } 146 | 147 | // Perform K Means clustering. 148 | tags = kMeans1D(data, dataLen, k, maxError, maxIters, centroids); 149 | 150 | // Clean up. 151 | free((void*)centroids); 152 | } 153 | 154 | return tags; 155 | } 156 | 157 | size_t* kMeansRandCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters) 158 | { 159 | // Sanity check. 160 | if (dataLen <= 1) 161 | { 162 | return NULL; 163 | } 164 | 165 | size_t* tags = NULL; 166 | 167 | double* centroids = (double*)malloc(sizeof(double) * k); 168 | if (centroids) 169 | { 170 | // Randomly select starting centroids. 171 | for (size_t i = 0; i < k; ++i) 172 | { 173 | size_t selected = rand() % k; 174 | centroids[i] = data[selected]; 175 | } 176 | 177 | // Perform K Means clustering. 178 | tags = kMeans1D(data, dataLen, k, maxError, maxIters, centroids); 179 | 180 | // Clean up. 181 | free((void*)centroids); 182 | } 183 | 184 | return tags; 185 | } 186 | -------------------------------------------------------------------------------- /c/KMeans.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _KMEANS_ 25 | #define _KMEANS_ 26 | 27 | #include 28 | 29 | /** 30 | * Performs K Means clustering on a one dimensional array, using the provided centroids. 31 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 32 | */ 33 | size_t* kMeans1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters, double* clusters); 34 | 35 | /** 36 | * Performs K Means clustering on a one dimensional array, setting the initial centroids to the data points farthest apart. 37 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 38 | */ 39 | size_t* kMeansEquallySpacedCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters); 40 | 41 | /** 42 | * Performs K Means clustering on a one dimensional array, using random initial centroids. 43 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 44 | */ 45 | size_t* kMeansRandCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /c/Powers.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2011 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Powers.h" 23 | 24 | unsigned long NearestPowerOf2(unsigned long num) 25 | { 26 | unsigned long n = num > 0 ? num - 1 : 0; 27 | 28 | n |= n >> 1; 29 | n |= n >> 2; 30 | n |= n >> 4; 31 | n |= n >> 8; 32 | n |= n >> 16; 33 | n++; 34 | 35 | return n; 36 | } 37 | -------------------------------------------------------------------------------- /c/Powers.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2011 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | unsigned long NearestPowerOf2(unsigned long num); 23 | -------------------------------------------------------------------------------- /c/Signals.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2020 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include "Statistics.h" 24 | 25 | // Smooths the data, which should be a list, by averaging with the given window size. 26 | double* smooth(double* inData, size_t inDataLen, size_t windowSize) 27 | { 28 | size_t outDataLen = inDataLen - windowSize + 1; 29 | if (outDataLen <= 0) 30 | return NULL; 31 | 32 | double* outData = malloc(sizeof(double) * outDataLen); 33 | for (size_t i = 0; i < outDataLen; ++i) 34 | { 35 | double val = statisticsAverageDouble(inData + i, windowSize); 36 | outData[i] = val; 37 | } 38 | return outData; 39 | } 40 | -------------------------------------------------------------------------------- /c/Signals.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2020 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _SIGNALS_ 25 | #define _SIGNALS_ 26 | 27 | double* smooth(double* inData, size_t inDataLen, size_t windowSize); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /c/SquareMatrix.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "SquareMatrix.h" 27 | 28 | SquareMatrixPtr squareMatrixCreate(size_t size) 29 | { 30 | register size_t i; 31 | 32 | SquareMatrixPtr matrix = (SquareMatrixPtr)malloc(sizeof(SquareMatrix)); 33 | if (matrix) 34 | { 35 | matrix->data = (double**)malloc(sizeof(double*) * size); 36 | matrix->size = size; 37 | 38 | for (i = 0; i < size; ++i) 39 | matrix->data[i] = (double*)malloc(sizeof(double) * size); 40 | } 41 | return matrix; 42 | } 43 | 44 | void squareMatrixDestroy(SquareMatrixPtr matrix) 45 | { 46 | register size_t i; 47 | 48 | if (matrix != NULL) 49 | { 50 | for (i = 0; i < matrix->size; ++i) 51 | { 52 | free((void*)matrix->data[i]); 53 | matrix->data[i] = NULL; 54 | } 55 | free((void*)matrix->data); 56 | free((void*)matrix); 57 | } 58 | } 59 | 60 | void squareMatrixPrint(SquareMatrixPtr matrix) 61 | { 62 | register size_t i, j; 63 | 64 | if (matrix != NULL) 65 | { 66 | for (i = 0; i < matrix->size; ++i) 67 | { 68 | printf("[ "); 69 | for (j = 0; j < matrix->size; ++j) 70 | { 71 | printf("%lf ", matrix->data[i][j]); 72 | } 73 | printf("]\n"); 74 | } 75 | printf("\n"); 76 | } 77 | } 78 | 79 | void squareMatrixMultiply(const SquareMatrixPtr A, const SquareMatrixPtr B, SquareMatrixPtr C) 80 | { 81 | register size_t i, j, k; 82 | 83 | // Compute C = A x B 84 | for (i = 0; i < A->size; ++i) 85 | { 86 | for (j = 0; j < B->size; ++j) 87 | { 88 | C->data[i][j] = 0.0; 89 | for (k = 0; k < C->size; ++k) 90 | { 91 | C->data[i][j] += A->data[i][k] * B->data[k][j]; 92 | } 93 | } 94 | } 95 | } 96 | 97 | void squareMatrixMultiplyByVector(const SquareMatrixPtr A, const VectorPtr B, VectorPtr C) 98 | { 99 | register size_t i, j; 100 | 101 | // Compute C = A x B 102 | for (i = 0; i < A->size; ++i) 103 | { 104 | C->data[i] = 0.0; 105 | for (j = 0; j < B->size; ++j) 106 | { 107 | C->data[i] += A->data[i][j] * B->data[j]; 108 | } 109 | } 110 | } 111 | 112 | void squareMatrixMultiplyByScalar(SquareMatrixPtr A, double B) 113 | { 114 | register size_t i, j; 115 | 116 | for (i = 0; i < A->size; ++i) 117 | { 118 | for (j = 0; j < A->size; ++j) 119 | { 120 | A->data[i][j] = A->data[i][j] * B; 121 | } 122 | } 123 | } 124 | 125 | void squareMatrixSubtract(const SquareMatrixPtr A, const SquareMatrixPtr B, SquareMatrixPtr C) 126 | { 127 | register size_t i, j; 128 | 129 | for (i = 0; i < A->size; ++i) 130 | { 131 | for (j = 0; j < A->size; ++j) 132 | { 133 | C->data[i][j] = A->data[i][j] - B->data[i][j]; 134 | } 135 | } 136 | } 137 | 138 | void squareMatrixSubtractScalar(SquareMatrixPtr A, double B) 139 | { 140 | register size_t i, j; 141 | 142 | for (i = 0; i < A->size; ++i) 143 | { 144 | for (j = 0; j < A->size; ++j) 145 | { 146 | A->data[i][j] = A->data[i][j] - B; 147 | } 148 | } 149 | } 150 | 151 | void squareMatrixZero(SquareMatrixPtr A) 152 | { 153 | register size_t i, j; 154 | 155 | for (i = 0; i < A->size; ++i) 156 | { 157 | for (j = 0; j < A->size; ++j) 158 | { 159 | A->data[i][j] = 0.0; 160 | } 161 | } 162 | } 163 | 164 | void squareMatrixIdentity(SquareMatrixPtr A) 165 | { 166 | register size_t i, j; 167 | 168 | for (i = 0; i < A->size; ++i) 169 | { 170 | for (j = 0; j < A->size; ++j) 171 | { 172 | if (i == j) 173 | A->data[i][j] = 1.0; 174 | else 175 | A->data[i][j] = 0.0; 176 | } 177 | } 178 | } 179 | 180 | void squareMatrixOnes(SquareMatrixPtr A) 181 | { 182 | register size_t i, j; 183 | 184 | for (i = 0; i < A->size; ++i) 185 | { 186 | for (j = 0; j < A->size; ++j) 187 | { 188 | A->data[i][j] = 1.0; 189 | } 190 | } 191 | } 192 | 193 | double squareMatrixDot(const SquareMatrixPtr A, const SquareMatrixPtr B) 194 | { 195 | register size_t i, j; 196 | double dot = 0.0; 197 | 198 | for (i = 0; i < A->size; ++i) 199 | { 200 | for (j = 0; j < B->size; ++j) 201 | { 202 | dot += *(A->data[i] + j * A->size) + 203 | *(B->data[i] + j * B->size); 204 | } 205 | } 206 | return dot; 207 | } 208 | -------------------------------------------------------------------------------- /c/SquareMatrix.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _SQUAREMATRIX_ 25 | #define _SQUAREMATRIX_ 26 | 27 | #include "Vector.h" 28 | 29 | typedef struct SquareMatrix 30 | { 31 | double** data; 32 | size_t size; 33 | } SquareMatrix; 34 | typedef SquareMatrix* SquareMatrixPtr; 35 | 36 | /** 37 | * Returns a square matrix of the specified size. 38 | */ 39 | SquareMatrixPtr squareMatrixCreate(size_t size); 40 | 41 | /** 42 | * Frees the memory of the square matrix of the specified size. 43 | */ 44 | void squareMatrixDestroy(SquareMatrixPtr matrix); 45 | 46 | /** 47 | * Prints the matrix to standard out. Intended for testing and debugging. 48 | */ 49 | void squareMatrixPrint(SquareMatrixPtr matrix); 50 | 51 | /** 52 | * Returns C = A x B, where A, B, and C are matrices. 53 | */ 54 | void squareMatrixMultiply(const SquareMatrixPtr A, const SquareMatrixPtr B, SquareMatrixPtr C); 55 | 56 | /** 57 | * Returns C = A x B, where A is a matrix and B and C are vectors. 58 | */ 59 | void squareMatrixMultiplyByVector(const SquareMatrixPtr A, const VectorPtr B, VectorPtr C); 60 | 61 | /** 62 | * Multiplies the matrix by the supplied scalar. 63 | */ 64 | void squareMatrixMultiplyByScalar(SquareMatrixPtr A, double B); 65 | 66 | /** 67 | * Returns C = A - B, where A, B, and C are matrices. 68 | */ 69 | void squareMatrixSubtract(const SquareMatrixPtr A, const SquareMatrixPtr B, SquareMatrixPtr C); 70 | 71 | /** 72 | * Subtracts the scalar from the vector. 73 | */ 74 | void squareMatrixSubtractScalar(SquareMatrixPtr A, double B); 75 | 76 | /** 77 | * Sets the value of A to the zero matrix. 78 | */ 79 | void squareMatrixZero(SquareMatrixPtr A); 80 | 81 | /** 82 | * Sets the value of A to the identity matrix. 83 | */ 84 | void squareMatrixIdentity(SquareMatrixPtr A); 85 | 86 | /** 87 | * Sets the value of A to the matrix of all ones. 88 | */ 89 | void squareMatrixOnes(SquareMatrixPtr A); 90 | 91 | /** 92 | * Returns the dot product of A (the current matrix) and B. 93 | */ 94 | double squareMatrixDot(const SquareMatrixPtr A, const SquareMatrixPtr B); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /c/Statistics.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1998 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | 24 | #include "Statistics.h" 25 | 26 | double statisticsAverageLong(const long* data, size_t numPoints) 27 | { 28 | register long index; 29 | register long sum = 0; 30 | 31 | for (index = 0; index < numPoints; index++) 32 | sum = sum + data[index]; 33 | return (double)sum / (double)numPoints; 34 | } 35 | 36 | double statisticsAverageDouble(const double* data, size_t numPoints) 37 | { 38 | register long index; 39 | register double sum = 0; 40 | 41 | for (index = 0; index < numPoints; index++) 42 | sum = sum + data[index]; 43 | return sum / (double)numPoints; 44 | } 45 | 46 | double statisticsVariance(const double* data, size_t numPoints, double mean) 47 | { 48 | register long index; 49 | register double numerator = 0; 50 | 51 | for (index = 0; index < numPoints; index++) 52 | numerator = numerator + ((data[index] - mean) * (data[index] - mean)); 53 | return numerator / (double)(numPoints - 1); 54 | } 55 | 56 | double statisticsStandardDeviation(const double* data, size_t numPoints, double mean) 57 | { 58 | double var = statisticsVariance(data, numPoints, mean); 59 | return sqrt(var); 60 | } 61 | 62 | double statisticsMax(const double* data, size_t numPoints) 63 | { 64 | register long index; 65 | register double result = data[0]; 66 | 67 | for (index = 1; index < numPoints; index++) 68 | { 69 | if (data[index] > result) 70 | result = data[index]; 71 | } 72 | return result; 73 | } 74 | 75 | size_t statisticsMaxInt(const size_t* data, size_t numPoints) 76 | { 77 | register long index; 78 | register size_t result = data[0]; 79 | 80 | for (index = 1; index < numPoints; index++) 81 | { 82 | if (data[index] > result) 83 | result = data[index]; 84 | } 85 | return result; 86 | } 87 | 88 | double statisticsMin(const double* data, size_t numPoints) 89 | { 90 | register long index; 91 | register double result = data[0]; 92 | 93 | for (index = 1; index < numPoints; index++) 94 | { 95 | if (data[index] < result) 96 | result = data[index]; 97 | } 98 | return result; 99 | } 100 | 101 | size_t statisticsMinInt(const size_t* data, size_t numPoints) 102 | { 103 | register long index; 104 | register size_t result = data[0]; 105 | 106 | for (index = 1; index < numPoints; index++) 107 | { 108 | if (data[index] < result) 109 | result = data[index]; 110 | } 111 | return result; 112 | } 113 | -------------------------------------------------------------------------------- /c/Statistics.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1998 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _STATISTICS_ 25 | #define _STATISTICS_ 26 | 27 | #include 28 | 29 | /** 30 | * Computes the average value in the given array. 31 | */ 32 | double statisticsAverageLong(const long* data, size_t numPoints); 33 | 34 | /** 35 | * Computes the average value in the given array. 36 | */ 37 | double statisticsAverageDouble(const double* data, size_t numPoints); 38 | 39 | /** 40 | * Computes the variance of the given array with the mean value supplied. 41 | */ 42 | double statisticsVariance(const double* data, size_t numPoints, double mean); 43 | 44 | /** 45 | * Computes the standard deviation of the given array with the mean value supplied. 46 | */ 47 | double statisticsStandardDeviation(const double* data, size_t numPoints, double mean); 48 | 49 | /** 50 | * Finds the largest value in the array. 51 | */ 52 | double statisticsMax(const double* data, size_t numPoints); 53 | size_t statisticsMaxInt(const size_t* data, size_t numPoints); 54 | 55 | /** 56 | * Finds the smallest value in the array. 57 | */ 58 | double statisticsMin(const double* data, size_t numPoints); 59 | size_t statisticsMinInt(const size_t* data, size_t numPoints); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /c/Vector.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "Vector.h" 28 | 29 | VectorPtr vectorCreate(size_t size) 30 | { 31 | VectorPtr vector = (VectorPtr)malloc(sizeof(Vector)); 32 | if (vector) 33 | { 34 | vector->size = size; 35 | vector->data = (double*)malloc(sizeof(double) * size); 36 | } 37 | return vector; 38 | } 39 | 40 | void vectorDestroy(VectorPtr vector) 41 | { 42 | if (vector != NULL) 43 | { 44 | free((void*)vector->data); 45 | free((void*)vector); 46 | } 47 | } 48 | 49 | void vectorCopy(const VectorPtr A, const VectorPtr B) 50 | { 51 | memcpy((void *)A->data, (void *)B->data, sizeof(double) * B->size); 52 | } 53 | 54 | double vectorMultiply(const VectorPtr A, const VectorPtr B) 55 | { 56 | register size_t i; 57 | double C = 0; 58 | 59 | for (i = 0; i < A->size; ++i) 60 | C += A->data[i] * B->data[i]; 61 | return C; 62 | } 63 | 64 | void vectorSubtract(const VectorPtr A, const VectorPtr B, VectorPtr C) 65 | { 66 | register size_t i; 67 | 68 | for (i = 0; i < A->size; ++i) 69 | C->data[i] = A->data[i] - B->data[i]; 70 | } 71 | 72 | double vectorDot(const VectorPtr A, const VectorPtr B) 73 | { 74 | register size_t i; 75 | double result = 0.0; 76 | 77 | for (i = 0; i < A->size; ++i) 78 | result += (A->data[i] * B->data[i]); 79 | return result; 80 | } 81 | 82 | double vectorLength(const VectorPtr A) 83 | { 84 | register size_t i; 85 | double sum = 0.0; 86 | 87 | for (i = 0; i < A->size; ++i) 88 | sum += (A->data[i] * A->data[i]); 89 | return (sqrt(sum)); 90 | } 91 | 92 | void vectorNormalize(VectorPtr A) 93 | { 94 | register size_t i; 95 | double norm; 96 | 97 | norm = vectorLength(A); 98 | for (i = 0; i < A->size; ++i) 99 | A->data[i] = A->data[i] / norm; 100 | } 101 | 102 | void vectorCross(const VectorPtr A, const VectorPtr B, VectorPtr C) 103 | { 104 | C->data[0] = (B->data[1] * A->data[2]) - (B->data[2] * A->data[1]); 105 | C->data[1] = (B->data[2] * A->data[0]) - (B->data[0] * A->data[2]); 106 | C->data[2] = (B->data[0] * A->data[1]) - (B->data[1] * A->data[0]); 107 | } 108 | 109 | void vectorPrint(VectorPtr A) 110 | { 111 | register size_t i; 112 | 113 | printf("["); 114 | for (i = 0; i < A->size; ++i) 115 | printf("%s%lf", i > 0 ? " " : "", A->data[i]); 116 | printf("]\n"); 117 | } 118 | -------------------------------------------------------------------------------- /c/Vector.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _VECTOR_ 25 | #define _VECTOR_ 26 | 27 | typedef struct Vector 28 | { 29 | double* data; 30 | size_t size; 31 | } Vector; 32 | typedef Vector* VectorPtr; 33 | 34 | /** 35 | * Returns a vector of the specified size. 36 | */ 37 | VectorPtr vectorCreate(size_t size); 38 | 39 | /** 40 | * Destroys a vector of the specified size. 41 | */ 42 | void vectorDestroy(VectorPtr vector); 43 | 44 | /** 45 | * Returns a copy of vector B in vector A. 46 | */ 47 | void vectorCopy(const VectorPtr A, const VectorPtr B); 48 | 49 | /** 50 | * Returns C = A x B, where A and B are vectors and C is a scalar. 51 | */ 52 | double vectorMultiply(const VectorPtr A, const VectorPtr B); 53 | 54 | /** 55 | * Returns C = A - B, where A, B, and C are vectors. 56 | */ 57 | void vectorSubtract(const VectorPtr A, const VectorPtr B, VectorPtr C); 58 | 59 | /** 60 | * Returns the dot product of A and B, where A and B are vectors. 61 | */ 62 | double vectorDot(const VectorPtr A, const VectorPtr B); 63 | 64 | /** 65 | * Computes the length of the vector A. 66 | */ 67 | double vectorLength(const VectorPtr A); 68 | 69 | /** 70 | * Normalizes vector A. 71 | */ 72 | void vectorNormalize(VectorPtr A); 73 | 74 | /** 75 | * Returns C = A x B, where A, B, and C are 3x3 vectors. 76 | */ 77 | void vectorCross(const VectorPtr A, const VectorPtr B, VectorPtr C); 78 | 79 | /** 80 | * Prints the contents of vector A to stdout. 81 | */ 82 | void vectorPrint(VectorPtr A); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /c/libmath.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /c/libmath.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /c/main.c: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | 25 | #include "Distance.h" 26 | #include "KMeans.h" 27 | #include "Powers.h" 28 | #include "Signals.h" 29 | #include "SquareMatrix.h" 30 | #include "Statistics.h" 31 | #include "Vector.h" 32 | 33 | void vectorTests() 34 | { 35 | printf("Vector Tests:\n"); 36 | printf("-------------\n"); 37 | 38 | VectorPtr v1 = vectorCreate(3); 39 | VectorPtr v2 = vectorCreate(3); 40 | v1->data[0] = 1; v1->data[1] = 2; v1->data[2] = 3; 41 | v2->data[0] = 1; v2->data[1] = 2; v2->data[2] = 3; 42 | printf("v1:\n"); 43 | vectorPrint(v1); 44 | printf("v2:\n"); 45 | vectorPrint(v2); 46 | printf("v1 x v2 = %lf\n", vectorMultiply(v1, v2)); 47 | printf("v1 dot v2 = %lf\n", vectorDot(v1, v2)); 48 | printf("length of v1 = %lf\n", vectorLength(v1)); 49 | vectorDestroy(v1); 50 | vectorDestroy(v2); 51 | } 52 | 53 | void squareMatrixTests() 54 | { 55 | printf("\nSquare Matrix Tests:\n"); 56 | printf("--------------------\n"); 57 | 58 | SquareMatrixPtr m = squareMatrixCreate(5); 59 | squareMatrixIdentity(m); 60 | printf("Identity matrix:\n"); 61 | squareMatrixPrint(m); 62 | squareMatrixDestroy(m); 63 | 64 | m = squareMatrixCreate(5); 65 | squareMatrixZero(m); 66 | printf("Zero matrix:\n"); 67 | squareMatrixPrint(m); 68 | squareMatrixOnes(m); 69 | printf("Ones matrix:\n"); 70 | squareMatrixPrint(m); 71 | squareMatrixMultiplyByScalar(m, 2.0); 72 | printf("Ones matrix multiplied by 2.0:\n"); 73 | squareMatrixPrint(m); 74 | squareMatrixDestroy(m); 75 | } 76 | 77 | void statisticsTests() 78 | { 79 | printf("Statistics Tests:\n"); 80 | printf("-----------------\n"); 81 | 82 | long v_int[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 83 | double v_int_avg = statisticsAverageLong(v_int, 9); 84 | printf("Average: %lf\n", v_int_avg); 85 | assert(v_int_avg == 5.0); 86 | 87 | double v_flt[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; 88 | double v_flt_avg = statisticsAverageDouble(v_flt, 9); 89 | printf("Average: %lf\n", v_flt_avg); 90 | assert(v_flt_avg == 5.0); 91 | 92 | double variance = statisticsVariance(v_flt, 9, v_flt_avg); 93 | printf("Variance: %lf\n", variance); 94 | assert(variance == 7.5); 95 | 96 | printf("Standard Deviation: %lf\n", statisticsStandardDeviation(v_flt, 9, v_flt_avg)); 97 | double max = statisticsMax(v_flt, 9); 98 | printf("Max: %lf\n", max); 99 | assert(max == 9.0); 100 | 101 | double min = statisticsMin(v_flt, 9); 102 | printf("Min: %lf\n\n", min); 103 | assert(min == 1.0); 104 | } 105 | 106 | void signalsTests() 107 | { 108 | printf("Signals Tests:\n"); 109 | printf("--------------\n"); 110 | 111 | double inData[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; 112 | size_t inDataLen = 9; 113 | size_t windowSize = 2; 114 | double* outData = smooth(inData, inDataLen, windowSize); 115 | 116 | printf("["); 117 | for (size_t i = 0; i < inDataLen - windowSize; ++i) 118 | { 119 | printf("%lf ", outData[i]); 120 | } 121 | printf("]\n\n"); 122 | } 123 | 124 | void powerTests() 125 | { 126 | printf("Power Tests:\n"); 127 | printf("------------\n"); 128 | 129 | unsigned long nearest = NearestPowerOf2(63); 130 | printf("Nearest power of 2 for 63 is %ld.\n\n", nearest); 131 | assert(nearest == 64); 132 | } 133 | 134 | void distanceTests() 135 | { 136 | printf("Distance Tests:\n"); 137 | printf("---------------\n"); 138 | 139 | size_t distance = hammingDistance("1011101", "1001001"); 140 | printf("Hamming Distance: %zu\n", distance); 141 | assert(distance == 2); 142 | 143 | distance = levenshteinDistance("foo", "foobar"); 144 | printf("Levenshtein Distance: %zu\n\n", distance); 145 | assert(distance == 3); 146 | } 147 | 148 | void kmeansTests() 149 | { 150 | printf("K-Means Tests:\n"); 151 | printf("--------------\n"); 152 | 153 | double kMeansIn[10]; 154 | kMeansIn[0] = 7.123; 155 | kMeansIn[1] = 0.999; 156 | kMeansIn[2] = 0.001; 157 | kMeansIn[3] = 0.5; 158 | kMeansIn[4] = 0.75; 159 | kMeansIn[5] = 0.002; 160 | kMeansIn[6] = 3.0; 161 | kMeansIn[7] = 2.0; 162 | kMeansIn[8] = 5.0; 163 | kMeansIn[9] = 0.001; 164 | size_t* tags = kMeansEquallySpacedCentroids1D(kMeansIn, 10, 3, (double)0.001, 3); 165 | if (tags) 166 | { 167 | for (size_t i = 0; i < 10; ++i) 168 | { 169 | printf("%zu\n", tags[i]); 170 | } 171 | free((void*)tags); 172 | } 173 | } 174 | 175 | int main(int argc, const char * argv[]) 176 | { 177 | vectorTests(); 178 | squareMatrixTests(); 179 | statisticsTests(); 180 | signalsTests(); 181 | powerTests(); 182 | distanceTests(); 183 | kmeansTests(); 184 | return 0; 185 | } 186 | -------------------------------------------------------------------------------- /cpp/BigInt.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "BigInt.h" 28 | 29 | namespace LibMath 30 | { 31 | BigInt::BigInt() 32 | { 33 | init(2048); 34 | } 35 | 36 | BigInt::BigInt(uint32_t bits) 37 | { 38 | init(bits); 39 | } 40 | 41 | BigInt::~BigInt() 42 | { 43 | free(); 44 | } 45 | 46 | void BigInt::init(uint32_t bits) 47 | { 48 | m_numBits = bits; 49 | m_numWords = m_numBits / sizeof(m_numWords); 50 | if (m_numWords % sizeof(m_numWords) > 0) 51 | ++m_numWords; 52 | m_data = new uint32_t[m_numWords]; 53 | m_error = BIG_INT_NO_ERROR; 54 | } 55 | 56 | void BigInt::free() 57 | { 58 | if (m_data) 59 | { 60 | memset(m_data, 0, m_numWords * sizeof(uint32_t)); 61 | delete[] m_data; 62 | m_data = NULL; 63 | m_error = BIG_INT_NO_ERROR; 64 | } 65 | } 66 | 67 | void BigInt::clear() 68 | { 69 | if (m_data) 70 | { 71 | memset(m_data, 0, m_numWords * sizeof(uint32_t)); 72 | m_error = BIG_INT_NO_ERROR; 73 | } 74 | } 75 | 76 | void BigInt::set(uint32_t n) 77 | { 78 | clear(); 79 | m_data[0] = n; 80 | } 81 | 82 | void BigInt::setMax() 83 | { 84 | for (size_t i = 0; i < m_numWords; ++i) 85 | { 86 | m_data[i] = (uint32_t)-1; 87 | } 88 | } 89 | 90 | void BigInt::setRand() 91 | { 92 | std::random_device rd; 93 | std::mt19937 gen(rd()); 94 | std::uniform_int_distribution dis(0, (uint32_t)-1); 95 | 96 | for (size_t i = 0; i < m_numWords; ++i) 97 | { 98 | m_data[i] = (uint32_t)dis(gen); 99 | } 100 | } 101 | 102 | uint32_t BigInt::addWords(uint32_t& a, uint32_t b) 103 | { 104 | uint32_t headroom = (uint32_t)-1 - b - 1; 105 | 106 | if (a <= headroom) 107 | { 108 | a += b; 109 | return 0; 110 | } 111 | 112 | a = (uint32_t)-1; 113 | return b - headroom; 114 | } 115 | 116 | uint32_t BigInt::subWords(uint32_t& a, uint32_t b) 117 | { 118 | if (b < a) 119 | { 120 | a -= b; 121 | return 0; 122 | } 123 | 124 | a = (uint32_t)((uint64_t)0x100000000 - (uint64_t)b); 125 | return 1; 126 | } 127 | 128 | void BigInt::add(const BigInt& n) 129 | { 130 | if (n.numBits() != m_numBits) 131 | return; 132 | 133 | uint32_t carry = 0; 134 | 135 | for (size_t i = 0; i < m_numWords; ++i) 136 | { 137 | carry += addWords(m_data[i], carry); 138 | carry += addWords(m_data[i], n.m_data[i]); 139 | } 140 | if (carry) // Overflow 141 | { 142 | m_error = BIG_INT_OVERFLOW; 143 | } 144 | } 145 | 146 | void BigInt::subtract(const BigInt& n) 147 | { 148 | if (n.numBits() != m_numBits) 149 | return; 150 | 151 | uint32_t borrow = 0; 152 | 153 | for (size_t i = 0; i < m_numWords; ++i) 154 | { 155 | if (borrow) 156 | { 157 | m_data[i] -= 1; 158 | } 159 | borrow = subWords(m_data[i], n.m_data[i]); 160 | } 161 | if (borrow) // Underflow 162 | { 163 | m_error = BIG_INT_UNDERFLOW; 164 | } 165 | } 166 | 167 | void BigInt::multiply(uint32_t n) 168 | { 169 | uint32_t carry = 0; 170 | 171 | for (size_t i = 0; i < m_numWords; ++i) 172 | { 173 | uint64_t temp = n * (uint64_t)m_data[i] + carry; 174 | m_data[i] = (uint32_t)temp; 175 | carry = temp >> 32; 176 | } 177 | if (carry) // Overflow 178 | { 179 | m_error = BIG_INT_OVERFLOW; 180 | } 181 | } 182 | 183 | void BigInt::multiply(const BigInt& n) 184 | { 185 | for (size_t i = 0; i < m_numWords; ++i) 186 | { 187 | } 188 | } 189 | 190 | void BigInt::divide(const BigInt& n) 191 | { 192 | for (size_t i = 0; i < m_numWords; ++i) 193 | { 194 | } 195 | } 196 | 197 | bool BigInt::compare(const BigInt& n) const 198 | { 199 | if (n.numBits() != m_numBits) 200 | return false; 201 | 202 | for (size_t i = 0; i < m_numWords; ++i) 203 | { 204 | if (m_data[i] != n.m_data[i]) 205 | return false; 206 | } 207 | return true; 208 | } 209 | 210 | bool BigInt::isPrime() const 211 | { 212 | return false; 213 | } 214 | 215 | std::string BigInt::toString() const 216 | { 217 | std::ostringstream strStream; 218 | 219 | strStream << "0x"; 220 | for (size_t i = m_numWords - 1; i > 0; --i) 221 | { 222 | strStream << std::setfill('0') << std::setw(8) << std::hex << m_data[i]; 223 | } 224 | strStream << std::setfill('0') << std::setw(8) << std::hex << m_data[0]; 225 | return strStream.str(); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /cpp/BigInt.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _BIGINT_ 25 | #define _BIGINT_ 26 | 27 | #include 28 | #include 29 | 30 | namespace LibMath 31 | { 32 | typedef enum BigIntError 33 | { 34 | BIG_INT_NO_ERROR = 0, 35 | BIG_INT_OVERFLOW, 36 | BIG_INT_UNDERFLOW 37 | } BigIntError; 38 | 39 | class BigInt 40 | { 41 | public: 42 | BigInt(); 43 | BigInt(uint32_t bits); 44 | virtual ~BigInt(); 45 | 46 | bool operator==(const BigInt& rhs) const { return compare(rhs); } 47 | BigInt& operator+=(const BigInt& rhs) { add(rhs); return *this; } 48 | BigInt& operator-=(const BigInt& lhs) { subtract(lhs); return *this; } 49 | BigInt& operator*=(const BigInt& lhs) { multiply(lhs); return *this; } 50 | BigInt& operator/=(const BigInt& lhs) { divide(lhs); return *this; } 51 | 52 | uint32_t numBits() const { return m_numBits; } 53 | 54 | void clear(); 55 | void set(uint32_t n); 56 | void setMax(); 57 | void setRand(); 58 | void add(const BigInt& n); 59 | void subtract(const BigInt& n); 60 | void multiply(uint32_t n); 61 | void multiply(const BigInt& n); 62 | void divide(const BigInt& n); 63 | 64 | bool compare(const BigInt& n) const; 65 | bool isPrime() const; 66 | 67 | std::string toString() const; 68 | 69 | private: 70 | uint32_t m_numBits; 71 | uint32_t m_numWords; 72 | uint32_t* m_data; // m_data[0] is least significant, m_data[m_numWords - 1] is most significant 73 | BigIntError m_error; 74 | 75 | void init(uint32_t bits); 76 | void free(); 77 | 78 | uint32_t addWords(uint32_t& a, uint32_t b); 79 | uint32_t subWords(uint32_t& a, uint32_t b); 80 | }; 81 | } 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18.1) 2 | 3 | project(libmath VERSION 1.0.0 DESCRIPTION "libmath") 4 | include_directories(${PROJECT_SOURCE_DIR}) 5 | add_library(${PROJECT_NAME} SHARED 6 | BigInt.cpp 7 | Calculus.cpp 8 | Distance.cpp 9 | Double.cpp 10 | Graphics.cpp 11 | KMeans.cpp 12 | Matrix.cpp 13 | Peaks.cpp 14 | Powers.cpp 15 | Prime.cpp 16 | Signals.cpp 17 | SquareMatrix.cpp 18 | Statistics.cpp 19 | Vector.cpp 20 | main.cpp) 21 | target_link_libraries(${PROJECT_NAME} "-pie -Wl,-E") 22 | set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE 1) 23 | -------------------------------------------------------------------------------- /cpp/Calculus.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2019 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Calculus.h" 23 | 24 | namespace LibMath 25 | { 26 | void derivative(double* in, double* out, size_t inLen, size_t spacing) 27 | { 28 | if (spacing >= 1) 29 | { 30 | for (size_t i = 0; i < inLen - spacing; i += spacing) 31 | { 32 | out[i] = (in[i + spacing] - in[i]) / spacing; 33 | } 34 | } 35 | } 36 | 37 | std::vector derivative(std::vector in, size_t spacing) 38 | { 39 | std::vector result; 40 | 41 | if (spacing >= 1) 42 | { 43 | auto iter = in.begin(); 44 | double lastY = (*iter); 45 | std::next(iter, spacing); 46 | 47 | while (iter != in.end()) 48 | { 49 | double currY = (*iter); 50 | double val = (currY - lastY) / (double)spacing; 51 | result.push_back(val); 52 | std::next(iter, spacing); 53 | } 54 | } 55 | return result; 56 | } 57 | 58 | double integral(double* data, size_t dataLen) 59 | { 60 | double area = (double)0.0; 61 | 62 | if (dataLen > 1) 63 | { 64 | for (size_t i = 1; i < dataLen; ++i) 65 | { 66 | double b = data[i] + data[i - 1]; 67 | area += ((double)0.5 * b); 68 | } 69 | } 70 | return area; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /cpp/Calculus.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2019 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _CALCULUS_ 25 | #define _CALCULUS_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class Calculus 32 | { 33 | public: 34 | /** 35 | * Computes the deriviative of the input line. 36 | */ 37 | static void derivative(double* in, double* out, size_t inLen, size_t spacing); 38 | static std::vector derivative(std::vector in, size_t spacing); 39 | 40 | /** 41 | * Computes the integral of the input line. 42 | */ 43 | static double integral(double* data, size_t dataLen); 44 | }; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cpp/Distance.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Distance.h" 23 | #include "Statistics.h" 24 | #include 25 | #include 26 | 27 | namespace LibMath 28 | { 29 | double Distance::toRad(double deg) 30 | { 31 | const double pi = (double)(3.141592653589793238); 32 | return deg * (pi / (double)(180.0)); 33 | } 34 | 35 | double Distance::haversineDistance(double loc1_lat, double loc1_lon, double loc1_alt, double loc2_lat, double loc2_lon, double loc2_alt) 36 | { 37 | double R = (double)6372797.560856; // radius of the earth in meters 38 | R += loc2_alt - loc1_alt; 39 | 40 | double latArc = toRad(loc1_lat - loc2_lat); 41 | double lonArc = toRad(loc1_lon - loc2_lon); 42 | 43 | double latH = sin(latArc * (double)0.5); 44 | latH *= latH; 45 | 46 | double lonH = sin(lonArc * (double)0.5); 47 | lonH *= lonH; 48 | 49 | double tmp = cos(toRad(loc1_lat)) * cos(toRad(loc2_lat)); 50 | double rad = (double)2.0 * asin(sqrt(latH + tmp * lonH)); 51 | 52 | return rad * R; 53 | } 54 | 55 | size_t Distance::hammingDistance(const char* str1, const char* str2) 56 | { 57 | size_t len1 = strlen(str1); 58 | 59 | // The strings must be the same length. 60 | if (len1 != strlen(str2)) 61 | return (size_t)-1; 62 | 63 | size_t distance = 0; 64 | 65 | for (size_t i = 0; i < len1; ++i) 66 | { 67 | if (str1[i] != str2[i]) 68 | ++distance; 69 | } 70 | return distance; 71 | } 72 | 73 | size_t Distance::levenshteinDistance(const char* str1, const char* str2) 74 | { 75 | size_t m = strlen(str1); 76 | size_t n = strlen(str2); 77 | 78 | // Test for empty strings. 79 | if (m == 0) 80 | return n; 81 | if (n == 0) 82 | return m; 83 | 84 | // Temp vectors. 85 | size_t vecSize = sizeof(size_t) * n; 86 | size_t* v0 = (size_t*)malloc(vecSize); 87 | if (!v0) 88 | { 89 | return (size_t)-1; 90 | } 91 | size_t* v1 = (size_t*)malloc(vecSize); 92 | if (!v1) 93 | { 94 | free((void*)v0); 95 | return (size_t)-1; 96 | } 97 | size_t* tempV = (size_t*)malloc(vecSize); 98 | if (!tempV) 99 | { 100 | free((void*)v0); 101 | free((void*)v1); 102 | return (size_t)-1; 103 | } 104 | 105 | for (size_t i = 0; i < n; ++i) 106 | { 107 | v0[i] = i; 108 | } 109 | for (size_t i = 0; i < m - 1; ++i) 110 | { 111 | v1[0] = i + 1; 112 | 113 | for (size_t j = 0; j < n - 1; ++j) 114 | { 115 | size_t costs[3]; // deletion, insertion, and substitution costs (in that order) 116 | costs[0] = v0[j + 1] + 1; 117 | costs[1] = v1[j] + 1; 118 | if (str1[i] == str2[j]) 119 | costs[2] = v0[j]; 120 | else 121 | costs[2] = v0[j] + 1; 122 | v1[j + 1] = Statistics::min(costs, 3); 123 | } 124 | 125 | // Copy v1 to v0. 126 | memcpy(tempV, v0, vecSize); 127 | memcpy(v0, v1, vecSize); 128 | memcpy(v1, tempV, vecSize); 129 | } 130 | 131 | // Save the final distance calculation, before freeing the vector. 132 | size_t distance = v0[n - 1]; 133 | 134 | // Clean up. 135 | free((void*)v0); 136 | free((void*)v1); 137 | free((void*)tempV); 138 | 139 | return distance; 140 | } 141 | 142 | double Distance::euclidianDistance1D(double pt1, double pt2) 143 | { 144 | return fabs(pt1 - pt2); 145 | } 146 | 147 | double Distance::euclidianDistance2D(double pt1X, double pt1Y, double pt2X, double pt2Y) 148 | { 149 | double tempX = pt2X - pt1X; 150 | double tempY = pt2Y - pt1Y; 151 | return sqrt((tempX * tempX) + (tempY * tempY)); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /cpp/Distance.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _DISTANCE_ 25 | #define _DISTANCE_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class Distance 32 | { 33 | public: 34 | /** 35 | * Computes the Haversine distance between two points on Earth's surface. 36 | */ 37 | static double haversineDistance(double loc1_lat, double loc1_lon, double loc1_alt, double loc2_lat, double loc2_lon, double loc2_alt); 38 | 39 | /** 40 | * Computes the Hamming distance of the strings. 41 | */ 42 | static size_t hammingDistance(const char* str1, const char* str2); 43 | 44 | /** 45 | * Computes the Levenshtein distance of str2 relative to str1. 46 | */ 47 | static size_t levenshteinDistance(const char* str1, const char* str2); 48 | 49 | /** 50 | * Computes the Euclidian distance between two points in a 1D space. 51 | */ 52 | static double euclidianDistance1D(double pt1, double pt2); 53 | 54 | /** 55 | * Computes the Euclidian distance between two points in a 2D space. 56 | */ 57 | static double euclidianDistance2D(double pt1X, double pt1Y, double pt2X, double pt2Y); 58 | 59 | private: 60 | static double toRad(double deg); 61 | }; 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /cpp/Double.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2019 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | 24 | bool roughlyEqual(double a, double b, double epsilon) 25 | { 26 | double absA = fabs(a); 27 | double absB = fabs(b); 28 | return fabs(a - b) <= ( (absA < absB ? absB : absA * epsilon) ); 29 | } 30 | -------------------------------------------------------------------------------- /cpp/Double.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2019 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _DOUBLE_ 25 | #define _DOUBLE_ 26 | 27 | bool roughlyEqual(double a, double b, double epsilon); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /cpp/Graphics.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2022 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Graphics.h" 23 | 24 | #include 25 | 26 | namespace LibMath 27 | { 28 | void QuadBezierFit2D(double in[][2], double out[][2], size_t numPoints, double t) 29 | { 30 | // Sanity check 31 | if (numPoints == 0) 32 | { 33 | return; 34 | } 35 | 36 | // If there's only one point, then just return it. 37 | if (numPoints == 1) 38 | { 39 | out[0][0] = in[0][0]; 40 | out[0][1] = in[0][1]; 41 | return; 42 | } 43 | 44 | // Copy the input matrix to the output matrix. 45 | memcpy(out, in, numPoints * sizeof(double) * 2); 46 | 47 | for (size_t i = numPoints - 1; i > 0; --i) 48 | { 49 | for (size_t j = 0; j < i; ++j) 50 | { 51 | out[j][0] = out[j][0] + t * (out[j + 1][0] - out[j][0]); 52 | out[j][1] = out[j][1] + t * (out[j + 1][1] - out[j][1]); 53 | } 54 | } 55 | } 56 | 57 | void QuadBezierFit3D(double in[][3], double out[][3], size_t numPoints, double t) 58 | { 59 | // Sanity check 60 | if (numPoints == 0) 61 | { 62 | return; 63 | } 64 | 65 | // If there's only one point, then just return it. 66 | if (numPoints == 1) 67 | { 68 | out[0][0] = in[0][0]; 69 | out[0][1] = in[0][1]; 70 | out[0][2] = in[0][2]; 71 | return; 72 | } 73 | 74 | // Copy the input matrix to the output matrix. 75 | memcpy(out, in, numPoints * sizeof(double) * 3); 76 | 77 | for (size_t i = numPoints - 1; i > 0; --i) 78 | { 79 | for (size_t j = 0; j < i; ++j) 80 | { 81 | out[j][0] = out[j][0] + t * (out[j + 1][0] - out[j][0]); 82 | out[j][1] = out[j][1] + t * (out[j + 1][1] - out[j][1]); 83 | out[j][2] = out[j][2] + t * (out[j + 1][2] - out[j][2]); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /cpp/Graphics.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2022 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _GRAPHICS_ 25 | #define _GRAPHICS_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | void QuadBezierFit2D(double in[][2], double out[][2], size_t numPoints, double t); 32 | void QuadBezierFit3D(double in[][3], double out[][3], size_t numPoints, double t); 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /cpp/KMeans.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "KMeans.h" 23 | #include "Distance.h" 24 | #include "Statistics.h" 25 | 26 | #include 27 | 28 | namespace LibMath 29 | { 30 | size_t* KMeans::kMeans1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters, double* centroids) 31 | { 32 | // Sanity check. 33 | if (k == 0) 34 | { 35 | return NULL; 36 | } 37 | 38 | // Create the output error array; describes the error for each data point. 39 | double* errors = (double*)new double[dataLen]; 40 | if (!errors) 41 | { 42 | return NULL; 43 | } 44 | 45 | // Create the cluster means array; describes the error for each data point. 46 | size_t* clusterSizes = (size_t*)new size_t[k]; 47 | if (!clusterSizes) 48 | { 49 | delete[] errors; 50 | return NULL; 51 | } 52 | 53 | // Create the output tag array. 54 | size_t* tags = (size_t*)new size_t[dataLen]; 55 | if (!tags) 56 | { 57 | delete[] clusterSizes; 58 | delete[] errors; 59 | return NULL; 60 | } 61 | 62 | // Assignment step. Find the closest centroid for each data point. 63 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 64 | { 65 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 66 | { 67 | double distance = Distance::euclidianDistance1D(data[dataIndex], centroids[clusterIndex]); 68 | if ((clusterIndex == 0) || (distance < errors[dataIndex])) 69 | { 70 | tags[dataIndex] = clusterIndex; 71 | errors[dataIndex] = distance; 72 | } 73 | } 74 | } 75 | 76 | // Update step. 77 | double avgError = (double)0.0; 78 | size_t iterCount = 0; 79 | size_t numRelocations = 0; 80 | do { 81 | // Recompute cluster means. 82 | memset(centroids, 0, sizeof(double) * k); 83 | memset(clusterSizes, 0, sizeof(size_t) * k); 84 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 85 | { 86 | size_t clusterIndex = tags[dataIndex]; 87 | centroids[clusterIndex] += data[dataIndex]; 88 | clusterSizes[clusterIndex]++; 89 | } 90 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 91 | { 92 | centroids[clusterIndex] /= clusterSizes[clusterIndex]; 93 | } 94 | 95 | // Measure each data point against it's own cluster mean, and all other cluster means. 96 | // Relocate the data point to the cluster that matches best. 97 | numRelocations = 0; 98 | for (size_t dataIndex = 0; dataIndex < dataLen; ++dataIndex) 99 | { 100 | for (size_t clusterIndex = 0; clusterIndex < k; ++clusterIndex) 101 | { 102 | double distance = Distance::euclidianDistance1D(data[dataIndex], centroids[clusterIndex]); 103 | if (distance < errors[dataIndex]) 104 | { 105 | tags[dataIndex] = clusterIndex; 106 | errors[dataIndex] = distance; 107 | ++numRelocations; 108 | } 109 | } 110 | } 111 | 112 | // Compute the average error. 113 | avgError = Statistics::averageDouble(errors, dataLen); 114 | 115 | ++iterCount; 116 | } while ((avgError > maxError) && (iterCount < maxIters) && (numRelocations > 0)); 117 | 118 | // Free memory. 119 | delete[] clusterSizes; 120 | delete[] errors; 121 | 122 | return tags; 123 | } 124 | 125 | size_t* KMeans::withEquallySpacedCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters) 126 | { 127 | // Sanity check. 128 | if (dataLen <= 1) 129 | { 130 | return NULL; 131 | } 132 | 133 | size_t* tags = NULL; 134 | 135 | double* centroids = (double*)new double[k]; 136 | if (centroids) 137 | { 138 | // Select the k data points that are farthest apart from each other. 139 | double min = Statistics::min(data, dataLen); 140 | centroids[0] = min; 141 | double max = Statistics::max(data, dataLen); 142 | centroids[k - 1] = max; 143 | double increment = (max - min) / (double)(k - 1); 144 | for (size_t i = 1; i < k - 1; ++i) 145 | { 146 | centroids[i] = min + (increment * (double)i); 147 | } 148 | 149 | // Perform K Means clustering. 150 | tags = kMeans1D(data, dataLen, k, maxError, maxIters, centroids); 151 | 152 | // Clean up. 153 | delete[] centroids; 154 | } 155 | 156 | return tags; 157 | } 158 | 159 | size_t* KMeans::withRandCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters) 160 | { 161 | // Sanity check. 162 | if (dataLen <= 1) 163 | { 164 | return NULL; 165 | } 166 | 167 | size_t* tags = NULL; 168 | 169 | double* centroids = (double*)new double[k]; 170 | if (centroids) 171 | { 172 | // Randomly select starting centroids. 173 | for (size_t i = 0; i < k; ++i) 174 | { 175 | size_t selected = rand() % k; 176 | centroids[i] = data[selected]; 177 | } 178 | 179 | // Perform K Means clustering. 180 | tags = kMeans1D(data, dataLen, k, maxError, maxIters, centroids); 181 | 182 | // Clean up. 183 | delete[] centroids; 184 | } 185 | 186 | return tags; 187 | } 188 | } 189 | 190 | -------------------------------------------------------------------------------- /cpp/KMeans.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _KMEANS_ 25 | #define _KMEANS_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class KMeans 32 | { 33 | public: 34 | /** 35 | * Performs K Means clustering on a one dimensional array, using the provided centroids. 36 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 37 | */ 38 | static size_t* kMeans1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters, double* clusters); 39 | 40 | /** 41 | * Performs K Means clustering on a one dimensional array, setting the initial centroids to the data points farthest apart. 42 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 43 | */ 44 | static size_t* withEquallySpacedCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters); 45 | 46 | /** 47 | * Performs K Means clustering on a one dimensional array, using random initial centroids. 48 | * Returns an array of length 'dataLen', that associates each input with a given cluster. 49 | */ 50 | static size_t* withRandCentroids1D(double* data, size_t dataLen, size_t k, double maxError, size_t maxIters); 51 | }; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /cpp/Matrix.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Matrix.h" 23 | 24 | #include 25 | 26 | namespace LibMath 27 | { 28 | Matrix::Matrix() 29 | { 30 | m_w = 0; 31 | m_h = 0; 32 | m_data = NULL; 33 | } 34 | 35 | Matrix::Matrix(size_t w, size_t h) 36 | { 37 | m_w = w; 38 | m_h = h; 39 | m_data = new double *[w]; 40 | for (auto i = 0; i < h; ++i) 41 | m_data[i] = new double[h]; 42 | } 43 | 44 | Matrix::~Matrix() 45 | { 46 | if (m_data != NULL) 47 | { 48 | for (auto i = 0; i < m_w; ++i) 49 | { 50 | delete m_data[i]; 51 | m_data[i] = NULL; 52 | } 53 | delete m_data; 54 | m_data = NULL; 55 | } 56 | } 57 | 58 | void Matrix::print(void) 59 | { 60 | if (m_data != NULL) 61 | { 62 | for (auto i = 0; i < m_w; ++i) 63 | { 64 | std::cout << "[ "; 65 | for (auto j = 0; j < m_h; ++j) 66 | { 67 | std::cout << m_data[i][j] << " "; 68 | } 69 | std::cout << "]" << std::endl; 70 | } 71 | std::cout << std::endl; 72 | } 73 | } 74 | 75 | void Matrix::multiply(const Matrix* B, Vector* C) 76 | { 77 | for (auto i = 0; i < m_w; ++i) 78 | { 79 | for (auto j = 0; j < m_h; ++j) 80 | { 81 | C->m_data[i] = this->m_data[i][j] * B->m_data[j][i]; 82 | } 83 | } 84 | } 85 | 86 | void Matrix::multiply(double B) 87 | { 88 | for (auto i = 0; i < m_w; ++i) 89 | { 90 | for (auto j = 0; j < m_h; ++j) 91 | { 92 | m_data[i][j] *= B; 93 | } 94 | } 95 | } 96 | 97 | void Matrix::subtract(const Matrix* B, Matrix* C) 98 | { 99 | for (auto i = 0; i < m_w; ++i) 100 | { 101 | for (auto j = 0; j < m_h; ++j) 102 | { 103 | C->m_data[i][j] = this->m_data[i][j] - B->m_data[i][j]; 104 | } 105 | } 106 | } 107 | 108 | void Matrix::subtract(double B) 109 | { 110 | for (auto i = 0; i < m_w; ++i) 111 | { 112 | for (auto j = 0; j < m_h; ++j) 113 | { 114 | m_data[i][j] -= B; 115 | } 116 | } 117 | } 118 | 119 | void Matrix::zero(void) 120 | { 121 | for (auto i = 0; i < m_w; ++i) 122 | { 123 | for (auto j = 0; j < m_h; ++j) 124 | { 125 | m_data[i][j] = 0.0; 126 | } 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /cpp/Matrix.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _MATRIX_ 25 | #define _MATRIX_ 26 | 27 | #include 28 | #include "Vector.h" 29 | 30 | namespace LibMath 31 | { 32 | class Matrix 33 | { 34 | public: 35 | Matrix(size_t w, size_t h); 36 | virtual ~Matrix(void); 37 | 38 | /** 39 | * Prints the matrix to standard out. Intended for testing and debugging. 40 | */ 41 | void print(void); 42 | 43 | /** 44 | * Returns the width of the matrix. 45 | */ 46 | size_t width(void) const { return m_w; } 47 | 48 | /** 49 | * Returns the height of the matrix. 50 | */ 51 | size_t height(void) const { return m_h; } 52 | 53 | /** 54 | * Sets the value of the specified element. 55 | */ 56 | void set(size_t i, size_t j, double value) { m_data[i][j] = value; } 57 | 58 | /** 59 | * Returns C = A x B, where A is a matrix and B and C are vectors. 60 | */ 61 | void multiply(const Matrix* B, Vector* C); 62 | 63 | /** 64 | * Multiplies the matrix by the supplied scalar. 65 | */ 66 | void multiply(double B); 67 | 68 | /** 69 | * Returns C = A - B, where A, B, and C are matrices. 70 | */ 71 | void subtract(const Matrix* B, Matrix* C); 72 | 73 | /** 74 | * Subtracts the scalar from the matrix. 75 | */ 76 | void subtract(double B); 77 | 78 | /** 79 | * Sets the value of this matrix to the zero matrix. 80 | */ 81 | void zero(void); 82 | 83 | protected: 84 | size_t m_w; 85 | size_t m_h; 86 | double** m_data; 87 | 88 | protected: 89 | Matrix(); 90 | }; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /cpp/Peaks.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _PEAKS_ 25 | #define _PEAKS_ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "Double.h" 32 | 33 | namespace LibMath 34 | { 35 | /** 36 | * Defines a point. X values are integers. Y values are floating point. 37 | */ 38 | class GraphPoint 39 | { 40 | public: 41 | uint64_t x; 42 | double y; 43 | 44 | GraphPoint() { x = 0; y = (double)0.0; } 45 | GraphPoint(uint64_t newX, double newY) { x = newX; y = newY; } 46 | GraphPoint(const GraphPoint& rhs) { x = rhs.x; y = rhs.y; } 47 | 48 | GraphPoint& operator=(const GraphPoint& rhs) 49 | { 50 | x = rhs.x; 51 | y = rhs.y; 52 | return *this; 53 | } 54 | 55 | bool operator==(const GraphPoint& rhs) const 56 | { 57 | bool xEqual = roughlyEqual(x, rhs.x, (double)0.0001); 58 | bool yEqual = roughlyEqual(y, rhs.y, (double)0.0001); 59 | return xEqual && yEqual; 60 | } 61 | 62 | void clear() 63 | { 64 | x = 0; 65 | y = (double)0.0; 66 | } 67 | }; 68 | 69 | /** 70 | * List of points. 71 | */ 72 | typedef std::vector GraphLine; 73 | 74 | /** 75 | * Defines a peak. A peak is described by three points: a left trough, a peak, and a right trough. 76 | */ 77 | class GraphPeak 78 | { 79 | public: 80 | GraphPoint leftTrough; 81 | GraphPoint peak; 82 | GraphPoint rightTrough; 83 | double area; 84 | 85 | GraphPeak() { clear(); } 86 | 87 | GraphPeak(const GraphPeak& rhs) 88 | { 89 | leftTrough = rhs.leftTrough; 90 | peak = rhs.peak; 91 | rightTrough = rhs.rightTrough; 92 | area = rhs.area; 93 | } 94 | 95 | GraphPeak& operator=(const GraphPeak& rhs) 96 | { 97 | leftTrough = rhs.leftTrough; 98 | peak = rhs.peak; 99 | rightTrough = rhs.rightTrough; 100 | area = rhs.area; 101 | return *this; 102 | } 103 | 104 | bool operator==(const GraphPeak& rhs) const 105 | { 106 | return (leftTrough == rhs.leftTrough) && (peak == rhs.peak) && (rightTrough == rhs.rightTrough); 107 | } 108 | 109 | bool operator < (const GraphPeak& rhs) const { return (area < rhs.area); } 110 | bool operator > (const GraphPeak& rhs) const { return (area > rhs.area); } 111 | 112 | void clear() 113 | { 114 | leftTrough.clear(); 115 | peak.clear(); 116 | rightTrough.clear(); 117 | area = (double)0.0; 118 | } 119 | }; 120 | 121 | /** 122 | * List of peaks. 123 | */ 124 | typedef std::vector GraphPeakList; 125 | 126 | /** 127 | * Collection of peak finding algorithms. 128 | */ 129 | class Peaks 130 | { 131 | public: 132 | /** 133 | * Returns a list of all statistically significant peaks in the given waveform. 134 | * These are defined as peaks that rise more than one standard deviation above the mean for at least three points on the x axis. 135 | */ 136 | static GraphPeakList findPeaks(double* data, size_t dataLen, size_t* numPeaks, double sigmas = 1.0); 137 | static GraphPeakList findPeaks(const std::vector& data, double sigmas = 1.0); 138 | static GraphPeakList findPeaks(const GraphLine& data, double sigmas = 1.0); 139 | static GraphPeakList findPeaksOfSize(const GraphLine& data, double minPeakArea, double sigmas = 1.0); 140 | 141 | private: 142 | static double average(const GraphLine& data); 143 | static double variance(const GraphLine& data, double mean); 144 | static double standardDeviation(const GraphLine& data, double mean); 145 | 146 | static void computeArea(double* data, size_t dataLen, GraphPeak& currentPeak); 147 | static void computeArea(const std::vector& data, GraphPeak& currentPeak); 148 | static void computeArea(const GraphLine& data, GraphPeak& currentPeak); 149 | }; 150 | } 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /cpp/Powers.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2011 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Powers.h" 23 | 24 | namespace LibMath 25 | { 26 | unsigned long NearestPowerOf2(unsigned long num) 27 | { 28 | unsigned long n = num > 0 ? num - 1 : 0; 29 | 30 | n |= n >> 1; 31 | n |= n >> 2; 32 | n |= n >> 4; 33 | n |= n >> 8; 34 | n |= n >> 16; 35 | n++; 36 | 37 | return n; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cpp/Powers.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2011 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _POWERS_ 25 | #define _POWERS_ 26 | 27 | namespace LibMath 28 | { 29 | unsigned long NearestPowerOf2(unsigned long num); 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /cpp/Prime.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Prime.h" 23 | #include 24 | #include 25 | 26 | namespace LibMath 27 | { 28 | uint64_t Prime::gcd(uint64_t a, uint64_t b) 29 | { 30 | if (a == 0) 31 | return b; 32 | if (b == 0) 33 | return a; 34 | uint64_t r = a % b; 35 | return gcd(b, r); 36 | } 37 | 38 | uint64_t Prime::randOdd(uint64_t a) 39 | { 40 | size_t b = rand() % (a - 2); 41 | if ((b & 1) == 0) 42 | ++b; 43 | return b; 44 | } 45 | 46 | uint64_t Prime::generateCoprime(uint64_t a) 47 | { 48 | while (true) 49 | { 50 | size_t b = 1 + randOdd(a - 1); // random number between 1 and a - 1 51 | if ((b & 1) == 0) 52 | ++b; 53 | if (gcd(a, b) == 1) 54 | return b; 55 | } 56 | return 1; 57 | } 58 | 59 | bool Prime::isPrimeFermat(uint64_t num) 60 | { 61 | // If the first test succeeds, then do a second test, 62 | // to make sure we don't have a Fermat liar. 63 | for (size_t i = 0; i < 2; ++i) 64 | { 65 | size_t n = generateCoprime(num); 66 | uint64_t temp = pow(n, num - 1); 67 | if (temp % num != 1) 68 | return false; 69 | } 70 | 71 | return true; 72 | } 73 | 74 | bool Prime::isPrimeMillerRabin(uint64_t num) 75 | { 76 | // size_t a = 2 + rand() % (num - 4); // random int in range [2, num - 2] 77 | return false; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /cpp/Prime.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _PRIME_ 25 | #define _PRIME_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class Prime 32 | { 33 | public: 34 | static uint64_t gcd(uint64_t a, uint64_t b); 35 | static uint64_t randOdd(uint64_t a); 36 | static uint64_t generateCoprime(uint64_t num); 37 | static bool isPrimeFermat(uint64_t num); 38 | static bool isPrimeMillerRabin(uint64_t num); 39 | }; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /cpp/Signals.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2020 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include "Signals.h" 23 | #include "Statistics.h" 24 | 25 | namespace LibMath 26 | { 27 | size_t Signals::smooth(const double* inData, double* outData, size_t numPointsIn, size_t windowSize) 28 | { 29 | size_t outDataLen = numPointsIn - windowSize + 1; 30 | if (outDataLen <= 0) 31 | return 0; 32 | 33 | size_t i = 0; 34 | for (; i < outDataLen && i < numPointsIn; ++i) 35 | { 36 | double val = Statistics::averageDouble(inData + i, windowSize); 37 | outData[i] = val; 38 | } 39 | return i; 40 | } 41 | 42 | std::vector Signals::smooth(const std::vector& inData, size_t windowSize) 43 | { 44 | std::vector outData; 45 | 46 | size_t outDataLen = inData.size() - windowSize + 1; 47 | if (outDataLen <= 0) 48 | return outData; 49 | 50 | size_t i = 0; 51 | for (auto iter = inData.begin(); i < outDataLen && iter != inData.end(); ++i, ++iter) 52 | { 53 | std::vector tempData(inData.begin() + i, inData.begin() + i + windowSize); 54 | double val = Statistics::averageDouble(tempData); 55 | outData.push_back(val); 56 | } 57 | return outData; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /cpp/Signals.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2020 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _SIGNALS_ 25 | #define _SIGNALS_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class Signals 32 | { 33 | public: 34 | /** 35 | * Smooths the data by averaging points with the given window size. 36 | * Returns the number of points written to 'outData'. 37 | **/ 38 | static size_t smooth(const double* inData, double* outData, size_t numPoints, size_t windowSize); 39 | 40 | /** 41 | * Smooths the data, which should be a list, by averaging with the given window size. 42 | **/ 43 | static std::vector smooth(const std::vector& inData, size_t windowSize); 44 | }; 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /cpp/SquareMatrix.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | 25 | #include "SquareMatrix.h" 26 | 27 | namespace LibMath 28 | { 29 | SquareMatrix::SquareMatrix() : Matrix() 30 | { 31 | m_size = 0; 32 | m_data = NULL; 33 | } 34 | 35 | SquareMatrix::SquareMatrix(size_t size) : Matrix(size, size) 36 | { 37 | m_size = size; 38 | m_data = new double *[m_size]; 39 | for (auto i = 0; i < m_size; ++i) 40 | m_data[i] = new double[m_size]; 41 | } 42 | 43 | SquareMatrix::~SquareMatrix(void) 44 | { 45 | if (m_data != NULL) 46 | { 47 | for (auto i = 0; i < m_size; ++i) 48 | { 49 | delete m_data[i]; 50 | m_data[i] = NULL; 51 | } 52 | delete m_data; 53 | m_data = NULL; 54 | } 55 | } 56 | 57 | void SquareMatrix::print(void) 58 | { 59 | if (m_data != NULL) 60 | { 61 | for (auto i = 0; i < m_size; ++i) 62 | { 63 | std::cout << "[ "; 64 | for (auto j = 0; j < m_size; ++j) 65 | { 66 | std::cout << m_data[i][j] << " "; 67 | } 68 | std::cout << "]" << std::endl; 69 | } 70 | std::cout << std::endl; 71 | } 72 | } 73 | 74 | void SquareMatrix::multiply(const SquareMatrix* B, SquareMatrix* C) 75 | { 76 | // Compute C = A x B 77 | for (auto i = 0; i < m_size; ++i) 78 | { 79 | for (auto j = 0; j < m_size; ++j) 80 | { 81 | C->m_data[i][j] = 0.0; 82 | for (auto k = 0; k < m_size; ++k) 83 | { 84 | C->m_data[i][j] += m_data[i][k] * B->m_data[k][j]; 85 | } 86 | } 87 | } 88 | } 89 | 90 | void SquareMatrix::multiply(const Vector* B, Vector* C) 91 | { 92 | // Compute C = A x B 93 | for (auto i = 0; i < m_size; ++i) 94 | { 95 | C->m_data[i] = 0.0; 96 | for (auto j = 0; j < m_size; ++j) 97 | { 98 | C->m_data[i] += m_data[i][j] * B->m_data[j]; 99 | } 100 | } 101 | } 102 | 103 | void SquareMatrix::multiply(double B) 104 | { 105 | for (auto i = 0; i < m_size; ++i) 106 | { 107 | for (auto j = 0; j < m_size; ++j) 108 | { 109 | m_data[i][j] *= B; 110 | } 111 | } 112 | } 113 | 114 | void SquareMatrix::subtract(const SquareMatrix* B, SquareMatrix* C) 115 | { 116 | for (auto i = 0; i < m_size; ++i) 117 | { 118 | for (auto j = 0; j < m_size; ++j) 119 | { 120 | C->m_data[i][j] = m_data[i][j] - B->m_data[i][j]; 121 | } 122 | } 123 | } 124 | 125 | void SquareMatrix::subtract(double B) 126 | { 127 | for (auto i = 0; i < m_size; ++i) 128 | { 129 | for (auto j = 0; j < m_size; ++j) 130 | { 131 | m_data[i][j] -= B; 132 | } 133 | } 134 | } 135 | 136 | void SquareMatrix::zero(void) 137 | { 138 | for (auto i = 0; i < m_size; ++i) 139 | { 140 | for (auto j = 0; j < m_size; ++j) 141 | { 142 | m_data[i][j] = 0.0; 143 | } 144 | } 145 | } 146 | 147 | void SquareMatrix::identity(void) 148 | { 149 | for (auto i = 0; i < m_size; ++i) 150 | { 151 | for (auto j = 0; j < m_size; ++j) 152 | { 153 | if (i == j) 154 | m_data[i][j] = 1.0; 155 | else 156 | m_data[i][j] = 0.0; 157 | } 158 | } 159 | } 160 | 161 | void SquareMatrix::ones(void) 162 | { 163 | for (auto i = 0; i < m_size; ++i) 164 | { 165 | for (auto j = 0; j < m_size; ++j) 166 | { 167 | m_data[i][j] = 1.0; 168 | } 169 | } 170 | } 171 | 172 | double SquareMatrix::dot(const SquareMatrix* B) 173 | { 174 | double dot = 0.0; 175 | 176 | for (auto i = 0; i < m_size; ++i) 177 | { 178 | for (auto j = 0; j < m_size; ++j) 179 | { 180 | dot += *(m_data[i] + j * m_size) + *(B->m_data[i] + j * B->m_size); 181 | } 182 | } 183 | return dot; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /cpp/SquareMatrix.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _SQUAREMATRIX_ 25 | #define _SQUAREMATRIX_ 26 | 27 | #include "Matrix.h" 28 | 29 | namespace LibMath 30 | { 31 | class SquareMatrix : public Matrix 32 | { 33 | public: 34 | SquareMatrix(size_t size); 35 | virtual ~SquareMatrix(void); 36 | 37 | /** 38 | * Prints the matrix to standard out. Intended for testing and debugging. 39 | */ 40 | void print(void); 41 | 42 | /** 43 | * Returns the number of elements in the matrix. 44 | */ 45 | size_t size(void) const { return m_size; } 46 | 47 | /** 48 | * Returns C = A x B, where A, B, and C are matrices. 49 | */ 50 | void multiply(const SquareMatrix* B, SquareMatrix* C); 51 | 52 | /** 53 | * Returns C = A x B, where A is a matrix and B and C are vectors. 54 | */ 55 | void multiply(const Vector* B, Vector* C); 56 | 57 | /** 58 | * Multiplies the matrix by the supplied scalar. 59 | */ 60 | void multiply(double B); 61 | 62 | /** 63 | * Returns C = A - B, where A, B, and C are matrices. 64 | */ 65 | void subtract(const SquareMatrix* B, SquareMatrix* C); 66 | 67 | /** 68 | * Subtracts the scalar from the matrix. 69 | */ 70 | void subtract(double B); 71 | 72 | /** 73 | * Sets the value of A to the zero matrix. 74 | */ 75 | void zero(void); 76 | 77 | /** 78 | * Sets the value of this matrix to the identity matrix. 79 | */ 80 | void identity(void); 81 | 82 | /** 83 | * Sets the value of this matrix to the matrix of all ones. 84 | */ 85 | void ones(void); 86 | 87 | /** 88 | * Returns the dot product of tthis matrix and B. 89 | */ 90 | double dot(const SquareMatrix* B); 91 | 92 | protected: 93 | size_t m_size; 94 | 95 | protected: 96 | SquareMatrix(); 97 | }; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /cpp/Statistics.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1998-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | 24 | #include "Statistics.h" 25 | 26 | namespace LibMath 27 | { 28 | double Statistics::averageLong(const long* data, size_t numPoints) 29 | { 30 | long sum = 0; 31 | 32 | for (auto index = 0; index < numPoints; index++) 33 | sum = sum + data[index]; 34 | return (double)sum / (double)numPoints; 35 | } 36 | 37 | double Statistics::averageLong(const std::vector& data) 38 | { 39 | long sum = 0; 40 | 41 | for (auto iter = data.begin(); iter != data.end(); ++iter) 42 | sum = sum + (*iter); 43 | return sum / (double)data.size(); 44 | } 45 | 46 | double Statistics::averageDouble(const double* data, size_t numPoints) 47 | { 48 | double sum = 0; 49 | 50 | for (auto index = 0; index < numPoints; index++) 51 | sum = sum + data[index]; 52 | return sum / (double)numPoints; 53 | } 54 | 55 | double Statistics::averageDouble(const std::vector& data) 56 | { 57 | double sum = 0; 58 | 59 | for (auto iter = data.begin(); iter != data.end(); ++iter) 60 | sum = sum + (*iter); 61 | return sum / (double)data.size(); 62 | } 63 | 64 | double Statistics::variance(const double* data, size_t numPoints, double mean) 65 | { 66 | double numerator = (double)0.0; 67 | 68 | for (auto index = 0; index < numPoints; index++) 69 | numerator = numerator + ((data[index] - mean) * (data[index] - mean)); 70 | return numerator / (double)(numPoints - 1); 71 | } 72 | 73 | double Statistics::variance(const std::vector& data, double mean) 74 | { 75 | double numerator = (double)0.0; 76 | 77 | for (auto iter = data.begin(); iter != data.end(); ++iter) 78 | numerator = numerator + ((*iter - mean) * (*iter - mean)); 79 | return numerator / (double)(data.size() - 1); 80 | } 81 | 82 | double Statistics::standardDeviation(const double* data, size_t numPoints, double mean) 83 | { 84 | double var = variance(data, numPoints, mean); 85 | return sqrt(var); 86 | } 87 | 88 | double Statistics::standardDeviation(const std::vector& data, double mean) 89 | { 90 | double var = variance(data, mean); 91 | return sqrt(var); 92 | } 93 | 94 | double Statistics::max(const double* data, size_t numPoints) 95 | { 96 | double result = data[0]; 97 | 98 | for (auto index = 1; index < numPoints; index++) 99 | { 100 | if (data[index] > result) 101 | result = data[index]; 102 | } 103 | return result; 104 | } 105 | 106 | double Statistics::max(const size_t* data, size_t numPoints) 107 | { 108 | size_t result = data[0]; 109 | 110 | for (auto index = 1; index < numPoints; index++) 111 | { 112 | if (data[index] > result) 113 | result = data[index]; 114 | } 115 | return result; 116 | } 117 | 118 | double Statistics::max(const std::vector& data) 119 | { 120 | if (data.size() == 0) 121 | { 122 | return (double)0; 123 | } 124 | 125 | double result = data.at(0); 126 | 127 | for (auto iter = data.begin(); iter != data.end(); ++iter) 128 | { 129 | if (*iter > result) 130 | result = *iter; 131 | } 132 | return result; 133 | } 134 | 135 | double Statistics::min(const double* data, size_t numPoints) 136 | { 137 | if (numPoints == 0) 138 | { 139 | return (double)0; 140 | } 141 | 142 | double result = data[0]; 143 | 144 | for (auto index = 1; index < numPoints; index++) 145 | { 146 | if (data[index] < result) 147 | result = data[index]; 148 | } 149 | return result; 150 | } 151 | 152 | double Statistics::min(const size_t* data, size_t numPoints) 153 | { 154 | if (numPoints == 0) 155 | { 156 | return (double)0; 157 | } 158 | 159 | size_t result = data[0]; 160 | 161 | for (auto index = 1; index < numPoints; index++) 162 | { 163 | if (data[index] < result) 164 | result = data[index]; 165 | } 166 | return result; 167 | } 168 | 169 | double Statistics::min(const std::vector& data) 170 | { 171 | if (data.size() == 0) 172 | { 173 | return (double)0; 174 | } 175 | 176 | double result = data.at(0); 177 | 178 | for (auto iter = data.begin(); iter != data.end(); ++iter) 179 | { 180 | if (*iter < result) 181 | result = *iter; 182 | } 183 | return result; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /cpp/Statistics.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1998 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _STATISTICS_ 25 | #define _STATISTICS_ 26 | 27 | #include 28 | #include 29 | 30 | namespace LibMath 31 | { 32 | class Statistics 33 | { 34 | public: 35 | /** 36 | * Computes the average value in the given array. 37 | */ 38 | static double averageLong(const long* data, size_t numPoints); 39 | static double averageLong(const std::vector& data); 40 | 41 | /** 42 | * Computes the average value in the given array. 43 | */ 44 | static double averageDouble(const double* data, size_t numPoints); 45 | static double averageDouble(const std::vector& data); 46 | 47 | /** 48 | * Computes the variance of the given array with the mean value supplied. 49 | */ 50 | static double variance(const double* data, size_t numPoints, double mean); 51 | static double variance(const std::vector& data, double mean); 52 | 53 | /** 54 | * Computes the standard deviation of the given array with the mean value supplied. 55 | */ 56 | static double standardDeviation(const double* data, size_t numPoints, double mean); 57 | static double standardDeviation(const std::vector& data, double mean); 58 | 59 | /** 60 | * Finds the largest value in the array. 61 | */ 62 | static double max(const double* data, size_t numPoints); 63 | static double max(const size_t* data, size_t numPoints); 64 | static double max(const std::vector& data); 65 | 66 | /** 67 | * Finds the smallest value in the array. 68 | */ 69 | static double min(const double* data, size_t numPoints); 70 | static double min(const size_t* data, size_t numPoints); 71 | static double min(const std::vector& data); 72 | }; 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /cpp/Vector.cpp: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include "Vector.h" 27 | 28 | namespace LibMath 29 | { 30 | Vector::Vector(size_t size) 31 | { 32 | m_size = size; 33 | m_data = new double[m_size]; 34 | } 35 | 36 | Vector::~Vector(void) 37 | { 38 | if (m_data != NULL) 39 | { 40 | delete[] m_data; 41 | m_data = NULL; 42 | } 43 | } 44 | 45 | void Vector::copy(const Vector* B) 46 | { 47 | memcpy((void *)m_data, (void *)B->m_data, sizeof(double) * m_size); 48 | } 49 | 50 | double Vector::multiply(const Vector* B) 51 | { 52 | double C = 0; 53 | 54 | // Compute C = A x B 55 | for (auto i = 0; i < m_size; ++i) 56 | C += m_data[i] * B->m_data[i]; 57 | 58 | // Return the result. 59 | return C; 60 | } 61 | 62 | void Vector::subtract(const Vector* B, Vector* C) 63 | { 64 | // Compute C = A - B 65 | for (auto i = 0; i < m_size; ++i) 66 | C[i] = m_data[i] - B->m_data[i]; 67 | } 68 | 69 | double Vector::dot(const Vector* B) 70 | { 71 | double result = 0.0; 72 | 73 | // Compute the dot product 74 | for (auto i = 0; i < m_size; ++i) 75 | result += (m_data[i] * B->m_data[i]); 76 | 77 | // Return the result 78 | return result; 79 | } 80 | 81 | double Vector::length(void) 82 | { 83 | double sum = 0.0; 84 | 85 | for (auto i = 0; i < m_size; ++i) 86 | sum += (m_data[i] * m_data[i]); 87 | return (sqrt(sum)); 88 | } 89 | 90 | void Vector::normalize(void) 91 | { 92 | double norm; 93 | 94 | norm = length(); 95 | for (auto i = 0; i < m_size; ++i) 96 | m_data[i] = m_data[i] / norm; 97 | } 98 | 99 | void Vector::cross(const Vector* A, const Vector* B) 100 | { 101 | m_data[0] = (B->m_data[1] * A->m_data[2]) - (B->m_data[2] * A->m_data[1]); 102 | m_data[1] = (B->m_data[2] * A->m_data[0]) - (B->m_data[0] * A->m_data[2]); 103 | m_data[2] = (B->m_data[0] * A->m_data[1]) - (B->m_data[1] * A->m_data[0]); 104 | } 105 | 106 | void Vector::print() 107 | { 108 | std::cout << "["; 109 | for (auto i = 0; i < m_size; ++i) 110 | { 111 | if (i > 0) 112 | std::cout << " "; 113 | std::cout << m_data[i]; 114 | } 115 | std::cout << "]" << std::endl; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /cpp/Vector.h: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 1997-2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #pragma once 23 | 24 | #ifndef _VECTOR_ 25 | #define _VECTOR_ 26 | 27 | #include 28 | 29 | namespace LibMath 30 | { 31 | class Vector 32 | { 33 | public: 34 | Vector(size_t size); 35 | virtual ~Vector(void); 36 | 37 | /** 38 | * Returns the number of elements in the vector. 39 | */ 40 | size_t size(void) const { return m_size; } 41 | 42 | /** 43 | * Returns a copy of vector B in vector A. 44 | */ 45 | void copy(const Vector* B); 46 | 47 | /** 48 | * Returns C = A x B, where A and B are vectors and C is a scalar. 49 | */ 50 | double multiply(const Vector* B); 51 | 52 | /** 53 | * Returns C = A - B, where A, B, and C are vectors. 54 | */ 55 | void subtract(const Vector* B, Vector* C); 56 | 57 | /** 58 | * Returns the dot product of A and B, where A and B are vectors. 59 | */ 60 | double dot(const Vector* B); 61 | 62 | /** 63 | * Computes the length of the vector A. 64 | */ 65 | double length(void); 66 | 67 | /** 68 | * Normalizes vector A. 69 | */ 70 | void normalize(void); 71 | 72 | /** 73 | * Returns C = A x B, where A, B, and C are 3x3 vectors. 74 | */ 75 | void cross(const Vector* A, const Vector* B); 76 | 77 | /** 78 | * Print vector A to stdout. 79 | */ 80 | void print(void); 81 | 82 | friend class Matrix; 83 | friend class SquareMatrix; 84 | 85 | public: 86 | double* m_data; 87 | 88 | protected: 89 | size_t m_size; 90 | }; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /cpp/libmath.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cpp/libmath.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/florida.csv: -------------------------------------------------------------------------------- 1 | -82.88318,24.72148,0.0 2 | -82.87484,24.72333,0.0 3 | -82.86562,24.72623,0.0 4 | -82.80018,24.72628,0.0 5 | -82.76651,24.70176,0.0 6 | -82.76668,24.66794,0.0 7 | -82.79523,24.62543,0.0 8 | -82.8008,24.61694,0.0 9 | -82.80563,24.6145,0.0 10 | -82.8051,24.61309,0.0 11 | -82.79965,24.60623,0.0 12 | -82.79801,24.60417,0.0 13 | -82.80441,24.6043,0.0 14 | -82.82175,24.59071,0.0 15 | -82.8218,24.59077,0.0 16 | -82.82191,24.59069,0.0 17 | -82.82857,24.58554,0.0 18 | -82.83616,24.58114,0.0 19 | -82.84905,24.57675,0.0 20 | -82.86119,24.57528,0.0 21 | -82.87484,24.57528,0.0 22 | -82.87807,24.57591,0.0 23 | -82.88097,24.57658,0.0 24 | -82.8871,24.57813,0.0 25 | -82.90028,24.58327,0.0 26 | -82.90433,24.58254,0.0 27 | -82.91531,24.58034,0.0 28 | -82.92824,24.57814,0.0 29 | -82.93711,24.57814,0.0 30 | -82.9475,24.57936,0.0 31 | -82.95816,24.58183,0.0 32 | -82.96559,24.58481,0.0 33 | -82.96559,24.5849,0.0 34 | -82.97482,24.58961,0.0 35 | -82.98066,24.59619,0.0 36 | -82.98339,24.60264,0.0 37 | -82.98624,24.61065,0.0 38 | -82.98748,24.61921,0.0 39 | -82.98748,24.62538,0.0 40 | -82.98748,24.62543,0.0 41 | -82.98553,24.64049,0.0 42 | -82.97774,24.65648,0.0 43 | -82.9641,24.6706,0.0 44 | -82.95144,24.67812,0.0 45 | -82.94072,24.68283,0.0 46 | -82.93289,24.68467,0.0 47 | -82.93083,24.68674,0.0 48 | -82.92465,24.69295,0.0 49 | -82.92258,24.69502,0.0 50 | -82.90202,24.71568,0.0 51 | -82.89993,24.71778,0.0 52 | -87.58552,30.99763,0.0 53 | -87.58143,30.99761,0.0 54 | -87.44355,30.99789,0.0 55 | -87.31233,30.99796,0.0 56 | -87.03714,30.99931,0.0 57 | -86.67211,30.99468,0.0 58 | -86.3694,30.99453,0.0 59 | -86.02421,30.99327,0.0 60 | -85.49265,30.997,0.0 61 | -85.15234,31.00093,0.0 62 | -85.0025,31.00068,0.0 63 | -85.00244,31.00068,0.0 64 | -84.9273,30.83896,0.0 65 | -84.68652,30.70389,0.0 66 | -83.83189,30.66308,0.0 67 | -82.65847,30.59601,0.0 68 | -82.23739,30.53222,0.0 69 | -82.20611,30.49104,0.0 70 | -82.20725,30.4583,0.0 71 | -82.20979,30.43224,0.0 72 | -82.20312,30.40143,0.0 73 | -82.18128,30.37108,0.0 74 | -82.14697,30.36191,0.0 75 | -82.11119,30.36569,0.0 76 | -82.06348,30.35858,0.0 77 | -82.04357,30.40736,0.0 78 | -82.01811,30.47325,0.0 79 | -82.01304,30.54839,0.0 80 | -82.0273,30.60704,0.0 81 | -82.04309,30.68636,0.0 82 | -82.01729,30.75567,0.0 83 | -81.96184,30.80128,0.0 84 | -81.88472,30.80873,0.0 85 | -81.77197,30.7638,0.0 86 | -81.68329,30.74793,0.0 87 | -81.59965,30.72923,0.0 88 | -81.34701,30.71244,0.0 89 | -81.34697,30.71217,0.0 90 | -81.37161,30.52655,0.0 91 | -81.33317,30.31537,0.0 92 | -81.20043,29.81151,0.0 93 | -81.14153,29.6487,0.0 94 | -81.0717,29.50025,0.0 95 | -80.94749,29.22979,0.0 96 | -80.75272,28.9214,0.0 97 | -80.49989,28.40943,0.0 98 | -80.529,28.2106,0.0 99 | -80.5,28.07829,0.0 100 | -80.39202,27.8753,0.0 101 | -80.2849,27.62531,0.0 102 | -80.21823,27.43672,0.0 103 | -80.01425,26.94169,0.0 104 | -79.97654,26.68748,0.0 105 | -80.00689,26.42646,0.0 106 | -80.08848,25.71036,0.0 107 | -80.11596,25.53363,0.0 108 | -80.11389,25.40626,0.0 109 | -80.22623,25.28698,0.0 110 | -80.31636,25.1254,0.0 111 | -80.39162,25.0394,0.0 112 | -80.51633,24.93695,0.0 113 | -80.68089,24.82077,0.0 114 | -80.90079,24.7147,0.0 115 | -81.02642,24.65898,0.0 116 | -81.19379,24.63065,0.0 117 | -81.33761,24.58476,0.0 118 | -81.49682,24.56203,0.0 119 | -81.5913,24.4653,0.0 120 | -81.7737,24.48664,0.0 121 | -81.90297,24.40087,0.0 122 | -82.0518,24.5,0.0 123 | -82.21828,24.5747,0.0 124 | -81.94524,24.65395,0.0 125 | -81.74981,24.71753,0.0 126 | -81.6405,24.77291,0.0 127 | -81.53411,24.83073,0.0 128 | -81.3756,24.875,0.0 129 | -81.21512,24.87439,0.0 130 | -81.05494,24.79338,0.0 131 | -80.92284,24.84727,0.0 132 | -81.02013,24.9309,0.0 133 | -81.15573,25.10858,0.0 134 | -81.19608,25.35706,0.0 135 | -81.27318,25.51913,0.0 136 | -81.41385,25.68897,0.0 137 | -81.57097,25.80204,0.0 138 | -81.75831,25.86479,0.0 139 | -81.85229,26.0701,0.0 140 | -81.92115,26.35451,0.0 141 | -82.11247,26.37789,0.0 142 | -82.31651,26.6552,0.0 143 | -82.46756,26.99799,0.0 144 | -82.62287,27.26077,0.0 145 | -82.82367,27.57508,0.0 146 | -82.90236,27.92705,0.0 147 | -82.89457,28.06374,0.0 148 | -82.90791,28.21281,0.0 149 | -82.79299,28.31877,0.0 150 | -82.75332,28.43734,0.0 151 | -82.74393,28.55522,0.0 152 | -82.76825,28.66929,0.0 153 | -82.79252,28.7513,0.0 154 | -82.80688,28.83351,0.0 155 | -82.80796,28.88649,0.0 156 | -82.84569,28.97339,0.0 157 | -82.87483,29.04497,0.0 158 | -83.10142,29.04763,0.0 159 | -83.24095,29.27517,0.0 160 | -83.31733,29.38432,0.0 161 | -83.46187,29.52763,0.0 162 | -83.59713,29.69166,0.0 163 | -83.69662,29.85831,0.0 164 | -83.82761,29.91491,0.0 165 | -83.99928,30.01195,0.0 166 | -84.12573,30.00328,0.0 167 | -84.25513,29.98857,0.0 168 | -84.31123,29.85732,0.0 169 | -84.49618,29.83173,0.0 170 | -84.60315,29.74316,0.0 171 | -84.74676,29.65094,0.0 172 | -84.91612,29.57522,0.0 173 | -85.03701,29.53747,0.0 174 | -85.10112,29.56047,0.0 175 | -85.17333,29.59091,0.0 176 | -85.24868,29.62587,0.0 177 | -85.331,29.60478,0.0 178 | -85.39241,29.62445,0.0 179 | -85.43623,29.68152,0.0 180 | -85.45967,29.7447,0.0 181 | -85.47296,29.8059,0.0 182 | -85.46908,29.87011,0.0 183 | -85.46353,29.90607,0.0 184 | -85.55501,29.93779,0.0 185 | -85.61594,29.99446,0.0 186 | -85.76266,30.0731,0.0 187 | -86.11861,30.25561,0.0 188 | -86.76981,30.33812,0.0 189 | -87.49998,30.23334,0.0 190 | -87.45238,30.3002,0.0 191 | -87.45538,30.3412,0.0 192 | -87.39878,30.4151,0.0 193 | -87.43258,30.4782,0.0 194 | -87.44629,30.52315,0.0 195 | -87.42605,30.55648,0.0 196 | -87.40874,30.58513,0.0 197 | -87.3937,30.62914,0.0 198 | -87.43361,30.68835,0.0 199 | -87.48362,30.71531,0.0 200 | -87.53522,30.75054,0.0 201 | -87.56787,30.7996,0.0 202 | -87.60348,30.83021,0.0 203 | -87.6272,30.85923,0.0 204 | -87.62123,30.89199,0.0 205 | -87.59581,30.94243,0.0 -------------------------------------------------------------------------------- /java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | 7 | com.mikesimms.libmath 8 | libmath 9 | 1.0 10 | 11 | 12 | 13 | 14 | 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 18 | 1.8 19 | 1.8 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /java/src/main/java/CsvReader.java: -------------------------------------------------------------------------------- 1 | 2 | // MIT License 3 | // 4 | // Copyright © 2019 Michael J Simms. All rights reserved. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import java.io.BufferedReader; 25 | import java.io.FileReader; 26 | import java.io.IOException; 27 | import java.util.ArrayList; 28 | 29 | /** 30 | *

CsvReader

31 | * Class for reading comma separated files. 32 | */ 33 | public class CsvReader 34 | { 35 | public static ArrayList readAsStrings(String fileName) throws IOException { 36 | ArrayList rows = new ArrayList(); 37 | BufferedReader br = null; 38 | 39 | try { 40 | String rowStr = ""; 41 | br = new BufferedReader(new FileReader(fileName)); 42 | while ((rowStr = br.readLine()) != null) { 43 | String[] row = rowStr.split(","); 44 | rows.add(row); 45 | } 46 | } finally { 47 | if (br != null) { 48 | try { 49 | br.close(); 50 | } catch (IOException e) { 51 | } 52 | } 53 | } 54 | return rows; 55 | } 56 | 57 | public static ArrayList readAsDoubles(String fileName) throws IOException { 58 | ArrayList rows = new ArrayList(); 59 | BufferedReader br = null; 60 | 61 | try { 62 | String rowStr = ""; 63 | br = new BufferedReader(new FileReader(fileName)); 64 | while ((rowStr = br.readLine()) != null) { 65 | String[] row = rowStr.split(","); 66 | double[] numRow = new double[row.length]; 67 | int numRowIndex = 0; 68 | for (String item:row) { 69 | double numItem = Double.parseDouble(item); 70 | numRow[numRowIndex++] = numItem; 71 | } 72 | rows.add(numRow); 73 | } 74 | } finally { 75 | if (br != null) { 76 | try { 77 | br.close(); 78 | } catch (IOException e) { 79 | } 80 | } 81 | } 82 | return rows; 83 | } 84 | 85 | public static ArrayList readAsDoublesColumnwise(String fileName) throws IOException { 86 | ArrayList columns = new ArrayList(); 87 | ArrayList rows = readAsDoubles(fileName); 88 | 89 | double[] tsList = new double[rows.size()]; 90 | double[] xList = new double[rows.size()]; 91 | double[] yList = new double[rows.size()]; 92 | double[] zList = new double[rows.size()]; 93 | 94 | for (int i = 0; i < rows.size(); ++i) { 95 | double[] row = rows.get(i); 96 | tsList[i] = row[0]; 97 | xList[i] = row[1]; 98 | yList[i] = row[2]; 99 | zList[i] = row[3]; 100 | } 101 | 102 | columns.add(tsList); 103 | columns.add(xList); 104 | columns.add(yList); 105 | columns.add(zList); 106 | return columns; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /java/src/main/java/GraphPeak.java: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2019 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /** 24 | *

GraphPeak

25 | * Represents a peak that was found with the peak finding algorithm. 26 | * A peak consists of a left trough, right trough, and peak (obvously). 27 | */ 28 | public class GraphPeak 29 | { 30 | public GraphPoint leftTrough; 31 | public GraphPoint peak; 32 | public GraphPoint rightTrough; 33 | public double area; 34 | 35 | /** 36 | * Constructor. 37 | */ 38 | GraphPeak() { 39 | this.leftTrough = new GraphPoint(); 40 | this.peak = new GraphPoint(); 41 | this.rightTrough = new GraphPoint(); 42 | this.area = (double)0.0; 43 | } 44 | 45 | /** 46 | * Copy constructor. 47 | * 48 | * @param rhs 49 | * Peak to be copied. 50 | */ 51 | GraphPeak(GraphPeak rhs) { 52 | this.leftTrough = rhs.leftTrough; 53 | this.peak = rhs.peak; 54 | this.rightTrough = rhs.rightTrough; 55 | this.area = rhs.area; 56 | } 57 | 58 | /** 59 | * Copy constructor. 60 | * 61 | * @param rhs 62 | * Peak to be copied. 63 | */ 64 | public void copy(GraphPeak rhs) { 65 | this.leftTrough = rhs.leftTrough; 66 | this.peak = rhs.peak; 67 | this.rightTrough = rhs.rightTrough; 68 | this.area = rhs.area; 69 | } 70 | 71 | /** 72 | * Comparitor. Peaks are the same if they have the same troughts and peak. 73 | * 74 | * @param rhs 75 | * Peak to be compared. 76 | */ 77 | public boolean compare(GraphPeak rhs) { 78 | return (this.leftTrough == rhs.leftTrough) && (this.peak == rhs.peak) && (this.rightTrough == rhs.rightTrough); 79 | } 80 | 81 | /** 82 | * Comparison by area. 83 | * 84 | * @param rhs 85 | * Peak to be compared. 86 | */ 87 | public boolean lessThan(GraphPeak str) { return (area < str.area); } 88 | public boolean greaterThan(GraphPeak str) { return (area > str.area); } 89 | 90 | /** 91 | * Sets all the values associated with the peak to zero. 92 | */ 93 | public void clear() { 94 | this.leftTrough.clear(); 95 | this.peak.clear(); 96 | this.rightTrough.clear(); 97 | this.area = (double)0.0; 98 | } 99 | }; 100 | -------------------------------------------------------------------------------- /java/src/main/java/GraphPoint.java: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2019 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | /** 24 | *

GraphPoint

25 | * Represents a point on a graph where the x value is an index and the y value is actual data. 26 | */ 27 | public class GraphPoint 28 | { 29 | public long x; 30 | public double y; 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param newX 36 | * x value of the new point. 37 | * @param newY 38 | * y value of the new point. 39 | * @param rhs 40 | * Point to be copied. 41 | */ 42 | GraphPoint() { 43 | x = 0; 44 | y = (double)0.0; 45 | } 46 | GraphPoint(long newX, double newY) { 47 | x = newX; 48 | y = newY; 49 | } 50 | GraphPoint(GraphPoint rhs) { 51 | x = rhs.x; 52 | y = rhs.y; 53 | } 54 | 55 | /** 56 | * Sets all the values associated with the point to zero. 57 | */ 58 | public void clear() { 59 | x = 0; 60 | y = (double)0.0; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /java/src/main/java/LibMathTests.java: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2019 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | import java.util.*; 24 | import java.io.*; 25 | 26 | public class LibMathTests 27 | { 28 | public static void statisticsTests() { 29 | long v_int[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 30 | double v_int_avg = Statistics.averageLong(v_int); 31 | System.out.println("Average: " + v_int_avg); 32 | double v_flt[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; 33 | double v_flt_avg = Statistics.averageDouble(v_flt); 34 | System.out.println("Average: " + v_flt_avg); 35 | double variance = Statistics.variance(v_flt, v_flt_avg); 36 | System.out.println("Variance: " + variance); 37 | } 38 | 39 | public static void peakFindingTests(String csvFileName) { 40 | if (csvFileName.length() > 0) { 41 | try { 42 | ArrayList csvData = CsvReader.readAsDoublesColumnwise(csvFileName); 43 | Iterator csvIter = csvData.iterator(); 44 | if (csvIter.hasNext()) { 45 | csvIter.next(); // Skip over the timestamp column 46 | int axisCount = 0; 47 | while (csvIter.hasNext()) { 48 | double[] columnData = csvIter.next(); 49 | System.out.println("Axis " + (++axisCount) + ": "); 50 | 51 | int peakCount = 0; 52 | ArrayList peaks = Peaks.findPeaks(columnData, (double)1.5); 53 | Iterator peakIter = peaks.iterator(); 54 | while (peakIter.hasNext()) { 55 | GraphPeak peak = peakIter.next(); 56 | System.out.println("Peak " + (++peakCount) + ": {" + peak.leftTrough.x + ", " + peak.peak.x + ", " + peak.rightTrough.x + ", " + peak.area + "}"); 57 | } 58 | } 59 | } 60 | } 61 | catch (IOException e) { 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * Entry point. 68 | */ 69 | public static void main(String[] args) { 70 | String csvFileName = new String(); 71 | 72 | for (int i = 0; i < args.length; ++i) { 73 | if (args[i].equals("--csv") && (i + 1 < args.length)) { 74 | csvFileName = args[++i]; 75 | } 76 | } 77 | 78 | System.out.println("Statistics Tests:"); 79 | System.out.println("-----------------"); 80 | statisticsTests(); 81 | 82 | System.out.println("\nPeak Finding Tests:"); 83 | System.out.println("-------------------"); 84 | peakFindingTests(csvFileName); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /java/src/main/java/Statistics.java: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2019 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | /** 23 | *

Statistics

24 | * Implements basic statistical functions. 25 | */ 26 | public class Statistics { 27 | 28 | /** 29 | * Constructor. 30 | */ 31 | Statistics() { 32 | } 33 | 34 | public static double averageLong(long[] data) { 35 | long sum = 0; 36 | 37 | for (int index = 0; index < data.length; index++) 38 | sum = sum + data[index]; 39 | return (double)sum / (double)data.length; 40 | } 41 | 42 | public static double averageDouble(double[] data) { 43 | double sum = 0; 44 | 45 | for (int index = 0; index < data.length; index++) 46 | sum = sum + data[index]; 47 | return sum / (double)data.length; 48 | } 49 | 50 | public static double[] noramlize(double[] data, double mean, double variance) { 51 | double[] normalized = new double[data.length]; 52 | for (int index = 0; index < data.length; index++) 53 | normalized[index] = (data[index] - mean) / variance; 54 | return normalized; 55 | } 56 | 57 | public static double variance(double[] data, double mean) { 58 | double numerator = 0; 59 | 60 | for (int index = 0; index < data.length; index++) 61 | numerator = numerator + ((data[index] - mean) * (data[index] - mean)); 62 | return numerator / (double)(data.length - 1); 63 | } 64 | 65 | public static double standardDeviation(double[] data, double mean) { 66 | double var = variance(data, mean); 67 | return Math.sqrt(var); 68 | } 69 | 70 | public static double max(double[] data) { 71 | if (data.length == 0) { 72 | return (double)0.0; 73 | } 74 | 75 | double result = data[0]; 76 | 77 | for (int index = 1; index < data.length; index++) { 78 | if (data[index] > result) 79 | result = data[index]; 80 | } 81 | return result; 82 | } 83 | 84 | public static double min(double[] data) { 85 | if (data.length == 0) { 86 | return (double)0; 87 | } 88 | 89 | double result = data[0]; 90 | 91 | for (int index = 1; index < data.length; index++) { 92 | if (data[index] < result) 93 | result = data[index]; 94 | } 95 | return result; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /julia/Distance.jl: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | module Distance 24 | 25 | export hamming_distance 26 | export levenshtein_distance 27 | export euclidian_distance_1D 28 | export euclidian_distance_2D 29 | 30 | # Hamming Distance 31 | function hamming_distance(str1, str2) 32 | len1 = length(str1) 33 | 34 | # The strings must be the same length. 35 | if len1 != length(str2) 36 | return -1 37 | end 38 | 39 | distance = 0 40 | 41 | for i in 1:len1 42 | if str1[i] != str2[i] 43 | distance = distance + 1 44 | end 45 | end 46 | 47 | distance 48 | end 49 | 50 | # Levenshtein Distance 51 | function levenshtein_distance(str1, str2) 52 | m = length(str1) 53 | n = length(str2) 54 | 55 | # Test for empty strings. 56 | if m == 0 57 | return n 58 | end 59 | if n == 0 60 | return m 61 | end 62 | 63 | # Temp vectors. 64 | v0 = zeros(n) 65 | v1 = zeros(n) 66 | for i in 1:n 67 | v0[i] = i - 1 68 | end 69 | 70 | for i in 1:m - 1 71 | v1[1] = i + 1 72 | 73 | for j in 1:n - 1 74 | costs = zeros(3) # deletion, insertion, and substitution costs (in that order) 75 | costs[1] = v0[j + 1] + 1 76 | costs[2] = v1[j] + 1 77 | if str1[i] == str2[j] 78 | costs[3] = v0[j] 79 | else 80 | costs[3] = v0[j] + 1 81 | end 82 | 83 | tempJ = j + 1 84 | v1[tempJ] = costs[1] 85 | if costs[2] < v1[tempJ] 86 | v1[tempJ] = costs[2] 87 | end 88 | if costs[3] < v1[tempJ] 89 | v1[tempJ] = costs[3] 90 | end 91 | end 92 | 93 | # Copy v1 to v0. 94 | tempV = v0 95 | v0 = v1 96 | v1 = tempV 97 | end 98 | 99 | # Save the final distance calculation. 100 | distance = v0[n] 101 | 102 | distance 103 | end 104 | 105 | # 1 dimensional Euclidian distance 106 | function euclidian_distance_1D(pt1, pt2) 107 | abs(pt1 - pt2) 108 | end 109 | 110 | # 2 dimensional Euclidian distance 111 | function euclidian_distance_2D(pt1X, pt1Y, pt2X, pt2Y) 112 | tempX = pt2X - pt1X 113 | tempY = pt2Y - pt1Y 114 | sqrt((tempX * tempX) + (tempY * tempY)) 115 | end 116 | 117 | end 118 | -------------------------------------------------------------------------------- /julia/LibMathTests.jl: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | include("Distance.jl") 24 | include("Peaks.jl") 25 | include("Powers.jl") 26 | include("Signals.jl") 27 | 28 | using Pkg 29 | Pkg.add("ArgParse") 30 | using ArgParse 31 | Pkg.add("CSV") 32 | using CSV 33 | 34 | function read_accelerometer_csv(filename::String) 35 | data = [] 36 | data = CSV.read(filename) 37 | ts = data[1] 38 | x = data[2] 39 | y = data[3] 40 | z = data[4] 41 | ts, x, y, z 42 | end 43 | 44 | function distance_tests() 45 | println("Distance Tests:") 46 | println("---------------") 47 | 48 | distance = Distance.hamming_distance("1011101", "1001001") 49 | println("Hamming Distance: ", distance) 50 | @assert distance == 2 51 | 52 | distance = Distance.levenshtein_distance("foo", "foobar") 53 | println("Levenshtein Distance: ", distance) 54 | @assert distance == 3 55 | end 56 | 57 | function signals_tests() 58 | println("Signals Tests:"); 59 | println("--------------"); 60 | 61 | indata = [ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 ] 62 | windowsize = 2 63 | outdata = Signals.smooth(indata, windowsize) 64 | 65 | println(outdata) 66 | end 67 | 68 | function power_tests() 69 | println("Power Tests:") 70 | println("------------") 71 | 72 | nearest = Powers.nearest_power_of_2(63) 73 | println("Nearest power of 2 for 63 is ", nearest) 74 | @assert nearest == 64 75 | end 76 | 77 | function peak_finding_tests(data) 78 | println("Peak Finding Tests:") 79 | println("-------------------") 80 | 81 | peaks = Peaks.find_peaks_over_stddev(data) 82 | println(peaks) 83 | end 84 | 85 | # Parses the command line arguments 86 | function parse_commandline() 87 | s = ArgParseSettings() 88 | 89 | @add_arg_table s begin 90 | "--csv" 91 | help = "A CSV file with accelerometer data" 92 | arg_type = String 93 | default = "../data/10_pullups.csv" 94 | end 95 | 96 | return parse_args(s) 97 | end 98 | 99 | # Run all the unit tests 100 | parsed_args = parse_commandline() 101 | ts, x, y, z = read_accelerometer_csv(parsed_args["csv"]) 102 | distance_tests() 103 | println("") 104 | signals_tests() 105 | println("") 106 | power_tests() 107 | println("") 108 | peak_finding_tests(x) 109 | println("") 110 | -------------------------------------------------------------------------------- /julia/Powers.jl: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | module Powers 24 | 25 | export nearest_power_of_2 26 | 27 | function nearest_power_of_2(num) 28 | n = num > 0 ? num - 1 : 0 29 | 30 | n |= n >> 1 31 | n |= n >> 2 32 | n |= n >> 4 33 | n |= n >> 8 34 | n |= n >> 16 35 | n = n + 1 36 | 37 | n 38 | end 39 | 40 | end 41 | -------------------------------------------------------------------------------- /julia/Signals.jl: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | module Signals 24 | 25 | import Statistics 26 | export smooth 27 | 28 | # Smooths the data, which should be a list, by averaging with the given window size. 29 | function smooth(indata, windowsize) 30 | outdata = [] 31 | outdatalen = length(indata) - windowsize 32 | if outdatalen <= 0 33 | return outdata 34 | end 35 | 36 | for i in 1:outdatalen 37 | tempdata = indata[i:i + windowsize] 38 | val = Statistics.mean(tempdata) 39 | push!(outdata, val) 40 | end 41 | 42 | outdata 43 | end 44 | 45 | end 46 | -------------------------------------------------------------------------------- /python/distance.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2018 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import math 24 | 25 | def haversine_distance(loc1_lat, loc1_lon, loc1_alt, loc2_lat, loc2_lon, loc2_alt): 26 | """Returns the Haversine distance between two points on the Earth's surface.""" 27 | R = 6372797.560856 # radius of the earth in meters 28 | R = R + loc2_alt - loc1_alt 29 | 30 | lat_arc = math.radians(loc1_lat - loc2_lat) 31 | lon_arc = math.radians(loc1_lon - loc2_lon) 32 | 33 | lat_h = math.sin(lat_arc * 0.5) 34 | lat_h = lat_h * lat_h 35 | 36 | lon_h = math.sin(lon_arc * 0.5) 37 | lon_h = lon_h * lon_h 38 | 39 | tmp = math.cos(math.radians(loc1_lat)) * math.cos(math.radians(loc2_lat)) 40 | rad = 2.0 * math.asin(math.sqrt(lat_h + tmp * lon_h)) 41 | 42 | return rad * R 43 | 44 | def haversine_distance_ignore_altitude(loc1_lat, loc1_lon, loc2_lat, loc2_lon): 45 | """Returns the Haversine distance between two points on the Earth's surface.""" 46 | R = 6372797.560856 # radius of the earth in meters 47 | 48 | lat_arc = math.radians(loc1_lat - loc2_lat) 49 | lon_arc = math.radians(loc1_lon - loc2_lon) 50 | 51 | lat_h = math.sin(lat_arc * 0.5) 52 | lat_h = lat_h * lat_h 53 | 54 | lon_h = math.sin(lon_arc * 0.5) 55 | lon_h = lon_h * lon_h 56 | 57 | tmp = math.cos(math.radians(loc1_lat)) * math.cos(math.radians(loc2_lat)) 58 | rad = 2.0 * math.asin(math.sqrt(lat_h + tmp * lon_h)) 59 | 60 | return rad * R 61 | 62 | def hamming_distance(str1, str2): 63 | len1 = len(str1) 64 | 65 | # The strings must be the same length. 66 | if len1 != len(str2): 67 | return -1 68 | 69 | distance = 0 70 | 71 | for i in range(0, len1): 72 | if str1[i] != str2[i]: 73 | distance += 1 74 | return distance 75 | 76 | def euclidian_distance_1_d(pt1, pt2): 77 | return abs(pt1 - pt2) 78 | 79 | def euclidian_distance_2_d(pt1_x, pt1_y, pt2_x, pt2_y): 80 | temp_x = pt2_x - pt1_x 81 | temp_y = pt2_y - pt1_y 82 | return math.sqrt((temp_x * temp_x) + (temp_y * temp_y)) 83 | -------------------------------------------------------------------------------- /python/graphics.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2019 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | def is_point_in_polygon(point, poly): 24 | """Implements the ray casting/crossing number algorithm. Returns TRUE if the point is within the bounds of the points that specify the polygon (poly is a list of points).""" 25 | 26 | # Sanity checks. 27 | if not isinstance(poly, list): 28 | return False 29 | 30 | num_crossings = 0 31 | num_vertices = len(poly) 32 | if num_vertices < 3: # Need at least three points to make a polygon 33 | return False 34 | 35 | test_x = point['x'] 36 | test_y = point['y'] 37 | for i in range(0, num_vertices): 38 | 39 | # Cache the y coordinate for the first point on the edge. 40 | poly_pt = poly[i] 41 | poly_pt1_y = poly_pt['y'] 42 | 43 | # Cache the second point on the edge, handling the wrap around that happens when we close the polygon. 44 | if i == num_vertices - 1: 45 | poly_pt = poly[0] 46 | poly_pt2_x = poly_pt['x'] 47 | poly_pt2_y = poly_pt['y'] 48 | else: 49 | poly_pt = poly[i + 1] 50 | poly_pt2_x = poly_pt['x'] 51 | poly_pt2_y = poly_pt['y'] 52 | 53 | # Test if the point is within the y limits of the edge. 54 | crosses_y = ((poly_pt1_y <= test_y) and (poly_pt2_y > test_y)) or ((poly_pt1_y > test_y) and (poly_pt2_y <= test_y)) 55 | if crosses_y: 56 | 57 | # Test if the ray extending to the right of the point crosses the edge. 58 | poly_pt1_x = (poly[i])['x'] 59 | if test_x < poly_pt1_x + ((test_y - poly_pt1_y) / (poly_pt2_y - poly_pt1_y)) * (poly_pt2_x - poly_pt1_x): 60 | num_crossings = num_crossings + 1 61 | 62 | return num_crossings & 1 63 | 64 | def is_point_in_poly_array(test_x, test_y, poly): 65 | """Implements the ray casting/crossing number algorithm. Returns TRUE if the point is within the bounds of the points that specify the polygon (poly is a list of points).""" 66 | 67 | # Sanity checks. 68 | if not isinstance(poly, list): 69 | return False 70 | 71 | num_crossings = 0 72 | num_vertices = len(poly) 73 | if num_vertices < 3: # Need at least three points to make a polygon 74 | return False 75 | 76 | for i in range(0, num_vertices): 77 | 78 | # Cache the y coordinate for the first point on the edge. 79 | poly_pt = poly[i] 80 | if len(poly_pt) != 2: 81 | return False 82 | poly_pt1_y = poly_pt[1] 83 | 84 | # Cache the second point on the edge, handling the wrap around that happens when we close the polygon. 85 | if i == num_vertices - 1: 86 | poly_pt = poly[0] 87 | poly_pt2_x = poly_pt[0] 88 | poly_pt2_y = poly_pt[1] 89 | else: 90 | poly_pt = poly[i + 1] 91 | poly_pt2_x = poly_pt[0] 92 | poly_pt2_y = poly_pt[1] 93 | 94 | # Test if the point is within the y limits of the edge. 95 | crosses_y = ((poly_pt1_y <= test_y) and (poly_pt2_y > test_y)) or ((poly_pt1_y > test_y) and (poly_pt2_y <= test_y)) 96 | if crosses_y: 97 | 98 | # Test if the ray extending to the right of the point crosses the edge. 99 | poly_pt1_x = (poly[i])[0] 100 | if test_x < poly_pt1_x + ((test_y - poly_pt1_y) / (poly_pt2_y - poly_pt1_y)) * (poly_pt2_x - poly_pt1_x): 101 | num_crossings = num_crossings + 1 102 | 103 | return num_crossings & 1 104 | -------------------------------------------------------------------------------- /python/kmeans.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2018 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import distance 24 | import random 25 | 26 | def kmeans_1_d(data, k, max_error, max_iters, centroids): 27 | """Performs K-Means analysis using the specified centroids as starting points.""" 28 | 29 | # Sanity check. 30 | data_len = len(data) 31 | if data_len <= 1: 32 | return [], None 33 | if k > data_len: 34 | return [], None 35 | 36 | # Create the output error array; describes the error for each data point. 37 | errors = [0.0] * data_len 38 | 39 | # Create the cluster means array; describes the error for each data point. 40 | cluster_sizes = [0] * data_len 41 | 42 | # Create the output tag array. 43 | tags = [0] * data_len 44 | 45 | # Assignment step. Find the closest centroid for each data point. 46 | for data_index in range(0, data_len): 47 | for cluster_index in range(0, k): 48 | distance_to_centroid = distance.euclidian_distance_1_d(data[data_index], centroids[cluster_index]) 49 | if (cluster_index == 0) or (distance_to_centroid < errors[data_index]): 50 | tags[data_index] = cluster_index 51 | errors[data_index] = distance_to_centroid 52 | 53 | # Update step. 54 | avg_error = 0.0 55 | iter_count = 0 56 | num_relocations = 0 57 | while True: 58 | 59 | # Recompute cluster means. 60 | for i in range(0, len(centroids)): 61 | centroids[i] = 0.0 62 | for i in range(0, len(cluster_sizes)): 63 | cluster_sizes[i] = 0 64 | for data_index in range(0, data_len): 65 | cluster_index = tags[data_index] 66 | centroids[cluster_index] = centroids[cluster_index] + data[data_index] 67 | cluster_sizes[cluster_index] = cluster_sizes[cluster_index] + 1 68 | for cluster_index in range(0, k): 69 | if abs(cluster_sizes[cluster_index]) < 0.001: # Check for possible floating point zero value 70 | centroids[cluster_index] = 0.0 71 | else: 72 | centroids[cluster_index] = centroids[cluster_index] / cluster_sizes[cluster_index] 73 | 74 | # Measure each data point against it's own cluster mean, and all other cluster means. 75 | # Relocate the data point to the cluster that matches best. 76 | num_relocations = 0 77 | for data_index in range(0, data_len): 78 | for cluster_index in range(0, k): 79 | distance_to_centroid = distance.euclidian_distance_1_d(data[data_index], centroids[cluster_index]) 80 | if distance_to_centroid < errors[data_index]: 81 | tags[data_index] = cluster_index 82 | errors[data_index] = distance_to_centroid 83 | num_relocations = num_relocations + 1 84 | 85 | # Compute the average error. 86 | avg_error = sum(errors) / len(errors) 87 | 88 | iter_count = iter_count + 1 89 | 90 | if (avg_error <= max_error) or (iter_count >= max_iters) or (num_relocations <= 0): 91 | break 92 | 93 | return tags, avg_error 94 | 95 | def kmeans_equally_space_centroids_1_d(data, k, max_error, max_iters): 96 | """Performs K-Means analysis on a one dimensional array, starting with centroids that are equally distributed across the rnage of input set.""" 97 | 98 | # Sanity check. 99 | data_len = len(data) 100 | if data_len <= 1: 101 | return [], None 102 | if k > data_len: 103 | return [], None 104 | 105 | centroids = [0.0] * k 106 | 107 | # Select the k data points that are farthest apart from each other. 108 | data_min = min(data) 109 | centroids[0] = data_min 110 | data_max = max(data) 111 | centroids[k - 1] = data_max 112 | increment = (data_max - data_min) / (k - 1) 113 | for i in range(0, k): 114 | centroids[i] = data_min + (increment * i) 115 | 116 | # Perform K Means clustering. 117 | return kmeans_1_d(data, k, max_error, max_iters, centroids) 118 | 119 | def kmeans_rand_centroids_1_d(data, k, max_error, max_iters): 120 | """Performs K-Means analysis on a one dimensional array, starting with centroids that are randomly distributed across the range of the input set.""" 121 | 122 | # Sanity check. 123 | data_len = len(data) 124 | if data_len <= 1: 125 | return [] 126 | if k > data_len: 127 | return [] 128 | 129 | centroids = [0.0] * k 130 | 131 | # Randomly select starting centroids. 132 | for i in range(0, k): 133 | selected = random.randint(0, k) 134 | centroids[i] = data[selected] 135 | 136 | # Perform K Means clustering. 137 | return kmeans_1_d(data, k, max_error, max_iters, centroids) 138 | -------------------------------------------------------------------------------- /python/signals.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2020 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import statistics 24 | 25 | def smooth(data_in, window_size): 26 | """Smooths the data, which should be a list, by averaging with the given window size.""" 27 | data_in_len = len(data_in) 28 | data_out_len = data_in_len - window_size + 1 29 | if data_out_len <= 0: 30 | return data_in 31 | 32 | data_out = [] 33 | for i in range(0, data_out_len): 34 | val = statistics.mean(data_in[i:i + window_size]) 35 | data_out.append(val) 36 | return data_out 37 | -------------------------------------------------------------------------------- /python/statistics.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) 2018 Michael J Simms. All rights reserved. 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # Note class is only useful in python2 as python3 includes it's own statistics class 24 | 25 | import math 26 | 27 | def mean(data): 28 | """Computes the mean of the numbers in the array 'data'.""" 29 | mean = 0.0 30 | for datum in data: 31 | mean = mean + datum 32 | return mean / len(data) 33 | 34 | def variance(data, mean): 35 | """Computes the variance of the numbers in the array 'data'.""" 36 | numerator = 0.0 37 | for datum in data: 38 | numerator = numerator + ((datum - mean) * (datum - mean)) 39 | return numerator / (len(data) - 1) 40 | 41 | def stddev(data, mean): 42 | """Computes the standard deviation of the numbers in the array 'data'.""" 43 | var = variance(data, mean) 44 | return math.sqrt(var) 45 | -------------------------------------------------------------------------------- /rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lib_math" 3 | version = "0.0.1" 4 | authors = ["Michael J Simms "] 5 | 6 | [dependencies] 7 | #rand = "*" 8 | csv = "*" 9 | -------------------------------------------------------------------------------- /rust/src/distance.rs: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2018 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | #[allow(dead_code)] 22 | 23 | use statistics; 24 | 25 | /// Returns the Haversine distance between two points on the Earth's surface. 26 | pub fn haversine_distance(loc1_lat: f64, loc1_lon: f64, loc1_alt: f64, loc2_lat: f64, loc2_lon: f64, loc2_alt: f64) -> f64 { 27 | let mut r = 6372797.560856; // radius of the earth in meters 28 | r = r + loc2_alt - loc1_alt; 29 | 30 | let lat_arc = (loc1_lat - loc2_lat).to_radians(); 31 | let lon_arc = (loc1_lon - loc2_lon).to_radians(); 32 | 33 | let mut lat_h = (lat_arc * 0.5).sin(); 34 | lat_h = lat_h * lat_h; 35 | 36 | let mut lon_h = (lon_arc * 0.5).sin(); 37 | lon_h = lon_h * lon_h; 38 | 39 | let tmp = loc1_lat.to_radians().cos() * loc2_lat.to_radians().cos(); 40 | let rad = 2.0 * (lat_h + tmp * lon_h).sqrt().asin(); 41 | 42 | rad * r 43 | } 44 | 45 | /// Computes the Hamming distance of the two strings. 46 | pub fn hamming_distance(str1: &str, str2: &str) -> usize { 47 | let len1 = str1.len(); 48 | 49 | // The strings must be the same length. 50 | if len1 != str2.len() { 51 | return usize::max_value(); 52 | } 53 | 54 | let mut distance = 0; 55 | 56 | let str1_bytes = str1.as_bytes(); 57 | let str2_bytes = str2.as_bytes(); 58 | 59 | for i in 0..len1 { 60 | if str1_bytes[i] != str2_bytes[i] { 61 | distance = distance + 1; 62 | } 63 | } 64 | 65 | distance 66 | } 67 | 68 | /// Computes the Levenshtein distance between the two strings. 69 | pub fn levenshtein_distance(str1: &str, str2: &str) -> usize { 70 | let m = str1.len(); 71 | let n = str2.len(); 72 | 73 | // Test for empty strings. 74 | if m == 0 { 75 | return n; 76 | } 77 | if n == 0 { 78 | return m; 79 | } 80 | 81 | let mut v0 = vec![0; n]; 82 | let mut v1 = vec![0; n]; 83 | 84 | let str1_bytes = str1.as_bytes(); 85 | let str2_bytes = str2.as_bytes(); 86 | 87 | for i in 0..n { 88 | v0[i] = i; 89 | } 90 | for i in 0..m-1 { 91 | v1[0] = i + 1; 92 | 93 | for j in 0..n-1 { 94 | let mut costs = vec![0; 3]; // deletion, insertion, and substitution costs (in that order) 95 | costs[0] = v0[j + 1] + 1; 96 | costs[1] = v1[j] + 1; 97 | if str1_bytes[i] == str2_bytes[j] { 98 | costs[2] = v0[j]; 99 | } 100 | else { 101 | costs[2] = v0[j] + 1; 102 | } 103 | v1[j + 1] = statistics::min_usize(&costs); 104 | } 105 | 106 | // Copy v1 to v0. 107 | let temp_v = v0.clone(); 108 | v0 = v1.clone(); 109 | v1 = temp_v.clone(); 110 | } 111 | 112 | // Save the final distance calculation, before freeing the vector. 113 | let distance = v0[n - 1]; 114 | distance 115 | } 116 | 117 | /// Computes the Euclidian distance between the two values. 118 | pub fn euclidian_distance_1_d(pt1: f64, pt2: f64) -> f64 { 119 | let distance = (pt1 - pt2).abs(); 120 | distance 121 | } 122 | 123 | /// Computes the Euclidian distance between the two points. 124 | pub fn euclidian_distance_2_d(pt1_x: f64, pt1_y: f64, pt2_x: f64, pt2_y: f64) -> f64 { 125 | let temp_x = pt2_x - pt1_x; 126 | let temp_y = pt2_y - pt1_y; 127 | let distance = ((temp_x * temp_x) + (temp_y * temp_y)).sqrt(); 128 | distance 129 | } 130 | 131 | /// Computes the Euclidian distance between two multidimensional points. 132 | /// Points must have the same dimensionality. 133 | pub fn euclidian_distance_n_d(pt1: Vec, pt2: Vec) -> f64 { 134 | let num_dimensions = pt1.len(); 135 | let mut sum = 0.0; 136 | for dimension in 0..num_dimensions { 137 | let temp = pt2[dimension] - pt1[dimension]; 138 | sum = sum + (temp * temp); 139 | } 140 | let distance = sum.sqrt(); 141 | distance 142 | } 143 | -------------------------------------------------------------------------------- /rust/src/graphics.rs: -------------------------------------------------------------------------------- 1 | // by Michael J. Simms 2 | // Copyright (c) 2020 Michael J. Simms 3 | 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in all 12 | // copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | // SOFTWARE. 21 | 22 | #[derive(Copy, Clone)] 23 | pub struct Point { 24 | pub x: f64, 25 | pub y: f64, 26 | } 27 | 28 | impl Point { 29 | pub fn new() -> Point { 30 | Point { x: 0.0, y: 0.0 } 31 | } 32 | } 33 | 34 | // Implements the ray casting/crossing number algorithm. Returns TRUE if the point is within the bounds of the points that specify the polygon (poly is a list of points) 35 | pub fn is_point_in_polygon(test_point: Point, poly: &Vec) -> bool { 36 | 37 | // Sanity checks. 38 | let mut num_crossings = 0; 39 | let num_vertices = poly.len(); 40 | 41 | // Need at least three points to make a polygon. 42 | if num_vertices < 3 { 43 | return false; 44 | } 45 | 46 | let test_x = test_point.x; 47 | let test_y = test_point.y; 48 | for i in 0..num_vertices { 49 | 50 | // Cache the y coordinate for the first point on the edge. 51 | let mut poly_pt = poly[i]; 52 | let poly_pt1_y = poly_pt.y; 53 | 54 | // Cache the second point on the edge, handling the wrap around that happens when we close the polygon. 55 | let poly_pt2_x; 56 | let poly_pt2_y; 57 | if i == num_vertices - 1 { 58 | poly_pt = poly[0]; 59 | poly_pt2_x = poly_pt.x; 60 | poly_pt2_y = poly_pt.y; 61 | } 62 | else { 63 | poly_pt = poly[i + 1]; 64 | poly_pt2_x = poly_pt.x; 65 | poly_pt2_y = poly_pt.y; 66 | } 67 | 68 | // Test if the point is within the y limits of the edge. 69 | let crosses_y = ((poly_pt1_y <= test_y) && (poly_pt2_y > test_y)) || ((poly_pt1_y > test_y) && (poly_pt2_y <= test_y)); 70 | if crosses_y { 71 | 72 | // Test if the ray extending to the right of the point crosses the edge. 73 | let poly_pt1_x = poly[i].x; 74 | if test_x < poly_pt1_x + ((test_y - poly_pt1_y) / (poly_pt2_y - poly_pt1_y)) * (poly_pt2_x - poly_pt1_x) { 75 | num_crossings = num_crossings + 1; 76 | } 77 | } 78 | } 79 | 80 | (num_crossings & 1) != 0 81 | } 82 | 83 | // Implements the ray casting/crossing number algorithm. Returns TRUE if the point is within the bounds of the points that specify the polygon (poly is a list of points). 84 | pub fn is_point_in_poly_array(test_x: f64, test_y: f64, poly: &Vec) -> bool { 85 | 86 | // Sanity checks. 87 | let mut num_crossings = 0; 88 | let num_vertices = poly.len(); 89 | 90 | // Need at least three points to make a polygon 91 | if num_vertices < 3 { 92 | return false; 93 | } 94 | 95 | for i in 0..num_vertices { 96 | 97 | // Cache the y coordinate for the first point on the edge. 98 | let mut poly_pt = poly[i]; 99 | let poly_pt1_y = poly_pt.y; 100 | 101 | // Cache the second point on the edge, handling the wrap around that happens when we close the polygon. 102 | let poly_pt2_x; 103 | let poly_pt2_y; 104 | if i == num_vertices - 1 { 105 | poly_pt = poly[0]; 106 | poly_pt2_x = poly_pt.x; 107 | poly_pt2_y = poly_pt.y; 108 | } 109 | else { 110 | poly_pt = poly[i + 1]; 111 | poly_pt2_x = poly_pt.x; 112 | poly_pt2_y = poly_pt.y; 113 | } 114 | 115 | // Test if the point is within the y limits of the edge. 116 | let crosses_y = ((poly_pt1_y <= test_y) && (poly_pt2_y > test_y)) || ((poly_pt1_y > test_y) && (poly_pt2_y <= test_y)); 117 | if crosses_y { 118 | 119 | // Test if the ray extending to the right of the point crosses the edge. 120 | let poly_pt1_x = poly[i].x; 121 | if test_x < poly_pt1_x + ((test_y - poly_pt1_y) / (poly_pt2_y - poly_pt1_y)) * (poly_pt2_x - poly_pt1_x) { 122 | num_crossings = num_crossings + 1; 123 | } 124 | } 125 | } 126 | 127 | (num_crossings & 1) != 0 128 | } 129 | -------------------------------------------------------------------------------- /rust/src/powers.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2018 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | pub fn nearest_power_of_2(num: u32) -> u32 24 | { 25 | let mut n = 0; 26 | 27 | if num > 0 { 28 | n = num - 1; 29 | } 30 | 31 | n |= n >> 1; 32 | n |= n >> 2; 33 | n |= n >> 4; 34 | n |= n >> 8; 35 | n |= n >> 16; 36 | n = n + 1; 37 | 38 | n 39 | } 40 | -------------------------------------------------------------------------------- /rust/src/signals.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2021 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | use statistics; 24 | 25 | pub fn smooth(data_in: &Vec, window_size: usize) -> Vec { 26 | // Smooths the data, which should be a list, by averaging with the given window size. 27 | let data_in_len = data_in.len(); 28 | let data_out_len = data_in_len - window_size + 1; 29 | if data_out_len <= 0 { 30 | return data_in.to_vec(); 31 | } 32 | 33 | let mut data_out: Vec = Vec::new(); 34 | for i in 0..data_out_len { 35 | let val = statistics::average_f64(&data_in[i..i + window_size].to_vec()); 36 | data_out.push(val); 37 | } 38 | 39 | data_out 40 | } 41 | -------------------------------------------------------------------------------- /rust/src/square_matrix.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2018 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | pub type MatrixData = Vec>; 24 | 25 | pub struct SquareMatrix { 26 | data: MatrixData, 27 | size: usize, 28 | } 29 | 30 | impl SquareMatrix { 31 | pub fn new(size: usize) -> SquareMatrix { 32 | SquareMatrix { size: size, data: SquareMatrix::create_matrix(size) } 33 | } 34 | 35 | fn create_matrix(size: usize) -> MatrixData { 36 | let c: MatrixData = vec![vec![0.0; size]; size]; 37 | c 38 | } 39 | 40 | pub fn print(&mut self) { 41 | for row in &mut self.data { 42 | print!("["); 43 | for i in 0..self.size { 44 | print!("{} ", row[i]); 45 | } 46 | println!("]"); 47 | } 48 | } 49 | 50 | pub fn multiply_by_matrix(&mut self, b: SquareMatrix) { 51 | for i in 0..self.size { 52 | for j in 0..self.size { 53 | self.data[i][j] = self.data[i][j] * b.data[i][j]; 54 | } 55 | } 56 | } 57 | 58 | pub fn multiply_by_scalar(&mut self, b: f64) { 59 | for row in &mut self.data { 60 | for i in 0..self.size { 61 | row[i] = row[i] * b; 62 | } 63 | } 64 | } 65 | 66 | pub fn subtract_scalar(&mut self, b: f64) { 67 | for row in &mut self.data { 68 | for i in 0..self.size { 69 | row[i] = row[i] - b; 70 | } 71 | } 72 | } 73 | 74 | pub fn zero(&mut self) { 75 | for row in &mut self.data { 76 | for i in 0..self.size { 77 | row[i] = 0.0; 78 | } 79 | } 80 | } 81 | 82 | pub fn identity(&mut self) { 83 | let mut i = 0; 84 | for row in &mut self.data { 85 | for j in 0..self.size { 86 | if i == j { 87 | row[j] = 1.0; 88 | } 89 | else { 90 | row[j] = 0.0; 91 | } 92 | } 93 | i = i + 1; 94 | } 95 | } 96 | 97 | pub fn ones(&mut self) { 98 | for row in &mut self.data { 99 | for i in 0..self.size { 100 | row[i] = 1.0; 101 | } 102 | } 103 | } 104 | 105 | pub fn dot(&mut self, b: SquareMatrix) -> f64 { 106 | let mut dot = 0.0; 107 | for i in 0..self.size { 108 | for j in 0..b.size { 109 | dot = dot + (self.data[i][j] * self.size as f64) + (b.data[i][j] * b.size as f64); 110 | } 111 | } 112 | dot 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /rust/src/statistics.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2018 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | pub fn average_u32(data: &Vec) -> f32 { 24 | let mut sum = 0; 25 | 26 | for item in data { 27 | sum = sum + *item; 28 | } 29 | 30 | let avg = sum as f32 / data.len() as f32; 31 | avg 32 | } 33 | 34 | pub fn average_f32(data: &Vec) -> f32 { 35 | let mut sum = 0.0; 36 | 37 | for item in data { 38 | sum = sum + *item; 39 | } 40 | 41 | let denominator = data.len(); 42 | sum = sum / denominator as f32; 43 | sum 44 | } 45 | 46 | pub fn average_f64(data: &Vec) -> f64 { 47 | let mut sum = 0.0; 48 | 49 | for item in data { 50 | sum = sum + *item; 51 | } 52 | 53 | let denominator = data.len(); 54 | sum = sum / denominator as f64; 55 | sum 56 | } 57 | 58 | pub fn variance_f32(data: &Vec, mean: f32) -> f32 { 59 | let mut numerator = 0.0; 60 | 61 | for item in data { 62 | numerator = numerator + ((*item - mean) * (*item - mean)); 63 | } 64 | 65 | let denominator = (data.len() - 1) as f32; 66 | let variance = numerator / denominator; 67 | variance 68 | } 69 | 70 | pub fn variance_f64(data: &Vec, mean: f64) -> f64 { 71 | let mut numerator = 0.0; 72 | 73 | for item in data { 74 | numerator = numerator + ((*item - mean) * (*item - mean)); 75 | } 76 | 77 | let denominator = (data.len() - 1) as f64; 78 | let variance = numerator / denominator; 79 | variance 80 | } 81 | 82 | pub fn standard_deviation_f32(data: &Vec, mean: f32) -> f32 { 83 | let var = variance_f32(data, mean); 84 | let std_dev = var.sqrt(); 85 | std_dev 86 | } 87 | 88 | pub fn standard_deviation_f64(data: &Vec, mean: f64) -> f64 { 89 | let var = variance_f64(data, mean); 90 | let std_dev = var.sqrt(); 91 | std_dev 92 | } 93 | 94 | pub fn max_f32(data: &Vec) -> f32 { 95 | let mut result = data[0]; 96 | 97 | for item in data { 98 | if *item > result { 99 | result = *item; 100 | } 101 | } 102 | result 103 | } 104 | 105 | pub fn max_f64(data: &Vec) -> f64 { 106 | let mut result = data[0]; 107 | 108 | for item in data { 109 | if *item > result { 110 | result = *item; 111 | } 112 | } 113 | result 114 | } 115 | 116 | pub fn min_f32(data: &Vec) -> f32 { 117 | let mut result = data[0]; 118 | 119 | for item in data { 120 | if *item < result { 121 | result = *item; 122 | } 123 | } 124 | result 125 | } 126 | 127 | pub fn min_f64(data: &Vec) -> f64 { 128 | let mut result = data[0]; 129 | 130 | for item in data { 131 | if *item < result { 132 | result = *item; 133 | } 134 | } 135 | result 136 | } 137 | 138 | pub fn max_usize(data: &Vec) -> usize { 139 | let mut result = data[0]; 140 | 141 | for item in data { 142 | if *item > result { 143 | result = *item; 144 | } 145 | } 146 | result 147 | } 148 | 149 | pub fn min_usize(data: &Vec) -> usize { 150 | let mut result = data[0]; 151 | 152 | for item in data { 153 | if *item < result { 154 | result = *item; 155 | } 156 | } 157 | result 158 | } 159 | -------------------------------------------------------------------------------- /rust/src/vector.rs: -------------------------------------------------------------------------------- 1 | // MIT License 2 | // 3 | // Copyright © 2018 Michael J Simms. All rights reserved. 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | #[allow(dead_code)] 23 | 24 | pub type VectorData = Vec; 25 | 26 | #[derive(Clone)] 27 | pub struct Vector { 28 | data: VectorData, 29 | size: usize, 30 | } 31 | 32 | impl Vector { 33 | pub fn new(size: usize) -> Vector { 34 | Vector { size: size, data: Vector::create_vector(size) } 35 | } 36 | 37 | fn create_vector(size: usize) -> VectorData { 38 | let v: VectorData = vec![0.0; size]; 39 | v 40 | } 41 | 42 | pub fn print(&mut self) { 43 | print!("["); 44 | for i in 0..self.size { 45 | print!("{} ", self.data[i]); 46 | } 47 | println!("]"); 48 | } 49 | 50 | pub fn set(&mut self, index: usize, val: f64) { 51 | self.data[index] = val; 52 | } 53 | 54 | pub fn multiply(&mut self, b: Vector) -> f64 { 55 | let mut c = 0.0; 56 | 57 | for i in 0..self.size { 58 | c = c + self.data[i] * b.data[i]; 59 | } 60 | c 61 | } 62 | 63 | pub fn subtract(&mut self, b: Vector, c: &mut Vector) { 64 | for i in 0..self.size { 65 | c.data[i] = self.data[i] - b.data[i]; 66 | } 67 | } 68 | 69 | pub fn dot(&mut self, b: Vector) -> f64 { 70 | let mut result = 0.0; 71 | 72 | // Compute the dot product 73 | for i in 0..self.size { 74 | result = result + (self.data[i] * b.data[i]); 75 | } 76 | result 77 | } 78 | 79 | pub fn length(&mut self) -> f64 { 80 | let mut sum = 0.0; 81 | 82 | for i in 0..self.size { 83 | sum = sum + (self.data[i] * self.data[i]); 84 | } 85 | let length = sum.sqrt(); 86 | length 87 | } 88 | 89 | pub fn normalize(&mut self) { 90 | let norm = self.data.len() as f64; 91 | 92 | for i in 0..self.size { 93 | self.data[i] = self.data[i] / norm; 94 | } 95 | } 96 | 97 | pub fn cross(&mut self, a: Vector, b: Vector) { 98 | self.data[0] = (b.data[1] * a.data[2]) - (b.data[2] * a.data[1]); 99 | self.data[1] = (b.data[2] * a.data[0]) - (b.data[0] * a.data[2]); 100 | self.data[2] = (b.data[0] * a.data[1]) - (b.data[1] * a.data[0]); 101 | } 102 | } 103 | --------------------------------------------------------------------------------