涉及变量和数组的Julia表达式的矢量化

时间:2017-08-30 19:53:57

标签: julia

我有以下代码,我正在尝试在Julia 0.6中实现水的most accurate equation of state

struct parameterizedeos
  Tc::Float64
  ρc::Float64
  R::Float64

  #parameters for ideal gas portion
  n₀::Vector{Float64}
  γ₀::Vector{Float64}
end

h2o_n₀ = [-8.3204464837497, 6.6832105275932, 3.00632, 0.012436, 0.97315, 1.27950,
          0.96956, 0.24873]
h2o_γ₀ = [1.28728967, 3.53734222, 7.74073708, 9.24437796, 27.5075105]

function Σ(expr)
    return sum(eval(@. expr))
end

function ig(eos, δ, τ)
  end_ = Σ(eos.n₀[4:8]*log(1-exp(-eos.γ₀)*τ))
  return log(δ) + eos.n₀[1] + eos.n₀[2]*τ + eos.n₀[3]*log(τ) + end_
end

Tc = 647.096
ρc = 322
R = 0.46151805

eos = parameterizedeos(Tc,ρc,R,h2o_n₀,h2o_γ₀)
δ₁ = 838.025/ρc
τ₁ = Tc/500
print(ig(eos,δ₁,τ₁))

Σ应该是来自数学的相应算子的简单形式,而δ和τ使用来自链接参考的命名法(无量纲密度和温度)。我得到LoadError: DimensionMismatch("Cannot multiply two vectors")

我在Julia REPL中玩过各种各样的子示例,它们似乎都像我期望的那样工作。 Σ(log(1-exp(-h2o_γ₀)*τ))按预期对元素进行矢量化和求和。哎呀,eval(@. h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ)愉快地返回一个5元素的向量。但是调用Σ(h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ))会中断。

我是朱莉娅的菜鸟和宏观之类的神秘事物,所以任何人都可以帮助我弄清楚这里发生了什么,这将是伟大的。

2 个答案:

答案 0 :(得分:1)

Try this (using .* and log. and exp. instead)

SELECT 
  GROUP_CONCAT(DISTINCT external_source_id ORDER BY external_source_id) AS external_source_id,
  GROUP_CONCAT(DISTINCT sources_id ORDER BY sources_id) AS sources_id,
  GROUP_CONCAT(DISTINCT ip_country ORDER BY ip_country) AS ip_country,
  GROUP_CONCAT(DISTINCT cidr ORDER BY cidr) AS cidr
FROM smf_tds_unique_statistic 
WHERE $dateRange

答案 1 :(得分:1)

您得到的错误:DimensionMismatch("Cannot multiply two vectors")在评估ig时在eos.n₀[4:8]*log(1-exp(-eos.γ₀)*τ)内部发生,之后应将结果传递给Σ

此外:@.在全局范围内的解析时扩展,它为函数调用和运算符添加点。 expr只是一个变量,不是运算符,不是函数调用,因此@. nothing eval也没有做任何事情,因此sum(eval(@. expr))与普通sum(expr)相同。但是由于程序在之前失败,这不是你的问题。

编辑:实际上eval不仅仅做任何事情。它做了一些工作;结果相同,但额外的工作完全被浪费了。)

解决方案:删除功能Σ,您不需要它。重写函数ig,如下所示:

function ig(eos, δ, τ)
  end_ = sum(@. eos.n₀[4:8] * log(1 - exp(-eos.γ₀) * τ))
  return log(δ) + eos.n₀[1] + eos.n₀[2]*τ + eos.n₀[3]*log(τ) + end_
end

修改

  

我已经在Julia REPL中使用过各种各样的子示例   他们似乎都像我期待的那样工作。 Σ(log(1-exp(-h2o_γ₀)*τ))   按预期对元素进行矢量化和求和。哎呀,eval(@. h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ)愉快地返回一个5元素的向量。   但是调用Σ(h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ))会中断。

这里的一切都按预期工作。目前,logexp会自动进行向量化,但不推荐使用该行为。在版本1.0中,在向量上调用logexp(或sinsqrt等)将会出错。

eval(@. h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ)按预期对该表达式进行矢量化。 (但是移除eval,你只是在一个值上调用它,这对eval没有意义。)

并且Σ(h2o_n₀[4:8]*log(1-exp(-h2o_γ₀)*τ))失败了,因为您正在尝试将两个向量相乘,这是一个从未工作过的东西(您可以使用点积(使用例如'*dot)或者做元素乘法。但是,你后来尝试将结果传递给Σ的事实是无关紧要的。