算法设计中的一些核心原则

发布于:2024-04-11 ⋅ 阅读:(141) ⋅ 点赞:(0)

1.命名并实体化一切非自解释的概念

这是算法设计的核心原则之一。可以进一步归结为:你不可让逻辑匿名地裸露出来。你必须命名一切你知晓的概念,并且通过注释、适当的代码粒度管理,命名,妥善封装这些概念,比如:

def isShartNotPlacedCenterized(arFreq, arValue, baseFreqOfShaft, arZeroDbValue):
    errorSpan = 0.15
    ratio = arFreq[0]/baseFreqOfShaft
    ratio = np.abs(ratio - 2)/2;
    
    if(ratio<=errorSpan):
        score = gp_vibration_helper.gp_getdbValuebyRawValue(arValue[0], arZeroDbValue);
        return (True, score);
    else:
        return (False, 0);

上面的写法是错误的。正确的写法是:

'''
功能说明:轴不对中判定
    版本:V1.0.20240410
    机制:轴不对中,二倍频谱线明显增强
    ParamIn:(arFreq, arValue, baseFreqOfShaft, arZeroDbValue)
        arFreq          低通滤波后的频谱中前N条最高幅度谱线的频率值
        arValue         低通滤波后的频谱中前N条最高幅度谱线的幅值
        baseFreqOfShart 轴频
        arZeroDbValue   用作db输出的系统最高幅值点
    ParamOut:(hasError, errorValue)
        hasError        有此类故障范围True,否则False
        score           故障严重程度,[-40,0],单位db
'''
def isShartNotPlacedCenterized(arFreq, arValue, baseFreqOfShaft, arZeroDbValue):
    isflag2xFreqAppeared = gp_vibration_helper.gp_IsSignalAppear(arFreq[0], 2*baseFreqOfShaft);
    if(isflag2xFreqAppeared):
        dbOfSignal = gp_vibration_helper.gp_getdbValuebyRawValue(arValue[0], arZeroDbValue);
        if(dbOfSignal>=-40):
            return (True, dbOfSignal);
    return (False, 0);

2.在进行任何探索性工作前必须构建好桩模块

比如:在进行轴承振动分析时,你很快会在构建代码的过程中,遇到一堆问题,比如:

  • 包络计算
  • 频点计算
  • db坐标与线性坐标转换
  • 功率谱密度、功率谱、与幅度谱
  • 频谱泄露
  • 窗函数
  • 相关性分析

这个列表是无穷尽的,明白吗。如果一路走下去,你会迷失在这个知识网络里,单独拉出任何一个项点,都是10小时,甚至更多时间的阅读和仿真工作量。比如:

使用 FFT 获得功率频谱密度估计- MATLAB & Simulink- MathWorks 中国

这个时候,哪怕你做错,也必须按照错的,做完,留下类似#TODO标记,然后快速构建好整套系统,然后再回头重构。

重构这个词源自一个已经可以工作的版本。没有这个版本的存在,你的工作是未完成,得0分。一个小学生过来把接口封装好,人家领5元钱走人,你一分都不该发——你没有提供应有的服务。

你确实清楚,此时的理解是不完备的,甚至写下来就是错的;或者误差很大,无法在工程上输出稳定结果。但是,即使是错误,也值得记录下来。因为它代表着一个随时可以拿起作为参照的凝固的理解。比如这个对于轴振动故障的一份完整示例:

import numpy as np
import sys
import gp_vibration_helper 

'''
功能说明:
    isShartNotPlacedCenterized
    功能:轴不对中判定
    版本:V1.0.20240410
    机制:轴不对中,二倍频谱线明显增强
    ParamIn:(arFreq, arValue, baseFreqOfShaft, arZeroDbValue)
        arFreq          低通滤波后的频谱中前N条最高幅度谱线的频率值
        arValue         低通滤波后的频谱中前N条最高幅度谱线的幅值
        baseFreqOfShart 轴频
        arZeroDbValue   用作db输出的系统最高幅值点
    ParamOut:(hasError, errorValue)
        hasError        有此类故障范围True,否则False
        score           故障严重程度,[-40,0],单位db
'''
def isShartNotPlacedCenterized(arFreq, arValue, baseFreqOfShaft, arZeroDbValue):
    isflag2xFreqAppeared = gp_vibration_helper.gp_IsSignalAppear(arFreq[0], 2*baseFreqOfShaft);
    if(isflag2xFreqAppeared):
        dbOfSignal = gp_vibration_helper.gp_getdbValuebyRawValue(arValue[0], arZeroDbValue);
        if(dbOfSignal>=-40):
            return (True, dbOfSignal);
    return (False, 0);


'''
    isShartNotPlacedCenterized
    功能:轴不平衡判定,
    机制:轴不平衡,一倍频谱线明显增强
    版本:V1.0.20240410
    ParamIn:(arFreq, arValue, baseFreqOfShaft, arZeroDbValue)
        arFreq          低通滤波后的频谱中前N条最高幅度谱线的频率值
        arValue         低通滤波后的频谱中前N条最高幅度谱线的幅值
        baseFreqOfShart 轴频
        arZeroDbValue   用作db输出的系统最高幅值点
    ParamOut:(hasError, errorValue)
        hasError        有此类故障范围True,否则False
        score           故障严重程度,[-40,0],单位db
'''
def isShartLoadNotCenterized(arFreq, arValue, baseFreqOfShart, arZeroDbValue):
    isflag2xFreqAppeared = gp_vibration_helper.gp_IsSignalAppear(arFreq[0], baseFreqOfShaft);
    if(isflag2xFreqAppeared):
        dbOfSignal = gp_vibration_helper.gp_getdbValuebyRawValue(arValue[0], arZeroDbValue);
        if(dbOfSignal>=-40):
            return (True, dbOfSignal);
    return (False, 0);

'''
    gpGetShaft_HealthScore
    功能:轴故障判定
    机制:返回不对中,不平衡的判断结果[百分制]
    版本:V1.0.20240410
    ParamIn:(fft_abs_array, scaleOfFreq, baseFreqOfShaft)
        fft_abs_array   原始振动加速度采样值的幅度值序列,单位幅度
        scaleOfFreq     加速度序列的档位,单位Hz
        baseFreqOfShart 轴频
    ParamOut:(scoreOfShaftLoad, scoreOfShartCenter)
        scoreOfShaftLoad    轴平衡健康度[0,100]
        scoreOfShartCenter  轴对中健康度[0,100]
'''
def gpGetShaft_HealthTestResult(dbView_fftOfVirbation, scaleOfFreq, baseFreqOfShaft):
    (arFreq, arValue) = gp_vibration_helper.gp_getdbValuebyRawValue(dbView_fftOfVirbation, scaleOfFreq, baseFreqOfShaft)
    if(arValue[0]<-40): #小于40db健康
        return (100, 100)
    maxValueInFullFreqRange = np.max(dbView_fftOfVirbation);
    (errLoad, dbLoad) = isShartLoadNotCenterized(arFreq, arValue, baseFreqOfShaft, maxValueInFullFreqRange);
    (errCenter, dbCenter) = isShartLoadNotCenterized(arFreq, arValue, baseFreqOfShaft, maxValueInFullFreqRange);
    
    scoreOfShartLoad = 100;
    scoreOfShartCenter = 100;
    if(errLoad):
        errorPercent = 100/40*(dbLoad-(-40.0))
        scoreOfShaftLoad = 100 - errorPercent;
    if(errCenter):
        errorPercent = 100/40*(dbCenter-(-40.0))
        scoreOfShartCenter = 100 - errorPercent;
    
    return (scoreOfShartLoad, scoreOfShartCenter);

它不对,不够准确,但是这是你现阶段的一份可能输出物,这就够了。

【待续...】


网站公告

今日签到

点亮在社区的每一天
去签到