开始设计
This commit is contained in:
@@ -0,0 +1 @@
|
||||
#include <c_LinearRegression.h>
|
||||
@@ -0,0 +1,106 @@
|
||||
#ifndef INCLUDED_C_LINEARREGRESSION_H
|
||||
#define INCLUDED_C_LINEARREGRESSION_H
|
||||
|
||||
#ifndef INCLUDED_C_BASE_H
|
||||
#include <c_Base.h>
|
||||
#endif /*INCLUDED_C_BASE_H*/
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
// Linear Regression Model Context Structure
|
||||
typedef struct {
|
||||
double slope; // Slope coefficient (Beta)
|
||||
double intercept; // Y-Intercept coefficient (Alpha)
|
||||
c_bool_t is_trained;// State flag tracking model training status
|
||||
} c_LinearRegression_t;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the Linear Regression Model context block.
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_LinearRegression_Init(c_LinearRegression_t* model) {
|
||||
if (model == NULL) return C_ERR_PARAM;
|
||||
|
||||
model->slope = 0.0;
|
||||
model->intercept = 0.0;
|
||||
model->is_trained = C_FALSE;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Train the model using Ordinary Least Squares (OLS) linear derivation math.
|
||||
* Time Complexity: O(N) | Auxiliary Space: O(1) in-place
|
||||
* @param model Pointer to the linear regression model context instance.
|
||||
* @param x Contiguous array tracking independent variable observations.
|
||||
* @param y Contiguous array tracking dependent variable target features.
|
||||
* @param num Total number of data points inside the training array sets.
|
||||
* @return C_ERR_OK if successful, C_ERR_PARAM for NULL targets,
|
||||
* or C_ERR_INVALID if variance evaluates to zero (vertical line slope anomaly).
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_LinearRegression_Fit(c_LinearRegression_t* model, const double* x, const double* y, c_size_t num) {
|
||||
if (model == NULL || x == NULL || y == NULL) return C_ERR_PARAM;
|
||||
if (num < 2) return C_ERR_PARAM; // Mandate at least two distinct points to draw a trend line
|
||||
|
||||
double sum_x = 0.0;
|
||||
double sum_y = 0.0;
|
||||
|
||||
// Step 1: Calculate the arithmetic mean values for features X and Y
|
||||
for (c_size_t i = 0; i < num; i++) {
|
||||
sum_x += x[i];
|
||||
sum_y += y[i];
|
||||
}
|
||||
double mean_x = sum_x / (double)num;
|
||||
double mean_y = sum_y / (double)num;
|
||||
|
||||
double num_covariance = 0.0;
|
||||
double den_variance = 0.0;
|
||||
|
||||
// Step 2: Accumulate sample covariance and independent feature variance maps
|
||||
for (c_size_t i = 0; i < num; i++) {
|
||||
double diff_x = x[i] - mean_x;
|
||||
num_covariance += diff_x * (y[i] - mean_y);
|
||||
den_variance += diff_x * diff_x;
|
||||
}
|
||||
|
||||
// Step 3: Guard against division-by-zero on perfectly vertical data layouts
|
||||
if (den_variance == 0.0) {
|
||||
model->is_trained = C_FALSE;
|
||||
return C_ERR_INVALID;
|
||||
}
|
||||
|
||||
// Step 4: Map final slope and intercept boundary coefficients
|
||||
model->slope = num_covariance / den_variance;
|
||||
model->intercept = mean_y - (model->slope * mean_x);
|
||||
model->is_trained = C_TRUE;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inference Lookahead: Predict the output target value for a specific input feature.
|
||||
* @param model Pointer to the constant trained model instance.
|
||||
* @param x The input independent scalar variable point.
|
||||
* @param out_val Pointer to the destination variable where the predicted Y value is written.
|
||||
* @return C_ERR_OK if successful, or C_ERR_INVALID if the model is untrained.
|
||||
*/
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_err_t c_LinearRegression_Predict(const c_LinearRegression_t* model, double x, double* out_val) {
|
||||
if (model == NULL || out_val == NULL) return C_ERR_PARAM;
|
||||
if (!model->is_trained) return C_ERR_INVALID;
|
||||
|
||||
// Execute standard linear function lookup: y = alpha + beta * x
|
||||
*out_val = model->intercept + (model->slope * x);
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /*INCLUDED_C_LINEARREGRESSION_H*/
|
||||
@@ -0,0 +1,71 @@
|
||||
#include "c_LinearRegression.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Your updated line tracing diagnostic macro
|
||||
#define EXPECT_EQ(actual, expected, msg) \
|
||||
do { \
|
||||
if ((actual) != (expected)) { \
|
||||
printf(" [X] Assert Failed: %s (Expected %d, got %d) %s:%d\n", msg, (int)(expected), (int)(actual), __FILE__, __LINE__); \
|
||||
return C_FALSE; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
// Helper macro for double comparisons with floating-point tolerance
|
||||
#define EXPECT_NEAR(actual, expected, tolerance, msg) \
|
||||
do { \
|
||||
if (fabs((actual) - (expected)) > (tolerance)) { \
|
||||
printf(" [X] Assert Failed: %s (Expected %f, got %f) %s:%d\n", msg, (double)(expected), (double)(actual), __FILE__, __LINE__); \
|
||||
return C_FALSE; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
c_bool_t test_linear_regression_ops(void) {
|
||||
c_LinearRegression_t model;
|
||||
|
||||
// Test Case 1: Param Parameter Enforcement Boundary Checks
|
||||
EXPECT_EQ(c_LinearRegression_Init(NULL), C_ERR_PARAM, "NULL model instance initializer guard missed");
|
||||
EXPECT_EQ(c_LinearRegression_Init(&model), C_ERR_OK, "Model context initialization failed");
|
||||
EXPECT_EQ(model.is_trained, C_FALSE, "Untrained model reported trained status flags on entry");
|
||||
|
||||
double pred_buffer = 0.0;
|
||||
EXPECT_EQ(c_LinearRegression_Predict(&model, 5.0, &pred_buffer), C_ERR_INVALID, "Untrained model permitted prediction inference runs");
|
||||
|
||||
// Prepare an un-ordered linear dataset mapping the pure mathematical trend line: y = 2.0 * x + 5.0
|
||||
double train_x[] = { 1.0, 2.0, 4.0, 5.0, 3.0 };
|
||||
double train_y[] = { 7.0, 9.0, 13.0, 15.0, 11.0 };
|
||||
c_size_t samples = sizeof(train_x) / sizeof(train_x[0]);
|
||||
|
||||
// Test Case 2: Core Model Fitting (Ordinary Least Squares verification)
|
||||
printf(" [LOG] Training Ordinary Least Squares Linear Regression Model...\n");
|
||||
EXPECT_EQ(c_LinearRegression_Fit(&model, train_x, train_y, samples), C_ERR_OK, "Model training fit routine failed");
|
||||
EXPECT_EQ(model.is_trained, C_TRUE, "Successful fit sequence missed toggling active trained flag status");
|
||||
|
||||
// Assert derived trend coefficients map exactly to Slope (Beta) = 2.0, Intercept (Alpha) = 5.0
|
||||
EXPECT_NEAR(model.slope, 2.0, 1e-6, "Derived model slope (Beta) coefficient mathematically incorrect");
|
||||
EXPECT_NEAR(model.intercept, 5.0, 1e-6, "Derived model y-intercept (Alpha) coefficient mathematically incorrect");
|
||||
|
||||
// Test Case 3: Inference Prediction Checking
|
||||
// Predict value for x = 10.0 -> y = 5.0 + 2.0 * 10.0 = 25.0
|
||||
EXPECT_EQ(c_LinearRegression_Predict(&model, 10.0, &pred_buffer), C_ERR_OK, "Prediction inference run crashed");
|
||||
EXPECT_NEAR(pred_buffer, 25.0, 1e-6, "Model inference lookup yielded inaccurate coordinate value");
|
||||
printf(" [STAT] Model Trained. Equation: y = %.2f + %.2fx | Prediction(x=10): %.2f\n", model.intercept, model.slope, pred_buffer);
|
||||
|
||||
// Test Case 4: Division-by-Zero Vertical Alignment Mathematical Anomaly Check
|
||||
double vertical_x[] = { 3.0, 3.0, 3.0 };
|
||||
double vertical_y[] = { 1.0, 5.0, 9.0 };
|
||||
EXPECT_EQ(c_LinearRegression_Fit(&model, vertical_x, vertical_y, 3), C_ERR_INVALID, "Vertical line infinite slope anomaly bypassed zero variance filter");
|
||||
EXPECT_EQ(model.is_trained, C_FALSE, "Failed fit sequence left model registered in an active trained state");
|
||||
|
||||
return C_TRUE;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("=== Starting Framework Verification: c_LinearRegression ===\n");
|
||||
if (test_linear_regression_ops()) {
|
||||
printf(" [PASS] Ordinary Least Squares Linear Regression Matrix Pipelines Verified.\n");
|
||||
} else {
|
||||
printf(" [FAIL] Mathematical Linear Modeling Processing Anomaly Intercepted.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user