间接平差(参数平差)编程实现

该博客介绍了一个使用Python实现的测量平差计算程序,该程序能够读取CSV文件的数据进行间接平差计算,包括误差方程、参数平差值、残差向量和单位权中误差等,并将结果输出到文件。程序参考了武汉大学的教材,适用于全要素输入和输出,计算精度高。运行示例展示了具体的数据和计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        本程序打开后可以直接运行,可以实现间接平差的各个部分计算以及输出,如误差方程、参数平差值、残差向量V最小二乘残差、参数平差值的权逆阵Qx、单位权中误差等。能够实现全要素的以文件的形式进行输入和输出也可以根据根据需要直接在代码上进行输入等极为方便和快捷。本程序是参考武汉大学出版社出版的第二版的《误差理论与测量平差》进行编写的,程序中用到的例题是武汉大学出版社出版的《误差理论与测量平差基础》中的7-8例题。计算出的结果精度很高。

具体代码如下:

以下三个.csv文件用于数据的输入:

第一个.csv:n_t.csv

6,2

 第二个.csv:权阵.csv

0.91,0.59,0.43,0.37,0.42,0.25

第三个.csv:系数参数矩阵

1,0,0
0,1,0
1,0,-4
0,1,-3
-1,1,-7
-1,0,-2

 上面三个输入文件也可以在代码中直接输入数据进行计算

运行代码如下:

import numpy as np
from numpy import linalg


def Example(n, t, A, L, P):

    N = np.dot(np.dot(A.T, P), A)  # N 参数平差值的权逆阵Qx
    U = np.dot(np.dot(A.T, P), L)
    X = np.dot(linalg.inv(N), U)    # X 参数平差值向量,数组长度为t,待计算
    V = np.dot(A, X) - L      # V 观测值残差向量数组长度为n,待计算
    μ = np.sqrt(np.dot(np.dot(V.T, P), V) / (n - t))   # 函数返回值—若计算成功,返回单位权中误差μ
    Qx = linalg.inv(N)
    return (X, V, μ, Qx)


if __name__ == "__main__":
    # 观测值总数和参数总数
    # 文件导入n、t     n 观测值个数;t 参数个数;
    original_data1 = list(map(int, np.loadtxt(open('n_t.csv'), delimiter=",", skiprows=0)))
    n, t = original_data1[0], original_data1[1]
    # 误差方程
    AL = np.array(np.loadtxt(open('系数参数矩阵.csv'), delimiter=",", skiprows=0), dtype=np.float64)
# 程序中使用的例题是武汉大学出版社出版的《误差理论与测量平差基础》中的7-8例题
    A = AL[:, :-1]     # A 误差方程系数矩阵数组长度为 n*t,已知
    L = AL[:, -1]    # L 观测值向量,数组长度为n,已知;
    # 定权
    P = np.diag(np.loadtxt(open('权阵.csv'), delimiter=",", skiprows=0))   # P 观测值权数组,只有权矩阵的对角线元素数组长度为n

    X, V, μ, Qx = Example(n, t, A, L, P)   # X 参数平差值向量,数组长度为t,待计算

    with open('计算结果.csv',  'w', encoding="utf-8") as f:
        f.writelines("误差方程:\n")
        f.writelines(str(AL))
        f.writelines("\n参数平差值X:\n")
        f.writelines(str(X))
        f.writelines("\n残差向量V最小二乘残差V:\n")
        f.writelines(str(V))
        f.writelines("\n参数平差值的权逆阵Qx\n")
        f.writelines(str(Qx))
        f.writelines("\n单位权中误差μ\n")
        f.writelines(str(μ))

运行结果如下:

结果.csv:

误差方程:
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 1.  0. -4.]
 [ 0.  1. -3.]
 [-1.  1. -7.]
 [-1.  0. -2.]]
参数平差值X:
[ 0.25895126 -2.85597136]
残差向量V最小二乘残差V:
[ 0.25895126 -2.85597136  4.25895126  0.14402864  3.88507739  1.74104874]
参数平差值的权逆阵Qx
[[0.53130053 0.16170016]
 [0.16170016 0.77385077]]
单位权中误差μ
2.223618663514489
间接原理写的代码,绝对有用,真实可靠 Dim strFileName As String Dim nn%, un%, tn%, hn% '已知点个数,未知点个数,总点数,观测值个数 Dim Pname() As String '点名数组 Dim Hknown() As Double '已知高程数组,存放已知点高程和高程近似值 Dim be%(), en%() '观测值的起点和终点编号数组,存储的是点序号 Dim h#(), s#() '高观测值数组和距离观测值数组 Dim A#(), X#(), P#(), L#() '间接的系数阵、解向量、权阵和常数向量 '计算 Private Sub mnuAdj_Click() Dim i%, j% ReDim X(1 To un) InAdjust A, P, L, X '调用间接的通用过程求解 '计算并显示高程结果 txtShow.Text = txtShow.Text & "计算结果:" & vbCrLf txtShow.Text = txtShow.Text & "点号 初始高程(m) 高程改正数(m) 后高程(m)" & vbCrLf For i = 1 To un txtShow.Text = txtShow.Text & Pname(nn + i) & " " & Format(Hknown(nn + i), "0.0000") Hknown(nn + i) = Hknown(nn + i) + X(i) txtShow.Text = txtShow.Text & " " & Format(X(i), "0.0000") & " " & Format(Hknown(nn + i), "0.0000") & vbCrLf Next i txtShow.Text = txtShow.Text & vbCrLf '计算并显示单位权中误--------->>精度评定部分应该也包含在间接模块里,一起来调用 ' Dim dblT As Double ' dblT = 0 ' For i = 1 To un ' ' Next i End Sub '列立误方程:给A、P、L赋值 Private Sub mnuEqu_Click() Dim i%, j% ReDim A(1 To hn, 1 To un), L(1 To hn), P(1 To hn, 1 To hn) '对每个观测值列误方程 For i = 1 To hn If en(i) > nn Then A(i, en(i) - nn) = 1 '若终点未知,则给终点对应的系数矩阵元素赋值 If be(i) > nn Then A(i, be(i) - nn) = -1 '若起点未知,则给起点对应的系数矩阵元素赋值 L(i) = -(Hknown(en(i)) - Hknown(be(i)) - h(i)) '根据起终点计算常数项 P(i, i) = 1 / s(i) '以距离的倒数为权 Next i '显示误方程 txtShow.Text = txtShow.Text & " 列立的误方程:" & vbCrLf For i = 1 To hn For j = 1 To un txtShow.Text = txtShow.Text & A(i, j) & " " Next j txtShow.Text = txtShow.Text & " " & Format(L(i), "0.0000") & vbCrLf Next i txtShow.Text = txtShow.Text & "权矩阵:" & vbCrLf For i = 1 To hn For j = 1 To hn txtShow.Text = txtShow.Text & P(i, j) & " " Next j txtShow.Text = txtShow.Text & vbCrLf Next i End Sub '计算近似高程 Private Sub mnuHeight_Click() Dim i%, j% For i = 1 To un For j = 1 To hn If be(j) = nn + i And en(j) < nn + i Then '找到一个起点相同且终点已知的观测值 Hknown(nn + i) = Hknown(en(j)) - h(j) Exit For End If If en(j) = nn + i And be(j) < nn + i Then '找到一个终点相同且起点已知的观测值 Hknown(nn + i) = Hknown(be(j)) + h(j) Exit For End If Next j Next i '显示近似高程计算结果 txtShow.Text = txtShow.Text & " 近似高程计算结果: " & vbCrLf For i = 1 To un txtShow.Text = txtShow.Text & Pname(i + nn) & ":" & Format(Hknown(i + nn), "0.000") & vbCrLf Next i End Sub '退出程序 Private Sub mnuExit_Click() End End Sub '打开文件 Private Sub mnuOpen_Click() Dim i As Integer '循环变量 Dim strT1 As String, strT2 As String CDg1.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*" CDg1.ShowOpen '打开对话框 strFileName = CDg1.FileName '获得选中的文件名和路径 Open strFileName For Input As #1 '打开文件 Input #1, nn, un, hn '读入已知点个数,未知点个数,观测值个数 tn = nn + un ReDim Pname(1 To tn), Hknown(1 To tn) ReDim h(1 To hn), s(1 To hn), be(1 To hn), en(1 To hn) For i = 1 To tn '读入点名 Input #1, Pname(i) Next i For i = 1 To nn '读入已知高程 Input #1, Hknown(i) Next i For i = 1 To hn '读入各观测值 Input #1, strT1, strT2, h(i), s(i) be(i) = Order(strT1): en(i) = Order(strT2) '给起终点数组排序 Next i '显示读入的数据 txtShow.Text = txtShow.Text & "读入的水准网数据:" & vbCrLf txtShow.Text = txtShow.Text & " 已知点" & nn & "个,未知点" & un & "个,观测值" & hn & "个。" & vbCrLf txtShow.Text = txtShow.Text & " 网中涉及的点名有:" For i = 1 To tn txtShow.Text = txtShow.Text & Pname(i) & "," Next i txtShow.Text = txtShow.Text & vbCrLf txtShow.Text = txtShow.Text & " 已知点高程为:" & vbCrLf For i = 1 To nn txtShow.Text = txtShow.Text & Pname(i) & "的高程为:" & Hknown(i) & vbCrLf Next i txtShow.Text = txtShow.Text & " 各观测值分别为:" & vbCrLf txtShow.Text = txtShow.Text & "起点" & " " & "终点" & " " & "高观测值 " & " 距离观测值" & vbCrLf For i = 1 To hn txtShow.Text = txtShow.Text & Pname(be(i)) & " " & Pname(en(i)) & " " & Format(h(i), "0.000") & " " & Format(s(i), "0.000") & vbCrLf Next i Close #1 '不要忘记关闭文件 End Sub '点名-序号转换函数 Public Function Order(str As String) As Integer Dim i% For i = 1 To tn If str = Pname(i) Then Order = i Exit For End If Next i End Function '保存计算结果 Private Sub mnuSave_Click() CDg1.Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*" CDg1.ShowSave strFileName = CDg1.FileName Open strFileName For Output As #1 Print #1, txtShow.Text Close #1 End Sub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值