c - 某个点计算不一致后的线性回归算法
问题描述
我的程序从文件中读取值并将它们存储在 xArray 和 yArray 中。我尝试实现线性回归算法,它可以工作,但是在某个点停止正确计算并且误差越来越大之后。我的错误在哪里?所需的 f(x) : = 2x + 0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define SIZE 20 //size of the sample input array
#define iterations_number 100
#define PI 3.14159
double start_value = 5.5;
double xArray[SIZE] = { 0 };
double yArray[SIZE] = { 0 };
int array_size = sizeof(xArray) / sizeof(xArray[0]);
FILE* file;
FILE* file_xArray;
FILE* file_yArray;
FILE* sample;
void print_result(double b0, double b1, double error);
void calculate(); //calculate the best linear function
double calculateAngle(double x2, double y2, double x1, double y1);
void add_next_item_to_buffer_and_remove_last_item(double item, double* buffer);
void generate_first_sample_data_and_fill_xArray();
void generate_first_sample_data_and_fill_yArray();
void generate_first_sample_data();
void print_xArray();
void print_yArray();
void read_from_file_and_fill_xArray_and_yArray();
void reverseArray(int arr[], int start, int end);
void main(){
generate_first_sample_data();
read_from_file_and_fill_xArray_and_yArray();
reverseArray(xArray, 0, 2*SIZE);
reverseArray(yArray, 0, 2*SIZE);
calculate();
// print_xArray();
// print_yArray();
}
void add_next_item_to_buffer_and_remove_last_item(double item, double *buffer) {
for (int i = SIZE - 1; i > 0; i--) {
buffer[i] = buffer[i - 1];
}
buffer[0] = item;
}
void print_result(double b0, double b1, double error) {
printf("f(x) = %5f x + %5f\n", b1, b0);
printf("Error: %5f ", error);
}
void print_xArray() {
for (int i = 0; i < array_size; i++) {
printf("%f\n", xArray[i]);
}
}
void print_yArray() {
for (int i = 0; i <array_size; i++) {
printf("%f\n", yArray[i]);
}
}
void calculate() {
double y = 1;
double err = 5.0;
double b0 = 0.0;
double b1 = 0.0;
double alpha = 0.01; //error rate
double degree = 0;
double prediction_number = 0.0;
errno_t returnValue = fopen_s(&file, "data.txt", "w" );
fprintf(file, "SAMPLE_NO, ITERATION_NO, REF_VAL, MEASUREMENT, ERROR\n");
for (int i = 0; i < iterations_number; i++) {
int L = i % SIZE; // L - iteration length - number of samples per iteration
for (int j = 0; j < L; j++) {
y = b0 + b1 * xArray[j]; //y - predicted y value, xArray[i] - x value
}
err = y - yArray[L];
b0 = b0 - alpha * err;
b1 = b1 - alpha * err * xArray[L];
degree = calculateAngle(xArray[L], y, 0.0, 0.0);
print_result(b0, b1, err);
fprintf(file, "%.5f ", xArray[L]);
fprintf(file, "%d. ", i);
fprintf(file, "%.5f ", y);
fprintf(file, "%.5f ", degree);
fprintf(file, "%.5f\n", err);
}
fclose(file);
print_result(b0, b1, err);
}
double calculateAngle(double x2, double y2, double x1, double y1){
double deltaX = x2 - x1;
double deltaY = y2 - y1;
double rad = atan2(deltaY, deltaX); //radians
double degree = rad * (180 / PI);
return degree;
}
void generate_first_sample_data_and_fill_xArray() {
//first data randomly generated
errno_t returnValue = fopen_s(&file_xArray, "xArray.txt", "w");
for (int i = 0; i < array_size; i++) {
xArray[i] = 1.37 + i * 0.3;
fprintf(file_xArray, "%f\n", xArray[i]);
}
fclose(file_xArray);
}
void generate_first_sample_data_and_fill_yArray() {
//first data randomly generated
errno_t returnValue = fopen_s(&file_yArray, "yArray.txt", "w");
for (int i = 0; i < array_size; i++) {
yArray[i] = 1.02 + i * 2.0;
fprintf(file_yArray, "%f\n", yArray[i]);
}
fclose(file_yArray);
}
void generate_first_sample_data() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "w");
for (int i = 0; i < array_size; i++) {
xArray[i] = i;
fprintf(sample, "%f ", xArray[i]);
yArray[i] = i * 2.0;
fprintf(sample, "%f\n", yArray[i]);
}
fclose(sample);
}
void read_from_file_and_fill_xArray_and_yArray() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "r");
char line[SIZE];
const char* standard_white_space = " ";
char* xCoordinate= '\0';
char* yCoordinate= '\0';
while (fgets(line, sizeof line, sample) != NULL) {
// printf("%s\n", buffer);
// Token will point to the part before the
xCoordinate = strtok(line, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(xCoordinate), &xArray);
// Token will point to the part after the
yCoordinate = strtok(NULL, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate), &yArray);
}
fclose(sample);
}
//example of reading from file in format
//x y degree
void read_from_file() {
errno_t returnValue = fopen_s(&sample, "sample.txt", "r");
char line[sizeof(xArray)];
char* search1 = " ";
char* search2= " ";
char* token;
while (fgets(line, sizeof line, sample) != NULL) {
// printf("%s\n", buffer);
// Token will point to the part before the " "
token = strtok(line, search1);
add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &xArray);
// Token will point to the part after the " "
token = strtok(search1, search2);
add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), &yArray);
// Token will point to the part at end of the line
token = strtok(NULL, search2);
//add_next_item_to_buffer_and_remove_last_item(strtod(token, NULL), °reeArray);
}
fclose(sample);
}
void reverseArray(int arr [], int start, int end)
{
if (start >= end)
return;
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
// Recursive Function calling
reverseArray(arr, start + 1, end - 1);
}
给定样本文件 |xCoordinate yCoordinate| 示例文件 输出:输出
有时我也会 在这里得到这个异常nullptrExceptrion
yCoordinate = strtok(NULL, standard_white_space);
add_next_item_to_buffer_and_remove_last_item(atof(yCoordinate), &yArray);
解决方案
推荐阅读
- react-native - 与 Redux 一起使用的 React-Native 最佳导航解决方案
- c++ - 使用 Sublime Text 3 在 Powershell 中构建 C++ 而不是 CMD
- html - 防止两个引导容器相互重叠。?
- javascript - 为什么有些函数需要在函数名之前声明“函数”?
- php - 在其他页面 PHP MySql 中获取会话数据
- java - RecyclerView 中的网格项未正确显示
- node.js - 与 API 服务器的云存储连接域
- android - Android Studio 未检测到 USB 设备
- haskell - 为什么在 Haskell 函数应用程序中使用逗号会导致不同的类型?
- java - 斯坦福 NLP:加载标记器模型时出错(可能缺少模型文件)