Drawing a regression line in C#

139 views Asked by At

The Python code gives me the following plot:

enter image description here

C# code gives me the following plot:

enter image description here

It is obvious that Python code is more accurate as the scales of the lines are preserved and the regression line goes through more points.

What is wrong with my C# code?


.

Python code

# Fit2.py
import numpy as np

def ReadDataFromFile(data_file_path):
    """
    Reads data from a file assuming two columns of numbers, separated by whitespace.
    Returns two lists, one for x-values and one for y-values.
    """
    with open(data_file_path, 'r') as file:
        lines = file.readlines()

    x_values = []
    y_values = []

    for line in lines:
        parts = line.strip().split()
        if len(parts) == 2:
            x_values.append(float(parts[0]))
            y_values.append(float(parts[1]))

    return x_values, y_values

def CreateRegressionLine(x_values, y_values):
    """
    Creates a regression line based on log-log transformed data.
    Returns two lists containing the log-space points of the regression line.
    """
    log_x_values = np.log(x_values)
    log_y_values = np.log(y_values)

    # Fit the regression using np.polyfit for a first degree polynomial, which is a linear fit
    slope, intercept = np.polyfit(log_x_values, log_y_values, 1)

    # Create the regression line in log space
    regression_log_y_values = slope * log_x_values + intercept

    # Convert the regression line back to linear space
    regression_y_values = np.exp(regression_log_y_values)

    return x_values, regression_y_values.tolist()

.

C# code

public static class Fit2
    {
        public static Tuple<List<double>, List<double>> ReadDataFromFile(string filePath)
        {
            var xList = new List<double>();
            var yList = new List<double>();

            foreach (var line in File.ReadAllLines(filePath))
            {
                if (line.StartsWith("#")) continue; // Skip the comment lines

                var parts = line.Split('\t');
                if (parts.Length == 2)
                {
                    if (double.TryParse(parts[0], out var x) && double.TryParse(parts[1], out var y))
                    {
                        xList.Add(x);
                        yList.Add(y);
                    }
                }
            }

            return Tuple.Create(xList, yList);
        }

        public static Tuple<double, double> CalculateLinearRegressionCoefficients(double[] xValues, double[] yValues)
        {
            if (xValues.Length != yValues.Length)
            {
                throw new ArgumentException("Input arrays must have the same length.");
            }

            var (a, b) = SimpleRegression.Fit(xValues, yValues);
            return Tuple.Create(a, b);
        }

        public static Tuple<List<double>, List<double>> CreateRegressionLine(List<double> xList, List<double> yList)
        {
            var xValues = xList.ToArray();
            var yValues = yList.ToArray();
            var coefficients = CalculateLinearRegressionCoefficients(xValues, yValues);

            var xVals = new List<double> { xValues.First(), xValues.Last() };
            var yVals = xVals.Select(x => coefficients.Item1 + coefficients.Item2 * x).ToList();

            return Tuple.Create(xVals, yVals);
        }
    }
0

There are 0 answers