电信专业课电子测量学科使用,包括粗大误差处理、肖维纳检验法、莱特检验法、 格拉布斯检验法、累进性误差判断、周期性误差判断及给定置信概率求取置信区间部分。
- 题目要求:
用C语言或Matlab设计测量数据误差处理的通用程序
(1)提供测试数据输入、粗大误差判别准则选择的人机界面
(2)编写程序使用说明
(3)通过实例来验证程序的正确性
- 涉及知识
测量误差的分类及特点
随机误差的处理与估计
系统误差的处理
粗大误差的处理
测量数据处理
- 流程图
import tkinter
import tkinter.messagebox
import math
import copy
# t分布积分表
table1_row = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 60, 120]
table1_col = [50, 60, 70, 80, 90, 95, 98, 99, 999]
table1 = [[1.000, 1.376, 1.936, 3.078, 6.314, 12.706, 31.821, 63.657, 636.619],
[0.816, 1.061, 1.386, 1.886, 2.920, 4.303, 6.965, 9.925, 31.598],
[0.765, 0.978, 1.250, 1.638, 2.353, 3.182, 4.541, 5.841, 12.924],
[0.741, 0.941, 1.190, 1.553, 2.132, 2.776, 3.747, 4.604, 8.610],
[0.727, 0.920, 1.156, 1.476, 2.015, 2.571, 3.365, 4.032, 6.859],
[0.718, 0.906, 1.134, 1.440, 1.943, 2.447, 3.143, 3.707, 5.959],
[0.711, 0.896, 1.119, 1.415, 1.895, 2.365, 2.998, 3.499, 5.405],
[0.706, 0.889, 1.108, 1.397, 1.860, 2.306, 2.896, 3.355, 5.041],
[0.703, 0.883, 1.100, 1.383, 1.833, 2.262, 2.821, 3.250, 4.781],
[0.700, 0.879, 1.093, 1.372, 1.812, 2.228, 2.764, 3.169, 4.587],
[0.691, 0.866, 1.074, 1.341, 1.753, 2.131, 2.602, 2.947, 4.073],
[0.687, 0.860, 1.064, 1.325, 1.725, 2.086, 2.528, 2.845, 3.850],
[0.684, 0.856, 1.058, 1.316, 1.708, 2.06, 2.485, 2.787, 3.725],
[0.683, 0.854, 1.055, 1.310, 1.697, 2.042, 2.457, 2.750, 3.646],
[0.681, 0.851, 1.050, 1.303, 1.684, 2.021, 2.423, 2.704, 3.551],
[0.679, 0.848, 1.046, 1.296, 1.671, 2.000, 2.390, 2.660, 3.460],
[0.677, 0.845, 1.041, 1.289, 1.658, 1.980, 2.358, 2.617, 3.373]]
# 肖维纳准则表
table2 = [1.65, 1.73, 1.79, 1.86, 1.92, 1.96, 2, 2.04, 2.07, 2.1, 2.13, 2.16, 2.18, 2.2, 2.22, 2.24, 2.26, 2.28, 2.3,
2.32, 2.33, 2.34, 2.35, 2.37, 2.38, 2.39, 2.45, 2.5, 2.58, 2.64, 2.74, 2.81, 3.02]
# 格拉布斯准则表
table3_95 = [1.15, 1.46, 1.67, 1.82, 1.94, 2.03, 2.11, 2.18, 2.23, 2.29, 2.33, 2.37, 2.41, 2.44, 2.47, 2.5, 2.53, 2.56,
2.58, 2.60, 2.62, 2.64, 2.66]
table3_99 = [1.16, 1.49, 1.75, 1.94, 2.1, 2.22, 2.32, 2.41, 2.48, 2.55, 2.61, 2.66, 2.71, 2.75, 2.79, 2.82, 2.85, 2.88,
2.91, 2.94, 2.96, 2.99, 3.01]
# 平均值
def average(data):
sum_num = 0.0
for i in data:
sum_num += i
return sum_num / len(data)
# 方差
def variance(data):
aver = average(data)
sum_num = 0
for i in data:
sum_num += (i - aver) ** 2
return math.sqrt(sum_num / len(data) / (len(data) - 1))
# 累进性系统误差判断
def system_error1(data):
aver = average(data)
max_num = abs(data[0] - aver)
for i in data:
if max_num < abs(i - aver):
max_num = abs(i - aver)
sum1 = sum2 = 0
for i in range(len(data) // 2 - 1):
sum1 += abs(data[i] - aver)
for i in range(len(data) // 2, len(data)):
sum2 += abs(data[i] - aver)
if abs(sum1 - sum2) >= max_num:
return "测量中存在累进性系统误差!"
else:
return "测量中无累进性系统误差"
# 周期性系统误差判断
def system_error2(data):
aver = average(data)
num = (variance(data) * math.sqrt(len(data))) ** 2 # 标准偏差的平方
sum_num = 0
for i in range(len(data) - 1):
sum_num += (data[i] - aver) * (data[i + 1] - aver)
sum_num = abs(sum_num)
if sum_num > num * math.sqrt(len(data) - 1):
return "测量中存在周期性系统误差"
else:
return "测量中无周期性系统误差"
# 剔除坏值
def cull(data, num):
while True:
varian = variance(data)
aver = average(data)
length = len(data)
for i in data:
if abs(i - aver) > num * varian * math.sqrt(length):
data.remove(i)
break
if len(data) == length:
break
return data
# 莱特检验法剔除坏值
def check1(data):
return cull(data, 3)
# 肖维纳检验法剔除坏值
def check2(data):
if len(data) < 5:
print("数据少于5个!不能使用肖维纳检验法")
return
ch = table2[len(data) - 5]
return cull(data, ch)
# 格拉布斯检验法剔除坏值
def check3(data, choose):
if len(data) < 3:
print("数据少于3个!不能使用格拉布斯检验法")
return
if choose == 95:
g = table3_95[len(data) - 3]
elif choose == 99:
g = table3_99[len(data) - 3]
return cull(data, g)
# 根据k和p查看置信系数
def find1(k, p):
row = None
col = None
try:
for i in range(len(table1_row)):
if table1_row[i] == k:
row = i
break
for i in range(len(table1_col)):
if table1_col[i] == p:
col = i
break
return table1[row][col]
except TypeError:
Tax3.insert(tkinter.END, "所查找的值不在表\n")
# 根据p求置信空间
def solve_range(data, p):
aver = average(data)
varian = variance(data)
try:
t = find1(len(data) - 1, p)
min_num = aver - t*varian
max_num = aver + t*varian
return [min_num, max_num]
except:
return None
# 根据置信空间求p
def solve_chance(data, min_num=None):
aver = average(data)
varian = variance(data)
t = (aver - min_num) / varian
return t
# 剔除坏值的检验法选择
def select1():
if var1.get() == -1:
var2.set(0)
# 剔除坏值的置信概率选择
def select2():
if var2.get() == 0:
var1.set(-1)
def main():
Tax3.delete(0.0, tkinter.END)
# 获得输入数据,并转换为列表
data_original = var.get()
data_original = data_original.strip()
data_original = data_original.split(',')
for i in range(len(data_original)):
data_original[i] = data_original[i].strip()
data_original[i] = float(data_original[i])
# 深拷贝原始数据
data_new = copy.deepcopy(data_original)
# 剔除坏值过程,choose11为用户的选择
choose11 = var1.get()
if choose11 == 0:
data_new = check1(data_new)
elif choose11 == 1:
data_new = check2(data_new)
elif choose11 == 2:
data_new = check3(data_new, var2.get())
else:
pass
# 求解置信区间或置信概率
choose21 = var4.get()
if choose21 == 0:
p = int(var5.get())
result_range = solve_range(data_new, p)
elif choose21 == 1:
num1 = float(var5.get())
result_t = solve_chance(data_new, num1)
# 数据的转换,都转换为字符串
aver1 = str(round(average(data_original), 3))
vari1 = str(round(variance(data_original), 3))
piancha1 = str(round((variance(data_original) * math.sqrt(len(data_original))), 3))
aver2 = str(round(average(data_new), 3))
vari2 = str(round(variance(data_new), 3))
piancha2 = str(round((variance(data_new) * math.sqrt(len(data_new))), 3))
str1 = system_error1(data_new)
str2 = system_error2(data_new)
# 把列表转换为字符串
for i in range(len(data_original)):
data_original[i] = str(data_original[i])
for i in range(len(data_new)):
data_new[i] = str(data_new[i])
data_original = ", ".join(data_original)
data_new = ", ".join(data_new)
Tax3.insert(tkinter.END, "测量数据:" + data_original + "\n")
Tax3.insert(tkinter.END, "测量数据的均值:" + aver1 + "\n")
Tax3.insert(tkinter.END, "测量数据的标准偏差:" + vari1 + "\n")
Tax3.insert(tkinter.END, "测量数据的方差:" + piancha1 + "\n")
if var1.get() != -1:
Tax3.insert(tkinter.END, "剔除坏值后测量数据:" + data_new + "\n")
Tax3.insert(tkinter.END, "剔除坏值后测量数据的均值:" + aver2 + "\n")
Tax3.insert(tkinter.END, "剔除坏值后测量数据的标准偏差:" + vari2 + "\n")
Tax3.insert(tkinter.END, "剔除坏值后测量数据的方差:" + piancha2 + "\n")
if var4.get() == 0:
try:
zuo = str(round(result_range[0], 3))
you = str(round(result_range[1], 3))
except:
Tax3.insert(tkinter.END, "所输入数据的自由度不在列表中,无法计算置信区间!\n")
else:
Tax3.insert(tkinter.END, "置信区间为:[" + zuo + ", " + you + "]\n")
if var4.get() == 1:
Tax3.insert(tkinter.END, "求出的t值为:" + str(round(result_t, 4)) + "\n")
if var3.get() == 1:
Tax3.insert(tkinter.END, str1 + "\n")
Tax3.insert(tkinter.END, str2)
if __name__ == "__main__":
window = tkinter.Tk()
window.title("测量数据误差处理程序")
window.geometry("900x700")
window.resizable(height=False, width=False)
# 窗口标题
Lab1 = tkinter.Label(window, text="测量数据误差处理程序", font=("", 25))
Lab1.place(x=250, y=0)
# 输入数据提示及输入文本框
var = tkinter.StringVar()
var.set("")
Lab2 = tkinter.Label(window, text="输入数据[数据,数据,...]:", font=("", 15))
Lab2.place(x=3, y=60)
Tax1 = tkinter.Entry(window, textvariable=var, width=125, font=("", 12))
Tax1.place(x=3, y=90)
# 误差处理的选择
Lab3 = tkinter.Label(window, text="误差处理方式:", font=("", 15))
Lab3.place(x=3, y=150)
# 选择剔除的检验法(单选)
Lab4 = tkinter.Label(window, text="剔除坏值检验法", font=("", 10))
Lab4.place(x=30, y=190)
var1 = tkinter.IntVar()
var1.set(-1)
Rbt1_1 = tkinter.Radiobutton(window, text="莱特检验法", variable=var1, value=0, command=select1)
Rbt1_2 = tkinter.Radiobutton(window, text="肖维纳检验法", variable=var1, value=1, command=select1)
Rbt1_3 = tkinter.Radiobutton(window, text="格布拉斯检验法", variable=var1, value=2, command=select1)
Rbt1_4 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var1, value=-1, command=select1)
Rbt1_1.place(x=30, y=210)
Rbt1_2.place(x=100, y=210)
Rbt1_3.place(x=170, y=210)
Rbt1_4.place(x=240, y=210)
# 选择剔除坏值的置信概率
Lab5 = tkinter.Label(window, text="剔除坏值置信概率", font=("", 10))
Lab5.place(x=30, y=240)
var2 = tkinter.IntVar()
var2.set(0)
Rbt2_1 = tkinter.Radiobutton(window, text="95%", variable=var2, value=95, command=select2)
Rbt2_2 = tkinter.Radiobutton(window, text="99%", variable=var2, value=99, command=select2)
Rbt2_3 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var2, value=0, command=select2)
Rbt2_1.place(x=30, y=260)
Rbt2_2.place(x=100, y=260)
Rbt2_3.place(x=170, y=260)
# 选择是否进行系统误差检测
Lab6 = tkinter.Label(window, text="是否进行系统误差检测", font=("", 10))
Lab6.place(x=30, y=290)
var3 = tkinter.IntVar()
var3.set(0)
Rbt3_1 = tkinter.Radiobutton(window, text="是", variable=var3, value=1)
Rbt3_2 = tkinter.Radiobutton(window, text="否", variable=var3, value=0)
Rbt3_1.place(x=30, y=310)
Rbt3_2.place(x=100, y=310)
# 选择求置信概率还是置信区间
Lab7 = tkinter.Label(window, text="求置信概率还是置信区间", font=("", 10))
Lab7.place(x=30, y=340)
var4 = tkinter.IntVar()
var4.set(0)
Rbt4_1 = tkinter.Radiobutton(window, text="置信概率", variable=var4, value=1)
Rbt4_2 = tkinter.Radiobutton(window, text="置信区间", variable=var4, value=0)
Rbt4_1.place(x=30, y=360)
Rbt4_2.place(x=100, y=360)
# 输入文本框(置信概率或置信区间)
Lab8 = tkinter.Label(window, text="请输入置信概率(求置信区间)\n(求置信概率,给出t值,自行查表)\n格式为:"
"50(表示50%置信概率)", font=("", 10))
Lab8.place(x=3, y=400)
var5 = tkinter.StringVar()
var5.set("")
Tax2 = tkinter.Entry(window, textvariable=var5, width=25, font=("", 12))
Tax2.place(x=30, y=450)
# 输出
Btn1 = tkinter.Button(window, text="运行", font=("", 20), command=main)
Btn1.place(x=70, y=510)
Tax3 = tkinter.Text(window, width=65, height=40)
Tax3.place(x=400, y=150)
window.mainloop()
- 程序运行
界面板块:
数据输入板块——输入数据,以“,”分割
误差处理方式选择板块——选择检验法与置信概率等必要选项
运行板块——点击运行按钮执行程序
输出板块——输出误差处理结果
个人水平有限,仅限于大学学习内容,希望对各位有所帮助。