Difference between revisions of "CoCoA:HowTo:Read Matrices"

From ApCoCoAWiki
(→‎Reading one integer: added code for negative numbers, multiple break charakters und multible break charakters between integers, documented the code)
Line 30: Line 30:
  
 
   Define Read_Integer(F)
 
   Define Read_Integer(F)
     Int := 0;
+
     Int := 0;                 -- Contains the read integer
     C  := Get(F,1);
+
     C  := Get(F,1);           -- Contains the actuall read charakter
 
     While Not C = ' ' Do
 
     While Not C = ' ' Do
       D := C - Ascii('0');
+
       D := C - Ascii('0');   -- Compute he digit, C represents
       If D IsIn [0..9] then
+
       If D IsIn [0..9] then   -- Check if it's really a digit
         Int := Int*10 + D;
+
         Int := Int*10 + D;   -- add the digit to the integer
 
       EndIf;
 
       EndIf;
       C := Get(F,1);
+
       C := Get(F,1);         -- Read next charakter
 
     EndWhile;
 
     EndWhile;
 
     Return Int;
 
     Return Int;
 
   EndDefine
 
   EndDefine
code by [[User:Dheldt|dheldt]] 17:00, 13 Jul 2005 (CEST)
+
code by [[User:Dheldt|dheldt]]
  
 
As you can see, here I simply ignore charakters, that do not fit in my format.
 
As you can see, here I simply ignore charakters, that do not fit in my format.
 
Now, we are able to read one integer.
 
Now, we are able to read one integer.
  
Optionally you can use this code now, to add a signum in front of it to support negative numbers, too.
+
In fact, there is a lot of room to improve this code. A first improvement is the following one:
Otherwise you can add something to find a '/' to support all rational numbers.
+
 
 +
  Define Read_Integer(F)
 +
    Int      := 0;            -- Contains the read integer
 +
    Negative := false;        -- Assume our Number is not negative.
 +
    Break := [' ',',',';'];    -- A list of Characters indicating the end of the integer,
 +
                              -- eventually add NewLine and Tab (HowTo Do this in CoCoA?)
 +
    C  := Get(F,1);          -- Contains the actuall read charakter
 +
 
 +
    While C IsIn Break Do      -- Skip multiple break characters at the beginning,
 +
      C  := Get(F,1);        -- e.g. some blanks or tabs to align the matrix in
 +
    EndWhile;                  -- the file
 +
   
 +
    If C='-'                  -- support negative integers
 +
      Negative := true;
 +
    EndIf;
 +
   
 +
    While Not C IsIn Break Do
 +
      D := C - Ascii('0');    -- Compute he digit, C represents
 +
      If D IsIn [0..9] then  -- Check if it's really a digit
 +
        Int := Int*10 + D;    -- add the digit to the integer
 +
      EndIf;
 +
      C := Get(F,1);          -- Read next charakter
 +
    EndWhile;
 +
    Return Int;
 +
  EndDefine
 +
code by [[User:Dheldt|dheldt]] 14:10, 14 Jul 2005 (CEST)
 +
 
 +
There is still no support for two possible notations of rational numbers (e.g. 1/4 and 0.25), so there is some work left to do...
  
 
But now it is time to read the complete matrix:
 
But now it is time to read the complete matrix:

Revision as of 12:10, 14 July 2005

This article is at the moment stub. I just wrote the code, but it is not properly tested and an description how to open and close the file is missing. Also support for negative and rational numbers is missing and perhaps there is a problem with newlines instead of blanks as seperators. multiple blanks will cause problems, too.

About

At the CoCoA Discussion Board enrico asked how to read matrices, given in a text file, such that we have a CoCoA Matrix. His matrices consist of integers, seperated by blanks and newlines, but it should not be a problem to adapt this.

The idea behind this is to use the Get function, or more generall the IO interface of CoCoA 4.

Reading one digit

Get returns one charakter, then we can use Ascii to convert this charakter into the coresponding Ascii value. Now we subtract the Ascii value of '0' and have the character convertet into it's coresponding digit (in case it was a number). The code for this looks something like:

 D := Ascii(Get(F,1)) - Ascii('0');
 If D IsIn [0..9] then
   Return D;
 Else
   Return 0;
 EndIf;

code by dheldt 17:00, 13 Jul 2005 (CEST)

Reading one integer

As you can see, in case of having other charakters inside your matrix they are simply going to be replaced by 0. Now we want to read complete integers, instead of only one digit. But an integer is just a list of digits, so it is not that complicated after all. let us assume, the integers are seperated by blanks. than we do the following:

 Define Read_Integer(F)
   Int := 0;                  -- Contains the read integer
   C   := Get(F,1);           -- Contains the actuall read charakter
   While Not C = ' ' Do
      D := C - Ascii('0');    -- Compute he digit, C represents
      If D IsIn [0..9] then   -- Check if it's really a digit
        Int := Int*10 + D;    -- add the digit to the integer
      EndIf;
      C := Get(F,1);          -- Read next charakter
   EndWhile;
   Return Int;
 EndDefine

code by dheldt

As you can see, here I simply ignore charakters, that do not fit in my format. Now, we are able to read one integer.

In fact, there is a lot of room to improve this code. A first improvement is the following one:

 Define Read_Integer(F)
   Int      := 0;             -- Contains the read integer
   Negative := false;         -- Assume our Number is not negative.
   Break := [' ',',',';'];    -- A list of Characters indicating the end of the integer, 
                              -- eventually add NewLine and Tab (HowTo Do this in CoCoA?)
   C   := Get(F,1);           -- Contains the actuall read charakter
 
   While C IsIn Break Do      -- Skip multiple break characters at the beginning,
      C   := Get(F,1);        -- e.g. some blanks or tabs to align the matrix in 
   EndWhile;                  -- the file
   
   If C='-'                   -- support negative integers
     Negative := true;
   EndIf;
   
   While Not C IsIn Break Do
      D := C - Ascii('0');    -- Compute he digit, C represents
      If D IsIn [0..9] then   -- Check if it's really a digit
        Int := Int*10 + D;    -- add the digit to the integer
      EndIf;
      C := Get(F,1);          -- Read next charakter
   EndWhile;
   Return Int;
 EndDefine

code by dheldt 14:10, 14 Jul 2005 (CEST)

There is still no support for two possible notations of rational numbers (e.g. 1/4 and 0.25), so there is some work left to do...

But now it is time to read the complete matrix:

Reading the complete matrix

A matrix is -more or less- just a rectangular thing filled up with numbers. so we simply have to read all this numbers and put them in a matrix.

This could look like:

 M := Mat([[Read_Integer(F) |I In 1..Columns]|J In 1..Rows]);

code by dheldt 17:00, 13 Jul 2005 (CEST)