├── .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 | []() []() []() [](https://www.rust-lang.org) [](https://www.python.org/) [](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 |
--------------------------------------------------------------------------------