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

时间:2013-12-26 20:16:53

标签: types fortran addition

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

背景:该主题涉及一个名为复杂系统的循环分析的东西,人们可能会在其中阅读,例如,Puccia,CJ和Levins,R。(1986 )。 复杂系统的定性建模:循环分析和时间平均介绍。哈佛大学出版社,剑桥,马萨诸塞州或莱文斯,R。(1974)。部分指定系统的定性分析。 纽约科学院年刊,231:123-138。虽然我可以使用数值矩阵代数实现这种技术(如其他地方所做的那样),但我有兴趣从不同的方向处理问题。循环分析的本质是复杂和昂贵的(我不是CS人,但我认为它类似于#P难度计算),我的长期目标是为各种各样的循环分析问题创建一组库,根据定性算法的属性采用修剪优化。如果这看起来毫无希望地被误导,请幽默我,并认为这是一种学习练习。

为了我的目的,QUALIT数据类型可以有4个值:-1,0,1和? (有时表示为 - ,0,+和+/-)。有关此数据类型的更多信息,请访问:I want to implement a small and fast qualitative data type in Fortran

我希望QUALIT类型数据反映算术二进制操作SUM()和PROD()。两个QUALIT值的总和,AB的工作方式如下:

A  B  A+B
-  -   -
-  0   -
-  +   ?
-  ?   ?
0  -   -
0  0   0
0  +   +
0  ?   ?
+  -   ?
+  0   +
+  +   +
+  ?   ?
?  -   ?
?  0   ?
?  +   ?
?  ?   ?

在数组形式中,两个QUALIT的总和如下:

       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求和:

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

我的问题(请回答两者):

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

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

  3. 在实施乘法而不是求和时,这个问题的答案是否会改变?

1 个答案:

答案 0 :(得分:1)

似乎您可以使用整数和位操作来表示您的数据类型。由于0似乎是求和中的中性元素,因此00代表它,然后-+0110?11。然后,您的求和可以表示为按位或。

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”。