Перевод кода Matlab с массивами в Фортран - PullRequest
0 голосов
/ 23 января 2019

Я пытаюсь перевести код Matlab в код Fortran. В настоящее время я борюсь с переводом массива типов данных.

Пример кода Matlab / GNU Octave выглядит следующим образом

function test1

clc;
close all;
start= 5;

function out = function1(start)
myarray = struct(...
    'list1', {'A', 'Cc', 'B', 'E', 'F', 'G', 'H', 'I'}, ...
    'list2', {1, 2,  3,  4, 5, 6, 7, 8},...
    'list3', {3, 3, 3, 3, 3, 2, 2, 2});

function list1 = function2(list2)
    done = false;
    ra = randi([1 numel(myarray)], 1, 1);
    list1 = myarray(ra);
    if list1.list1 == 'E'
        list1.list1 = round(randn(1,1) * 5);
    end
end

x = {}; 
y = [];
list2 = 0;    

    list1 = function2(list2);
    list2 = list2 + list1.list3;

    x = [x, list1.list1];
    y = [y, list2];
  out = struct('x', {x}, 'y', {y});
end
disp(function1(2));
end

Выход октавы:

scalar structure containing the fields:
x =
{
  [1,1] = G
}
y =  2

В моей попытке на Фортране есть ошибки, с которыми я борюсь. Проблема связана с моей обработкой массивов и способом написания кода Matlab.

function function1(start) result(out1)

implicit none

 type array
  character list1
  integer   list2, list3
 end type array

 type(array), dimension(8) :: myarray
               integer :: start;
               integer :: out1;

    character, dimension(8,1), allocatable ::x
    character, dimension(1,8), allocatable ::y

  myarray=[array('A',1,3), array('C',2,3), array('B',3,3), & 
           array('E',4,3), array('F',4,3), array('G',5,3), & 
           array('H',6,3), array('I',5,3)]


    deallocate(x);                              !<- in matlab x={}
    deallocate(y);                              !<- in matlab y=[]
    deallocate(list2);                          !<- in matlab list2 = 0;    

      list1 = function2(list2);
      list2 = list2 + list1%list3;

      x = [x, list1%list1];              !<- this line not translated
      y = [y, list2];                    !<- this line not translated
   out1 = struct('x', {x}, 'y', {y});   !<- this line not translated


   contains

    function function2(list2) result(list1)

    implicit none

    integer, intent(in) :: list2;             ! input
    integer :: list1;                         ! output  
    logical :: done;  
    integer, dimension(1,1) :: ra;
    real    :: rnd1;
    integer :: test;

     done = .FALSE.
     call random_number(rnd1);
     ra = nint(rnd1*size(myarray));  
     list1=myarray(ra); 

     if (list1%list1 .EQV. 'E') then   
       call random_number(rnd1);
       list1%list1 = nint(rnd1*5);     
     end if

    end function function2

end function function1

program test1

 use iso_fortran_env
 implicit none

  integer                 :: start, xout;
  integer                 :: function1;

 start =5;
 xout=function1(2);
 print*, "my output is ", xout;
end program test1

Обычно Matlab не определяет заранее переменную для типа массива. Это не относится к Фортрану. Я отметил проблемные строки кода. Все они имеют общую основу, которая передает значение массива в другую переменную или передает значение в переменную. Любые советы и предложения?

Код ошибки, который я получаю:

  gfortran  -Ofast -Wall -o "test1" "test1.f90"  
  test1.f90:22:20:
  deallocate(list2);                          !<- in matlab list2 = 0;
                1
  Error: Allocate-object at (1) is not a nonprocedure pointer nor an    allocatable variable
  test1.f90:25:30:
     list2 = list2 + list1%list3;
                          1
   Error: Symbol ‘list1’ at (1) has no IMPLICIT type
   test1.f90:27:22:
     x = [x, list1%list1];              !<- this line not translated
                  1
   Error: Symbol ‘list1’ at (1) has no IMPLICIT type
   test1.f90:29:25:
   out1 = struct('x', {x}, 'y', {y});   !<- this line not translated
                     1
   Error: Syntax error in argument list at (1)
   test1.f90:48:19:
      if (list1%list1 .EQV. 'E') then
               1
   Error: Unexpected ‘%’ for nonderived-type variable ‘list1’ at (1)
   test1.f90:50:17:
        list1%list1 = nint(rnd1*5);
             1
   Error: Unexpected ‘%’ for nonderived-type variable ‘list1’ at (1)
   test1.f90:51:14:
        end if
          1
   Error: Expecting END FUNCTION statement at (1)
   test1.f90:24:13:
     list1 = function2(list2);
         1
   Error: Symbol ‘list1’ at (1) has no IMPLICIT type
   test1.f90:24:31:
     list1 = function2(list2);
                           1
   Error: Symbol ‘list2’ at (1) has no IMPLICIT type
   test1.f90:12:46:
   character, dimension(8,1), allocatable ::x
                                          1
   Error: Allocatable array ‘x’ at (1) must have a deferred shape or     assumed rank
   test1.f90:13:46:
   character, dimension(1,8), allocatable ::y
                                          1
   Error: Allocatable array ‘y’ at (1) must have a deferred shape or assumed rank
   test1.f90:47:23:
      list1=myarray(ra);
                   1
 Error: Array index at (1) is an array of rank 2
 Compilation failed.
...