[{"data":1,"prerenderedAt":741},["ShallowReactive",2],{"article:column:/column/math-beauty/trustworthy-numerical-results":3},{"id":4,"title":5,"body":6,"description":12,"extension":731,"meta":732,"navigation":174,"path":737,"seo":738,"stem":739,"__hash__":740},"column/column/math-beauty/trustworthy-numerical-results.md","回到模型：怎样判断一个数值结果可信到几位",{"type":7,"value":8,"toc":723},"minimark",[9,13,16,19,23,26,29,32,35,38,41,44,47,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,102,105,108,111,114,117,120,123,126,129,132,572,575,578,581,584,587,590,596,599,602,605,608,611,614,617,620,623,626,629,632,635,638,641,644,647,650,653,660,663,666,672,675,678,681,692,701,710,713,716,719],[10,11,12],"p",{},"先修：17 最小二乘与投影；35 浮点表示；36 条件性；37 算法稳定性",[10,14,15],{},"第17章给三条虚构读数(0,1)、(1,2)、(2,2)找到了最佳直线：ŷ＝x/2＋7/6。今天让程序计算，它可能交回a＝0.5000000000000002、b＝1.1666666666666663。多出来的数字应当相信吗？若程序还报告残差平方和约为0.1667，是计算不够准确吗？",[10,17,18],{},"这两个疑问不能只靠增加显示位数解决。第36章区分了问题对数据的敏感程度，第37章区分了算法额外引入的误差。现在把它们接回同一个模型：先问数据能确定什么，再选择计算路径，最后用原问题独立检查结果。",[20,21,22],"h2",{"id":22},"先问数据能把参数钉得多牢",[10,24,25],{},"仍记X＝[x u]，u＝(1,1,1)，参数θ＝(a,b)，预测Xθ＝ax＋bu。原来的x＝(0,1,2)，三个位置彼此分开。另造一组教学数据，把位置挤到1附近：",[10,27,28],{},"x＝(1,1＋ε,1−ε)，y＝(1,2,0)，ε＝10⁻⁸。",[10,30,31],{},"这里先把这些数当作精确实数。第一条记录要求a＋b＝1；第二条减第一条，得到aε＝1。因此a＝1/ε＝10⁸，b＝1−1/ε；第三条也满足，精确残差为0。",[10,33,34],{},"可是，参数并没有因此变得可靠。把参数改成(a＋t,b−t)，三个预测只改变",[10,36,37],{},"X(t,−t)＝(0,tε,−tε)。",[10,39,40],{},"t＝1时，两个参数都改变了1，预测却只改变10⁻⁸。两列接近重合，使相反的参数改动几乎互相抵消；从输出反推参数就很敏感。这是第16章“相关列有零方向”的近似版本：这里没有真正的零方向，却有几乎看不见的方向。",[10,42,43],{},"再把间距ε改成1.01ε，保持y不变。只有两个输入各移动10⁻¹⁰，精确斜率却变成10⁸/1.01，约下降0.99%。若原始位置的不确定程度已经有10⁻¹⁰，就不能凭一次计算报出的长小数，把斜率承诺到十几位。增加计算精度也不能补回没有测准的输入。",[10,45,46],{},"单看参数很大，并不足以判定问题敏感；更换单位也能产生大数字。这里的根据是明确比较了输入改动与答案改动。谈“误差很大”时也要说清尺度：误差100对一个一亿的参数只是百万分之一的相对误差，却足以否定“绝对误差小于百万分之一”的承诺。",[10,48,49],{},[50,51],"img",{"alt":52,"src":53},"两组输入的端点只相差十的负十次方，保持输出不变时，精确斜率却相差约百分之一；这是数据敏感性，不是算法误差","/collections-assets/math-beauty/ch38/01-input-sensitivity.png",[10,55,56],{},"图1：两组数据各自都能被直线精确拟合。图中把相对中心1的微小间距放大展示；斜率变化由a＝1/ε直接推出。",[10,58,59],{},"因此，“预测贴住这几个点”和“参数可信”是两件事。对于这个例子，靠近1的预测可能仍有用，远处的外推却可能剧烈变化。可靠程度还取决于我们最终要报告参数、局部预测，还是远处预测。",[10,61,62],{},"这种区分也能帮助我们改进采样。如果任务确实关心斜率，把三次测量都挤在几乎同一个位置，便很难看清“随位置变化”的效果。在允许的实验范围内增加位置的分散程度，可能比打印更多数字更有用。不过，扩大范围也可能暴露原直线模型的不足；改善参数辨识与检查模型是否适用，仍须一起进行。",[20,64,65],{"id":65},"再问计算路径有没有丢掉信息",[10,67,68],{},"第17章从正交条件得到XᵀXθ＝Xᵀy。推导在实数中成立，却没有要求程序必须先形成XᵀX。",[10,70,71],{},"对刚才的近共线数据，精确的XᵀX两行是(3＋2ε²,3)与(3,3)。区别藏在2ε²＝2×10⁻¹⁶里。把它加到3附近，binary64可能已经留不住：原矩阵中还能分开的列，经过点积后可能被算成完全重合的行。随后再精确地解这个已改变的方程，也找不回丢掉的信息。",[10,73,74],{},"有没有沿着投影思想、直接处理原矩阵的路？回到原来的x＝(0,1,2)、y＝(1,2,2)。第17章不能把y分别投影到x与u再相加，是因为x·u＝3，两条方向不正交。我们先在同一个平面里换两条互相垂直的单位方向。",[10,76,77],{},"先取q₁＝x/√5。u沿q₁的投影是(u·q₁)q₁＝3x/5，把它去掉，剩下",[10,79,80],{},"v＝u−3x/5＝(1,2/5,−1/5)。",[10,82,83],{},"它与x的点积为2/5−2/5＝0，长度为√(6/5)。再除以长度，得到q₂＝(5,2,−1)/√30。于是q₁、q₂彼此正交、各长1，而且仍张成原来的预测平面。",[10,85,86],{},"把它们排成Q＝[q₁ q₂]，原来的两列便能写成",[10,88,89],{},"x＝√5 q₁，u＝(3/√5)q₁＋√(6/5)q₂。",[10,91,92],{},"这就是X＝QR，其中R的第一行为(√5,3/√5)，第二行为(0,√(6/5))。R记录旧方向在新方向下的坐标；左下角为0，所以它是上三角矩阵。",[10,94,95],{},"这里没有添加新的模型能力。新方向与旧方向张成同一个平面，每套原有预测仍能表示，平面外的观测也没有被悄悄搬进来。换坐标的作用是让两个方向互不干扰，方便把“找到最近预测”和“读回原参数”分成两个明确步骤。",[10,97,98],{},[50,99],{"alt":100,"src":101},"先从u中减去沿q1的投影，得到垂直方向v，再单位化为q2；原矩阵写为QR，投影坐标通过上三角方程变回斜率和截距","/collections-assets/math-beauty/ch38/02-orthogonal-qr.png",[10,103,104],{},"图2：左侧在原预测平面内画出方向，右侧记录坐标变换。这里的两个坐标轴是q₁、q₂，不是原始输入、输出轴。",[10,106,107],{},"新方向互不干扰，y的投影坐标可以分别计算：",[10,109,110],{},"c＝Qᵀy＝(6/√5,7/√30)。",[10,112,113],{},"为什么解Rθ＝c就能完成拟合？令p＝Qc。由于y−p垂直于Q的两列，而Q保持二维坐标向量的长度，我们有",[10,115,116],{},"‖y−QRθ‖²＝‖y−p‖²＋‖c−Rθ‖²。",[10,118,119],{},"第一项不随θ变化，第二项是非负数，令它为0就得到最小值。这个勾股分解，正是第17章证明在新坐标中的写法。",[10,121,122],{},"从上三角方程的第二行先解：√(6/5)b＝7/√30，所以b＝7/6；代回第一行得5a＋3b＝6，因而a＝1/2。我们找到了同一个答案，却无需先计算XᵀX。[1]",[10,124,125],{},"这段手算用减投影说明QR的几何含义，不是推荐照抄朴素经典Gram–Schmidt作为稳健实现。有限精度中，它可能丢失列之间的正交性。成熟库采用经过分析的分解方法；例如LAPACK提供使用QR的最小二乘求解器，也提供其他适用于秩不足情况的求解器。[1][2] 数学分解、实现该分解的算法、调用哪个库接口，不能混为一谈。",[20,127,128],{"id":128},"用原问题检查程序交回的答案",[10,130,131],{},"下面直接调用NumPy的lstsq求最小二乘解，再从原始X、y重新计算残差。[3] 同一段代码也复跑近共线例；输出环境信息，便于比较。",[133,134,139],"pre",{"className":135,"code":136,"language":137,"meta":138,"style":138},"language-python shiki shiki-themes github-dark","import platform\nimport numpy as np\n\nprint(platform.python_version(), np.__version__, platform.machine())\nnp.set_printoptions(precision=17)\nX = np.column_stack(([0., 1., 2.], np.ones(3)))\ny = np.array([1., 2., 2.])\ntheta, _, rank, _ = np.linalg.lstsq(X, y, rcond=None)\nr = y - X @ theta\nprint(\"theta, rank:\", theta, rank)\nprint(\"SSE, XTr:\", r @ r, X.T @ r)\n\neps = 1e-8\nA = np.column_stack(([1., 1. + eps, 1. - eps], np.ones(3)))\nz = np.array([1., 2., 0.])\nprint(\"Gram:\", A.T @ A)\ntry:\n    print(\"normal:\", np.linalg.solve(A.T @ A, A.T @ z))\nexcept np.linalg.LinAlgError as error:\n    print(type(error).__name__, str(error))\nt, _, rank, _ = np.linalg.lstsq(A, z, rcond=None)\nprint(\"lstsq, rank:\", t, rank)\nprint(\"residual norm:\", np.linalg.norm(z - A @ t))\n","python","",[140,141,142,155,169,176,192,211,245,269,290,313,328,351,356,367,405,427,445,454,478,492,517,536,549],"code",{"__ignoreMap":138},[143,144,147,151],"span",{"class":145,"line":146},"line",1,[143,148,150],{"class":149},"snl16","import",[143,152,154],{"class":153},"s95oV"," platform\n",[143,156,158,160,163,166],{"class":145,"line":157},2,[143,159,150],{"class":149},[143,161,162],{"class":153}," numpy ",[143,164,165],{"class":149},"as",[143,167,168],{"class":153}," np\n",[143,170,172],{"class":145,"line":171},3,[143,173,175],{"emptyLinePlaceholder":174},true,"\n",[143,177,179,183,186,189],{"class":145,"line":178},4,[143,180,182],{"class":181},"sDLfK","print",[143,184,185],{"class":153},"(platform.python_version(), np.",[143,187,188],{"class":181},"__version__",[143,190,191],{"class":153},", platform.machine())\n",[143,193,195,198,202,205,208],{"class":145,"line":194},5,[143,196,197],{"class":153},"np.set_printoptions(",[143,199,201],{"class":200},"s9osk","precision",[143,203,204],{"class":149},"=",[143,206,207],{"class":181},"17",[143,209,210],{"class":153},")\n",[143,212,214,217,219,222,225,228,231,233,236,239,242],{"class":145,"line":213},6,[143,215,216],{"class":153},"X ",[143,218,204],{"class":149},[143,220,221],{"class":153}," np.column_stack(([",[143,223,224],{"class":181},"0",[143,226,227],{"class":153},"., ",[143,229,230],{"class":181},"1",[143,232,227],{"class":153},[143,234,235],{"class":181},"2",[143,237,238],{"class":153},".], np.ones(",[143,240,241],{"class":181},"3",[143,243,244],{"class":153},")))\n",[143,246,248,251,253,256,258,260,262,264,266],{"class":145,"line":247},7,[143,249,250],{"class":153},"y ",[143,252,204],{"class":149},[143,254,255],{"class":153}," np.array([",[143,257,230],{"class":181},[143,259,227],{"class":153},[143,261,235],{"class":181},[143,263,227],{"class":153},[143,265,235],{"class":181},[143,267,268],{"class":153},".])\n",[143,270,272,275,277,280,283,285,288],{"class":145,"line":271},8,[143,273,274],{"class":153},"theta, _, rank, _ ",[143,276,204],{"class":149},[143,278,279],{"class":153}," np.linalg.lstsq(X, y, ",[143,281,282],{"class":200},"rcond",[143,284,204],{"class":149},[143,286,287],{"class":181},"None",[143,289,210],{"class":153},[143,291,293,296,298,301,304,307,310],{"class":145,"line":292},9,[143,294,295],{"class":153},"r ",[143,297,204],{"class":149},[143,299,300],{"class":153}," y ",[143,302,303],{"class":149},"-",[143,305,306],{"class":153}," X ",[143,308,309],{"class":149},"@",[143,311,312],{"class":153}," theta\n",[143,314,316,318,321,325],{"class":145,"line":315},10,[143,317,182],{"class":181},[143,319,320],{"class":153},"(",[143,322,324],{"class":323},"sU2Wk","\"theta, rank:\"",[143,326,327],{"class":153},", theta, rank)\n",[143,329,331,333,335,338,341,343,346,348],{"class":145,"line":330},11,[143,332,182],{"class":181},[143,334,320],{"class":153},[143,336,337],{"class":323},"\"SSE, XTr:\"",[143,339,340],{"class":153},", r ",[143,342,309],{"class":149},[143,344,345],{"class":153}," r, X.T ",[143,347,309],{"class":149},[143,349,350],{"class":153}," r)\n",[143,352,354],{"class":145,"line":353},12,[143,355,175],{"emptyLinePlaceholder":174},[143,357,359,362,364],{"class":145,"line":358},13,[143,360,361],{"class":153},"eps ",[143,363,204],{"class":149},[143,365,366],{"class":181}," 1e-8\n",[143,368,370,373,375,377,379,381,383,386,389,392,394,396,398,401,403],{"class":145,"line":369},14,[143,371,372],{"class":153},"A ",[143,374,204],{"class":149},[143,376,221],{"class":153},[143,378,230],{"class":181},[143,380,227],{"class":153},[143,382,230],{"class":181},[143,384,385],{"class":153},". ",[143,387,388],{"class":149},"+",[143,390,391],{"class":153}," eps, ",[143,393,230],{"class":181},[143,395,385],{"class":153},[143,397,303],{"class":149},[143,399,400],{"class":153}," eps], np.ones(",[143,402,241],{"class":181},[143,404,244],{"class":153},[143,406,408,411,413,415,417,419,421,423,425],{"class":145,"line":407},15,[143,409,410],{"class":153},"z ",[143,412,204],{"class":149},[143,414,255],{"class":153},[143,416,230],{"class":181},[143,418,227],{"class":153},[143,420,235],{"class":181},[143,422,227],{"class":153},[143,424,224],{"class":181},[143,426,268],{"class":153},[143,428,430,432,434,437,440,442],{"class":145,"line":429},16,[143,431,182],{"class":181},[143,433,320],{"class":153},[143,435,436],{"class":323},"\"Gram:\"",[143,438,439],{"class":153},", A.T ",[143,441,309],{"class":149},[143,443,444],{"class":153}," A)\n",[143,446,448,451],{"class":145,"line":447},17,[143,449,450],{"class":149},"try",[143,452,453],{"class":153},":\n",[143,455,457,460,462,465,468,470,473,475],{"class":145,"line":456},18,[143,458,459],{"class":181},"    print",[143,461,320],{"class":153},[143,463,464],{"class":323},"\"normal:\"",[143,466,467],{"class":153},", np.linalg.solve(A.T ",[143,469,309],{"class":149},[143,471,472],{"class":153}," A, A.T ",[143,474,309],{"class":149},[143,476,477],{"class":153}," z))\n",[143,479,481,484,487,489],{"class":145,"line":480},19,[143,482,483],{"class":149},"except",[143,485,486],{"class":153}," np.linalg.LinAlgError ",[143,488,165],{"class":149},[143,490,491],{"class":153}," error:\n",[143,493,495,497,499,502,505,508,511,514],{"class":145,"line":494},20,[143,496,459],{"class":181},[143,498,320],{"class":153},[143,500,501],{"class":181},"type",[143,503,504],{"class":153},"(error).",[143,506,507],{"class":181},"__name__",[143,509,510],{"class":153},", ",[143,512,513],{"class":181},"str",[143,515,516],{"class":153},"(error))\n",[143,518,520,523,525,528,530,532,534],{"class":145,"line":519},21,[143,521,522],{"class":153},"t, _, rank, _ ",[143,524,204],{"class":149},[143,526,527],{"class":153}," np.linalg.lstsq(A, z, ",[143,529,282],{"class":200},[143,531,204],{"class":149},[143,533,287],{"class":181},[143,535,210],{"class":153},[143,537,539,541,543,546],{"class":145,"line":538},22,[143,540,182],{"class":181},[143,542,320],{"class":153},[143,544,545],{"class":323},"\"lstsq, rank:\"",[143,547,548],{"class":153},", t, rank)\n",[143,550,552,554,556,559,562,564,567,569],{"class":145,"line":551},23,[143,553,182],{"class":181},[143,555,320],{"class":153},[143,557,558],{"class":323},"\"residual norm:\"",[143,560,561],{"class":153},", np.linalg.norm(z ",[143,563,303],{"class":149},[143,565,566],{"class":153}," A ",[143,568,309],{"class":149},[143,570,571],{"class":153}," t))\n",[10,573,574],{},"本文在Linux x86_64、Python 3.12.14、NumPy 2.3.5的float64环境实际运行。原三点数据的输出为a＝0.5000000000000002、b＝1.1666666666666663，SSE＝0.16666666666666674；Xᵀr两项约为−4.44×10⁻¹⁶与2.22×10⁻¹⁶。它们支持结果接近已知最优解，不要求逐位等于0。",[10,576,577],{},"SSE没有接近0，恰恰符合数学结论。精确最优解的残差是r*＝(−1/6,1/3,−1/6)，SSE＝1/6。它是选定直线模型对这三条记录的拟合残差；可能涉及读数波动、取整或模型限制，不能全部记到机器舍入的账上。",[10,579,580],{},"设程序参数与精确最优参数相差Δθ。如果暂用精确算术重新代回，那么",[10,582,583],{},"y−X(θ*＋Δθ)＝r*−XΔθ，",[10,585,586],{},"SSE(θ*＋Δθ)＝1/6＋‖XΔθ‖²。",[10,588,589],{},"r*是原问题已经留下的差，XΔθ是参数计算偏差造成的预测位移。程序实际计算残差与平方和时还会舍入，所以这条精确恒等式是解释和核对的依据，不是浮点输出必须逐位满足的断言。",[10,591,592],{},[50,593],{"alt":594,"src":595},"观测y到最优预测p的差r星是拟合残差，最优预测p到计算预测p帽的差是计算偏差造成的位移；两者在精确算术中正交","/collections-assets/math-beauty/ch38/03-fit-numeric-residual.png",[10,597,598],{},"图3：对固定X、y，最优预测与计算预测都在列空间中。图中为了看清方向放大了计算位移；它不表示本次误差的真实比例。",[10,600,601],{},"检查Xᵀr是在问：残差是否还明显指向模型能调整的方向？它接近0支持最优性；要求r本身接近0，却可能是在要求模型完成不可能的拟合。即使前者通过，也尚未证明参数对输入可靠。",[10,603,604],{},"独立检查还要保留原来的问题。若只把算出的参数代回已经形成的Gram矩阵，所检查的是那组经过舍入的新方程；形成矩阵时丢掉的区别可能被一起掩盖。重新用原X计算预测和残差，至少让这一步没有重复依赖同一个中间结果。它仍在浮点环境里进行，不能当成精确证明；本例还有手算分数可作另一条核验路径。",[10,606,607],{},"近共线例把这一点显出来：本次运行得到全3的Gram矩阵，正规方程求解报“Singular matrix”；lstsq仍判定数值秩为2，得到a约100000000.58、b约−99999999.58，重新计算的残差范数约2.13×10⁻⁸。小残差与很大的参数可以同时出现，且参数仍承受前面证明的输入敏感性。",[10,609,610],{},"这些末位和报错是本环境的观察，不保证各平台完全一致。尤其1±10⁻⁸在输入时已转换成浮点数，程序实际处理的数据与纸上的精确十进制数据略有区别；不能把两者参数之差全部归因于求解器。这次实验展示一种可能的失败路径，普遍性的理由来自前面的精确推导。",[10,612,613],{},"库返回的rank也需要这样读：它是按数值阈值作出的判断，不是测量仪器精度的报告。默认阈值与机器精度和矩阵大小有关；判为满秩，并不表示现实数据已经足以精确确定参数。[3] 同样，前面的平方和恒等式限制的是预测位移XΔθ；如果X能把较大的参数变化压成很小的预测变化，它就不能单独给出强的参数误差保证。",[20,615,616],{"id":616},"可信到几位要落实到误差范围",[10,618,619],{},"对原三点模型，可以亲手算出一份输入误差预算。假定输入位置0、1、2厘米精确不变；输入、输出都按厘米取数值，每个输出误差的数值绝对值不超过h。将输出数值写成任意的(y₁,y₂,y₃)，由同一组正规方程消元可得",[10,621,622],{},"a＝(y₃−y₁)/2，b＝(5y₁＋2y₂−y₃)/6。",[10,624,625],{},"若输出分别改变e₁、e₂、e₃，且每个|eᵢ|≤h，由三角不等式得到",[10,627,628],{},"|Δa|≤h，|Δb|≤4h/3。",[10,630,631],{},"例如每个输出允许误差为0.01厘米，即h＝0.01，那么斜率的不确定范围至多为0.50±0.01，截距至多为(7/6±0.01334)厘米。这是对所有允许输出改动的上界，不是只试几个随机扰动后的印象。它说明输入只测到这个程度时，打印十几位没有对应的证据。若输入位置本身也不确定，还要分析它们的影响，不能沿用这份只允许输出变化的预算。",[10,633,634],{},"这些范围描述的是：在允许的数据变化下，每次重新求出的最佳拟合参数可能在哪里。它们既不是未来读数必落入的区间，也不是对现实中某条“真正直线”的证明。第34章关于模型选择和新数据检验的问题，仍然存在。",[10,636,637],{},"若确实需要承诺四舍五入后的某一位，可以先建立可信的误差区间，再检查区间内所有值是否都会舍入成同一个结果。只看计算值离某个整齐小数很近是不够的，特别是在舍入边界附近。误差区间必须有来源，显示格式不会自动产生它。",[10,639,640],{},"检查的尺度也必须跟着问题走。原例输出以厘米计；若只把输出改记为毫米，y与残差扩大10倍，SSE扩大100倍，而模型的贴合程度没有因此变坏。Xᵀr各分量还受相应列的尺度影响，所以不能给所有数据统一规定“低于10⁻⁶就合格”。",[10,642,643],{},"对非零残差，可把每个点积与‖X的第j列‖‖r‖比较，得到无量纲的正交偏离；残差极小时，这种比例本身可能受舍入支配，还须考虑原数据、计算中间量的尺度与累加误差。容差来自这些分析和应用允许的误差，而不是屏幕小数点后有几位。",[10,645,646],{},"若要承诺某一位可靠，最终需要约束答案可能偏离多少。输入误差经条件性放大后的影响，与算法的计算误差，都要计入；靠近0的结果尤其应说明绝对误差。重新测量、改变合理范围内的数据，能检验前一部分；提高精度或换成熟求解路径，主要检验后一部分。一次成功的残差检查不能代替它们。",[10,648,649],{},"因此本章没有一个适用于所有数值结果的位数答案。对精确给定的三点教学题，分数答案和独立代回提供了强核验；对有限精度的真实读数，可信位数还受输入精度与条件性约束。数值计算做的是把这些边界交代清楚。下一章再问更根本的问题：如果允许足够时间，是否所有程序行为都能由另一段程序事先判断？",[20,651,652],{"id":652},"顺手试一下",[10,654,655,659],{},[656,657,658],"strong",{},"题目1："," 原三点拟合中，一个程序返回(a,b)＝(1/2,7/6＋1/100)。在精确算术下，求残差、Xᵀr与SSE。它的残差和很小，是否就已经最优？",[10,661,662],{},"**提示：**三个预测同时上移1/100；利用r*分别与x、u正交。",[10,664,665],{},"**参考答案：**残差为(−53/300,97/300,−53/300)。Xᵀr＝(−3/100,−3/100)，所以仍能通过整体下移改进，并非最优。SSE＝1/6＋3×(1/100)²＝5009/30000。拟合本来就有非零残差；这里判断未到最优的依据，是残差还含有可行方向分量，而不是SSE没有降到0。",[10,667,668,671],{},[656,669,670],{},"题目2："," 对x＝(1,1＋ε,1−ε)、y＝(1,2,0)，把输出改为y′＝(1,2＋δ,−δ)，输入保持不变。求新的精确参数与参数变化。ε＝10⁻⁸、δ＝10⁻⁶时，若新程序得到残差0，能据此说原参数可靠到小数点后六位吗？",[10,673,674],{},"**提示：**第一条记录仍给出a＋b＝1；第二条与第一条相减。",[10,676,677],{},"**参考答案：**新参数a′＝(1＋δ)/ε，b′＝1−(1＋δ)/ε，第三条也精确满足。因此Δa＝δ/ε＝100、Δb＝−100。两个输出只变动10⁻⁶，参数却改变100；残差0只说明拟合了改变后的数据，不能保证原参数的绝对精度。是否可靠还要结合允许的数据误差和所关心的输出，显示六位小数没有提供这种保证。",[20,679,680],{"id":680},"参考与延伸",[10,682,683,684,691],{},"[1] David Bindel，康奈尔大学CS 6210课程讲义，",[685,686,690],"a",{"href":687,"rel":688},"https://www.cs.cornell.edu/courses/cs6210/2025fa/lec/2025-09-29.html",[689],"nofollow","Householder, Givens, and QR factorization","，2025年9月29日。核对QR最小二乘分解、经典Gram–Schmidt的正交性问题与成熟正交分解算法的区别。",[10,693,694,695,700],{},"[2] LAPACK Users’ Guide，",[685,696,699],{"href":697,"rel":698},"https://www.netlib.org/lapack/lug/node27.html",[689],"Linear Least Squares Problems","。核对满秩求解器使用QR或LQ，以及针对可能秩不足问题的其他求解器；本文未把所有库接口说成同一种算法。",[10,702,703,704,709],{},"[3] NumPy官方文档，",[685,705,708],{"href":706,"rel":707},"https://numpy.org/doc/stable/reference/generated/numpy.linalg.lstsq.html",[689],"numpy.linalg.lstsq","。核对最小二乘目标、返回值和数值秩阈值语义。本文保留完整复跑代码；具体实验版本为NumPy 2.3.5，文档的stable页面会随版本更新。",[10,711,712],{},"本章三幅图均为原创。近共线数据为专门构造的教学例，不是实际测量记录。",[714,715],"hr",{},[10,717,718],{},"作者：Jiancheng Wang · 数学之美（独立原创）",[720,721,722],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":138,"searchDepth":171,"depth":171,"links":724},[725,726,727,728,729,730],{"id":22,"depth":157,"text":22},{"id":65,"depth":157,"text":65},{"id":128,"depth":157,"text":128},{"id":616,"depth":157,"text":616},{"id":652,"depth":157,"text":652},{"id":680,"depth":157,"text":680},"md",{"collection":733,"order":734,"slug":735,"author":736},"数学之美",38,"trustworthy-numerical-results","Jiancheng Wang","/column/math-beauty/trustworthy-numerical-results",{"title":5,"description":12},"column/math-beauty/trustworthy-numerical-results","tzGJUqdK6uyR_JewjkCg4o0OxTfmxPLSWrsjSuTirpE",1791935829242]