我的问题:我注意到很多关于SO的Matlab问题的好答案经常使用这个功能bsxfun.为什么?
动机:在Matlab文档中bsxfun,提供了以下示例:
A = magic(5);
A = bsxfun(@minus, A, mean(A))
Run Code Online (Sandbox Code Playgroud)
当然我们可以使用以下方法执行相同的操作:
A = A - (ones(size(A, 1), 1) * mean(A));
Run Code Online (Sandbox Code Playgroud)
事实上,简单的速度测试表明第二种方法的速度提高了约20%.那么为什么要使用第一种方法?我猜测在某些情况下使用bsxfun将比"手动"方法快得多.我真的很想看到这种情况的一个例子,并解释为什么它更快.
此外,这个问题的最后一个元素,再次来自Matlab文档bsxfun:"C = bsxfun(fun,A,B)将函数句柄fun指定的逐元素二元运算应用于数组A和B,使用单例扩展已启用." 短语"启用单例扩展"是什么意思?
考虑以下简单的速度测试arrayfun:
T = 4000;
N = 500;
x = randn(T, N);
Func1 = @(a) (3*a^2 + 2*a - 1);
tic
Soln1 = ones(T, N);
for t = 1:T
for n = 1:N
Soln1(t, n) = Func1(x(t, n));
end
end
toc
tic
Soln2 = arrayfun(Func1, x);
toc
Run Code Online (Sandbox Code Playgroud)
在我的机器上(Linux Mint 12上的Matlab 2011b),该测试的输出是:
Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.
Run Code Online (Sandbox Code Playgroud)
什么了?!?arrayfun虽然公认的解决方案更清洁,但速度要慢一个数量级.这里发生了什么?
此外,我做了类似的测试方式cellfun,发现它比显式循环慢约3倍.同样,这个结果与我的预期相反.
我的问题是:为什么是arrayfun和cellfun这么多慢?鉴于此,有没有充分的理由使用它们(除了使代码看起来很好)?
注意:我说的是arrayfun这里的标准版本,而不是并行处理工具箱中的GPU版本.
编辑:为了清楚起见,我知道 …
2018年更新:请务必检查所有回复,因为这个问题的答案多年来已经多次改变.在此更新时,Revise.jl答案可能是最佳解决方案.
我有一个文件"/SomeAbsolutePath/ctbTestModule.jl",其内容是:
module ctbTestModule
export f1
f1(x) = x + 1
end
Run Code Online (Sandbox Code Playgroud)
我在一个运行"〜/ .juliarc.jl"的终端中点燃Julia.启动代码包括以下行:
push!(LOAD_PATH, "/SomeAbsolutePath/")
Run Code Online (Sandbox Code Playgroud)
因此我可以立即输入Julia控制台:
using ctbTestModule
Run Code Online (Sandbox Code Playgroud)
加载我的模块.正如预期的f1(1)回报2.现在我突然决定要编辑f1.我在编辑器中打开"/SomeAbsolutePath/ctbTestModule.jl",并将内容更改为:
module ctbTestModule
export f1
f1(x) = x + 2
end
Run Code Online (Sandbox Code Playgroud)
我现在尝试在我的活跃Julia会话中重新加载模块.我试试
using ctbTestModule
Run Code Online (Sandbox Code Playgroud)
但f1(1)仍然返回2.接下来我尝试:
reload("ctbTestModule")
Run Code Online (Sandbox Code Playgroud)
正如这里所建议的,但f1(1)仍然会回归2.最后,我尝试:
include("/SomeAbsolutePath/ctbTestModule.jl")
Run Code Online (Sandbox Code Playgroud)
正如这里所建议的那样,这是不理想的,因为我必须输入完整的绝对路径,因为当前目录可能不是"/ SomeAbsolutePath".我收到的警告信息Warning: replacing module ctbTestModule听起来很有希望,但f1(1)仍然会返回2.
如果我关闭当前的Julia会话,启动一个新会话并输入using ctbTestModule,我现在得到所需的行为,即f1(1)返回3.但显然我想在不 …
我是朱莉娅的新手,鉴于我的Matlab起源,我在确定如何编写利用多个调度和Julia的类型系统的"好"Julia代码时遇到了一些困难.
考虑我有一个提供a的平方的函数的情况Float64.我可以这样写:
function mysquare(x::Float64)
return(x^2);
end
Run Code Online (Sandbox Code Playgroud)
有时,我想Float64在一维数组中对所有s 进行平方,但不想mysquare每次都写出一个循环,所以我使用多次调度并添加以下内容:
function mysquare(x::Array{Float64, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
Run Code Online (Sandbox Code Playgroud)
但是现在我有时正在使用Int64,所以我写了两个利用多个调度的函数:
function mysquare(x::Int64)
return(x^2);
end
function mysquare(x::Array{Int64, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
Run Code Online (Sandbox Code Playgroud)
这是正确的吗?或者是否有更具思想性的方法来应对这种情况?我应该使用这样的类型参数吗?
function mysquare{T<:Number}(x::T)
return(x^2);
end
function mysquare{T<:Number}(x::Array{T, 1})
y = Array(Float64, length(x));
for k = 1:length(x)
y[k] = x[k]^2;
end
return(y);
end
Run Code Online (Sandbox Code Playgroud)
这感觉很合理,但我的代码运行速度会与避免参数类型的情况一样快吗?
总之,我的问题分为两部分:
如果快速代码对我很重要,我应该如上所述使用参数类型,还是应该为不同的具体类型写出多个版本?或者我应该完全做其他事情? …
问题:当我构建自己的模块时,Julia using与importJulia有什么区别?
我基于阅读文档的猜测: using用于将另一个模块带入当前模块的名称空间.import用于将特定类型/函数/变量从其他模块引入当前模块的名称空间.
那么,我有多难?
第二次编辑: github上的这个拉取请求将解决问题.只要有人运行Julia v0.5 +,匿名函数就会像常规函数一样快.案件已经结案.
编辑:我已经将问题和函数定义更新为更一般的情况.
举一个简单的例子,当函数传递函数或在函数中定义函数时,Julia编译器似乎不会优化.这让我感到惊讶,因为这在优化包中非常普遍.我是正确还是我做了一些愚蠢的事情?一个简单的例子如下:
f(a::Int, b::Int) = a - b #A simple function
function g1(N::Int, fIn::Function) #Case 1: Passing in a function
z = 0
for n = 1:N
z += fIn(n, n)
end
end
function g2(N::Int) #Case 2: Function defined within a function
fAnon = f
z = 0
for n = 1:N
z += fAnon(n, n)
end
return(z)
end
function g3(N::Int) #Case 3: Function not defined within function
z = 0
for n …Run Code Online (Sandbox Code Playgroud) 我想在R和Julia中生成相同的随机数.默认情况下,这两种语言似乎都使用Mersenne-Twister库,但在Julia 1.0.0中:
julia> using Random
julia> Random.seed!(3)
julia> rand()
0.8116984049958615
Run Code Online (Sandbox Code Playgroud)
生产0.811...,而在R:
set.seed(3)
runif(1)
Run Code Online (Sandbox Code Playgroud)
生产0.168.
有任何想法吗?
我感兴趣的用例:通过比较输出与R中等效库的输出,测试需要随机数生成(例如统计引导)的新Julia代码
问题:我想在不触发内存分配的情况下索引到数组,尤其是在将索引元素传递给函数时.从阅读朱莉娅文档,我怀疑答案围绕使用该sub函数,但不能完全看到如何...
工作示例:我构建了一个Float64(x)的大向量,然后是每个观察的索引x.
N = 10000000
x = randn(N)
inds = [1:N]
Run Code Online (Sandbox Code Playgroud)
现在我时间mean切换功能x和x[inds](I运行mean(randn(2))第一,以避免在任何定时编译凹凸):
@time mean(x)
@time mean(x[inds])
Run Code Online (Sandbox Code Playgroud)
这是一个相同的计算,但正如预期的那样,时间的结果是:
elapsed time: 0.007029772 seconds (96 bytes allocated)
elapsed time: 0.067880112 seconds (80000208 bytes allocated, 35.38% gc time)
Run Code Online (Sandbox Code Playgroud)
那么,对于任意选择inds(以及任意选择的数组和函数),是否存在解决内存分配问题的方法?
假设我有x和y向量,我知道我可以做plot(x,y)或者plot(y,x)达到我想要的.但是,我的问题具体是:如果我已经在图中创建了一个图plot(x,y),我怎样才能以编程方式交换水平和垂直轴,以便我有效地说plot(y,x)?
初步说明:我在朱莉娅工作,但这个问题可能适用于许多语言.
设置:我有一个复合类型如下:
type MyType
x::Vector{String}
end
Run Code Online (Sandbox Code Playgroud)
我写了一些方法来采取行动MyType.例如,我编写了一个允许我插入新元素的方法x,例如function insert!(d::MyType, itemToInsert::String).
问题:应该MyType是可变的还是一成不变的?
我的理解:我已经阅读了关于这个的Julia文档,以及关于Stackoverflow的更一般(和高度投票)的问题(例如这里或这里),但我仍然没有很好地处理它意味着什么从实际角度看可变/不可变(特别是对于不可变复合类型的情况,包含可变类型的可变数组!)
尽管如此,这是我的尝试:如果MyType是不可变的,那么这意味着该字段x必须始终指向同一个对象.该对象本身(字符串的向量)是可变的,因此我可以在其中插入新元素.我不允许做的是尝试改变,MyType以便该字段x指向一个完全不同的对象.例如,执行以下操作的方法是可以的:
MyType.x[1] = "NewValue"
push!(MyType.x, "NewElementToAdd")
Run Code Online (Sandbox Code Playgroud)
但是执行以下操作的方法并不合适:
MyType.x = ["a", "different", "string", "array"]
Run Code Online (Sandbox Code Playgroud)
这是正确的吗?另外,是否认为不可变类型字段值被锁定的对象是在构造函数中创建的对象?
最后一点:如果这似乎与SO上的其他问题重复,我道歉.如上所述,我已经仔细研究过,并且无法理解我所追求的.