افزودنِ وزن به داده‌های کالیبراسیون، فقط تغییرِ یک گزینهٔ حل‌گر نیست؛ تابعی را که کمینه می‌کنیم عوض می‌کند. اگر ردیف‌ها را به جای ریشهٔ وزن در خودِ وزن ضرب کنیم، برنامه ممکن است بی‌خطا اجرا شود اما مسئلهٔ دیگری را حل کند. این درس با سه زوجِ کاملاً تألیفی، یک ماژولِ برازش خطِ وزن‌دار می‌سازد و ضرایبش را با حساب کسری مستقل می‌سنجد. هیچ ابزار واقعی، عدم قطعیتِ اندازه‌گیری یا مدلِ آموزش‌دیده‌ای ارزیابی نمی‌شود.

۱. وزن نمونه را از واحد و واقعیت ابزار جدا کنیم

وزنِ قراردادی، واحدِ اندازه‌گیری را عوض نمی‌کند
تصویر مفهومی: وزنِ قراردادی، واحدِ اندازه‌گیری را عوض نمی‌کند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

ورودیِ مرجع، ولتاژهای صفر، یک و دو ولت و پاسخِ ساختگی، جریان‌های صفر، دو و دو میلی‌آمپر است. مدل را y = a + b*x می‌گیریم؛ عرض از مبدأ a واحد میلی‌آمپر و شیب b واحد میلی‌آمپر بر ولت دارد. این شیب را مقاومت نمی‌نامیم؛ در این مدل، جریان در برابر ولتاژ برازش می‌شود، نه ولتاژ در برابر جریان.

وزن‌های یک، یک و چهار، عددهای مثبتِ بی‌بُعد و ازپیش‌داده‌شده‌اند. ردیف سوم در معیارِ انتخابی چهار برابرِ ردیفی با همان باقیمانده و وزن یک سهم دارد. این اعداد را از واریانسِ حسگر، تکرار آزمایش یا کالیبراسیون قبلی استخراج نکرده‌ایم؛ چهار به معنی چهار برابر اطمینانِ تأییدشده نیست. انتخابِ نامناسبِ وزن همچنان می‌تواند مدل نامناسبی بسازد.

تعریف کمترین مربعات وزن‌دار در NIST، معیار را مجموعِ وزن ضرب‌در مربعِ باقیمانده معرفی می‌کند. پارامترها متغیرِ بهینه‌سازی‌اند؛ داده و وزن‌ها ثابت‌اند. در این تمرین، باقیمانده داده منهای پیش‌بینی است و معیار، واحد میلی‌آمپرِ مربع دارد. از این تعریف، فاصلهٔ اطمینان یا اعتبارِ آماریِ وزن‌های تألیفی نتیجه نمی‌گیریم.

برازش بدون وزنِ جریان و ولتاژ، مرجع دیگری با سهم برابر نمونه‌ها داشت. اینجا وزن بخشی از قراردادِ ورودی است؛ حذف یا جابه‌جاییِ آن، همان آزمایش قبلی نیست. هر ولتاژ، پاسخ و وزنِ متناظرش باید با هم بمانند. هم‌اندازه بودن سه فهرست، به‌تنهایی هویتِ درستِ ردیف‌ها را اثبات نمی‌کند.

۲. برازش وزن‌دار را با ریشهٔ وزن و مرکزکردن بسازیم

دو گامِ وزن‌دهی و مرکزکردن پیش از حل
تصویر مفهومی: دو گامِ وزن‌دهی و مرکزکردن پیش از حل؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

برای تبدیلِ معیار وزن‌دار به نرمِ معمول، هر ردیفِ ماتریس طراحی و همان عضوِ پاسخ را در ریشهٔ وزن ضرب می‌کنیم. مربعِ باقیماندهٔ تبدیل‌شده، وزن ضرب‌در مربعِ باقیماندهٔ اصلی می‌شود. اگر خودِ وزن را ضریب بگیریم، پس از مربع‌کردن وزنِ مربع‌شده وارد معیار می‌شود. برای دادهٔ حاضر، این خطای آموزشی شیب را از شش‌هفتم به بیست‌ودو بیست‌وهفتم تغییر می‌دهد.

کد پیش از حل، مرکزِ وزن‌دارِ ورودی و پاسخ را می‌گیرد. در مثال، مرکزِ ولتاژ یک‌ونیم ولت و مرکزِ جریان پنج‌سوم میلی‌آمپر است. اختلافِ ولتاژ از مرکز را بر گسترهٔ ولتاژ، یعنی دو ولت، تقسیم می‌کنیم. ستونِ تازه بی‌بُعد است؛ ستونِ ثابت و ستونِ مرکز‌شده، پس از ضرب در ریشهٔ وزن به حل‌گر می‌روند.

ضرایبِ این دستگاهِ تبدیل‌شده، مستقیماً a و b نهایی نیستند. ضریبِ ستونِ مرکز‌شده بر گستره تقسیم می‌شود تا شیبِ میلی‌آمپر بر ولت ساخته شود؛ سپس میانگینِ پاسخ و جابه‌جاییِ مرکزِ ولتاژ در بازیابیِ عرض از مبدأ وارد می‌شوند. ضریبِ ثابتِ کوچکِ دستگاهِ مرکز‌شده را هم بی‌توضیح صفر نمی‌کنیم؛ حسابِ شناور ممکن است آن را دقیقاً صفر نسازد.

قرارداد lstsq در NumPy 2.4، کمینه‌کردنِ نرم، رتبه و مقدارهای منفرد را توضیح می‌دهد. این فایل همان تابع را با rcond=None اجرا می‌کند؛ اجرای QR جداگانه ادعا نمی‌شود. مرکزکردن و مقیاس‌بندی، انتخابِ عددیِ این مسیر است و به‌خودیِ خود تضمینِ استحکامِ همهٔ داده‌ها یا درستیِ مدلِ فیزیکی نیست.

۳. کد کامل و قرارداد ورودی محدود

دروازهٔ قرارداد دادهٔ کالیبراسیون
تصویر مفهومی: دروازهٔ قرارداد دادهٔ کالیبراسیون؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

سه ورودی باید tuple واقعی، هم‌اندازه و دارای سه تا ۳۲ عضو باشند. ولتاژِ مرجع حداکثر شانزده ولت و قدرِ پاسخ حداکثر ۶۴ میلی‌آمپر است. مقدارها فقط int یا float دقیقِ متناهی‌اند؛ bool، رشته، مختلط و اسکالر NumPy خودکار تبدیل نمی‌شوند. وزن فقط int دقیقِ یک تا شانزده است؛ صفر به معنی حذفِ پنهانیِ یک مشاهده پذیرفته نمی‌شود.

"""Original bounded weighted affine calibration; no real instrument data."""
from fractions import Fraction
import itertools
import json
import math
import platform
import numpy as np

ABS, REL = 1e-10, 1e-10
MIN_SPAN_V = 1 / 16


def fit_weighted(x_v, y_ma, weights):
    if any(type(v) is not tuple for v in (x_v, y_ma, weights)):
        raise TypeError("three actual tuples required")
    if not 3 <= len(x_v) <= 32 or not len(x_v) == len(y_ma) == len(weights):
        raise ValueError("matching lengths in 3..32 required")
    for values, bound in ((x_v, 16), (y_ma, 64)):
        for value in values:
            if type(value) not in (int, float):
                raise TypeError("actual int/float required, no bool or coercion")
            if not -bound <= value <= bound or not math.isfinite(value):
                raise ValueError("finite bounded observation required")
    if any(type(w) is not int or not 1 <= w <= 16 for w in weights):
        raise ValueError("actual positive integer relative weights in 1..16 required")
    span = float(max(x_v) - min(x_v))
    if span < MIN_SPAN_V:
        raise ValueError("reference-input span is below chosen 1/16 V floor")
    total_w = sum(weights)
    x_center = math.fsum(w * float(x) for w, x in zip(weights, x_v)) / total_w
    y_center = math.fsum(w * float(y) for w, y in zip(weights, y_ma)) / total_w
    z = (np.array(x_v, dtype=np.float64) - x_center) / span
    root_w = np.sqrt(np.array(weights, dtype=np.float64))
    design = np.column_stack((np.ones(len(x_v)), z)) * root_w[:, None]
    target = (np.array(y_ma, dtype=np.float64) - y_center) * root_w
    coefficients, library_residuals, rank, singular = np.linalg.lstsq(design, target, rcond=None)
    if rank != 2:
        raise ValueError("two identifiable affine parameters required")
    slope = float(coefficients[1] / span)
    intercept = float(y_center + coefficients[0] - slope * x_center)
    predicted = tuple(intercept + slope * float(x) for x in x_v)
    residual = tuple(float(y) - p for y, p in zip(y_ma, predicted))
    return {
        "intercept_ma": intercept, "slope_ma_per_v": slope,
        "predicted_ma": predicted, "residual_ma": residual,
        "weighted_sse_ma_squared": math.fsum(w * r * r for w, r in zip(weights, residual)),
        "weighted_residual_sum_ma": math.fsum(w * r for w, r in zip(weights, residual)),
        "weighted_x_residual_sum_v_ma": math.fsum(w * float(x) * r for w, x, r in zip(weights, x_v, residual)),
        "unweighted_residual_sum_ma": math.fsum(residual),
        "x_center_v": x_center, "y_center_ma": y_center, "x_span_v": span,
        "scaled_design_singular_values": singular.tolist(), "rank": int(rank),
        "library_transformed_residuals": library_residuals.tolist(),
    }


def rational_reference(x_v, y_ma, weights):
    # Tiny independent normal-equation closed form, not the main transformed solve.
    xs, ys = tuple(map(Fraction, x_v)), tuple(map(Fraction, y_ma))
    s0 = Fraction(sum(weights))
    sx = sum((w * x for w, x in zip(weights, xs)), Fraction())
    sy = sum((w * y for w, y in zip(weights, ys)), Fraction())
    sxx = sum((w * x * x for w, x in zip(weights, xs)), Fraction())
    sxy = sum((w * x * y for w, x, y in zip(weights, xs, ys)), Fraction())
    determinant = s0 * sxx - sx * sx
    intercept = (sxx * sy - sx * sxy) / determinant
    slope = (s0 * sxy - sx * sy) / determinant
    residual = tuple(y - intercept - slope * x for x, y in zip(xs, ys))
    criterion = sum((w * r * r for w, r in zip(weights, residual)), Fraction())
    return intercept, slope, residual, criterion


def close(a, b):
    return math.isclose(float(a), float(b), abs_tol=ABS, rel_tol=REL)


def rejected(*args):
    try:
        fit_weighted(*args)
    except (TypeError, ValueError):
        return True
    return False


def run_checks():
    x, y, weights = (0, 1, 2), (0, 2, 2), (1, 1, 4)
    result = fit_weighted(x, y, weights)
    exact = rational_reference(x, y, weights)
    checks = {}
    checks["literal_weighted_hand_parameters_residuals_and_criterion"] = (
        exact == (Fraction(8, 21), Fraction(6, 7),
                  (Fraction(-8, 21), Fraction(16, 21), Fraction(-2, 21)), Fraction(16, 21))
        and close(result["intercept_ma"], exact[0]) and close(result["slope_ma_per_v"], exact[1])
        and all(close(a, b) for a, b in zip(result["residual_ma"], exact[2]))
        and close(result["weighted_sse_ma_squared"], exact[3])
    )
    checks["weighted_orthogonality_does_not_require_unweighted_residual_sum_zero"] = (
        close(result["weighted_residual_sum_ma"], 0)
        and close(result["weighted_x_residual_sum_v_ma"], 0)
        and close(result["unweighted_residual_sum_ma"], Fraction(2, 7))
    )
    wrong = fit_weighted(x, y, tuple(w * w for w in weights))
    checks["multiplying_rows_by_weight_instead_of_root_weight_changes_problem"] = (
        close(wrong["intercept_ma"], Fraction(32, 81))
        and close(wrong["slope_ma_per_v"], Fraction(22, 27))
        and not close(wrong["slope_ma_per_v"], result["slope_ma_per_v"])
    )
    cases, oracle_ok = 0, True
    max_errors = {"intercept_ma": 0.0, "slope_ma_per_v": 0.0, "criterion_ma_squared": 0.0}
    for w in itertools.product((1, 2, 4), repeat=4):
        for profile in range(3):
            xs = (-2, 0, 1, 3)
            ys = tuple(2 * v + 1 + ((i + profile) % 3 - 1) for i, v in enumerate(xs))
            actual = fit_weighted(xs, ys, w)
            a, slope, residual, q = rational_reference(xs, ys, w)
            for quantity, actual_value, expected in (("intercept_ma", actual["intercept_ma"], a),
                                                       ("slope_ma_per_v", actual["slope_ma_per_v"], slope),
                                                       ("criterion_ma_squared", actual["weighted_sse_ma_squared"], q)):
                oracle_ok = oracle_ok and close(actual_value, expected)
                max_errors[quantity] = max(max_errors[quantity], abs(actual_value - float(expected)))
            oracle_ok = oracle_ok and close(actual["weighted_residual_sum_ma"], 0) and close(actual["weighted_x_residual_sum_v_ma"], 0)
            cases += 1
    checks["independent_fraction_243_fixtures_one_group"] = oracle_ok and cases == 243
    equal = fit_weighted(x, y, (1, 1, 1))
    checks["equal_weights_recover_hand_unweighted_fit"] = close(equal["intercept_ma"], Fraction(1, 3)) and close(equal["slope_ma_per_v"], 1)
    doubled = fit_weighted(x, y, tuple(2 * w for w in weights))
    checks["common_weight_scale_preserves_fit_scales_criterion"] = (
        close(doubled["intercept_ma"], result["intercept_ma"])
        and close(doubled["slope_ma_per_v"], result["slope_ma_per_v"])
        and close(doubled["weighted_sse_ma_squared"], 2 * result["weighted_sse_ma_squared"])
    )
    order = (2, 0, 1)
    permuted = fit_weighted(tuple(x[i] for i in order), tuple(y[i] for i in order), tuple(weights[i] for i in order))
    checks["joint_observation_weight_permutation"] = close(permuted["intercept_ma"], result["intercept_ma"]) and close(permuted["slope_ma_per_v"], result["slope_ma_per_v"])
    shifted_x = fit_weighted(tuple(v + 3 for v in x), y, weights)
    checks["reference_input_origin_shift_changes_intercept_not_slope"] = close(shifted_x["slope_ma_per_v"], result["slope_ma_per_v"]) and close(shifted_x["intercept_ma"], result["intercept_ma"] - 3 * result["slope_ma_per_v"])
    shifted_y = fit_weighted(x, tuple(v + 3 for v in y), weights)
    checks["response_offset_moves_only_intercept"] = close(shifted_y["intercept_ma"], result["intercept_ma"] + 3) and close(shifted_y["slope_ma_per_v"], result["slope_ma_per_v"])
    scaled_y = fit_weighted(x, tuple(v * 2 for v in y), weights)
    checks["response_gain_scales_coefficients_and_squared_criterion"] = close(scaled_y["intercept_ma"], 2 * result["intercept_ma"]) and close(scaled_y["slope_ma_per_v"], 2 * result["slope_ma_per_v"]) and close(scaled_y["weighted_sse_ma_squared"], 4 * result["weighted_sse_ma_squared"])
    line = fit_weighted((-1, 0, 2), (-1, 1, 5), (1, 4, 2))
    checks["exact_line_with_unequal_weights"] = close(line["intercept_ma"], 1) and close(line["slope_ma_per_v"], 2) and close(line["weighted_sse_ma_squared"], 0)
    boundary = fit_weighted((-16, 16, 0) * 10 + (-16, 16), (-64, 64, 0) * 10 + (-64, 64), (16,) * 32)
    checks["inclusive_observation_weight_and_32_row_bounds"] = close(boundary["intercept_ma"], 0) and close(boundary["slope_ma_per_v"], 4)
    checks["chosen_input_span_floor_and_exact_floor_acceptance"] = (
        rejected((0, 0, 0), y, weights) and rejected((0, 1 / 64, 1 / 32), y, weights)
        and close(fit_weighted((0, 1 / 32, 1 / 16), (0, 1, 2), weights)["slope_ma_per_v"], 32)
    )
    checks["container_length_and_numeric_contract_errors"] = (
        rejected(list(x), y, weights) and rejected(x, y[:2], weights)
        and rejected((0, 1), (0, 1), (1, 1)) and rejected(x * 11, y * 11, weights * 11)
        and all(rejected((0, 1, v), y, weights) for v in (True, "2", 1j, np.float64(2), math.nan, math.inf, 17, 10 ** 500))
        and all(rejected(x, (0, 2, v), weights) for v in (True, math.nan, -math.inf, 65, -65))
    )
    checks["positive_integer_relative_weight_contract_errors"] = all(rejected(x, y, (1, 1, v)) for v in (0, -1, 17, True, 1.0, "1", 10 ** 500))
    assert all(type(v) is bool and v for v in checks.values())
    return {"python": platform.python_version(), "numpy": np.__version__,
            "scipy_executed": False, "units": {"x": "V", "y_and_intercept": "mA", "slope": "mA/V", "weights": "dimensionless supplied relative weights", "criterion": "mA**2", "weighted_x_residual_moment": "V*mA"},
            "minimum_reference_span_v": MIN_SPAN_V, "absolute_tolerance": ABS, "relative_tolerance": REL,
            "hand_x_v": x, "hand_y_ma": y, "hand_weights": weights, "hand_result": result,
            "hand_exact_intercept_ma": str(exact[0]), "hand_exact_slope_ma_per_v": str(exact[1]),
            "hand_exact_criterion_ma_squared": str(exact[3]), "equal_weight_result": equal,
            "wrong_squared_weight_result": wrong, "fraction_oracle_cases_inside_one_group": cases,
            "maximum_oracle_absolute_difference_by_quantity": max_errors,
            "checks": checks, "unique_check_groups": len(checks), "all_passed": True,
            "limits": ["Supplied relative weights are not inferred variances or verified instrument uncertainties",
                       "Different weights define a different objective; no general calibration/robustness/accuracy improvement claimed",
                       "Tiny Fraction normal-equation oracle is not the recommended large numerical solver",
                       "No extrapolation guarantee, model adequacy, confidence interval or real hardware experiment"]}


if __name__ == "__main__":
    print(json.dumps(run_checks(), ensure_ascii=False, indent=2))

گسترهٔ ولتاژ باید دست‌کم یک‌شانزدهم ولت باشد. این کف، سیاستِ محدودِ تمرین است، نه حدِ تفکیکِ واقعیِ ابزار یا شرطِ عمومیِ NumPy. ورودیِ ثابت و گسترهٔ کوچک‌تر رد می‌شوند. رتبهٔ دستگاه نیز باید دو باشد. پاسخِ پیش‌بینی و معیار از ضرایبِ بازیابی‌شده دوباره محاسبه می‌شوند؛ آرایهٔ residuals کتابخانه جای گزارشِ روشنِ مسئلهٔ اصلی را نمی‌گیرد.

واحدِ هر خروجی در گزارش آمده است. جمعِ وزن‌دارِ باقیمانده واحد میلی‌آمپر و جمعِ وزن ضرب‌در ولتاژ ضرب‌در باقیمانده، واحد ولت‌میلی‌آمپر دارد. برای مقایسهٔ این fixtureها، تلورانس نسبی و مطلق ده به توان منفی ده انتخاب شده؛ بخشِ مطلق در واحد همان کمیت تفسیر می‌شود. این تلورانس، مشخصاتِ دقتِ یک حسگر نیست.

اجرای واقعی با Python 3.14.5 و NumPy 2.4.6 انجام شده و کل خروجی ذخیره است. SciPy، MATLAB و دادهٔ شبکه‌ای وارد برنامه نشده‌اند. ورودی‌ها بازنویسی نمی‌شوند و وزن‌ها از پاسخ تخمین زده نمی‌شوند. برون‌یابی، حذف دادهٔ پرت و مدلِ خطای ولتاژِ مرجع نیز جزو این تابع نیستند؛ برای آن‌ها قرارداد و شاهدِ تازه لازم است.

۴. مرجع کسری و دو شرط باقیماندهٔ وزن‌دار

دو مسیر مستقل برای بررسیِ ضرایب و باقیمانده
تصویر مفهومی: دو مسیر مستقل برای بررسیِ ضرایب و باقیمانده؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

مرجعِ کوچک، پنج جمعِ دقیق از وزن، ولتاژ، جریان، مربعِ ولتاژ و حاصل‌ضربِ ولتاژ و جریان می‌سازد. سپس دستگاهِ دو در دوِ معادله‌های نرمال را با فرمولِ بسته و Fraction حل می‌کند. از مرکزکردن، ریشهٔ وزن، ماتریسِ تبدیل‌شده یا lstsq کمک نمی‌گیرد. این مسیر برای fixtureهای کوچک مرجع است؛ پیشنهادِ حلِ عددیِ مسائل بزرگ با معادله‌های نرمال نیست.

در حسابِ دقیق، عرض از مبدأ هشت‌بیست‌ویکم میلی‌آمپر و شیب شش‌هفتم میلی‌آمپر بر ولت است. باقیمانده‌ها منفی هشت‌بیست‌ویکم، شانزده‌بیست‌ویکم و منفی دو‌بیست‌ویکم میلی‌آمپرند. معیارِ وزن‌دار شانزده‌بیست‌ویکم میلی‌آمپرِ مربع می‌شود. این پاسخ از همان سه ردیف می‌آید؛ مقدار واقعیِ یک دستگاهِ ناشناخته را کشف نکرده‌ایم.

جمعِ معمولِ باقیمانده‌ها دو‌هفتم است و لازم نیست صفر شود. در مقابل، جمعِ وزن‌دارِ باقیمانده و جمعِ وزن ضرب‌در ولتاژ ضرب‌در باقیمانده در حسابِ دقیق صفرند؛ این‌ها شرط‌های ایستاییِ معیار با عرض از مبدأ و شیبِ آزادند. اجرای ثبت‌شده برای آن دو، حدود ۱٫۷۸ و ۲٫۸۹ ضرب‌در ده به توان منفی پانزده داده است. صفرِ نزدیک را جایگزینِ دادهٔ خام نکرده‌ایم.

{
  "python": "3.14.5",
  "numpy": "2.4.6",
  "scipy_executed": false,
  "units": {
    "x": "V",
    "y_and_intercept": "mA",
    "slope": "mA/V",
    "weights": "dimensionless supplied relative weights",
    "criterion": "mA**2",
    "weighted_x_residual_moment": "V*mA"
  },
  "minimum_reference_span_v": 0.0625,
  "absolute_tolerance": 1e-10,
  "relative_tolerance": 1e-10,
  "hand_x_v": [
    0,
    1,
    2
  ],
  "hand_y_ma": [
    0,
    2,
    2
  ],
  "hand_weights": [
    1,
    1,
    4
  ],
  "hand_result": {
    "intercept_ma": 0.3809523809523807,
    "slope_ma_per_v": 0.8571428571428572,
    "predicted_ma": [
      0.3809523809523807,
      1.238095238095238,
      2.095238095238095
    ],
    "residual_ma": [
      -0.3809523809523807,
      0.7619047619047621,
      -0.0952380952380949
    ],
    "weighted_sse_ma_squared": 0.7619047619047616,
    "weighted_residual_sum_ma": 1.7763568394002505e-15,
    "weighted_x_residual_sum_v_ma": 2.886579864025407e-15,
    "unweighted_residual_sum_ma": 0.2857142857142865,
    "x_center_v": 1.5,
    "y_center_ma": 1.6666666666666667,
    "x_span_v": 2.0,
    "scaled_design_singular_values": [
      2.449489742783178,
      0.9354143466934854
    ],
    "rank": 2,
    "library_transformed_residuals": [
      0.7619047619047615
    ]
  },
  "hand_exact_intercept_ma": "8/21",
  "hand_exact_slope_ma_per_v": "6/7",
  "hand_exact_criterion_ma_squared": "16/21",
  "equal_weight_result": {
    "intercept_ma": 0.3333333333333335,
    "slope_ma_per_v": 1.0,
    "predicted_ma": [
      0.3333333333333335,
      1.3333333333333335,
      2.3333333333333335
    ],
    "residual_ma": [
      -0.3333333333333335,
      0.6666666666666665,
      -0.3333333333333335
    ],
    "weighted_sse_ma_squared": 0.6666666666666667,
    "weighted_residual_sum_ma": -4.440892098500626e-16,
    "weighted_x_residual_sum_v_ma": -4.440892098500626e-16,
    "unweighted_residual_sum_ma": -4.440892098500626e-16,
    "x_center_v": 1.0,
    "y_center_ma": 1.3333333333333333,
    "x_span_v": 2.0,
    "scaled_design_singular_values": [
      1.7320508075688772,
      0.7071067811865475
    ],
    "rank": 2,
    "library_transformed_residuals": [
      0.6666666666666666
    ]
  },
  "wrong_squared_weight_result": {
    "intercept_ma": 0.39506172839506193,
    "slope_ma_per_v": 0.8148148148148148,
    "predicted_ma": [
      0.39506172839506193,
      1.2098765432098766,
      2.0246913580246915
    ],
    "residual_ma": [
      -0.39506172839506193,
      0.7901234567901234,
      -0.024691358024691468
    ],
    "weighted_sse_ma_squared": 0.7901234567901236,
    "weighted_residual_sum_ma": -1.9984014443252818e-15,
    "weighted_x_residual_sum_v_ma": -3.552713678800501e-15,
    "unweighted_residual_sum_ma": 0.37037037037037,
    "x_center_v": 1.8333333333333333,
    "y_center_ma": 1.8888888888888888,
    "x_span_v": 2.0,
    "scaled_design_singular_values": [
      4.242640687119286,
      1.0606601717798212
    ],
    "rank": 2,
    "library_transformed_residuals": [
      0.7901234567901235
    ]
  },
  "fraction_oracle_cases_inside_one_group": 243,
  "maximum_oracle_absolute_difference_by_quantity": {
    "intercept_ma": 2.220446049250313e-15,
    "slope_ma_per_v": 1.3322676295501878e-15,
    "criterion_ma_squared": 7.105427357601002e-15
  },
  "checks": {
    "literal_weighted_hand_parameters_residuals_and_criterion": true,
    "weighted_orthogonality_does_not_require_unweighted_residual_sum_zero": true,
    "multiplying_rows_by_weight_instead_of_root_weight_changes_problem": true,
    "independent_fraction_243_fixtures_one_group": true,
    "equal_weights_recover_hand_unweighted_fit": true,
    "common_weight_scale_preserves_fit_scales_criterion": true,
    "joint_observation_weight_permutation": true,
    "reference_input_origin_shift_changes_intercept_not_slope": true,
    "response_offset_moves_only_intercept": true,
    "response_gain_scales_coefficients_and_squared_criterion": true,
    "exact_line_with_unequal_weights": true,
    "inclusive_observation_weight_and_32_row_bounds": true,
    "chosen_input_span_floor_and_exact_floor_acceptance": true,
    "container_length_and_numeric_contract_errors": true,
    "positive_integer_relative_weight_contract_errors": true
  },
  "unique_check_groups": 15,
  "all_passed": true,
  "limits": [
    "Supplied relative weights are not inferred variances or verified instrument uncertainties",
    "Different weights define a different objective; no general calibration/robustness/accuracy improvement claimed",
    "Tiny Fraction normal-equation oracle is not the recommended large numerical solver",
    "No extrapolation guarantee, model adequacy, confidence interval or real hardware experiment"
  ]
}

پانزده گروه نام‌دار اجرا شده‌اند. ۲۴۳ ترکیبِ وزن و پاسخِ کوچک، فقط یک گروهِ مرجع کسری هستند؛ اختلافِ عرض از مبدأ، شیب و معیار، جدا و با واحدِ خودشان ثبت شده‌اند؛ بیشینه‌ای با مخلوط‌کردنِ این سه واحد نمی‌سازیم. پاسخِ دستی، شاهدِ وزنِ مربع‌شده، تغییرِ مبدأ، بهرهٔ پاسخ، جابه‌جاییِ مشترک ردیف‌ها و مرزهای قرارداد جدا بررسی شدند. این مجموعه، همهٔ داده‌های مجاز یا برآوردِ خطای عمومی نیست.

۵. چهار پرسش و حد اعتبار ضرایب

ضرایبِ تأییدشده جای ارزیابی ابزار را نمی‌گیرند
تصویر مفهومی: ضرایبِ تأییدشده جای ارزیابی ابزار را نمی‌گیرند؛ بدون مقیاس عددی و مستقل از نتایج اجرای کد.

پرسش اول: چرا همهٔ وزن‌ها را دو برابر کنیم، ضرایب ثابت می‌مانند؟ پاسخ: کلِ معیار در دو ضرب می‌شود و محلِ کمینه عوض نمی‌شود؛ مقدار معیار نیز دو برابر می‌شود. کد این شاهد را درون دامنهٔ وزن‌ها اجرا می‌کند. از این خاصیت نباید نتیجه گرفت تغییرِ فقط وزنِ ردیف سوم بی‌اثر است؛ نسبتِ سهم‌ها در آن حالت عوض می‌شود.

پرسش دوم: چرا وزن را مستقیماً در ردیف ضرب نکنیم؟ پاسخ: باقیماندهٔ تبدیل‌شده بعداً مربع می‌شود و سهم آن وزنِ مربع‌شده خواهد شد. با وزن‌های یک، یک و شانزده، ضرایبِ تازه سی‌ودو هشتادویکم و بیست‌ودو بیست‌وهفتم‌اند. معیارِ گزارش‌شدهٔ آن اجرا نیز برای وزن‌های تازه است؛ دو معیار با وزن متفاوت را بی‌توضیح با هم مقایسه نمی‌کنیم.

پرسش سوم: جمعِ غیرصفرِ باقیمانده، برازش را خراب می‌کند؟ پاسخ: خیر؛ در مثال دو‌هفتم است. شرطِ متناظر با عرض از مبدأِ این مسئله، جمعِ وزن‌دار است. نام و واحدِ کنترل را باید همراهِ تابعِ هدف انتخاب کرد. کنترل‌های باقیمانده و حساسیتِ دستگاه خطی نیز بدون تعریفِ مسئله قابل انتقالِ کور نیستند.

پرسش چهارم: آیا شیبِ تأییدشده یعنی حسگر کالیبره شده است؟ پاسخ: خیر؛ تنها حسابِ مدلِ خطی با داده و وزنِ اعلام‌شده سنجیده شده است. خطای ابزار، منبع وزن، تغییر دما، غیرخطی بودن و پوششِ دامنه ارزیابی نشده‌اند. منابع در ۲۶ مهر ۱۴۰۵ خوانده شدند؛ نسخهٔ مستندات NumPy 2.4 و بخشِ NIST جدا از اجرای محلی ثبت‌اند. تاریخِ انتشار اولیهٔ این صفحات مشخص نیست و مطلب خبر تازه نیست.

منابع و مطالعهٔ بیشتر

بررسی منابع: ۲۶ مهر ۱۴۰۵. تحلیل‌ها و پیشنهادهای اجرایی، جمع‌بندی نویسنده‌اند.