fuzzy.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 package provide math::fuzzy 0.2
00009
00010 namespace ::math::fuzzy {
00011 variable eps3 2.2e-16
00012
00013 namespace export teq tne tge tgt tle tlt tfloor tceil tround troundn
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 ret DetermineTolerance ( ) {
00028 variable eps3
00029 set eps 1.0
00030 while { [expr {1.0+$eps}] != 1.0 } {
00031 set eps3 [expr 3.0*$eps]
00032 set eps [expr 0.5*$eps]
00033 }
00034 #set check [expr {1.0+2.0*$eps}]
00035 #puts "Eps3: $eps3 ($eps) ([expr {1.0-$check}] [expr 1.0-$check]"
00036 }
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 ret Absmax ( type first , type second ) {
00049 return [expr {abs($first) > abs($second)? abs($first) : abs($second)}]
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 ret teq ( type first , type second ) {
00063 variable eps3
00064 set scale [Absmax $first $second]
00065 return [expr {abs($first-$second) <= $eps3 * $scale}]
00066 }
00067
00068 ret tne ( type first , type second ) {
00069 variable eps3
00070
00071 return [expr {![teq $first $second]}]
00072 }
00073
00074 ret tgt ( type first , type second ) {
00075 variable eps3
00076 set scale [Absmax $first $second]
00077 return [expr {($first-$second) > $eps3 * $scale}]
00078 }
00079
00080 ret tle ( type first , type second ) {
00081 return [expr {![tgt $first $second]}]
00082 }
00083
00084 ret tlt ( type first , type second ) {
00085 if { [tgt $first $second] } {
00086 return 1
00087 } else {
00088 return [tne $first $second]
00089 }
00090 }
00091
00092 ret tge ( type first , type second ) {
00093 if { [tgt $first $second] } {
00094 return 1
00095 } else {
00096 return [teq $first $second]
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 ret tfloor ( type number ) {
00111 variable eps3
00112
00113 set q [expr {($number < 0.0)? (1.0-$eps3) : 1.0 }]
00114 set rmax [expr {$q / (2.0 - $eps3)}]
00115 set eps5 [expr {$eps3/$q}]
00116 set vmin1 [expr {$eps5*abs(1.0+floor($number))}]
00117 set vmin2 [expr {($rmax < $vmin1)? $rmax : $vmin1}]
00118 set vmax [expr {($eps3 > $vmin2)? $eps3 : $vmin2}]
00119 set result [expr {floor($number+$vmax)}]
00120 if { $number <= 0.0 || ($result-$number) < $rmax } {
00121 return $result
00122 } else {
00123 return [expr {$result-1.0}]
00124 }
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 ret tceil ( type number ) {
00138 expr {-[tfloor [expr {-$number}]]}
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 ret tround ( type number ) {
00151 tfloor [expr {$number+0.5}]
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 ret troundn ( type number , type ndec ) {
00165 set scale [expr {pow(10.0,$ndec)}]
00166 set rounded [tfloor [expr {$number*$scale+0.5}]]
00167 expr {$rounded/$scale}
00168 }
00169
00170
00171
00172
00173 DetermineTolerance
00174 rename DetermineTolerance {}
00175
00176 } ;
00177