英文:
MethodError with julia: cannot `convert` an object of type Matrix{ComplexF64}
问题
I was working with Scilab and I decide to work with Julia however there are some errors which I didn't arrive to solve. For instance, I would like to fill out a vector using values of a given function but I got this error. Here is the code that I used:
使用Scilab时,我决定改用Julia,但出现了一些错误,我无法解决。例如,我想要使用给定函数的值来填充一个向量,但我遇到了这个错误。以下是我使用的代码:
using LinearAlgebra
A = [5/12 -1/12; 3/4 1/4]; c=[1/3;1]; b=[3/4; 1/4];
N = 10; T = 4; ts = (0:N)*T/N;
dt = T/N; λ = 10^(-14/(2*N+1));
m=length(c) ;
em0=b'/A # b^t * inv(A)
em1 = 1 .-em0*ones(m,1)
γ(z) =@. z/(1.0 -z*em1)
u_hat=complex(zeros(1,N+1));
u_hat[1]=γ(im)
英文:
I was working with Scilab and I decide to work with Julia however there are some errors which I didn't arrive to solve. For instance, I would like to fill out a vector using values of a given function but I got this error. Here is the code that I used:
using LinearAlgebra
A = [5/12 -1/12; 3/4 1/4]; c=[1/3;1]; b=[3/4; 1/4];
N = 10; T = 4; ts = (0:N)*T/N;
dt = T/N; λ = 10^(-14/(2*N+1));
m=length(c) ;
em0=b'/A # b^t * inv(A)
em1 = 1 .-em0*ones(m,1)
γ(z) =@. z/(1.0 -z*em1)
u_hat=complex(zeros(1,N+1));
u_hat[1]=γ(im)
答案1
得分: 2
你正在面临的主要问题是,从Scilab转过来,你可能不习惯区分标量、向量和矩阵。就像在Matlab中一样,Scilab中的标量实际上是1x1矩阵,而向量实际上是Nx1或1xN矩阵。
在Julia中,情况非常不同。标量与1x1矩阵不同,向量与Nx1矩阵不同。因此,你应该小心区分它们。特别是,当你真正需要的是向量时,应该避免创建矩阵 zeros(M, 1)
。
错误消息的直接原因是 γ(im)
是一个矩阵,因为 em1
是一个矩阵:
julia> γ(im)
1x1 Matrix{ComplexF64}:
0.0 + 1.0im
û
也是 ComplexF64
类型的矩阵,你试图将矩阵分配为其元素之一,这自然不会起作用,只有标量值可以成为 Matrix{ComplexF64}
的元素。
我在此基础上整理了你的代码:
A = [5/12 -1/12; 3/4 1/4]
# 在定义向量时使用逗号(这只是关于风格的问题)
b = [3/4, 1/4]
N = 10
## 以下变量均未被使用,尽量将示例简化
c = [1/3, 1]
T = 4
dt = T/N;
ts = (0:N) .* dt
λ = 10^(-14/(2*N+1))
m = length(c)
############### <- 未被使用
# 首选向量而不是1xN或Nx1矩阵
em0 = A' \ b
# 向量与全为1的向量的点积只是求和,但非常浪费和慢。
em1 = 1 - sum(em0)
# 不要使用全局变量(!!!),并删除 `@.`
γ(z, a) = z / (1 - z * a)
# 使用向量而不是1xN矩阵,直接创建复数矩阵而不是将实矩阵转换为复数矩阵。
û = zeros(ComplexF64, N+1)
# 现在这个部分可以正常工作
û[1] = γ(im, em1)
我将 `u_hat` 重命名为 `û`,仅供娱乐。
另外,请记住将你的代码放入一个函数中,这是一个好的实践。
英文:
The over-arching issue you are facing is that, coming from Scilab, you are probably not used to distinguishing scalars, vectors and matrices. Like in Matlab, Scilab scalars are really 1x1 matrices, and vectors are really Nx1 or 1xN matrices.
This is very different in Julia. A scalar is not the same as a 1x1 matrix, and a vector is not the same as a Nx1 matrix. You should therefore take care to distinguish them. In particular, you should avoid creating a matrix, zeros(M, 1)
, when what you really need is a vector, zeros(M)
.
The direct reason for the error message is that γ(im)
is a matrix, because em1
is a matrix:
julia> γ(im)
1×1 Matrix{ComplexF64}:
0.0 + 1.0im
u_hat
is also a matrix of ComplexF64
, and you are trying to assign a matrix as one of its elements, which naturally won't work, only scalar values can be elements of a Matrix{ComplexF64}
.
I took the liberty of writing a cleaned up version of your code:
A = [5/12 -1/12; 3/4 1/4]
# use commas when defining vectors (this is just about style)
b = [3/4, 1/4]
N = 10
## None of the below variables are used. Try to make your example minimal
c = [1/3, 1]
T = 4
dt = T/N;
ts = (0:N) .* dt
λ = 10^(-14/(2*N+1))
m = length(c)
############### <- not used
# prefer vectors over 1xN or Nx1 matrices
em0 = A' \ b
# dot product of a vector and a vector of ones is just a sum, but super-wasterful and slow.
em1 = 1 - sum(em0)
# don't use global variables(!!!), and remove the `@.`
γ(z, a) = z / (1 - z * a)
# use vectors, not 1xN matrices, and directly create a complex matrix instead of converting a real one.
û = zeros(ComplexF64, N+1)
# Now this works
û[1] = γ(im, em1)
I renamed u_hat
to û
for fun.
Also: remember to put your code in a function, always.
答案2
得分: 1
问题出在你将 em1
声明为 em1 = 1 .- em0 * ones(m,1)
的地方。因为 em0 * ones(m,1)
的输出预计是标量,你可以使用 only
函数来获取它(我不反对你的方法,这超出了这个答案的范围):
julia> using LinearAlgebra
# 请注意,通过这种修改,不再需要 `@.` 了。
julia> γ(z) = z / (1.0 - z * em1)
γ (generic function with 1 method)
julia> A = [5/12 -1/12; 3/4 1/4]; c = [1/3; 1]; b = [3/4; 1/4];
N = 10; T = 4; ts = (0:N) * T / N;
dt = T / N; λ = 10^(-14 / (2 * N + 1));
m = length(c);
em0 = b' / A;
# 这是问题可以解决的地方
em1 = 1 - only(em0 * ones(m, 1));
u_hat = complex(zeros(1, N + 1));
u_hat[1] = γ(im)
0.0 + 1.0im
julia> u_hat
1×11 Matrix{ComplexF64}:
0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im … 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
英文:
Just in the case of locating the root of the problem:
The problem is where you declared the em1
as em1 = 1 .-em0*ones(m,1)
. Since the output of the em0*ones(m,1)
is expected to be a scalar, you can grasp it using the only
function (I don't argue with your approach, and that's out of the interest of this answer):
julia> using LinearAlgebra
# Note that with this modification, there isn't any need for `@.` anymore.
julia> γ(z) = z/(1.0 -z*em1)
γ (generic function with 1 method)
julia> A = [5/12 -1/12; 3/4 1/4]; c=[1/3;1]; b=[3/4; 1/4];
N = 10; T = 4; ts = (0:N)*T/N;
dt = T/N; λ = 10^(-14/(2*N+1));
m=length(c);
em0=b'/A;
#This is where the problem can be solved
em1 = 1 - only(em0*ones(m,1));
u_hat=complex(zeros(1,N+1));
u_hat[1]=γ(im)
0.0 + 1.0im
julia> u_hat
1×11 Matrix{ComplexF64}:
0.0+1.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im … 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im 0.0+0.0im
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论