I am trying to split a string using an integer array as mask.
The task is simple but I am not accustomed to ADA (which is a constraint).
Here is my code. It works exept that I have an one character offset when testing against a file. Can someone help me remove this offset. it is drinving me nuts.
generic_functions.adb :
package body Generic_Functions is
-- | Sums up the elements of an array of Integers
function Sum_Arr_Int(Arr_To_Sum: Int_Array) return Integer is
Sum: Integer;
begin
Sum := 0;
for I in Arr_To_Sum'Range loop
Sum := Sum + Arr_To_Sum(I);
end loop;
return Sum;
end Sum_Arr_Int;
-- | Split up a String into a array of Unbounded_String following pattern from an Int_Array
function Take_Enregistrements(Decoup_Tab: Int_Array; Str_To_Read: String) return Str_Array is
Previous, Next : Integer;
Arr_To_Return : Str_Array(Decoup_Tab'Range);
begin
if Sum_Arr_Int(Decoup_Tab) > Str_To_Read'Length then
raise Constraint_Error;
else
Previous := Decoup_Tab'First;
Next := Decoup_Tab(Decoup_Tab'First);
for I in Decoup_Tab'Range loop
if I /= Decoup_Tab'First then
Previous := Next + 1;
Next := (Previous - 1) + Decoup_Tab(I);
end if;
Arr_To_Return(I) := To_Unbounded_String(Str_To_Read(Previous..Next));
end loop;
return Arr_To_Return;
end if;
end Take_Enregistrements;
end Generic_Functions;
generic_functions.ads :
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
package Generic_Functions is
-- | Types
type Int_Array is array(Positive range <>) of Integer;
type Str_Array is array(Positive range <>) of Unbounded_String;
-- | end of Types
-- | Functions
function Sum_Arr_Int(Arr_To_Sum: Int_Array) return Integer;
function Take_Enregistrements(Decoup_Tab: Int_Array; Str_To_Read: String) return Str_Array;
-- | end of Functions
end Generic_Functions;
generic_functions_tests.adb :
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Generic_Functions; use Generic_Functions;
procedure Generic_Functions_Tests is
-- | Variables
Decoup_Test : constant Int_Array(1..8) := (11, 19, 60, 24, 255, 10, 50, 255);
Test_Str_Arr : Str_Array(Decoup_Test'Range);
Test_Str_Arr2 : Str_Array(Decoup_Test'Range);
Test_Str_Arr3 : Str_Array(Decoup_Test'Range);
--Test_Int : Integer;
Test_Handle : File_Type;
-- | end of Variables
begin
Open(Test_Handle, In_File, "EXPORTFINAL.DAT");
Test_Str_Arr := Take_Enregistrements(Decoup_Test, Get_Line(Test_Handle));
Test_Str_Arr2 := Take_Enregistrements(Decoup_Test, Get_Line(Test_Handle));
Test_Str_Arr3 := Take_Enregistrements(Decoup_Test, Get_Line(Test_Handle));
for I in Test_Str_Arr'Range loop
Put_Line(To_String(Test_Str_Arr(I)));
end loop;
for I in Test_Str_Arr2'Range loop
Put_Line(To_String(Test_Str_Arr2(I)));
end loop;
for I in Test_Str_Arr3'Range loop
Put_Line(To_String(Test_Str_Arr3(I)));
end loop;
-- for I in Test_Str_Arr'Range loop
-- Test_Int := To_String(Test_Str_Arr(I))'Length;
-- Put_Line(Integer'Image(Test_Int));
-- end loop;
-- for I in Test_Str_Arr2'Range loop
-- Test_Int := To_String(Test_Str_Arr2(I))'Length;
-- Put_Line(Integer'Image(Test_Int));
-- end loop;
-- for I in Test_Str_Arr3'Range loop
-- Test_Int := To_String(Test_Str_Arr3(I))'Length;
-- Put_Line(Integer'Image(Test_Int));
-- end loop;
Close(Test_Handle);
end Generic_Functions_Tests;
and finaly the file:
000000000012012-01-01 10:00:00 IBM IBM COMPAGNIE IBM FRANCE 17 AVENUE DE l'EUROPE 92275 BOIS-COLOMBES CEDEX CONFIGURATION COMPLETE SERVEUR000000000000000000000019 .6000000000001000000000000000000001000.00000000000000000000000000000196.00000000000000000000000000001196.00000000
000000000022012-01-01 11:00:00 MICROSOFT MSC 39 QUAI DU PRESIDENT ROOSEVELT 92130 ISSY-LES-MOULINEAUX AMENAGEMENT SALLE INFORMATIQUE000000000000000000000019.6000000000001000000000000000000001000.00000000000000000000000000000196.00000000000000000000000000001196.00000000
000000000032012-01-01 12:00:00 MICROSOFT MSC 39 QUAI DU PRESIDENT ROOSEVELT 92130 ISSY-LES-MOULINEAUX TESTS SUR SITE000000000000000000000019.6000000000001000000000000000000003226.52000000000000000000000000000632.39792000000000000000000000003858.91792000 DELEGATION TECHNICIEN HARD000000000000000000000019.60000000000000000000000000000001.00000000000000000000000000001000.00000000000000000000000000000196.00000000000000000000000000001196.00000000
These lines:
if I = Decoup_Tab'Last then
Arr_To_Return(I) := To_Unbounded_String(Str_To_Read(Previous..Next));
end if;
will overwrite the last element in your array.
Also, are you sure that the line number (00000000001, 00000000002, etc) is one of the strings you want to split based on the integer mask? As your code is right now, you use '11' twice, once for the line number and once for the date-field. If you skip the line number, the other numbers seem to make more sense.
Related
I am writing a simple program in Ada95 to check to see if a chess board layout input is valid or not. I am quite new to Ada and I understand I have a lot to learn.
The error messages that I keep getting are:
35:31: argument of type conversion must be single expression
47:07: argument of type conversion must be single expression
47:22: illegal operand for array conversion
53:10: argument of type conversion must be single expression
58:10: argument of type conversion must be single expression
61:13: argument of type conversion must be single expression
64:13: argument of type conversion must be single expression
66:13: argument of type conversion must be single expression
68:13: argument of type conversion must be single expression
76:15: invalid use of subtype mark in expression or call
I have included my full code below so that if there is anything that could be causing an issue in a declaration, it is available for reference.
-- RULES:
-- Only black squares may have pieces on them
-- Black squares start at the bottom left hand corner
-- Total checker count for a color cannot exceed 12
-- A color may not have more than 7 kings
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure Checker_Checker is
type Checkers_Piece is ("b", "BK", "RK", "BC", "RC");
type Checkers_Board is array (1..8, 1..8) of Checkers_Piece;
Checkers_String: String(1..64);
invalid,
BK_Count, -- black king checker
RK_Count, -- red king checker
RC_Count, -- red checker
BC_Count, -- black checker
b_Count, -- blank space
Char_Count : Integer := 0;
procedure Print_Board (Object: in Checkers_Board) is
Print_Divider: String(1..17);
Print_Squares: String(1..17);
begin
Print_Divider := "-----------------";
Print_Squares := "| | | | | | | | |";
for X in 1..8 loop
Put_Line(Print_Divider);
for Y in 1..8 loop
Print_Squares(Y+1) := Checkers_Board(X, Y);
end loop;
Put_Line(Print_Squares);
end loop;
Put_Line(Print_Divider);
end Print_Board;
begin
Get(Checkers_String);
for I in 1..8 loop
for J in 1..8 loop
Char_Count := Char_Count + 1;
Checkers_Board(I, J) := Checkers_String(Char_Count);
end loop;
end loop;
for Y in 1..8 loop
for X in 1..8 loop
if Checkers_Board(Y, X) = 'b' then
Put_Line("There is a piece on a white space.");
invalid := invalid + 1;
end if;
if Checkers_Board(Y, X) = "BK" then
BK_Count := BK_Count + 1;
BC_Count := BC_Count + 1;
elsif Checkers_Board(Y, X) = "RK" then
RK_Count := RK_Count + 1;
RC_Count := RC_Count + 1;
elsif Checkers_Board(Y, X) = "RC" then
RC_Count := RC_Count + 1;
elsif Checkers_Board(Y, X) = "BC" then
BC_Count := BC_Count + 1;
elsif Checkers_Board(Y, X) = "b" then
b_Count := b_Count + 1;
else
Put_Line("There is an unidentified character on the board.");
end if;
end loop;
end loop;
Print_Board;
if RK_Count > 7 then
Put_Line("There are more than 7 Red Kings on the board.");
end if;
if BK_Count > 7 then
Put_Line("There are more than 7 Black Kings on the board.");
end if;
if RC_Count > 12 then
Put_Line("There are more than 12 Red Checkers on the board.");
end if;
if BC_Count > 12 then
Put_Line("There are more than 12 Black Checkers on the board.");
end if;
if b_Count < 32 then
Put_Line("There are too many checkers on the board.");
end if;
if invalid = 0 then
Put_Line("This is a valid checker board.");
else
Put_Line("This is an invalid checker board.");
end if;
end Checker_Checker;
I know my code is a mess.. please don't be too critical of it.. I am trying my best at learning Ada.
Thank you for your help.
For a start,
type Checkers_Piece is ("b", "BK", "RK", "BC", "RC");
is trying to declare an enumeration; but enumeration literals are identifiers, not strings.
So that should be
type Checkers_Piece is (b, BK, RK, BC, RC);
Then, in
Print_Squares := "| | | | | | | | |";
for X in 1..8 loop
Put_Line(Print_Divider);
for Y in 1..8 loop
Print_Squares(Y+1) := Checkers_Board(X, Y);
end loop;
Put_Line(Print_Squares);
end loop;
you were clearly expecting Checkers_Board(X, Y) to be a single Character, but in your declaration you intended it to be a sort of String, with up to 2 Characters.
You have to decide what representation you want that lets you distinguish a red king from a black king in a single character. Or, better, accept that you need 2 characters to represent your pieces. Or perhaps you could use single Characters with the convention that lower-case values are uncrowned, upper-case are crowned, space means unoccupied.
The reason for your 'argument of type conversion' errors is that, in lines like
Checkers_Board(I, J) := Checkers_String(Char_Count);
Checkers_Board is a type; you need an object of that type here, not the type itself. The syntax you’re using is for a type conversion (ARM 4.6).
I have a problem with translating VHDL to Verilog.
It's part of my source code on VHDL.
With I/O I somehow understood, but have some problems to translate this string
ib1 <= std_logic_vector(to_unsigned(i,ib1'length));
to verilog?
COMPONENT GenerateModel
PORT(
ib1 : IN std_logic_vector(3 downto 0);
);
END COMPONENT;
--Inputs
signal ib1 : std_logic_vector(3 downto 0) := (others => '0');
BEGIN
uut: GenerateModel PORT MAP (
ib1 => ib1,
);
process
begin
for i in 0 to 15 loop
ib1 <= std_logic_vector(to_unsigned(i,ib1'length));
wait for 10 ns;
end loop;
end process;
end;
To extend into Verilog from Paebbels' comment, the line you are looking at does an explicit conversion from the type of the loop variable i to the port variable ib1. In Verilog, that explicit conversion is not needed, you can just assign the port variable directly. So, for example (in Verilog IEEE 1364-1995 compatible):
integer i;
...
for (i = 0; i < 16; i = i + 1) begin
ib1 = i; // <-- The line
#10; // -- Assume 1 step is 1 ns, can specific timescale if needed
end
If you want, you can even loop through the variable directly if its of type reg (ie, not a net):
for (ib1 = 0; ib1 < 15; ib1 = ib1 + 1) begin
#10;
end
#10;
[Note that as Greg mentioned, you need to be sure you dont create an infinite loop as if ib1 is 4-bits wide, it will always be less than 16, thus I fixed the example above to loop until ib1 is 15 (4'b1111)]
I need to get some data from a module I was given, but I don't know if it is even possible or how to approach the problem.
Is it possible to get information from another module if that module doesn't have an entity map? It only has a generic with TIME statements.
Is it at all possible to get anything out of this module?
It writes to a memory, could I pull things out of that?
This is the file I have.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
use STD.TEXTIO.all;
use IEEE.STD_LOGIC_TEXTIO.all;
entity MIPS is
generic (
MEM_DLY : TIME := 0.5 ns;
CYC_TIME: TIME := 2 ns
);
end entity MIPS;
architecture MIPS of MIPS is
signal PC : STD_LOGIC_VECTOR ( 31 downto 0 ) := X"0000_0010";
signal READ_DATA2 : STD_LOGIC_VECTOR ( 31 downto 0 ) := ( others => '0');
signal HUH : BIT_VECTOR ( 31 downto 0 );
signal HUHINS : STRING ( 1 to 25 );
signal INSTRUC : STD_LOGIC_VECTOR ( 31 downto 0 );
signal M_DATA_IN : STD_LOGIC_VECTOR ( 31 downto 0 ) := ( others => 'Z');
signal M_DATA_OUT : STD_LOGIC_VECTOR ( 31 downto 0 ):= ( others => 'Z');
signal M_ADDR : STD_LOGIC_VECTOR ( 11 downto 0 ) := ( others => '0');
signal CLK : STD_LOGIC := '0';
signal MEMREAD : STD_LOGIC := '0';
signal M_DATA_WHEN : STD_LOGIC := '0';
signal MEMWRITE : STD_LOGIC := '0';
signal CYCLE : INTEGER := 1;
begin
CLOCK_PROC:
process
begin
CLK <= '1';
wait for CYC_TIME/2;
CLK <= '0';
wait for CYC_TIME/2;
CYCLE <= CYCLE + 1;
end process;
TEST_PC_PROC:
process ( CLK ) is
begin
if RISING_EDGE ( CLK ) then
PC <= PC + 4;
end if;
end process;
INSTR_MEM_PROC:
process ( PC ) is -- make subject only to address
type INSTR_STR_ARY is array ( 0 to 1023 ) of STRING ( 1 to 25 );
variable MEMSTRR : INSTR_STR_ARY:=(others => " ");
type MEMORY is array ( 0 to 1023 ) of BIT_VECTOR ( 31 downto 0 );
variable MEM : MEMORY := ( others => X"0000_0000");
variable IADDR : INTEGER; -- integer for address
variable DTEMP : BIT_VECTOR ( 31 downto 0 );
variable INIT : INTEGER := 0; -- when to initialize...
file IN_FILE : TEXT open READ_MODE is "instr_mem.txt";
variable BUF : LINE;
variable ADR_STR : STD_LOGIC_VECTOR ( 31 downto 0 );
variable TADR : INTEGER;
variable TDATA : STD_LOGIC_VECTOR ( 31 downto 0 );
variable BDATA : BIT_VECTOR ( 31 downto 0 );
variable STR_ING : STRING ( 1 to 25 );
begin
if INIT = 0 then
while not (ENDFILE ( IN_FILE )) loop
READLINE ( IN_FILE, BUF );
HREAD ( BUF, ADR_STR ); -- get the address on the line
TADR := CONV_INTEGER ( ADR_STR (14 downto 2));
HREAD ( BUF, TDATA ); -- get the data on the line
BDATA := To_bitvector (TDATA);
MEM ( TADR ) := BDATA; -- put into memory
for J in 1 to 25 loop
STR_ING(J) := ' ';
end loop;
READ ( BUF, STR_ING ); -- get instruction string
MEMSTRR ( TADR ) := STR_ING;
report "iteration of loop";
end loop;
INIT := 1; -- when all data in, set INIT to 1;
end if; -- end of INIT check
IADDR := CONV_INTEGER ( PC ( 14 downto 2 ));
HUH <= MEM ( IADDR );
INSTRUC <= To_StdLogicVector ( MEM ( IADDR )) after MEM_DLY;
HUHINS <= MEMSTRR ( IADDR );
report "should hit INSTRUC";
end process;
M_DATA_IN_STMT:
M_DATA_IN <= READ_DATA2 ;
-- The following is the magic process
-- User must supply:
-- M_ADDR - memory address (data memory) as a 12 bit STD_LOGIC_VECTOR
-- Remember the M_ADDR is a WORD address
-- M_DATA_IN - value going to memory from hardware (data path)
-- Remember that this is 32 bit STD_LOGIC_VECTOR, user supplied
-- READ_DATA2 - this is to be replaced by user's sourceof info for memory
DATA_MEMORY_PROCESS: -- name of process ...
process ( M_ADDR, CLK, MEMREAD ) is -- Sens: M_ADDR, CLK, MEMREAD
file IN_FILE: TEXT open READ_MODE is "data_mem_init.txt"; -- initial data
file OUT_FILE: TEXT open WRITE_MODE is "mem_trans.txt"; -- results
variable BUF : LINE; -- declare BUF as LINE
variable TVAL : STD_LOGIC_VECTOR ( 31 downto 0 ); -- var for temp value
variable TADRHEX : STD_LOGIC_VECTOR ( 31 downto 0 ); -- var for address
variable TADR : INTEGER; -- address as integer
type MEM_TYPE is array ( 0 to 1023 ) of STD_LOGIC_VECTOR ( 31 downto 0 );
variable THE_MEMORY : MEM_TYPE := ( others => X"00000000" ); -- the memory
variable FIRST : BOOLEAN := TRUE; -- flag for first time thru
constant STR : STRING ( 1 to 3 ) := " "; -- 3 spaces - for printing
constant WR_STR : STRING ( 1 to 3 ) := "W "; -- for write
constant RD_STR : STRING ( 1 to 3 ) := "R "; -- for read
variable TSTR2 : STRING ( 1 to 29 ); -- to create a string
type MEMSTR_TYPE is array ( 0 to 1023 ) of STRING ( 1 to 29 ); --
variable INSTRS : MEMSTR_TYPE;
begin -- start here
if FIRST then -- first time thru,
while FIRST loop -- loop on data available - until
if not ( ENDFILE ( IN_FILE )) then -- end of file shows up
READLINE(IN_FILE, BUF); -- read a line from file,
HREAD(BUF, TADRHEX); -- get address from BUF
TADR := CONV_INTEGER ( TADRHEX ); -- turn it into integer
HREAD(BUF, TVAL); -- next, get value from BUF
THE_MEMORY(TADR/4) := TVAL; -- put TVAL into the memory
else -- the 'else' is for end of file
FIRST := FALSE; -- EOF shows up - set FIRST false
end if;
end loop; -- where loop ends...
end if; -- where if FIRST ends ...
if MEMREAD = '1' then -- now, memory function 'read'
M_DATA_OUT <= THE_MEMORY ( CONV_INTEGER ( M_ADDR ) / 4 ); -- get val from
M_DATA_WHEN <= not M_DATA_WHEN; -- and invert M_DATA_WHEN
else -- if not MEMREAD,
M_DATA_OUT <= ( others => 'Z' ); -- set memory out to 'Z's
end if;
if RISING_EDGE ( CLK ) then -- on clock edge...
if MEMREAD = '1' then -- if MEMREAD asserted,
TADR := CONV_INTEGER ( M_ADDR ) / 4; -- set TADR to address as int
TVAL := THE_MEMORY ( TADR ); -- and get contents to TVAL
WRITE (BUF, RD_STR); -- then build BUF; put read indi
HWRITE (BUF, M_ADDR); -- and the address
WRITE (BUF, STR); -- some spaces
HWRITE (BUF, TVAL); -- and the value
WRITE (BUF, STR); -- more spaces
WRITE (BUF, NOW); -- current simulation time
WRITELINE (OUT_FILE, BUF); -- and send line to file.
elsif MEMWRITE = '1' then -- if not read, but it is write
TADR := CONV_INTEGER ( M_ADDR ) / 4; -- set TADR to address as int
TVAL := M_DATA_IN; -- set TVAL as data in value
WRITE (BUF, WR_STR); -- start buffer with write indi
HWRITE (BUF, M_ADDR); -- then the address
WRITE (BUF, STR); -- then some spaces
HWRITE (BUF, TVAL); -- and the value written
WRITE (BUF, STR); -- still more spaces
WRITE (BUF, NOW); -- simulation time
WRITELINE (OUT_FILE, BUF); -- and send line to file
THE_MEMORY ( CONV_INTEGER ( M_ADDR ) / 4) := M_DATA_IN;
-- and finally, value to the mem
end if;
end if;
end process;
end architecture MIPS;
The code you presented simulates the memories that your MIPS processor will interact with - a program memory and a data memory.
Your MIPS will interact with the program memory by providing a value for PC; the corresponding instruction will be handed to your CPU on signal INSTRUCT. You'll probably delete the lines corresponding to the TEST_PC_PROC process, since the actual PC value will come from the MIPS. The program to be run by the CPU is given in file data_mem_init.txt. This program memory is asynchronous.
Your MIPS will interact with the data memory through signals M_ADDR, M_DATA_OUT, M_DATA_IN, and MEMREAD. To read data, your CPU will set M_ADDR and MEMREAD=1, and provide the address in M_ADDR. The given code will set M_DATA_OUT with the requested data. To write data, you will set M_DATA_IN or READ_DATA2 (or replace READ_DATA2 with a signal of your choice). The data will be written on the rising edge of CLK.
Don't be distracted by the WRITE/HWRITE calls, they just keep a log on file mem_trans.txt.
IMO, this interface is much more complicated than it needed to be. You're probably better or if you keep your MIPS implementation in totally separate files, and just add the signals needed to interact with this model to its ports list.
It's not entirely clear from your question what you are hoping to achieve with this mystery module that you have... but here's some ideas which might trigger something:
If you have a component for the module in question, then you can instantiate it within your design and then manipulate its inputs to make its outputs do what they should. Maybe it has some documentation to give you some clues!
If it writes to memory and you have a multi port memory controller within your system connected to the same memory, you could build something which will read data from the memory after your mystery module has written to it.
Or finally, if this is an FPGA, you can embed a logic analyser into the FPGA bitstream to observe the signals going to and from the secret module.
I am new to DB2 queries.
Here, I am passing a comma separated value as an IN parameter in a Stored Procedure. I want to search on the basis of those values.
Select * from USER where user_id in (IN_User);
Here, IN_User will have values of the kind ('val1','val2','val3')
It should return all the rows which has val1 or val2 or val3 as the User_id. As much as I know this can be done using UDF but I want to know is there any other way to do it without UDF.
please create a function to split the comma separated string
Please see the below function
CREATE FUNCTION StringToRows(
cString1 CLOB (10 M) ,
cStringSplitting1 VARCHAR(10) )
RETURNS TABLE (Lines VARCHAR(500))
SPECIFIC StringToRows_Big
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
BEGIN ATOMIC
DECLARE cStringSplitting VARCHAR(10);
DECLARE LenSplit SMALLINT;
SET cStringSplitting = cStringSplitting1;
SET LenSplit = LENGTH(cStringSplitting);
IF LENGTH(TRIM(cStringSplitting)) = 0 THEN
SET cStringSplitting = ' ', LenSplit = 1 ;
END IF ;
RETURN WITH
TEMP1 ( STRING) as (values (cString1) ),
TEMP2 ( Lines, STRING_left) as
(SELECT
SUBSTR(STRING,1, CASE WHEN LOCATE(cStringSplitting, STRING) = 0 THEN LENGTH(STRING) ELSE LOCATE(cStringSplitting,STRING) - 1 END),
(CASE WHEN (LOCATE(cStringSplitting, STRING) = 0) THEN '' ELSE SUBSTR(STRING, LOCATE(cStringSplitting,STRING) + LenSplit) END)
FROM TEMP1 WHERE LENGTH(STRING) > 0
UNION ALL
SELECT
SUBSTR(STRING_left,1, CASE LOCATE(cStringSplitting,STRING_left) WHEN 0 THEN LENGTH(STRING_left) ELSE LOCATE(cStringSplitting,STRING_left) - 1 END),
(CASE WHEN LOCATE(cStringSplitting,STRING_left) = 0 THEN '' ELSE SUBSTR(STRING_left, LOCATE(cStringSplitting,STRING_left) + LenSplit) END)
FROM TEMP2 WHERE LENGTH(STRING_left) > 0 )
SELECT Lines FROM TEMP2;
END
please see the sample stored procedure to call the function
CREATE PROCEDURE TEST_USR(IN #inputParam CLOB (10 M))
SPECIFIC TEST_USR
DYNAMIC RESULT SETS 1
P1: BEGIN
DECLARE CURSOR1 CURSOR WITH RETURN FOR
Select * from USER where user_id IN (SELECT * FROM TABLE(StringToRows(#inputParam, ',')) AS test);
OPEN CURSOR1;
END P1
Hi there =) And sorry for my English, in advance
I have a task to calculate hurst exponent by method of linear regression. And I have text description of solution. It looks very easy, but always i get values, that go out from range 0..1. Usually, value is 1.9 or something similar. Sometimes it gets negative value that is close to zero.
I have looked over code about thousand times but couldn't see a mistake.
var
max_z,min_z,x_m:real; //max and min of cumulative sum and mean value of X for every Tau
st,ss,sst,st2 :real;
Al, Herst: real;
x_vr:array of double; //a piece of array with length=tau
i, j, nach: integer;
begin
//file opening and getting values of X array are in another function
nach:=3; //initial value of tau
Setlength(ln_rs,l-nach); //length of ln(R/S) array
Setlength(ln_t,l-nach); //length of ln(tau) array
Setlength(r,l-nach); //length of R array
Setlength(s,l-nach); //length of S array
//Let's start
for tau:=nach to l do //we will change tau
begin
Setlength(x_vr,tau+1); //set new local array (length=tau)
for i:=0 to length(x_vr)-1 do
x_vr[i]:=x[i];
x_m:=Mean(x_vr); //mean value
Setlength(y,tau+1); //length of array of difference from mean value
Setlength(z,tau+1); //length of array of cumulative sum
for i:=0 to tau do
y[i]:=x_vr[i]-x_m; //difference from mean value
z[0]:=y[0];
for i:=1 to tau do //cumulative sum
for j :=i downto 0 do
z[i]:=z[i]+y[j];
max_z:=z[0];
for i:=1 to tau do //max of cumulative sum
max_z:=max(max_z,z[i]);
min_z:=z[0];
for i:=1 to tau do //min of cumulative sum
min_z:=min(min_z,z[i]);
r[tau-nach]:=max_z-min_z; //R value
s[tau-nach]:=0;
for i:=0 to tau do
s[tau-nach]:=power(y[i],2)+s[tau-nach]; //S value
s[tau-nach]:=sqrt(s[tau-nach]/(tau+1));
//new array values
ln_rs[tau-nach]:=Ln(R[tau-nach]/S[tau-nach]); // ln(R/S)
ln_t[tau-nach]:=ln(tau); // ln (tau)
end; //End of calculating
//Method of Least squares
for i:=0 to length(ln_rs)-1 do
st:=st+ln_t[i];
st:=(1/length(ln_rs))*st;
for i:=0 to length(ln_rs)-1 do
ss:=ss+ln_rs[i];
ss:=(1/length(ln_rs))*ss;
for i:=0 to length(ln_rs)-1 do
sst:=sst+ln_t[i]*ln_rs[i];
sst:=(1/length(ln_rs))*sst;
for i:=0 to length(ln_rs)-1 do
st2:=st2+ln_t[i]*ln_t[i];
st2:=(1/length(ln_rs))*st2;
Herst:=(sst-st*ss)/(st2-st*st); //coefficient of approximal function
al:=ss-st*Herst;
Thanks everybody =)
P.S.
for tau:=nach to l do
There is L, not 1. And L is Length of X array. And L>nach always besides last step, when l=nach.
P.P.S.
It works, guys. But values are not right. And they go out from range. Maybe, there is mistake in algorithm. Or maybe I skiped some step.
Last Update
It's mystic, but i only changed method of calculating array Z and it started works correctly....
Thanks all =)
First thing I see:
nach := 3;
for tau := nach to l do //w
This counts up. And because nach>1, the body of this loop won't be executed.
If you expect to count down. Use the downto variant. To count down:
for tau := nach downto l do //w
Given that the main loop (for tau) iterates from nach to l, the first four SetLength calls should set the length of l - nach + 1 instead of l - nach.
Should the line
z[i]:=z[i]+y[j];
not be
z[i]:=z[i - 1]+y[j];
?