-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMinMaxScaler.cs
150 lines (128 loc) · 4.42 KB
/
MinMaxScaler.cs
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
146
147
148
149
150
//MinMaxScalerByte scales numeric integer sequences down to their
//lower limit, and allows reversal to be accomplished again without
//any problems.
//There are certainly many applications for MinMaxScalerByte, and
//the one that comes to mind spontaneously could possibly be data
//compression. It would have to be adapted specifically for this.
//MinMaxScalerByte is freely changeable as well as available.
//A small hint to my repository is enough.
//https://github.com/exc-jdbi/MinMaxScalerBytes
//Thanks and greetings exc-jdbi.
//MinMaxScalerByte skaliert numerische Ganzzahlenfolgen runter an
//ihren unteren Grenzwert, und lässt eine Umkehrung problemlos
//wieder bewerkstelligen.
//Für MinMaxScalerByte gibt es sicher viele Einsatzorte, und die die mir
//spontan einfällt könnte eventuell die Datenkompression sein. Müsste
//spezifisch dafür angepasst werden.
//MinMaxScalerByte ist frei veränderbar wie auch verfügbar.
//Ein kleiner Hinweis zu meiner Repository reicht schon.
//https://github.com/exc-jdbi/MinMaxScalerBytes
//Danke und gruss exc-jdbi.
namespace exc.jdbi.Algorithms.MinMaxScalers;
public class MinMaxScalerByte
{
public static byte ToLimited(
ReadOnlySpan<byte> input,
int abort_after_round = 20)
{
var iter = 0;
var aver = 0m;
var maxval = int.MaxValue;
var length = input.Length;
var bytes = input.ToArray();
while (true)
{
var min = (int)bytes.Min();
var max = (int)bytes.Max();
var average = bytes.Average(Convert.ToDecimal);
if (iter > 3 && average == aver) return (byte)maxval;
for (var i = 0; i < length; i++)
bytes[i] = (byte)ModuloSpec(bytes[i] + min, max + 1);
iter++;
if (max < maxval) { maxval = max; iter = 0; }
if (aver != average) { aver = average; }
if (iter > abort_after_round) return (byte)maxval;
}
}
public static bool MinMaxScaler(
ReadOnlySpan<byte> input, byte limit,
out (byte[] Source, byte[] MinMax) result,
int abort_after_round = 20)
{
result = default;
var iter = 0;
var aver = 0m;
var length = input.Length;
var mm = new List<byte>();
var minval = int.MaxValue;
var bytes = input.ToArray();
while (true)
{
var min = (int)bytes.Min();
var max = (int)bytes.Max();
var average = bytes.Average(Convert.ToDecimal);
if (max <= limit && average == aver) break;
for (var i = 0; i < length; i++)
bytes[i] = (byte)ModuloSpec(bytes[i] + min, max + 1);
iter++;
if (aver != average) { aver=average; }
if (max < minval) { minval = max; iter = 0; }
if (iter > abort_after_round) return false;
mm.AddRange([(byte)min, (byte)max]);
}
result = (bytes, mm.ToArray());
return true;
}
public static (byte[] Source, byte[] MinMax) MinMaxScaler(
ReadOnlySpan<byte> input,
byte limit,
int abort_after_round = 20)
{
var iter = 0;
var aver = 0m;
var length = input.Length;
var mm = new List<byte>();
var minval = int.MaxValue;
var bytes = input.ToArray();
while (true)
{
var min = (int)bytes.Min();
var max = (int)bytes.Max();
var average = bytes.Average(Convert.ToDecimal);
if (max <= limit && average == aver) break;
//if (max <= limit) break;
for (var i = 0; i < length; i++)
bytes[i] = (byte)ModuloSpec(bytes[i] + min, max + 1);
iter++;
if (aver != average) { aver = average; }
if (max < minval) { minval = max; iter = 0; }
if (iter > abort_after_round) return default;
mm.AddRange([(byte)min, (byte)max]);
}
return (bytes, mm.ToArray());
}
public static byte[] MinMaxDescaler((byte[] src, byte[] minmax) input) =>
MinMaxDescaler(input.src, input.minmax);
public static byte[] MinMaxDescaler(
ReadOnlySpan<byte> input, ReadOnlySpan<byte> minmax)
{
var length = input.Length;
var bytes = input.ToArray();
for (var i = 1; i < minmax.Length; i += 2)
{
var max = (int)minmax[^i];
var min = (int)minmax[^(i + 1)];
for (var j = 0; j < length; j++)
bytes[j] = (byte)ModuloSpec(bytes[j] - min, max + 1);
}
return bytes;
}
private static int ModuloSpec(int basic, int mod)
{
var result = basic % mod;
result += mod;
result %= mod;
return result;
}
}