' linear_regression.pb — Linear regression with gradient descent
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL xData(50) AS DOUBLE
    LOCAL yData(50) AS DOUBLE
    LOCAL numPoints AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL m AS DOUBLE
    LOCAL b AS DOUBLE
    LOCAL learningRate AS DOUBLE
    LOCAL numEpochs AS LONG
    LOCAL epoch AS LONG
    LOCAL predicted AS DOUBLE
    LOCAL errorVal AS DOUBLE
    LOCAL dm AS DOUBLE
    LOCAL db AS DOUBLE
    LOCAL totalError AS DOUBLE
    LOCAL mse AS DOUBLE
    LOCAL rSquared AS DOUBLE
    LOCAL meanY AS DOUBLE
    LOCAL ssRes AS DOUBLE
    LOCAL ssTot AS DOUBLE
    LOCAL xMean AS DOUBLE
    LOCAL yMean AS DOUBLE
    LOCAL tempVal AS DOUBLE
    LOCAL iter AS LONG
    LOCAL sampleIdx AS LONG
    LOCAL convergenceVal AS DOUBLE

    numPoints = 10
    learningRate = 0.01
    numEpochs = 100

    PRINT "=== Linear Regression ==="
    PRINT "Points: " + STR$(numPoints)

    FOR i = 0 TO numPoints - 1
        xData(i) = i * 1.0
        yData(i) = 3.0 * i * 1.0 + 5.0 + i MOD 3 * 2
    NEXT i

    PRINT "Data:"
    FOR i = 0 TO numPoints - 1
        PRINT "  x=" + STR$(xData(i)) + " y=" + STR$(yData(i))
    NEXT i

    m = 0.0
    b = 0.0

    FOR epoch = 1 TO numEpochs
        dm = 0.0
        db = 0.0
        totalError = 0.0

        FOR i = 0 TO numPoints - 1
            predicted = m * xData(i) + b
            errorVal = predicted - yData(i)
            dm = dm + errorVal * xData(i)
            db = db + errorVal
            totalError = totalError + errorVal * errorVal
        NEXT i

        dm = dm / numPoints
        db = db / numPoints
        mse = totalError / numPoints

        m = m - learningRate * dm
        b = b - learningRate * db

        IF epoch / 20 * 20 = epoch THEN
            PRINT "  Epoch " + STR$(epoch) + ": m=" + STR$(m) + " b=" + STR$(b) + " MSE=" + STR$(mse)
        END IF
    NEXT epoch

    PRINT "Final: y = " + STR$(m) + "x + " + STR$(b)

    meanY = 0
    FOR i = 0 TO numPoints - 1
        meanY = meanY + yData(i)
    NEXT i
    meanY = meanY / numPoints

    ssRes = 0
    ssTot = 0
    FOR i = 0 TO numPoints - 1
        predicted = m * xData(i) + b
        ssRes = ssRes + (yData(i) - predicted) * (yData(i) - predicted)
        ssTot = ssTot + (yData(i) - meanY) * (yData(i) - meanY)
    NEXT i

    IF ssTot > 0 THEN
        rSquared = 1.0 - ssRes / ssTot
    ELSE
        rSquared = 1.0
    END IF
    PRINT "R-squared: " + STR$(rSquared)

    PRINT "Predictions:"
    FOR i = 0 TO numPoints - 1
        predicted = m * xData(i) + b
        PRINT "  x=" + STR$(xData(i)) + " actual=" + STR$(yData(i)) + " pred=" + STR$(predicted)
    NEXT i

    PRINT "=== End Linear Regression ==="
    FUNCTION = 0
END FUNCTION
