【发布时间】:2019-06-21 11:44:24
【问题描述】:
Matlab 具有动态类型数组的能力。比如matlab代码是
function testing1
clc;
close all;
chrom_len = 35;
function out = newChromosome(len)
genes_pool = struct(...
'gene', {'#', 'U-', 'Rs', '+', '-', '*', '/', '^'}, ...
'stackDepth', {0, 0, 1, 2, 2, 2, 2, 2},...
'deltaStack', {1, 1, 0, -1, -1, -1, -1, -1});
function gene = newGene(stackDepth)
% Select an appropriate gene
done = false;
while ~done
ind = randi([1 numel(genes_pool)], 1, 1);
if genes_pool(ind).stackDepth <= stackDepth
done = true;
end
end
% Generate output
gene = genes_pool(ind);
disp('start');
disp('gene.gene is ');
disp(gene.gene);
disp('stop');
if gene.gene == '#'
gene.gene = round(randn(1,1) * 5);
disp('new gene.gene is ');
disp(gene.gene);
disp('the gene is ');
disp(gene);
end
end
genes = {}; stack = [];
stackDepth = 0;
i = 1;
while i <= len || (i > len && stackDepth ~= 1)
gene = newGene(stackDepth);
% disp('outside gene');
% disp(gene);
class(gene.gene)
stackDepth = stackDepth + gene.deltaStack;
% disp('stackDepth');
% disp(stackDepth);
genes = [genes, gene.gene];
% disp('genes');
% disp(genes);
stack = [stack, stackDepth];
% disp('stack')
% disp(stack);
i = i + 1;
if strcmp(gene.gene, 'X') && rand(1,1) < 0.5
genes = [genes, randi([2 4], 1)]; stackDepth = stackDepth + 1;
stack = [stack, stackDepth];
genes = [genes, '^']; stackDepth = stackDepth - 1;
stack = [stack, stackDepth];
end
return;
end
out = struct('genes', {genes}, 'stack', {stack});
return;
end
newChromosome(2)
end
第一次运行 Matlab 的输出(我用的是 GNU Octave 也是一样的)是,
start
gene.gene is
U-
stop
ans = char
第二次运行Matlab的输出是,
start
gene.gene is
#
stop
new gene.gene is
-11
the gene is
scalar structure containing the fields:
gene = -11
stackDepth = 0
deltaStack = 1
ans = double
当我将 Matlab 翻译成 Fortran 时,我想复制输出,以便输出 Fortran 与 Matlab 中的类型相同。 gene.gene 结果可以是字符或双精度。这意味着,它可以有两种类型。 是否可以在 Fortran 中做同样的事情?如何在 Fortran 中动态键入变量?我相信这与类型转换有关。 到目前为止,我的 Fortran 解决方案是,
function newchromosome(clen) result(out1)
implicit none
type garray
character*2 :: gene;
integer :: stackdepth;
integer :: deltastack;
end type
type(garray), dimension(8) :: genespool
type(garray), dimension(1) :: gene2
integer,intent(in) :: clen;
integer :: out1;
integer :: inttest;
genespool = [garray('#',0,1),garray('X',0,1),garray('U-',1,0), &
garray('+',2,-1),garray('-',2,-1),garray('*',2,-1), &
garray('/',2,-1),garray('^',2,-1) ]
gene2 = [garray('s',0,0) ]
out1 = clen;
inttest = newgene(2);
contains
function newgene(stackdepth) result(out2)
integer, intent(in) :: stackdepth;
integer :: out2;
logical :: done;
integer :: ind;
real :: rnd1;
character*2, dimension(:), allocatable:: answer2;
character*2 :: answer;
answer = 'ye'
out2=0;
allocate(answer2(1));
! gene=0;
! gene = stackdepth;
done = .FALSE.
do while (done .EQV. .FALSE.)
call random_number(rnd1);
ind = nint(rnd1*size(genespool));
if (genespool(ind)%stackdepth <= stackdepth) then
done = .True.
end if
end do
! Generate output
print*, "genespool(ind) ", genespool(ind);
print*, "gene 2 ", gene2;
gene2=genespool(ind)
print*, "new gene 2 ",gene2;
print*, "new gene2.gene ",gene2%gene;
answer2=gene2%gene;
print*, "test 2 ", answer;
if ( gene2(1)%gene == '#' ) then
call random_number(rnd1);
! gene2%gene = nint(rnd1*5); !<------ problem (convert integer to string integer)
endif
return;
end function newgene
end function newchromosome
program testing1
! ------ unit declaration ----------------------------------------------
use iso_fortran_env
implicit none
! ----------------------------------------------------------------------
! ------ variable declaration ------------------------------------------
integer :: chromlen;
integer :: newchromosome;
integer :: test;
chromlen = 35;
test = 0;
test=int(newChromosome(chromlen));
print*, "newChromosome is ", test;
flush( output_unit )
end program testing1
我添加了一些虚拟变量,例如“answer2”,仅用于调试目的。我用箭头标记了我在 FORTRAN 中的代码由于 Matlab 动态类型声明而导致麻烦的地方。在 FORTRAN 中,不可能有一个既是字符又是双精度(实数)的变量。在 FORTRAN 中,我不能像在 Matlab 中那样拥有 U- 和 -11,因为在 FORTRAN 中将gene2 类型声明为字符。 Matlab 是灵活的,FORTRAN 是严格的。在 FORTRAN 中,如何让gene2.gene 接受“真实类型”-11 而不会导致错误?有没有更好的方法为异构数组声明进行类型声明,例如 %ptr 或 class(*)?
【问题讨论】:
-
您有一些 Fortran 代码可以讨论吗? Fortran 是静态类型语言,但可能存在一些多态性 (
class(*))。但这在这里可能没有帮助。需要确定的是 Fortran 代码。它可能只是一个XY problem。 -
我添加了 fortran 代码解决方案。由于发生动态变量的matlab代码行的性质,我在卡住的地方用箭头标记了。也就是说,它既可以是字符,也可以是双精度。
-
请注意,您的语法很奇怪。您不需要那些分号 (
;)。 Matlab不需要,Fortran也不需要,这点和Matlab差不多。 -
那么函数
newgene和newchromosome返回的最终答案或结果应该是什么?一个数字还是一个字符串?你不只需要整数到字符串的转换吗? stackoverflow.com/questions/1262695/…我没有看到要在任何地方设置的函数结果。 -
好吧,我不知道fortran中分号的原因。但是,如果您不想在输出窗口中看到每个变量的输出,matlab 确实需要它。
标签: arrays dynamic types casting fortran