Workarounds for High Floating-Point Error in NumPy Arrays Raised to Powers

138 views Asked by At

I have data that represents responses from a 24(?)-bit A/D converter. I am setting up the data to go into a polynomial regression in the function below, but I am getting detrimental amounts of floating-point error, so much so that it makes the coefficients of my regression completely unusable later.

The data, once normalized, ranges between -1 and 1. I am getting floating-point errors of roughly ~0.15 in terms that go up to the fourth degree. Due to extraneous reasons, I can't lower the degree of the regression terms, but thank you @Robert Dodier for pointing out that this method, in general, gets fairly unstable when higher degrees are added.

Is there a way to reduce the floating-point error? Speed nor memory isn't the chief goal here: the accuracy needs to be close to exact, if possible. The data set is pretty small (~ 400 rows).

I also tried using the gmpy2 library's "mpfr" class, but that didn't seem to make a difference. For completeness, I've included that version, too.

After this function, I simply feed the data into a QR-decomposed regression (see below).

After processing the data, I also checked if the floating-point error could be attributed to the regression, but when I run an SVD-style regression, I get almost identical coefficients as in the QR-style, so that is not the problem.

Here are those functions:

import numpy as np
def load_data(path):
    data = np.loadtxt(path, delimiter=',')

    # Features
    A = data[:, 1:3]

    # Normalize the data
    A /= (2 ** 24)

    # Extract columns P and T
    P = A[:, 0]
    T = A[:, 1]

    # Compute new columns based on P and T
    col_ones = np.ones_like(P, dtype=float)
    T2 = T ** 2
    T3 = T ** 3
    PT = P * T
    PT2 = P * (T ** 2)

    # ... continue making features

    # Combine the new columns into a new array
    A = np.column_stack((col_ones, T, T2, T3, P, PT, PT2)) # ... add higher degree features
    b = data[:, 0]  # ref

    return A, b
import gmpy2
from gmpy2 import mpfr
def load_data_gmpy(path):
    data = np.loadtxt(path, delimiter=',', skiprows=15)

    # Features
    b = data[:, 0]  # ref
    P = data[:, 1]
    T = data[:, 2]

    gmpy2.set_context(gmpy2.context())
    with gmpy2.local_context() as ctx:
        ctx.precision = 2000

        # Normalize the data
        P = [mpfr(p) / (2 ** 24) for p in P]
        T = [mpfr(t) / (2 ** 24) for t in T]

        # Compute new columns based on P and T
        col1 = np.ones_like(P, dtype=float)
        T2 =   np.array([float(t ** 2) for t in T])
        T3 =   np.array([float(t ** 3) for t in T])
        PT =   np.array([float(p * t) for p, t in zip(P, T)])
        PT2 =  np.array([float(p * (t ** 2)) for p, t in zip(P, T)])
        # ... continue making features

        # Convert the results back to numpy arrays
        # add higher-degree features here...
        A = np.column_stack((col1, np.array(T, dtype=float), T2, T3, np.array(P, dtype=float), PT, PT2)) 

        return A, b

EDIT: Here is the other code I'm using:

def do_qr_regression(X, y):
    # QR decomposition
    Q, R = np.linalg.qr(X)
    beta = np.linalg.inv(R).dot(Q.T).dot(y)

    # predict using coefficients
    yhat = X.dot(beta)

    return beta, yhat


def do_svd_regression(X, y):
    # calculate coefficients

    beta = np.linalg.pinv(X).dot(y)
    # predict using coefficients
    yhat = X.dot(beta)

    return beta, yhat


if __name__ == '__main__':
    data, ref = load_data("path\to\file.txt")

    coefs_qr, values = do_qr_regression(data, ref)
    residuals_qr: np.array = values - ref

    coefs_svd, values = do_svd_regression(data, ref)
    residuals_svd: np.array = values - ref

    plt.plot(residuals_qr, 'r-', label='QR')
    plt.plot(residuals_svd, 'g-', label='SVD')

    plt.xlabel('Index')
    plt.ylabel('Residuals')  
    plt.title('Comparison of Residuals')

    plt.legend()
    plt.grid()
    plt.show()

    coefs_qr = np.array(coefs_qr)
    coefs_svd = np.array(coefs_svd)

    # Combine the coefficients into a single array for easier handling
    coefficients = np.column_stack((coefs_qr, coefs_svd))

    fig, ax = plt.subplots()

    # Hide the axes
    ax.axis('tight')
    ax.axis('off')

    table = ax.table(cellText=coefficients, colLabels=['QR', 'SVD'], loc='center')

    plt.show()

Here is the data I'm working with, comma-separated:

-3.79209332168102E-02,7099245.9,7858558.6,0
-1.70869659632444E-02,7100756.73333333,7871731.93333333,0
2.81271850690246E-03,7102327.96666667,7884444.56666667,0
9.36040934175253E-03,7103800.66666667,7895645.66666667,0
-2.79413126409054E-02,7105061.4,7904756.23333333,0
-8.74655845109373E-04,7106050,7911871.56666667,0
6.24037310481071E-02,7106884.86666667,7916973.93333333,0
-2.94671542942524E-02,7107334.73333333,7920926.13333333,0
-3.12367863953114E-02,7107785.43333333,7923975.76666667,0
-1.45234884694219E-02,7108178.7,7926395.46666667,0
-1.92804485559464E-02,7108474,7928171.03333333,0
-4.53804135322571E-02,7108595.13333333,7929486.1,0
-5.98167441785336E-03,7108821.33333333,7930345.16666667,0
1.31415268406272E-02,7108845.83333333,7931080.26666667,0
2.4978460278362E-03,7108934.23333333,7931916.93333333,0
2.45027570053935E-03,7109045.6,7932515.3,0
9.87916067242622E-03,7109136.06666667,7932965.66666667,0
4.31683212518692E-02,7109269.63333333,7933144.7,0
2.00799219310284E-02,7109163.5,7933265.43333333,0
-1.38221913948655E-02,7109125.3,7933400.83333333,0
6.25846162438393E-02,7109318.86666667,7933660.8,0
3.29688005149364E-02,7109344.7,7933879.2,0
-0.049491997808218,7109224.43333333,7934110.6,0
5.38606084883213E-02,7109377.9,7934038.76666667,0
0.046255461871624,7109361.93333333,7933981.06666667,0
-2.44040284305811E-02,7109167,7934010.16666667,0
-3.04582342505455E-03,7109178.06666667,7934082.06666667,0
-2.04245466738939E-02,7109236.86666667,7934336.33333333,0
3.32059040665627E-02,7109441.43333333,7934345.6,0
9.03827371075749E-04,7109281.06666667,7934420.7,0
-3499.73901367188,1202227.26666667,7934381.06666667,0
-2799.94750976563,2304463.93333333,7934337.03333333,0
-2100.15991210938,3449484.63333333,7934287.53333333,0
-1400.3271484375,4635445.83333333,7934274.23333333,0
-699.855041503906,5858549,7934317.1,0
-1.61615032702684E-02,7109198.86666667,7934278.73333333,0
699.784729003906,8378929.6,7934309.36666667,0
1400.33154296875,9658856.5,7934361.6,0
2100.10986328125,10935471.5666667,7934317.63333333,0
2799.98217773438,12201155.9333333,7934394.7,0
3499.77807617188,13448160.3333333,7934492.96666667,0
2100.14331054688,10935360.0666667,7934492,0
699.819885253906,8379085,7934628.4,0
-699.844909667969,5858840.93333333,7934707.96666667,0
-2100.10327148438,3450137.6,7934749.63333333,0
-3499.79321289063,1202676.8,7934767.03333333,0
8.03543347865343E-03,7109186.6,7934803.13333333,0
-9.97814815491438E-03,7109341.6,7934805.36666667,0
1.38494540005922E-02,7109324.26666667,7934681.5,0
-9.96059738099575E-03,7109348.36666667,7934635.8,0
-1.35194389149547E-02,7109378.2,7934483.73333333,0
-3.13356779515743E-02,7109289.9,7934504.9,0
-4.50224168598652E-02,7109315.33333333,7934413.96666667,0
6.23549288138747E-03,7109341.03333333,7934317.83333333,0
-3.34550850093365E-02,7108801.1,7929951.3,0
1.12465918064117E-02,7107938,7920887.5,0
-1.28802107647061E-02,7106526.06666667,7910323.06666667,0
-0.039332490414381,7105237.73333333,7900160.56666667,0
-0.043127778917551,7104207.3,7891344.73333333,0
-1.92340034991503E-02,7103242.8,7884079.7,0
-4.84014675021172E-02,7102440.16666667,7878276.76666667,0
-4.76139895617962E-02,7101828.73333333,7873784.73333333,0
3.18983495235443E-02,7101437.2,7870437.93333333,0
9.64516401290894E-02,7101117.96666667,7867993.23333333,0
8.89699254184961E-03,7100847.33333333,7866227.33333333,0
-3.06270942091942E-02,7100583.8,7864736,0
5.08495047688484E-03,7100603.36666667,7863470.23333333,0
-0.010664333589375,7100353.5,7862663.23333333,0
2.65998281538486E-02,7100255.1,7862184.06666667,0
6.04479247704148E-03,7100135.13333333,7862000.73333333,0
-1.09656411223114E-03,7100172.4,7861730.8,0
-4.44185733795166E-03,7100128.23333333,7861559.9,0
-4.51760971918702E-03,7099993.9,7861277,0
-1.36335138231516E-02,7100083.4,7861058.4,0
-2.23144199699163E-02,7100031,7861020.8,0
-2.40478087216616E-02,7100023.73333333,7861114.53333333,0
0.022402485832572,7100087.36666667,7861231.93333333,0
-4.91335950791836E-02,7099976.53333333,7861280.7,0
-5.69252856075764E-03,7100084.96666667,7861182.93333333,0
-4.99452725052834E-02,7099891.23333333,7861115.36666667,0
3.33451516926289E-02,7100095.53333333,7861021.03333333,0
1.38003788888454E-02,7100033.56666667,7861150.43333333,0
2.38548628985882E-02,7100072.3,7861265.3,0
-4.68269409611821E-03,7100125.73333333,7861413.7,0
-3499.7578125,1123048.16666667,7861512.4,0
-2799.97534179688,2238191.83333333,7861524.56666667,0
-2100.11962890625,3397073.1,7861466.73333333,0
-1400.32946777344,4596996.43333333,7861535.36666667,0
-699.830017089844,5834631.26666667,7861499.76666667,0
-1.43672842532396E-02,7100015.03333333,7861518.9,0
699.810241699219,8384897.4,7861349.3,0
1400.34008789063,9679774.6,7861376.6,0
2100.12841796875,10971193.2666667,7861391.83333333,0
2799.93481445313,12251729.0333333,7861329.36666667,0
3499.79321289063,13513466.1666667,7861291.8,0
2100.072265625,10971180.2333333,7861337.43333333,0
699.802185058594,8384749.86666667,7861384.66666667,0
-699.831359863281,5834669.86666667,7861344.13333333,0
-2100.1416015625,3397190.4,7861383.76666667,0
-3499.73583984375,1122820.1,7861450.23333333,0
-1.53773836791515E-02,7099952.66666667,7861562.16666667,0
2.16550659388304E-02,7100005.5,7861625.33333333,0
1.52593497186899E-02,7100141,7861707.73333333,0
5.74888987466693E-03,7100072.46666667,7861745.36666667,0
-4.55636046826839E-02,7100108.8,7861690.1,0
2.12178695946932E-02,7100126.8,7861712.5,0
8.85779663803987E-05,7100150.3,7861695.1,0
3.49641516804695E-02,7100172.93333333,7861648.96666667,0
2.02182307839394E-02,7099726.8,7857342.46666667,0
4.49221767485142E-02,7098711.5,7848147.13333333,0
-8.8534401729703E-03,7097407.46666667,7837623.96666667,0
3.99499833583832E-02,7096186.56666667,7827610.93333333,0
-2.05677356570959E-02,7095130.56666667,7819117.36666667,0
-1.31802512332797E-02,7094238.83333333,7812281.93333333,0
-1.42691014334559E-02,7093479.46666667,7806904.6,0
-0.012847593985498,7092893.4,7802742.43333333,0
-2.66020242124796E-02,7092492.5,7799630.43333333,0
-0.018302321434021,7092206.46666667,7797321.86666667,0
5.29859401285648E-02,7092082.1,7795496.43333333,0
7.84578826278448E-03,7091791.5,7794286.1,0
-5.35906804725528E-03,7091603.5,7793303.96666667,0
-2.07541678100824E-02,7091501.26666667,7792598.83333333,0
1.80722959339619E-02,7091396.2,7791806.6,0
-3.94488051533699E-02,7091242.73333333,7791149.7,0
3.63344862125814E-03,7091250.63333333,7790762.53333333,0
-4.55112680792809E-02,7091237.03333333,7790489.26666667,0
-2.56204847246408E-02,7091167.66666667,7790459.83333333,0
-6.77033793181181E-03,7091144.66666667,7790522.96666667,0
-1.52006316930056E-02,7091146.06666667,7790626.46666667,0
-1.74931231886148E-02,7091231.06666667,7790489.6,0
3.04559525102377E-02,7091258.33333333,7790312.63333333,0
1.87910366803408E-02,7091165.03333333,7790190.86666667,0
-2.39088479429483E-02,7091008.23333333,7790078,0
6.64425388094969E-05,7091084.43333333,7790061.56666667,0
-2.25651804357767E-02,7091043.03333333,7790273.06666667,0
2.07707360386848E-02,7091126.56666667,7790437.6,0
2.37347651273012E-02,7091263.5,7790441.1,0
-5.41624277830124E-02,7091120.63333333,7790323.3,0
-3499.80859375,1044735.63333333,7790352.43333333,0
-2800.00073242188,2172890.5,7790237.03333333,0
-2100.14575195313,3345007.56666667,7790201.13333333,0
-1400.36584472656,4558900.56666667,7790226.4,0
-699.809997558594,5810935.03333333,7790239.93333333,0
4.18546199798584E-02,7091075.83333333,7790161.23333333,0
699.776672363281,8390556.96666667,7790070.46666667,0
1400.3115234375,9700408.83333333,7790018.73333333,0
2100.16650390625,11006604.2,7790171.36666667,0
2799.94165039063,12301380.2,7790211.56666667,0
3499.7763671875,13577070.8,7790279.46666667,0
2100.16162109375,11006471.9333333,7790350.63333333,0
699.780151367188,8390505.33333333,7790456,0
-699.810913085938,5811202.36666667,7790453.13333333,0
-2100.10302734375,3345652.06666667,7790539.86666667,0
-3499.73876953125,1045294.73333333,7790582.16666667,0
1.73759907484055E-02,7091025.03333333,7790644.8,0
2.01047714799643E-02,7091107.53333333,7790558.2,0
2.24752072244883E-03,7091140.16666667,7790580.2,0
-1.32585959509015E-02,7091096.56666667,7790555.4,0
-7.19826202839613E-03,7091107.06666667,7790543.36666667,0
3.61428130418062E-03,7091133.53333333,7790461.93333333,0
-2.32487842440605E-02,7091052.1,7790335.33333333,0
-5.49840591847897E-02,7091149.4,7790207.7,0
3.98981757462025E-02,7090648.96666667,7785734.23333333,0
1.46631279494613E-03,7089523.6,7776410.16666667,0
-0.034836120903492,7088133.86666667,7765643.56666667,0
-1.33202392607927E-02,7087033.73333333,7755333.3,0
4.77167181670666E-02,7085954.53333333,7746603.5,0
-2.35397387295961E-02,7084947.7,7739336.36666667,0
-1.58618856221437E-02,7084149.43333333,7733360.33333333,0
2.09058001637459E-02,7083611.56666667,7728649.2,0
4.73269168287516E-03,7083061.13333333,7725033.83333333,0
-8.72943364083767E-03,7082670.06666667,7722187.66666667,0
6.07541063800454E-04,7082414.83333333,7720449.5,0
2.11557392030954E-02,7082177.1,7719157.63333333,0
-8.93950648605824E-03,7081983.33333333,7718230.36666667,0
1.48135358467698E-02,7082007.53333333,7717559.86666667,0
-1.74845289438963E-02,7081917.73333333,7716896.56666667,0
-3.58402319252491E-02,7081759.63333333,7716298.53333333,0
-9.83892288058996E-03,7081661.13333333,7715940.8,0
-5.3809960372746E-03,7081551.06666667,7715748.26666667,0
-3.37877981364727E-02,7081636.8,7715558.76666667,0
-3.07282358407974E-02,7081567,7715645.33333333,0
-1.86734683811665E-02,7081683.2,7715833.46666667,0
4.15685400366783E-03,7081710.03333333,7715698.3,0
-4.20616194605827E-02,7081505.43333333,7715539.7,0
-5.11215217411518E-02,7081459.93333333,7715489.3,0
-1.06146400794387E-02,7081480.83333333,7715480.9,0
4.61808376712725E-04,7081543.13333333,7715439.33333333,0
-1.48327779024839E-02,7081488.86666667,7715699.1,0
4.04580915346742E-03,7081575.73333333,7715893.5,0
1.58266047947109E-03,7081648.43333333,7716037.63333333,0
-1.35219632647932E-03,7081690.16666667,7715966.86666667,0
-3499.7919921875,962689.433333333,7716014.93333333,0
-2799.97314453125,2104150.43333333,7715927.1,0
-2100.17724609375,3290496.3,7715859.6,0
-1400.34716796875,4519015.36666667,7715808.83333333,0
-699.774841308594,5786147.43333333,7715839.83333333,0
-5.68454014137387E-03,7081484.03333333,7715817.6,0
699.842895507813,8396739.46666667,7715818.8,0
1400.36413574219,9722084.36666667,7715858.53333333,0
2100.17211914063,11043774.1333333,7715881.66666667,0
2799.99145507813,12353820.6,7715903.03333333,0
3499.73315429688,13644476,7715889.2,0
2100.158203125,11043704.0333333,7715882.53333333,0
699.841979980469,8396717.2,7715932.06666667,0
-699.787963867188,5786328.96666667,7715940.26666667,0
-2100.16064453125,3290925.26666667,7716020.4,0
-3499.77075195313,962726.9,7715981.1,0
-2.16855364851654E-03,7081460.93333333,7716077.46666667,0
3.91276776790619E-02,7081648.6,7716030.43333333,0
1.10400456469506E-03,7081471.23333333,7716112.13333333,0
-1.04349572211504E-02,7081666,7716014.43333333,0
0.018389604985714,7081695.36666667,7715970.26666667,0
1.04607185348868E-02,7081480.43333333,7715969.53333333,0
-3.41426394879818E-02,7081491.5,7715824.03333333,0
3.98268969729543E-03,7081678.86666667,7715708.9,0
4.61700260639191E-02,7082303.46666667,7735863,0
9.88708143268013E-06,7086371.1,7778853.1,0
-2.10136622190475E-02,7091733.53333333,7823589.7,0
-8.28896164894104E-02,7097000.16666667,7863218.13333333,0
-2.90316268801689E-02,7101574.23333333,7895984.76666667,0
-4.51886840164661E-02,7105412.4,7922301.46666667,0
-8.85282643139362E-03,7108472,7942881.2,0
8.17723281215876E-04,7110800.96666667,7958968.36666667,0
-3.56500074267387E-02,7112605.33333333,7971182.8,0
-2.40123625844717E-02,7114010.03333333,7980626.06666667,0
2.13804934173822E-02,7115218.66666667,7987816.93333333,0
3.75584177672863E-02,7116124.36666667,7993192.8,0
-1.80327799171209E-02,7116639.7,7996903.86666667,0
-2.38293204456568E-02,7117014.23333333,7999355.96666667,0
-1.09991738572717E-02,7117254.53333333,8001154.3,0
5.18193654716015E-03,7117444.13333333,8002569.36666667,0
-3.07104792445898E-02,7117692.33333333,8003610.36666667,0
3.38072143495083E-02,7117916.43333333,8004628.83333333,0
-1.69666297733784E-02,7117918,8005442.33333333,0
1.77701096981764E-03,7118039.16666667,8005927.16666667,0
5.37889217957854E-03,7118148.2,8006099.16666667,0
-1.92022491246462E-02,7118113.26666667,8006286.3,0
-9.50242951512337E-03,7118129.76666667,8006489.56666667,0
1.36461891233921E-02,7118214.9,8006677.13333333,0
-1.52958864346147E-02,7118143.03333333,8006937.4,0
-3.89085412025452E-02,7118193.03333333,8007191,0
-2.84714680165052E-02,7118230.73333333,8007397.73333333,0
-1.43435895442963E-02,7118243.2,8007497,0
-5.30800186097622E-02,7118305.6,8007391.06666667,0
2.48046685010195E-02,7118336.5,8007365.66666667,0
-6.10402273014188E-03,7118275.06666667,8007229.2,0
2.57898680865765E-02,7118345.96666667,8007308.26666667,0
-1.62047185003757E-02,7118334.7,8007419.1,0
-4.70929257571697E-02,7118304.26666667,8007538.66666667,0
6.07083551585674E-02,7118504.3,8007508.96666667,0
-5.40002668276429E-03,7118424.6,8007315.56666667,0
3.23888137936592E-02,7118403.33333333,8007244.23333333,0
-3499.79907226563,1280792.03333333,8007201.13333333,0
-2799.90942382813,2369980.83333333,8007228.6,0
-2100.13354492188,3501743.13333333,8007199.8,0
-1400.35778808594,4673710.63333333,8007273.96666667,0
-699.814392089844,5882406.56666667,8007345.6,0
3.67461107671261E-02,7118409.23333333,8007356.33333333,0
699.881713867188,8373388.63333333,8007395.36666667,0
1400.31982421875,9637808.46666667,8007463.36666667,0
2100.09692382813,10899629.9666667,8007490.4,0
2799.95971679688,12150662.8666667,8007532.2,0
3499.82153320313,13383592.0333333,8007588.96666667,0
2100.072265625,10899499.9666667,8007597.8,0
699.8173828125,8373096.33333333,8007601.1,0
-699.840087890625,5882589.8,8007534.7,0
-2100.1220703125,3502230.96666667,8007502.26666667,0
-3499.74658203125,1281037.56666667,8007444.73333333,0
-1.11853713169694E-02,7118179.8,8007418.66666667,0
2.13318057358265E-02,7118354.93333333,8007406.06666667,0
-1.65873449295759E-02,7118301.9,8007329.63333333,0
1.63328442722559E-02,7118304.63333333,8007280.2,0
-4.71936166286469E-02,7118305.53333333,8007227.83333333,0
4.02847342193127E-02,7118463.6,8007213.4,0
-1.44817039836198E-03,7118286.5,8007201.4,0
-5.0851539708674E-03,7118309.53333333,8007205.73333333,0
-3.98449134081602E-04,7118504.9,8011980.13333333,0
-6.03146515786648E-02,7119515.13333333,8021868.36666667,0
-4.03936672955751E-03,7120863.96666667,8032189.9,0
-6.98103802278638E-03,7122073.83333333,8041542.23333333,0
4.83530722558498E-02,7123372.7,8049472.83333333,0
-2.28271950036287E-02,7124021.9,8056005.9,0
2.81748063862324E-02,7124839.2,8061085.23333333,0
1.82347325608134E-03,7125391.5,8064816.86666667,0
-6.12296303734183E-03,7125748.43333333,8067568.3,0
4.73247654736042E-02,7126241.66666667,8069591.7,0
-5.71926683187485E-03,7126280.86666667,8071140.93333333,0
-2.27651512250304E-03,7126484.63333333,8072162.16666667,0
-8.50704964250326E-03,7126569.73333333,8073022.3,0
-5.63930440694094E-03,7126653.03333333,8073734.63333333,0
-2.53348681144416E-03,7126804.23333333,8074387.53333333,0
3.93001642078161E-03,7126859.56666667,8074948.43333333,0
1.09315607696772E-02,7126942.63333333,8075495.23333333,0
-2.10541188716888E-02,7126995.23333333,8075703.5,0
1.45042343065143E-02,7127057.76666667,8075796.8,0
3.60367936082184E-03,7126993.03333333,8075887.36666667,0
-2.91402102448046E-03,7126977.53333333,8075924.86666667,0
-3.79348583519459E-02,7126975.1,8076016.56666667,0
-4.09707948565483E-02,7126975.8,8076238.5,0
-7.12174223735929E-03,7127122.5,8076391.73333333,0
-5.99638512358069E-03,7127117.83333333,8076460.9,0
1.56288663856685E-03,7127184.96666667,8076374.23333333,0
1.09642092138529E-03,7127106.63333333,8076258.16666667,0
0.016278225928545,7127143.06666667,8076284,0
1.83248687535524E-02,7127077.06666667,8076419.66666667,0
-1.65796279907227E-02,7127119.96666667,8076572.66666667,0
-3499.77880859375,1355708.13333333,8076676,0
-2799.95971679688,2432605.1,8076737.76666667,0
-2100.1455078125,3551531.9,8076754.56666667,0
-1400.35522460938,4710194.43333333,8076727.63333333,0
-699.85595703125,5905108.83333333,8076735.8,0
-3.29180955886841E-02,7127131.73333333,8076705,0
699.765197753906,8367857.7,8076656.8,0
1400.35363769531,9618727.36666667,8076612,0
2100.1962890625,10866536.0333333,8076532.16666667,0
2799.95556640625,12103889.5666667,8076466.7,0
3499.74584960938,13323243.8666667,8076399.2,0
2100.10327148438,10866507.7666667,8076403.76666667,0
699.800842285156,8367921.1,8076404,0
-699.841247558594,5905151.16666667,8076431.43333333,0
-2100.15576171875,3551458.73333333,8076400.6,0
-3499.77734375,1355352.33333333,8076425.43333333,0
-5.93360476195812E-02,7126896.36666667,8076473.66666667,0
3.64837385714054E-02,7127127.13333333,8076496.13333333,0
6.18775747716427E-03,7127107.5,8076546.86666667,0
5.72802796959877E-02,7127264.93333333,8076595.46666667,0
1.55833698809147E-02,7127157.3,8076656.36666667,0
3.46873626112938E-02,7127225.46666667,8076730.93333333,0
9.63039509952068E-03,7127202.3,8076771.63333333,0
3.82525869645178E-03,7127286.3,8076864.43333333,0
2.24332846701145E-02,7127459.53333333,8081277.83333333,0
-7.82423280179501E-03,7128421.56666667,8090686.66666667,0
1.48659506812692E-02,7129608.66666667,8100729.5,0
-2.69332826137543E-02,7130733.6,8109870.63333333,0
-0.031025119125843,7131771.46666667,8117673.53333333,0
-2.49610245227814E-02,7132679.4,8124054.16666667,0
5.15121594071388E-02,7133479.76666667,8129157.93333333,0
1.81873627007008E-02,7134086.1,8133071.83333333,0
2.11541038006544E-02,7134474.16666667,8135979.83333333,0
5.75242005288601E-03,7134779.4,8137973.7,0
-4.52917255461216E-02,7134811.33333333,8139276.66666667,0
-4.35533635318279E-02,7134973.93333333,8140199.2,0
-6.00391067564487E-02,7135104.26666667,8140983.86666667,0
-5.12299053370953E-02,7135256.56666667,8141566.93333333,0
2.56956275552511E-02,7135377,8141867.13333333,0
-1.19852740317583E-02,7135357.36666667,8141955.9,0
5.14724873937666E-04,7135521.03333333,8142101.26666667,0
1.36296544224024E-02,7135426.36666667,8142274.26666667,0
-4.29645599797368E-03,7135398.6,8142437.4,0
-2.54887882620096E-02,7135453.1,8142671.2,0
-5.81305585801601E-02,7135371.4,8142723.76666667,0
-1.31594445556402E-02,7135455.06666667,8142622.5,0
4.17865766212344E-03,7135454.16666667,8142527.1,0
-6.31118519231677E-03,7135462.96666667,8142507.2,0
-7.93107785284519E-03,7135447.33333333,8142565.53333333,0
-2.60955952107906E-02,7135595.9,8142635.03333333,0
2.28419457562268E-03,7135472.9,8142639.83333333,0
-1.20748803019524E-02,7135484.4,8142583.06666667,0
2.95779556035995E-02,7135615.73333333,8142516.56666667,0
6.0245580971241E-04,7135481.13333333,8142458.96666667,0
-3499.75561523438,1425869.76666667,8142458.1,0
-2799.95336914063,2491207,8142467.83333333,0
-2100.13159179688,3598205.9,8142531.33333333,0
-1400.34716796875,4744452.16666667,8142564.43333333,0
-699.84033203125,5926634.1,8142622,0
1.41168404370546E-02,7135535.46666667,8142676.03333333,0
699.789306640625,8362908.1,8142657.2,0
1400.41955566406,9600406.4,8142689.8,0
2100.16333007813,10834801.6666667,8142687.6,0
2799.95581054688,12058939.7,8142625.83333333,0
3499.76977539063,13265575.1,8142587.63333333,0
2100.11010742188,10834801.6333333,8142513.4,0
699.760375976563,8362953,8142452,0
-699.815490722656,5926588.76666667,8142387.16666667,0
-2100.15576171875,3598124.83333333,8142304.6,0
-3499.77612304688,1425477.66666667,8142238.9,0
1.88514944165945E-02,7135325.96666667,8142174.66666667,0
0.01649852655828,7135405.9,8142137.4,0
-4.3846950866282E-03,7135382.13333333,8142088.63333333,0
-1.14312199875712E-02,7135431.9,8142108.23333333,0
-4.01271730661392E-02,7135286.06666667,8142081.6,0
4.51517812907696E-02,7135541.73333333,8142075.76666667,0
2.85129714757204E-02,7135410.1,8142138.03333333,0
0.006099758669734,7135470.46666667,8142165.3,0
1.02824606001377E-02,7134510.53333333,8132538.73333333,0
-2.0309251267463E-03,7131902.96666667,8108401.86666667,0
2.09176428616047E-02,7128429.8,8078909.3,0
-4.88846525549889E-02,7124728.23333333,8050414.2,0
9.68774256762117E-04,7121720.06666667,8025573.8,0
1.36344395577908E-02,7119039.66666667,8005253.6,0
1.07799442484975E-02,7116918.86666667,7988969.83333333,0
-1.22267631813884E-02,7115146.06666667,7976052.53333333,0
1.52191026136279E-02,7113903.8,7965842.96666667,0
-2.48756278306246E-02,7112695.5,7957889.83333333,0
-1.06162242591381E-02,7111895.56666667,7951755.96666667,0
-1.45216090604663E-02,7111213.86666667,7947399.63333333,0
-2.66577322036028E-02,7110733.06666667,7944315.56666667,0
9.33546398300678E-04,7110476.93333333,7942078.73333333,0
-2.09947116672993E-02,7110238.73333333,7940342.13333333,0
-3.88443656265736E-02,7109937.8,7938704.8,0
3.89803200960159E-02,7109920.53333333,7937410.83333333,0
1.33107425644994E-02,7109717.6,7936618.03333333,0
3.34281765390188E-04,7109606.4,7936202.56666667,0
-5.09452447295189E-02,7109490.13333333,7936089.73333333,0
2.59053613990545E-02,7109693.8,7936036.13333333,0
5.85916265845299E-02,7109758.53333333,7935821.9,0
9.43354889750481E-03,7109565.9,7935476.16666667,0
0.011418279260397,7109456.8,7935225.1,0
-5.88321499526501E-03,7109472.8,7935093.23333333,0
-2.02441923320293E-02,7109351.3,7935176.26666667,0
-2.41300072520971E-02,7109365.96666667,7935323.96666667,0
5.2553890272975E-03,7109484.83333333,7935497.73333333,0
-1.75673943012953E-02,7109465.06666667,7935474.06666667,0
-5.93241788446903E-02,7109337.06666667,7935293.5,0
3.71915078721941E-03,7109429.93333333,7935136,0
1.06351356953382E-02,7109444.76666667,7935094.66666667,0
-0.040563065558672,7109235.1,7935166.96666667,0
-3.11746001243591E-02,7109487.96666667,7935387.56666667,0
-8.15856456756592E-02,7109371.16666667,7935601.16666667,0
-1.21781807392836E-02,7109510.86666667,7935603.43333333,0
-1.32531290873885E-02,7109431.93333333,7935415,0
-3499.84399414063,1203117.56666667,7935305.66666667,0
-2799.91088867188,2305275.4,7935271.63333333,0
-2100.1162109375,3450292.66666667,7935299.4,0
-1400.34167480469,4635995.2,7935352.1,0
-699.805419921875,5859010.06666667,7935378.1,0
-8.10023956000805E-03,7109360.8,7935475.9,0
699.84423828125,8379023.33333333,7935498.73333333,0
1400.29040527344,9658355.86666667,7935567.83333333,0
2100.146484375,10934762.3666667,7935684.73333333,0
2799.95581054688,12200104.9,7935743.7,0
3499.7783203125,13447040.8,7935825.33333333,0
2100.1796875,10934636.2333333,7935894.53333333,0
699.794372558594,8378867.83333333,7935990,0
-699.801940917969,5859394.56666667,7935990.26666667,0
-2100.15161132813,3451070.1,7935992.7,0
-3499.77319335938,1204084.1,7935981.46666667,0
9.18023637495935E-04,7109362.63333333,7935944.23333333,0
-4.76761683821678E-02,7109374.7,7935834.56666667,0
-0.030737467110157,7109448.16666667,7935805.56666667,0
4.49777618050575E-02,7109478.7,7935678.73333333,0
8.50645173341036E-03,7109433.46666667,7935668.63333333,0
0.019097026437521,7109456.8,7935566.9,0
-1.60152022726834E-03,7109385.53333333,7935556.43333333,0
3.06411702185869E-02,7109504.26666667,7935489.5,0
3499.76123046875,13447402.8666667,7935538.43333333,0
3499.79418945313,13447368.4333333,7935557.1,0
3499.740234375,13447198.7,7935563.46666667,0
3499.75415039063,13447247,7935589.4,0
3499.74682617188,13447236.2,7935591.8,0
-3499.7880859375,1203555.3,7935625.8,0
-3499.83813476563,1203285.6,7935726.23333333,0
-3499.81005859375,1203411.66666667,7935760.26666667,0
-3499.77783203125,1203464.8,7935861.33333333,0
-3499.81323242188,1203469.26666667,7935891.83333333,0
-3499.75219726563,1203670.63333333,7935907.53333333,0
-3499.736328125,1203693.73333333,7935915.96666667,0
-3499.75512695313,1203720.7,7935978.8,0
-3499.74072265625,1203788.2,7936078.3,0
-3499.74536132813,1203864.16666667,7936108.96666667,0
-3499.79760742188,1203808.1,7936129.83333333,0
-3499.79736328125,1203925.53333333,7936095.6,0
-3499.70556640625,1203868.8,7936092,0
-3499.74462890625,1203924.66666667,7936069.03333333,0
-3499.7607421875,1203752.63333333,7936098.43333333,0
-3499.77465820313,1203778.43333333,7936065,0
-3499.8017578125,1203646.8,7936028.36666667,0
-3499.77734375,1203654.06666667,7936027.76666667,0
-3499.80346679688,1203508.76666667,7935972.5,0
1

There are 1 answers

5
OM222O On

There are generally 2 approaches to preventing floating point errors:

  1. Using integers/fractional representation (a/b) and only converting to float in the last step when all of the additions, subtractions, multiplications, etc have been carried out. Since you're using a 24-bit ADC, I suspect this will be the best approach: Read your 24-bit data into a larger buffer (for example 64 bits, but be careful if they're signed values as you'll need some bit shifting to prevent messing up the sign). Run your regression using integers only and only when trying to display the values to the user use floats

  2. If you must convert to float and use floats, the only real options are to either use double instead of float (since you're not memory-constrained this should be an easy test) or to sort the floats before you add, multiply, divide etc. You can also look into Kahan Summation algorithm which is a more efficient way of doing the same thing but you said performance isn't an issue. I haven't tried benchmarking sorting vs Kahan, but from previous experiences they'll be very similar.

Like others mentioned, posting your data (since you say it's small and ~400 rows should be fine to post it raw here) and your code which has reproducible errors, it would be a lot easier to recommend a proper fix or solution.