' perceptron.pb — Perceptron learning algorithm
#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN() AS LONG
    LOCAL weights(10) AS DOUBLE
    LOCAL bias AS DOUBLE
    LOCAL inputs(10) AS DOUBLE
    LOCAL numFeatures AS LONG
    LOCAL i AS LONG
    LOCAL j AS LONG
    LOCAL k AS LONG
    LOCAL epoch AS LONG
    LOCAL numEpochs AS LONG
    LOCAL learningRate AS DOUBLE
    LOCAL sumVal AS DOUBLE
    LOCAL outputVal AS DOUBLE
    LOCAL targetVal AS DOUBLE
    LOCAL errorVal AS DOUBLE
    LOCAL weightUpdate AS DOUBLE
    LOCAL converged AS LONG
    LOCAL correctCount AS LONG
    LOCAL totalSamples AS LONG
    LOCAL sample AS LONG
    LOCAL numSamples AS LONG
    LOCAL predictions(20) AS LONG
    LOCAL prediction AS LONG

    numFeatures = 2
    learningRate = 0.1
    numEpochs = 50

    PRINT "=== Perceptron Learning ==="
    PRINT "Features: " + STR$(numFeatures)

    weights(0) = 0.0
    weights(1) = 0.0
    bias = 0.0

    numSamples = 4

    FOR epoch = 1 TO numEpochs
        converged = 1
        correctCount = 0

        FOR sample = 0 TO numSamples - 1
            IF sample = 0 THEN inputs(0) = 0.0
            IF sample = 0 THEN inputs(1) = 0.0
            IF sample = 0 THEN targetVal = 0.0

            IF sample = 1 THEN inputs(0) = 0.0
            IF sample = 1 THEN inputs(1) = 1.0
            IF sample = 1 THEN targetVal = 0.0

            IF sample = 2 THEN inputs(0) = 1.0
            IF sample = 2 THEN inputs(1) = 0.0
            IF sample = 2 THEN targetVal = 0.0

            IF sample = 3 THEN inputs(0) = 1.0
            IF sample = 3 THEN inputs(1) = 1.0
            IF sample = 3 THEN targetVal = 1.0

            sumVal = bias
            FOR i = 0 TO numFeatures - 1
                sumVal = sumVal + inputs(i) * weights(i)
            NEXT i

            IF sumVal > 0 THEN
                outputVal = 1.0
            ELSE
                outputVal = 0.0
            END IF

            errorVal = targetVal - outputVal
            IF errorVal <> 0 THEN converged = 0

            bias = bias + learningRate * errorVal
            FOR i = 0 TO numFeatures - 1
                weights(i) = weights(i) + learningRate * errorVal * inputs(i)
            NEXT i

            IF outputVal = targetVal THEN correctCount = correctCount + 1
        NEXT sample

        IF epoch = numEpochs OR epoch / 10 * 10 = epoch THEN
            PRINT "  Epoch " + STR$(epoch) + ": " + STR$(correctCount) + "/" + STR$(numSamples) + " correct"
        END IF
    NEXT epoch

    PRINT "Final weights: w0=" + STR$(weights(0)) + " w1=" + STR$(weights(1)) + " b=" + STR$(bias)

    PRINT "Testing AND function:"
    FOR j = 0 TO 3
        IF j = 0 THEN inputs(0) = 0.0
        IF j = 0 THEN inputs(1) = 0.0
        IF j = 1 THEN inputs(0) = 0.0
        IF j = 1 THEN inputs(1) = 1.0
        IF j = 2 THEN inputs(0) = 1.0
        IF j = 2 THEN inputs(1) = 0.0
        IF j = 3 THEN inputs(0) = 1.0
        IF j = 3 THEN inputs(1) = 1.0

        sumVal = bias
        FOR i = 0 TO numFeatures - 1
            sumVal = sumVal + inputs(i) * weights(i)
        NEXT i
        IF sumVal > 0 THEN prediction = 1 ELSE prediction = 0
        PRINT "  " + STR$(inputs(0)) + " AND " + STR$(inputs(1)) + " = " + STR$(prediction)
    NEXT j

    PRINT "=== End Perceptron ==="
    FUNCTION = 0
END FUNCTION
