开始设计
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
#ifndef INCLUDED_C_VECTOR_H
|
||||
#define INCLUDED_C_VECTOR_H
|
||||
|
||||
#ifndef INCLUDED_C_BASE_H
|
||||
#include <c_Base.h>
|
||||
#endif /*INCLUDED_C_BASE_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
typedef struct {
|
||||
double* components; // Contiguous array block tracking dimension coefficients
|
||||
c_size_t dimensions; // Size of the coordinate dimension (N)
|
||||
} c_Vector_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
c_err_t c_Vector_Init(c_Vector_t* vec, c_size_t dimensions);
|
||||
|
||||
void c_Vector_Destroy(c_Vector_t* vec);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
/**
|
||||
* Euclidean Vector Addition: res = v1 + v2
|
||||
* Time Complexity: O(N) | Auxiliary Space: O(1)
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_Add(c_Vector_t* res, const c_Vector_t* v1, const c_Vector_t* v2) {
|
||||
if (res == NULL || v1 == NULL || v2 == NULL) return C_ERR_PARAM;
|
||||
if (v1->dimensions != v2->dimensions || v1->dimensions != res->dimensions) return C_ERR_FAIL;
|
||||
|
||||
for (c_size_t i = 0; i < v1->dimensions; i++) {
|
||||
res->components[i] = v1->components[i] + v2->components[i];
|
||||
}
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_Sub(c_Vector_t* res, const c_Vector_t* v1, const c_Vector_t* v2) {
|
||||
if (res == NULL || v1 == NULL || v2 == NULL) return C_ERR_PARAM;
|
||||
if (v1->dimensions != v2->dimensions || v1->dimensions != res->dimensions) return C_ERR_FAIL;
|
||||
|
||||
for (c_size_t i = 0; i < v1->dimensions; i++) {
|
||||
res->components[i] = v1->components[i] - v2->components[i];
|
||||
}
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dot Product (Scalar Product): v1 · v2
|
||||
* Time Complexity: O(N)
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_DotProduct(const c_Vector_t* v1, const c_Vector_t* v2, double* out_scalar) {
|
||||
if (v1 == NULL || v2 == NULL || out_scalar == NULL) return C_ERR_PARAM;
|
||||
if (v1->dimensions != v2->dimensions) return C_ERR_FAIL;
|
||||
|
||||
double dot = 0.0;
|
||||
for (c_size_t i = 0; i < v1->dimensions; i++) {
|
||||
dot += v1->components[i] * v2->components[i];
|
||||
}
|
||||
|
||||
*out_scalar = dot;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the Euclidean Magnitude (L2 Norm / Length): ||v|| = sqrt(v · v)
|
||||
* Time Complexity: O(N)
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
double c_Vector_Magnitude(const c_Vector_t* vec) {
|
||||
if (vec == NULL || vec->dimensions == 0) return 0.0;
|
||||
|
||||
double sum_sq = 0.0;
|
||||
for (c_size_t i = 0; i < vec->dimensions; i++) {
|
||||
sum_sq += vec->components[i] * vec->components[i];
|
||||
}
|
||||
return sqrt(sum_sq);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Vector Normalization (Unit Vector Scaling): v_hat = v / ||v||
|
||||
* Time Complexity: O(N)
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_Normalize(c_Vector_t* vec) {
|
||||
if (vec == NULL || vec->dimensions == 0) return C_ERR_PARAM;
|
||||
|
||||
double mag = c_Vector_Magnitude(vec);
|
||||
if (mag == 0.0) return C_ERR_FAIL; // Prevent division-by-zero on zero-vectors
|
||||
|
||||
for (c_size_t i = 0; i < vec->dimensions; i++) {
|
||||
vec->components[i] /= mag;
|
||||
}
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vector Scalar Multiplication (In-place Scaling): v = alpha * v
|
||||
* Time Complexity: O(N) | Auxiliary Space: O(1)
|
||||
* @param vec Pointer to the Euclidean vector instance.
|
||||
* @param alpha The scalar scaling factor coefficient.
|
||||
* @return C_ERR_OK if successful, C_ERR_PARAM if vec or components are NULL.
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_Scale(c_Vector_t* vec, double alpha) {
|
||||
if (vec == NULL || vec->components == NULL) return C_ERR_PARAM;
|
||||
|
||||
// Linear unrolled loops pass across N-dimensional coordinates
|
||||
for (c_size_t i = 0; i < vec->dimensions; i++) {
|
||||
vec->components[i] *= alpha;
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the Euclidean Distance between two vectors: result = ||a - b||
|
||||
* Time Complexity: O(N) | Auxiliary Space: O(1) in-place
|
||||
* @param a Pointer to the first vector instance.
|
||||
* @param b Pointer to the second vector instance.
|
||||
* @param result Pointer to the destination variable where the scalar distance is written.
|
||||
* @return C_ERR_OK if successful, C_ERR_PARAM for NULL targets,
|
||||
* or C_ERR_FAIL for unequal dimensions.
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_DistanceTo(const c_Vector_t* a, const c_Vector_t* b, double* result) {
|
||||
if (a == NULL || b == NULL || result == NULL) return C_ERR_PARAM;
|
||||
if (a->components == NULL || b->components == NULL) return C_ERR_PARAM;
|
||||
if (a->dimensions != b->dimensions) return C_ERR_FAIL;
|
||||
|
||||
double sum_sq_diff = 0.0;
|
||||
|
||||
// Linear unrolled coordinate passes tracking differences across N-dimensions
|
||||
for (c_size_t i = 0; i < a->dimensions; i++) {
|
||||
double diff = a->components[i] - b->components[i];
|
||||
sum_sq_diff += diff * diff;
|
||||
}
|
||||
|
||||
*result = sqrt(sum_sq_diff);
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the direction (unit vector) of a given vector: result = vector / ||vector||
|
||||
* Time Complexity: O(N) | Auxiliary Space: O(1) in-place
|
||||
* @param result Pointer to the destination vector where the direction components are written.
|
||||
* @param vector Pointer to the source input vector.
|
||||
* @return C_ERR_OK if successful, C_ERR_PARAM for NULL targets,
|
||||
* or C_ERR_INVALID for unequal dimensions or zero-magnitude origin vectors.
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_Vector_Direction(c_Vector_t* result, const c_Vector_t* vector) {
|
||||
if (result == NULL || vector == NULL) return C_ERR_PARAM;
|
||||
if (result->components == NULL || vector->components == NULL) return C_ERR_PARAM;
|
||||
if (result->dimensions != vector->dimensions) return C_ERR_INVALID;
|
||||
|
||||
// Step 1: Calculate the magnitude of the input vector (L2 Norm)
|
||||
double sum_sq = 0.0;
|
||||
for (c_size_t i = 0; i < vector->dimensions; i++) {
|
||||
double val = vector->components[i];
|
||||
sum_sq += val * val;
|
||||
}
|
||||
double magnitude = sqrt(sum_sq);
|
||||
|
||||
// Step 2: Prevent division-by-zero on origin vectors (magnitude == 0)
|
||||
if (magnitude == 0.0) return C_ERR_INVALID;
|
||||
|
||||
// Step 3: Compute the unit vector direction components
|
||||
for (c_size_t i = 0; i < vector->dimensions; i++) {
|
||||
result->components[i] = vector->components[i] / magnitude;
|
||||
}
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
#endif /*INCLUDED_C_VECTOR_H*/
|
||||
Reference in New Issue
Block a user