我正在阅读关于$ @全局变量的一些问题,以及它是如何在它被处理之前被破坏的,因为成功的eval擦拭干净.
但是,如果它被并发线程中发生的错误所破坏呢?新的线程包说默认情况下不会共享内容,这意味着它是为数不多的主流语言之一"$ a = $ a;" 默认是确定性的(并且认为人们说大型项目中C#和Java比Perl更好).但我不确定特殊的全局变量.
我的直觉表明他们就像任何其他变量一样,因此他们不会被分享.我的大脑的本能说'让我们检查一下Stackoverflow上的向导'.
我检查了Perldoc上的线程教程,它涵盖了共享部分中的常规变量,但似乎继续进行而没有覆盖特殊变量.
即使我没有首先对它们进行本地化,我是否可以使用特殊变量而不会被其他线程破坏?例如,我可以从$ @中提取一个值而不必担心并行线程中发生的错误吗?
我目前正在编写一个项目,我大量使用ListTmonad变换器.使用普通列表时,实现非确定性很容易.但是,一旦我必须将我的代码转换为ListT,它就会变得更加复杂1.
举个简单的例子:转换[a]为ListT a实际需要组成两个函数:
conv :: (Monad m) => [a] -> ListT m a
conv = ListT . return
Run Code Online (Sandbox Code Playgroud)
虽然很简单,但我很惊讶它还没有出现.
问题:
ListT?1确切的原因非常复杂,所以我真的不想详细说明.
下面的代码(计算余弦相似度),在我的计算机上重复运行时,将输出1.0,0.9999999999999998或1.0000000000000002.当我取出normalize函数时,它只返回1.0.我认为浮点运算应该是确定性的.如果每次在同一台计算机上对相同的数据应用相同的操作,我的程序会导致什么?是否可能与堆栈中的哪个位置调用normalize函数有关?我怎么能阻止这个?
#! /usr/bin/env python3
import math
def normalize(vector):
sum = 0
for key in vector.keys():
sum += vector[key]**2
sum = math.sqrt(sum)
for key in vector.keys():
vector[key] = vector[key]/sum
return vector
dict1 = normalize({"a":3, "b":4, "c":42})
dict2 = dict1
n_grams = list(list(dict1.keys()) + list(dict2.keys()))
numerator = 0
denom1 = 0
denom2 = 0
for n_gram in n_grams:
numerator += dict1[n_gram] * dict2[n_gram]
denom1 += dict1[n_gram]**2
denom2 += dict2[n_gram]**2
print(numerator/(math.sqrt(denom1)*math.sqrt(denom2)))
Run Code Online (Sandbox Code Playgroud) 旅行推销员优化(TSP-OPT)是NP难问题,旅行推销员搜索(TSP)是NP完全的.但是,TSP-OPT可以简化为TSP,因为如果TSP可以在多项式时间内求解,那么TSP-OPT(1)也可以.我认为A要降低到B,B必须要比A更难.如我在下面的参考文献中所见,TSP-OPT可以降低到TSP.TSP-OPT应该比TSP更难.我很迷惑...
参考文献:(1)算法,Dasgupta,Papadimitriou,Vazirani练习8.1 http://algorithmics.lsi.upc.edu/docs/Dasgupta-Papadimitriou-Vazirani.pdf https://cseweb.ucsd.edu/classes/sp08/cse101 /hw/hw6soln.pdf
complexity-theory time-complexity non-deterministic computation-theory np
下面的python代码使用PyOpenCL 用数组b中的元素之和填充数组a_plus_b(这不是我的实际目标,但它是我能找到的最简单的代码仍然显示问题).
import pyopencl as cl
import numpy as np
import numpy.linalg as la
height = 50
width = 32
b = np.arange(width,dtype=np.int32)
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b)
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, height*4)
prg = cl.Program(ctx, """
__kernel void sum(__global const int *b, __global int *c)
{
int x = get_global_id(1);
int y;
c[x] = 0;
for(y=0;y<get_global_size(0);y++) {
c[x] += b[y];
}
}
""").build()
prg.sum(queue, (width,height), None, …Run Code Online (Sandbox Code Playgroud) 我试图找出 Spark 中非确定性的所有来源。我知道不确定性可能来自用户提供的函数,例如在 map(f) 中,f 涉及随机。相反,我正在寻找可能导致非确定性的操作,无论是在较低级别的转换/操作方面,例如改组。
我试图在Coq中建模一种不太天真的monadic编码的非确定性(比MonadPlus和常见列表更不天真),这在Haskell中经常使用; 例如,列表的编码看起来像
data List m a = Nil | Cons (m a) (m (List m a))
Run Code Online (Sandbox Code Playgroud)
而Coq中的相应定义如下.
Inductive List (M: Type -> Type) (A: Type) :=
Nil: List M A
| Cons : M A -> M (List M A) -> List M A.
Run Code Online (Sandbox Code Playgroud)
但是,由于归纳数据类型的"严格正"条件,Coq中不允许这种定义.
我不确定我是否打算在Haskell中针对Coq特定的答案或替代实现,我可以在Coq中形式化,但我很高兴阅读有关如何克服此问题的任何建议.
使用StateTmonad 转换器,我可以创建与StateT s [] a同构的类型s -> [(a, s)]。现在我更喜欢使用STTmonad 转换器,因为我想要多个不同类型的可变变量,并且希望能够根据早期计算的结果随意实例化它们。
但是,STT明确提及的链接文档:
这个 monad 转换器不应该与可以包含多个答案的 monad 一起使用,比如列表 monad。原因是状态标记将在不同的答案中重复,这会导致坏事发生(例如失去参考透明度)。安全的 monad 包括 monads State、Reader、Writer、Maybe 以及它们对应的 monad 转换器的组合。
那么我的选择是什么?
完全清楚:
编辑:(编辑编辑:下面的反例是无效的,因为ListT不应该应用于非可交换的 monadST和State。)我开始意识到按照 的方式STT行事的monad 转换器StateT本质上是不安全的。有了它,我们可以构建一个类型STT sloc (ListT (ST sglob)) a。这里,sglob是全局状态sloc的名称,而是局部状态的名称。* 现在我们可以使用全局状态在线程之间交换局部状态引用,从而潜在地获得对未初始化变量的引用。
*为了比较,对应的StateT构造是StateT sloc (ListT (State sglob)) a,与 同构sloc -> …
C# 浮点代码的结果可能会导致不同的结果。
这个问题不是0.1 + 0.2 != 0.3关于浮点机器数的原因和固有的不精确性。
这与以下事实有关:具有相同目标架构(例如 x64)的相同C# 代码可能会导致不同的结果,具体取决于所使用的实际机器/处理器。
这个问题与这个问题直接相关:Is浮点数学在C#中是一致的吗?是真的吗?,其中讨论了 C# 问题。
作为参考,C# 规范中的这一段明确说明了该风险:
浮点运算可以以比运算结果类型更高的精度执行。例如,某些硬件体系结构支持具有比双精度类型更大的范围和精度的“扩展”或“长双精度”浮点类型,并使用这种更高精度类型隐式执行所有浮点运算。只有在性能方面付出过高的代价,这样的硬件架构才能以较低的精度执行浮点运算,并且 C# 允许对所有浮点运算使用更高精度的类型,而不是要求实现同时牺牲性能和精度。除了提供更精确的结果之外,这很少有任何可测量的效果
事实上,我们实际上在仅使用 的算法中经历了〜1e-14数量级的差异double,并且我们担心这种差异会传播到使用此结果的其他迭代算法,等等,使得我们的结果对于不同的质量/法律要求不能一致地再现我们在我们的领域(医学成像研究)有。
C# 和 F# 共享相同的 IL 和公共运行时,但是,据我了解,它可能更多地是由编译器驱动的,这对于 F# 和 C# 来说是不同的。
我觉得自己不够精明,无法理解问题的根源是否是两者共有的,或者如果 F# 有希望,我们是否应该跳入 F# 来帮助我们解决这个问题。
C# 语言规范中明确描述了这种不一致问题。我们尚未在 F# 规范中找到等效项(但我们可能没有在正确的位置进行搜索)。
F# 在这方面是否有更多的一致性?
即,如果我们切换到 F#,我们是否能保证在跨架构的浮点计算中获得更一致的结果?
假设我正在创建一个可以抛出错误的简单解释器,例如
type Error = String
data Term = Con Int | Div Term Term
eval :: (MonadError Error m) => Term -> m Int
eval (Con a) = return a
eval (Div u v) = do
a <- eval u
b <- eval v
if b == 0 then
throwError "Division by zero"
else
return $ a `div` b
Run Code Online (Sandbox Code Playgroud)
具体错误处理程序的典型选择是Either Error.
runEval :: Term -> Either Error Int
runEval = eval
Run Code Online (Sandbox Code Playgroud)
现在假设我想扩展这个解释器来处理非确定性。例如,我可以添加一个Choice Term Term可以评估其第一个或第二个参数的术语。
data Term …Run Code Online (Sandbox Code Playgroud)