Skip to content

Commit b0663e7

Browse files
committed
Brought kin_cpp to current branch
1 parent f74b635 commit b0663e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2627
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
#include "misc_linalg.h"
2+
#include <cmath>
3+
#include <cassert>
4+
#include <iostream>
5+
#include <gsl/gsl_multimin.h>
6+
using namespace blaze;
7+
/* Generates rotation matrix
8+
Params :
9+
- unit_vec(3D StaticVector) -- unit vector to apply rotation around.
10+
- theta(double) -- rotation angle (radians)
11+
Return value : 3x3 rotation StaticMatrix. */
12+
StaticMatrix<double, 3UL, 3UL> rotation_matrix(const StaticVector<double, 3UL> &unit_vec, double theta) {
13+
/* Sanitize inputs to 3D space */
14+
assert (size(unit_vec) == 3);
15+
/* Extract coordinates */
16+
double ux = unit_vec[0], uy = unit_vec[1], uz = unit_vec[2];
17+
double cos_t = cos(theta), sin_t = sin(theta);
18+
19+
StaticMatrix<double, 3UL, 3UL> rot_mat{
20+
{ pow(ux, 2) * (1 - cos_t) + cos_t,
21+
ux * uy * (1 - cos_t) - uz * sin_t,
22+
ux * ux * (1 - cos_t) + uy * sin_t },
23+
24+
{ ux * uy * (1 - cos_t) + uz * sin_t,
25+
pow(uy, 2) * (1 - cos_t) + cos_t,
26+
uy * uz * (1 - cos_t) - ux * sin_t },
27+
28+
{ ux * uz * (1 - cos_t) - uy * sin_t,
29+
uy * uz * (1 - cos_t) + ux * sin_t,
30+
pow(uz, 2) * (1 - cos_t) + cos_t }
31+
};
32+
33+
return rot_mat;
34+
}
35+
36+
/* Calculates plane from 3 points
37+
- General equation: a(x - x_{0}) + b(y - y_{0}) + c(z - z_{0}) = 0
38+
Params :
39+
- points (3x3 StaticMatrix) -- 3 points, each a column vector in 3D space
40+
Return value : 6D StaticVector -- parameters defining plane
41+
- in form [a, b, c, x_0, y_0, z_0] */
42+
StaticVector<double, 6UL> plane(StaticMatrix<double, 3UL, 3UL> &points) {
43+
/* Sanitize inputs to 3D space */
44+
assert (columns(points) == 3);
45+
/* Get 2 vectors that define a plane*/
46+
StaticVector<double, 3UL> PQ = column(points, 1) - column(points, 0);
47+
StaticVector<double, 3UL> PR = column(points, 2) - column(points, 0);
48+
49+
/* Get vector normal to plane */
50+
StaticVector<double, 3UL> normal_vec = cross(PQ, PR);
51+
52+
/* Fill return value */
53+
StaticVector<double, 3UL> col_0 = column(points, 0);
54+
StaticVector<double, 6UL> plane_vec = {
55+
normal_vec[0],
56+
normal_vec[1],
57+
normal_vec[2],
58+
col_0[0],
59+
col_0[1],
60+
col_0[2]
61+
};
62+
63+
return plane_vec;
64+
}
65+
66+
/* Calculates point on a plane given two independent variables
67+
- General equation: a(x - x_{0}) + b(y - y_{0}) + c(z - z_{0}) = 0
68+
Params :
69+
- points(3x3 StaticMatrix) -- 3 points, each a column vector in 3D space
70+
- x(double) -- x coordinate of point
71+
- y(double) -- y coordinate of point
72+
Return value : 3D StaticVector -- point on plane in form [x, y, x] */
73+
StaticVector<double, 3UL> plane_eval(StaticMatrix<double, 3UL, 3UL> &points, double x, double y) {
74+
/* Sanitize inputs to 3D space */
75+
assert (columns(points) == 3);
76+
77+
/* Get parameters defining plane and unpack them */
78+
StaticVector<double, 6> _plane = plane(points);
79+
double a = _plane[0], b = _plane[1], c = _plane[2];
80+
double x_0 = _plane[3], y_0 = _plane[4], z_0 = _plane[5];
81+
82+
/* Compute missing coordinate */
83+
double z = a / c *(x_0 - x) + b / c * (y_0 - y) + z_0;
84+
85+
/* Package point coordinates together */
86+
StaticVector<double, 3> point{x, y, z};
87+
return point;
88+
}
89+
90+
/* Fsolve for one variable
91+
(The driver function to minimize any given function)
92+
93+
To call fsolve1:
94+
95+
// Initial guess for x (e.g., x = 0)
96+
gsl_vector *initial_guess = gsl_vector_alloc(1);
97+
gsl_vector_set(initial_guess, 0, 0.0);
98+
99+
// Call the driver function to minimize the function
100+
double min_value = fsolve1(function_to_minimize, initial_guess);
101+
102+
std::cout << "The minimum value of the function is at x = " << min_value << std::endl;
103+
104+
// Free the memory
105+
gsl_vector_free(initial_guess);
106+
*/
107+
108+
double fsolve1(double (*func)(const gsl_vector *, void *), gsl_vector *initial_guess) {
109+
// Define the GSL minimization context
110+
gsl_multimin_function min_func;
111+
min_func.n = 1; // Number of parameters (we minimize over one variable here)
112+
min_func.f = func; // The function to minimize
113+
min_func.params = nullptr; // No extra parameters for the function
114+
115+
// Create a minimizer (use Nelder-Mead simplex method)
116+
gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex, 1);
117+
118+
// Set the initial guess and step size (e.g., step size = 0.1)
119+
gsl_vector *step_size = gsl_vector_alloc(1);
120+
gsl_vector_set(step_size, 0, 0.1); // Step size of 0.1 for the first (and only) parameter
121+
122+
// Set the minimizer with the function, initial guess, and step size
123+
gsl_multimin_fminimizer_set(s, &min_func, initial_guess, step_size);
124+
125+
// Perform the minimization (find the value where the function is minimized)
126+
int status;
127+
int iteration = 0;
128+
do {
129+
iteration++;
130+
131+
// Take a step
132+
status = gsl_multimin_fminimizer_iterate(s);
133+
134+
if (status) {
135+
std::cout << "Error during iteration " << iteration << std::endl;
136+
break;
137+
}
138+
139+
// Check for convergence
140+
double size = gsl_multimin_fminimizer_size(s);
141+
if (size < 1e-5) { // Convergence threshold
142+
break;
143+
}
144+
} while (true);
145+
146+
// Return the minimized value (x value where the function is minimized)
147+
double min_value = gsl_vector_get(s->x, 0);
148+
149+
// Free the memory allocated for the minimizer
150+
gsl_multimin_fminimizer_free(s);
151+
gsl_vector_free(step_size);
152+
153+
return min_value;
154+
}
155+
156+
//
157+
158+
// Fsolve for two variables (can be modified to inlcude more variables if needed)
159+
/*(The driver function to minimize any given function)
160+
To call fsolve2:
161+
162+
// Number of variables (e.g., 2 variables x1, x2)
163+
size_t n = 2;
164+
165+
// Initial guess for x1, x2 (e.g., x1 = 0, x2 = 0)
166+
gsl_vector *initial_guess = gsl_vector_alloc(n);
167+
gsl_vector_set(initial_guess, 0, 0.0);
168+
gsl_vector_set(initial_guess, 1, 0.0);
169+
170+
// Call the driver function to minimize the system of equations
171+
gsl_vector *solution = fsolve2(function_to_minimize, initial_guess, n);
172+
173+
// Print the solution (values of x1, x2, ...)
174+
std::cout << "The solution to the system is:" << std::endl;
175+
for (size_t i = 0; i < n; i++) {
176+
std::cout << "x" << i + 1 << " = " << gsl_vector_get(solution, i) << std::endl;
177+
}
178+
179+
// Free the memory
180+
gsl_vector_free(initial_guess);
181+
gsl_vector_free(solution);
182+
183+
*/
184+
// The driver function to minimize the system of equations
185+
gsl_vector* fsolve2(double (*func)(const gsl_vector *, void *), gsl_vector *initial_guess, size_t n) {
186+
// Define the GSL minimization context
187+
gsl_multimin_function min_func;
188+
min_func.n = n; // Number of parameters
189+
min_func.f = func; // The function to minimize
190+
min_func.params = nullptr; // No extra parameters for the function
191+
192+
// Create a minimizer (use Nelder-Mead simplex method)
193+
gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex, n);
194+
195+
// Set the initial guess and step size (e.g., step size = 0.1 for each parameter)
196+
gsl_vector *step_size = gsl_vector_alloc(n);
197+
for (size_t i = 0; i < n; i++) {
198+
gsl_vector_set(step_size, i, 0.1); // Set step size for each parameter
199+
}
200+
201+
// Set the minimizer with the function, initial guess, and step size
202+
gsl_multimin_fminimizer_set(s, &min_func, initial_guess, step_size);
203+
204+
// Perform the minimization (find the value where the function is minimized)
205+
int status;
206+
int iteration = 0;
207+
do {
208+
iteration++;
209+
210+
// Take a step
211+
status = gsl_multimin_fminimizer_iterate(s);
212+
213+
if (status) {
214+
std::cout << "Error during iteration " << iteration << std::endl;
215+
break;
216+
}
217+
218+
// Check for convergence
219+
double size = gsl_multimin_fminimizer_size(s);
220+
if (size < 1e-5) { // Convergence threshold
221+
break;
222+
}
223+
} while (true);
224+
225+
// Return the vector containing the minimized values (solutions to the system)
226+
gsl_vector *solution = gsl_vector_alloc(n);
227+
gsl_vector_memcpy(solution, s->x);
228+
229+
// Free the memory allocated for the minimizer and step size
230+
gsl_multimin_fminimizer_free(s);
231+
gsl_vector_free(step_size);
232+
233+
return solution;
234+
}
235+
236+
/* Return cubic function mapping double->double
237+
Params :
238+
- in -- independent variable value
239+
- out -- dependent variable value
240+
Note : i'th data point is (in[i], out[i]) */
241+
std::shared_ptr<std::function<double(double)>> cubic_spline (double in[], double out[], double length) {
242+
// Degree of polynomial is 3
243+
const int N = 3;
244+
/* Values of sum(in^n) for 0 <= n <= 2N. Highest n at lowest index */
245+
double cum_x [2 * N + 1];
246+
/* Values of sum(out * in^n) for 0 <= n <= N. Highest n at lowest index */
247+
double cum_xy [N + 1];
248+
249+
/* Populate cum_x, cum_xy */
250+
for (int n1 = 0; n1 <= 2 * N; n1++) {
251+
/* I don't fucking remember if stack pages are zeroed out on being
252+
faulted in...covering my ass -- Arnav */
253+
/* Later matrices have highest pows at lowest indices, so reverse indices here */
254+
int n = 2 * N - n1;
255+
cum_x[n] = 0;
256+
cum_xy[n] = 0;
257+
for (int i = 0; i < length; i++) {
258+
cum_x[n] += pow (in[i], n);
259+
260+
/* Account for bounds difference for cum_xy */
261+
if (n <= N) {
262+
cum_xy[n] += out[i] * pow (in[i], n);
263+
}
264+
}
265+
}
266+
267+
StaticMatrix<double, N + 1, N + 1> x_pows;
268+
StaticVector<double, N + 1> xy_pows (cum_xy);
269+
270+
/* Populate x_pows */
271+
for (int i = 0; i <= 2 * N; i++) {
272+
for (int j = 0; j <= 2 * N; j++) {
273+
x_pows(i, j) = cum_x[i + j];
274+
}
275+
}
276+
277+
/* Solve x_pows * weights = xy_pows */
278+
StaticVector<double, N + 1> coeffs = solve (x_pows, xy_pows);
279+
280+
auto lambda = [coeffs](double in) -> double {
281+
/* Extract coefficients */
282+
double a3 = coeffs[0], a2 = coeffs[1], a1 = coeffs[2], a0 = coeffs[3];
283+
/* Compute output from spline */
284+
return a3 * pow (in, 3) + a2 * pow (in, 2) + a1 * in + a0;
285+
};
286+
287+
auto spline_func = std::make_shared<std::function<double(double)>> (lambda);
288+
289+
return spline_func;
290+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef MISC_LINALG_H
2+
#define MISC_LINALG_H
3+
4+
#include <blaze/Math.h>
5+
using namespace blaze;
6+
7+
/* Generates rotation matrix
8+
Params :
9+
- unit_vec(3D StaticVector) -- unit vector to apply rotation around.
10+
- theta(double) -- rotation angle (radians)
11+
Return value : 3x3 rotation StaticMatrix. */
12+
StaticMatrix<double, 3UL, 3UL> rotation_matrix(const StaticVector<double, 3UL> &, double);
13+
14+
/* Calculates plane from 3 points
15+
- General equation: a(x - x_{0}) + b(y - y_{0}) + c(z - z_{0}) = 0
16+
Params :
17+
- points (3x3 StaticMatrix) -- 3 points, each a column vector in 3D space
18+
Return value : 6D StaticVector -- parameters defining plane
19+
- in form [a, b, c, x_0, y_0, z_0] */
20+
StaticVector<double, 6UL> plane(const StaticMatrix<double, 3UL, 3UL> &);
21+
22+
/* Calculates point on a plane given two independent variables
23+
- General equation: a(x - x_{0}) + b(y - y_{0}) + c(z - z_{0}) = 0
24+
Params :
25+
- points(3x3 StaticMatrix) -- 3 points, each a column vector in 3D space
26+
- x(double) -- x coordinate of point
27+
- y(double) -- y coordinate of point
28+
Return value : 3D StaticVector -- point on plane in form [x, y, x] */
29+
StaticVector<double, 3UL> plane_eval(const StaticMatrix<double, 3UL, 3UL> &, double, double);
30+
31+
/* Return cubic function mapping double->double
32+
Params :
33+
- in -- independent variable value
34+
- out -- dependent variable value
35+
Note : i'th data point is (in[i], out[i]) */
36+
std::shared_ptr<std::function<double(double)>> cubic_spline (double in[], double out[], double length);
37+
38+
#endif //MISC_LINALG
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <blaze/Math.h>
2+
#include <iostream>
3+
#include <cstdio>
4+
#include "../primary_elements/beam.h"
5+
int main() {
6+
Node a({0, 1, 2});
7+
Node b({3, 4, 5});
8+
Beam beam(&a, &b);
9+
10+
printf("a : %.2f, b : %.2f", beam.getInboardNode()->position[0], beam.getOutboardNode()->position[0]);
11+
return 0;
12+
}
274 KB
Binary file not shown.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include <iostream>
2+
#include "../primary_elements/node.h"
3+
#include "../primary_elements/beam.h"
4+
#include "../secondary_elements/tie.h"
5+
6+
using namespace std;
7+
8+
int main() {
9+
array<double, 3> position1 = {0.0, 0.0, 0.0};
10+
array<double, 3> position2 = {1.0, 1.0, 1.0};
11+
12+
Node node1(position1);
13+
Node node2(position2);
14+
Beam beam1(&node1, &node2);
15+
Kingpin kp1(&beam1);
16+
17+
Tie tie1(&beam1, &kp1);
18+
19+
cout << tie1.getAngle() << endl;
20+
// cout << tie1.getInboardNode() << endl;
21+
// cout << tie1.getOutboardNode() << endl;
22+
cout << tie1.getLength() << endl;
23+
24+
return 0;
25+
}

0 commit comments

Comments
 (0)