How to represent data with complete scalar range in the first state then represent it as zero to one in the next state while using the same memory space?
Any approaches to the problem is appreciated, the example procedures does not have to be like that if solution requires them to change.
Example
Reading values from a file and then normalize it. Float_Array
is for raw value with any range that comes directly from file.
Feature_Array
is for normalized values.
type Float_Array is array (Integer range <>) of Float;
type Feature is new Float range 0.0 .. 1.0;
type Feature_Array is array (Integer range <>) of Feature;
The first step is to read floats into an Float_Array
and finding max and min value.
procedure Read (Name : String; Result : out Float_Array; Last : out Integer; Min : out Float; Max : out Float) is
use Ada.Text_IO;
use Ada.Float_Text_IO;
F : File_Type;
begin
Open (F, In_File, Name);
for I in Result'Range loop
exit when End_Of_File (F);
Get (F, Result (I));
Min := Float'Min (Min, Result (I));
Max := Float'Max (Max, Result (I));
Last := I;
end loop;
Close (F);
end;
Float_Array
is just temporarily being used to read and find min max. The next step is to normalize all values.
function Normalize (Value : Float; Min, Max : Float) return Float is
begin
return (Value - Min) / (Max - Min);
end;
procedure Normalize (Min : Float; Max : Float; Scale : Float; Result : in out Float_Array) is
begin
for E of Result loop
E := Normalize (E, Min, Max) * Scale;
end loop;
end;
After normalization I want the values to be represented as Feature_Array
.
Bad solution that does no range check.
There is no range check so it is not a proper solution. Scaling the values from one to three does not yield range check error. So at this point there is no point to have Feature_Array
if there is no range check.
Last : Integer;
Data : Float_Array (1 .. 100);
Min : Float := Float'First;
Max : Float := Float'Last;
begin
Read ("frequency.lines_of_float", Data, Last, Min, Max);
Normalize (Min, Max, 1.0, Data);
-- Normalize (Min, Max, 3.0, Data);
declare
The_Features : Feature_Array (Data'Range) with Address => Data'Address;
begin
Put (The_Features);
end;
I have tried attribute 'Valid on the array i.e. The_Features'Valid
but it only works on scalar types. And using 'Valid for range check will involve extra code.