Types 我想在Fortran中对一种小而快速的定性数据类型执行求和

Types 我想在Fortran中对一种小而快速的定性数据类型执行求和,types,fortran,addition,Types,Fortran,Addition,这是关于在Fortran中实现定性数据类型的一系列问题的一部分 背景:本主题涉及一种称为复杂系统循环分析的东西,人们可以在Puccia,C.J.和Levins,R.(1986)中读到。复杂系统的定性建模:回路分析和时间平均介绍。哈佛大学出版社,剑桥,马萨诸塞州,或莱文斯,R.(1974年)。部分指定系统的定性分析。《纽约科学院年鉴》,231:123–138。虽然我可以使用数值矩阵代数实现这项技术(正如其他地方所做的那样),但我感兴趣的是从不同的方向来处理这个问题。循环分析的本质是复杂和昂贵的(我

这是关于在Fortran中实现定性数据类型的一系列问题的一部分

背景:本主题涉及一种称为复杂系统循环分析的东西,人们可以在Puccia,C.J.和Levins,R.(1986)中读到。复杂系统的定性建模:回路分析和时间平均介绍。哈佛大学出版社,剑桥,马萨诸塞州,或莱文斯,R.(1974年)。部分指定系统的定性分析。《纽约科学院年鉴》,231:123–138。虽然我可以使用数值矩阵代数实现这项技术(正如其他地方所做的那样),但我感兴趣的是从不同的方向来处理这个问题。循环分析的本质是复杂和昂贵的(我不是CS人员,但我认为这类似于a#P难度计算),我的长期目标是为各种各样的循环分析问题创建一组库,这些问题采用基于定性算法属性的修剪优化。如果这似乎是错误的误导,请幽默我,并认为这是一个学习的锻炼。 出于我的目的,QUALIT数据类型可以有4个值:-1、0、1和?(有时表示为-、0、+、和+/-)。有关此数据类型的详细信息,请单击此处:

我希望QUALIT类型数据反映算术二进制运算SUM()和PROD()。两个质量值的总和,
A
B
的工作原理如下:

A  B  A+B
-  -   -
-  0   -
-  +   ?
-  ?   ?
0  -   -
0  0   0
0  +   +
0  ?   ?
+  -   ?
+  0   +
+  +   +
+  ?   ?
?  -   ?
?  0   ?
?  +   ?
?  ?   ?
ELEMENTAL FUNCTION QUALSUM(x,y)
  IMPLICIT NONE
  TYPE(QUALIT)::QUALSUM
  TYPE(QUALIT), INTENT(IN)::x,y
  TYPE(QUALIT)::summation_array(4,4)
  LOGICAL::xbit1, xbit2, ybit1, ybit2
  INTEGER::index1, index2
  summation_array(1,1) = QUALIT(.FALSE.,.FALSE.)
  summation_array(1,2) = QUALIT(.FALSE.,.FALSE.)
  summation_array(1,3) = QUALIT(.TRUE., .TRUE.)
  summation_array(1,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(2,1) = QUALIT(.FALSE.,.FALSE.)
  summation_array(2,2) = QUALIT(.FALSE.,.TRUE.)
  summation_array(2,3) = QUALIT(.TRUE., .FALSE.)
  summation_array(2,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(3,1) = QUALIT(.TRUE., .TRUE.)
  summation_array(3,2) = QUALIT(.TRUE., .FALSE.)
  summation_array(3,3) = QUALIT(.TRUE., .FALSE.)
  summation_array(3,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,1) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,2) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,3) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,4) = QUALIT(.TRUE., .TRUE.)
  xbit1 = x%bit1
  xbit2 = x%bit2
  ybit1 = y%bit1
  ybit2 = y%bit2
  index1 = 1 + (2*COUNT([xbit2])) + COUNT([xbit1])
  index2 = 1 + (2*COUNT([ybit2])) + COUNT([ybit1])
  QUALSUM = summation_array(index1,index2)
  END FUNCTION QUALSUM
在数组形式中,两个质量的总和如下所示:

       QUALIT 1
      -  0  +  ?

Q -   -  -  ?  ?
U   
A 0   -  0  +  ?
L  
I +   ?  +  +  ?
T
2 ?   ?  ?  ?  ?
此数组包含布尔值:

       QUALIT 1
      00 01 10 11

Q 00  00 00 11 11
U   
A 01  00 01 10 11
L  
I 10  11 10 10 11
T
2 11  11 11 11 11
对于乘法,这样的数组应该是:

       QUALIT 1
      00 01 10 11

Q 00  10 01 00 11
U   
A 01  01 01 01 01
L  
I 10  00 01 10 11
T
2 11  11 01 11 11
我可以这样实现QUALIT求和:

A  B  A+B
-  -   -
-  0   -
-  +   ?
-  ?   ?
0  -   -
0  0   0
0  +   +
0  ?   ?
+  -   ?
+  0   +
+  +   +
+  ?   ?
?  -   ?
?  0   ?
?  +   ?
?  ?   ?
ELEMENTAL FUNCTION QUALSUM(x,y)
  IMPLICIT NONE
  TYPE(QUALIT)::QUALSUM
  TYPE(QUALIT), INTENT(IN)::x,y
  TYPE(QUALIT)::summation_array(4,4)
  LOGICAL::xbit1, xbit2, ybit1, ybit2
  INTEGER::index1, index2
  summation_array(1,1) = QUALIT(.FALSE.,.FALSE.)
  summation_array(1,2) = QUALIT(.FALSE.,.FALSE.)
  summation_array(1,3) = QUALIT(.TRUE., .TRUE.)
  summation_array(1,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(2,1) = QUALIT(.FALSE.,.FALSE.)
  summation_array(2,2) = QUALIT(.FALSE.,.TRUE.)
  summation_array(2,3) = QUALIT(.TRUE., .FALSE.)
  summation_array(2,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(3,1) = QUALIT(.TRUE., .TRUE.)
  summation_array(3,2) = QUALIT(.TRUE., .FALSE.)
  summation_array(3,3) = QUALIT(.TRUE., .FALSE.)
  summation_array(3,4) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,1) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,2) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,3) = QUALIT(.TRUE., .TRUE.)
  summation_array(4,4) = QUALIT(.TRUE., .TRUE.)
  xbit1 = x%bit1
  xbit2 = x%bit2
  ybit1 = y%bit1
  ybit2 = y%bit2
  index1 = 1 + (2*COUNT([xbit2])) + COUNT([xbit1])
  index2 = 1 + (2*COUNT([ybit2])) + COUNT([ybit1])
  QUALSUM = summation_array(index1,index2)
  END FUNCTION QUALSUM
我的问题(请同时回答两个问题):

  • SUM的最快实现是声明一个静态4*4数组,其中的元素由第一个和第二个输入QUALIT值索引,如我上面的示例所示吗

  • 如果我想对序列执行这些操作,问题1的答案是否会改变?例如给定(伪代码):
    类型(QUALIT)示例:(/-,+,+,0,+,+,+,?,+,0,0,-/)
    在遇到第一个时,跨任意数目的操作数的任何求和操作都应返回(无论是在输入中,还是在当前总和中,因此在
    示例中的第二个元素之后,我们知道整个序列的总和是)并停止剩余的计算。我将要执行大量这样的总和,并对大向量的QUALIT数据执行它们

  • 当实现乘法而不是求和时,这个问题的答案会改变吗


  • 似乎您可以使用整数和位运算来表示数据类型。因为
    0
    似乎是求和中的中性元素,所以用
    00
    表示它,然后
    -
    +
    01
    10
    ,而
    11
    。然后,您的求和可以表示出来作为按位or

    program qualit
    integer :: a, b, c
    character :: symbol(0:3) = (/'0','-','+','?'/)    
    do a=0,3
    do b=0,3
    c = ior(a,b)
    write(*,'(3(1X,A1))') symbol(a), symbol(b), symbol(c)
    end do
    end do
    end program qualit
    

    如果您有大量数据,您可以手动将16个值打包成一个整数,并在整个过程中一次执行1个“ior”。

    不要保留新问题,编辑原始问题。这不是重复问题。但这是一个相关问题。Meta-SO表明复杂的问题(即许多部分答案)不如不同的问题令人满意(标签和链接使它们的关联性变得明显)。这个问题是站得住脚的。我不想说,但是如果你发现自己将多个值塞进了单个整数中,你应该问“Fortran是这个项目的正确语言吗?”为了提高存储效率,您可以将所有数据放在一个大字符缓冲区中,不幸的是,Fortran没有提供访问字符类型的单个位的干净方法。使用Fortran执行单个位操作实际上并不复杂,尽管C可能是实现这一点的更自然的语言。