summaryrefslogtreecommitdiff
path: root/common/statistic_average.sh
blob: f5bdbfbc7a9cec2d873d935ef8b53c53e50a822b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/bin/bash

## Description:
##    output the max value of the passed 2 parameters
## Usage:
##    f_max "${val1}" "${val2}"
## Example:
##    max=$(f_max "1.5" "2.0")
f_max(){
    local val1=$1
    local val2=$2
    [ -z "$val1" ] && echo $val2
    [ -z "$val2" ] && echo $val1

    local compare=$(echo "$val1>$val2"|bc)
    if [ "X$compare" = "X1" ];then
        echo $val1
    else
        echo $val2
    fi
}

## Description:
##    output the min value of the passed 2 parameters
## Usage:
##    f_min "${val1}" "${val2}"
## Example:
##    min=$(f_min "1.5" "2.0")
f_min(){
    local val1=$1
    local val2=$2
    [ -z "$val1" ] && echo $val1
    [ -z "$val2" ] && echo $val2

    local compare=$(echo "$val1<$val2"|bc)
    if [ "X$compare" = "X1" ];then
        echo $val1
    else
        echo $val2
    fi
}

standard_deviation_error(){
    local average=$1
    if [ -z "${average}" ]; then
        return
    fi
    shift

    local values=$1
    if [ -z "${values}" ]; then
        return
    fi
    shift
    local deviations_sum=0
    local count=0
    for s_value in $values ; do
        s_deviation=$(echo "${average},${s_value}"|awk -F, '{printf "%.2f",($2-$1)^2;}')
        deviations_sum=$(echo "${deviations_sum},${s_deviation}"|awk -F, '{printf "%.2f",$1+$2;}')
        count=$(echo "${count},1"|awk -F, '{printf $1+$2;}')
    done
    local deviation=$(echo "${deviations_sum},${count}"|awk -F, '{printf "%.2f",sqrt($1/$2);}')
    local std_err=$(echo "${deviation},${count}"|awk -F, '{printf "%.2f",$1/sqrt($2);}')
    echo "${deviation},${std_err}"
}
## Description:
##   calculate the average value for specified csv file.
##   The first field of that csv file should be the key/name of that line,
##   Lines have the same key should be together.
## Usage:
##    statistic "${csv_file_path}" "${file_number}"
## Example:
##    statistic "$f_res_starttime" 2
## Note:
##    if less than 4 samples for that key/item there, average will be calculated as total/count
##    if 4 or more samples for that key/item there, average will be calculated with max and min excluded
statistic(){
    local f_data=$1
    if ! [ -f "$f_data" ]; then
        return
    fi
    local field_no=$2
    if [ -z "$field_no" ]; then
        field_no=2
    fi

    local units_field_no=$3
    local units=""

    local total=0
    local old_key=""
    local new_key=""
    local count=0
    local values=""
    for line in $(cat "${f_data}"); do
        if ! echo "$line"|grep -q ,; then
            continue
        fi
        new_key=$(echo $line|cut -d, -f1)
        value=$(echo $line|cut -d, -f${field_no})
        if [ "X${new_key}" = "X${old_key}" ]; then
            total=$(echo ${total},${value}|awk -F, '{printf "%.2f",$1+$2;}')
            values="${values} ${value}"
            count=$(echo "$count + 1"|bc)
        else
            if [ "X${old_key}" != "X" ]; then
                local average=$(echo ${total},${count}|awk -F, '{printf "%.2f",$1/$2;}')
                local sigma_stderr=$(standard_deviation_error "${average}" "${values}")
                local sigma=$(echo ${sigma_stderr}|cut -d, -f1)
                local std_err=$(echo ${sigma_stderr}|cut -d, -f2)
                if [ -z "${units}" ]; then
                    echo "${old_key}=${average}"
                    echo "${old_key}_sigma=${sigma}"
                    echo "${old_key}_std_err=${std_err}"
                else
                    echo "${old_key}=${average},${units}"
                    echo "${old_key}_sigma=${sigma},${units}"
                    echo "${old_key}_std_err=${std_err},${units}"
                fi
            fi
            total="${value}"
            values="${value}"
            old_key="${new_key}"
            count=1
            if [ -n "${units_field_no}" ]; then
                units=$(echo $line|cut -d, -f${units_field_no})
            fi
        fi
    done
    if [ "X${new_key}" != "X" ]; then
        local average=$(echo ${total},${count}|awk -F, '{printf "%.2f",$1/$2;}')
        local sigma_stderr=$(standard_deviation_error "${average}" "${values}")
        local sigma=$(echo ${sigma_stderr}|cut -d, -f1)
        local std_err=$(echo ${sigma_stderr}|cut -d, -f2)
        if [ -z "${units}" ]; then
            echo "${old_key}=${average}"
            echo "${old_key}_sigma=${sigma}"
            echo "${old_key}_std_err=${std_err}"
        else
            echo "${old_key}=${average},${units}"
            echo "${old_key}_sigma=${sigma},${units}"
            echo "${old_key}_std_err=${std_err},${units}"
        fi
    fi
}