重写无限矩阵
Rewriting on Infinite Matrices
我参加了一个名为“符号线性代数”的项目,该项目是关于对无限矩阵进行基本运算,如加法、乘法、访问特定元素等。我将在 Julia 上实现这些。
为了指定那些无限矩阵,我们将有一些数学案例,例如:
所以矩阵的视觉表示如下:
例如,假设我们要为此示例查找 A + A'。这里我们的案例发生了变化,所以我们需要重写这些案例以获得所需的输出吗?我知道 Mathematica 会这样做,但我该如何实现呢?是的,这太笼统了,所以让我问一些问题;
- 让我们从案例作为输入开始。很多情况下可能有不同的规则,比如如果 i % 2 == 0 或 i == j 就像在这个例子中我如何提供通用输入?
- 假设我已经完成了输入,我想进行那些简单的操作。我怎样才能用像 Julia 这样的编程语言组合这些案例?
我已经写了一些非通用的愚蠢代码,看看事情会如何发展,所以我将提供我的代码来应用最小可重现示例,但不要认真对待它,我想我只是在寻找线索或摆脱脑海中问号的路线图。
using Parameters
struct inf_matrix
mod_of :: Integer
mod_value :: Integer
i_coefficient :: Integer
j_coefficient :: Integer
value :: Integer
end
function single_demo(_mod_of :: Integer, _mod_value :: Integer, _i_coefficient :: Integer, _j_coefficient :: Integer, _value :: Integer)
test_matrix = inf_matrix(_mod_of, _mod_value, _i_coefficient, _j_coefficient, _value)
return test_matrix
end
function get_elem(st::inf_matrix ,i :: Integer, j :: Integer)
#This function is not completed yet
if (i % st.mod_of == st.mod_value) && (2 * st.i_coefficient == j)
return st.value;
else
return -1
end
end
demo_1 = single_demo(2, 0 ,1, 2, 1)
println(get_elem(demo_1, 1, 0))
如有任何帮助,我们将不胜感激。
这里是你如何做到这一点
import Base: getindex, +, *
abstract type InfiniteMatrix end
struct InfiniteIdentity <: InfiniteMatrix end
getindex(::InfiniteIdentity, i, j) = i .== j'
struct InfiniteConstant <: InfiniteMatrix
c
end
getindex(m::InfiniteConstant, i::Integer, j::Integer) = m.c
getindex(m::InfiniteConstant, i, j) = fill(m.c, size(i)..., size(j)...)
struct InfiniteMatrixFilter <: InfiniteMatrix
condition::Function
iftrue::InfiniteMatrix
iffalse::InfiniteMatrix
end
getindex(m::InfiniteMatrixFilter, i, j) = ifelse.(m.condition.(i,j'), m.iftrue[i,j], m.iffalse[i,j])
struct InfiniteMatrixFunction <: InfiniteMatrix
f::Function
args
end
getindex(m::InfiniteMatrixFunction, i, j) = m.f(getindex.(m.args, Ref(i), Ref(j))...)
+(m1::InfiniteMatrix, m2::InfiniteMatrix) = InfiniteMatrixFunction(+, (m1, m2))
*(n::Number, m::InfiniteMatrix) = InfiniteMatrixFunction(x -> n*x, (m,))
julia> i = InfiniteIdentity()
InfiniteIdentity()
julia> c1 = InfiniteConstant(1)
InfiniteConstant(1)
julia> (2i+3c1)[1:5, 1:5]
5×5 Array{Int64,2}:
5 3 3 3 3
3 5 3 3 3
3 3 5 3 3
3 3 3 5 3
3 3 3 3 5
julia> m = InfiniteMatrixFilter((i,j) -> i%2 == 0, c1, 0c1)
InfiniteMatrixFilter(var"#43#44"(), InfiniteConstant(1), InfiniteMatrixFunction(var"#41#42"{Int64}(0), (InfiniteConstant(1),)))
julia> m[1:5, 1:5]
5×5 Array{Int64,2}:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
(这只是概念验证,并未优化或无错误)
我参加了一个名为“符号线性代数”的项目,该项目是关于对无限矩阵进行基本运算,如加法、乘法、访问特定元素等。我将在 Julia 上实现这些。
为了指定那些无限矩阵,我们将有一些数学案例,例如:
所以矩阵的视觉表示如下:
例如,假设我们要为此示例查找 A + A'。这里我们的案例发生了变化,所以我们需要重写这些案例以获得所需的输出吗?我知道 Mathematica 会这样做,但我该如何实现呢?是的,这太笼统了,所以让我问一些问题;
- 让我们从案例作为输入开始。很多情况下可能有不同的规则,比如如果 i % 2 == 0 或 i == j 就像在这个例子中我如何提供通用输入?
- 假设我已经完成了输入,我想进行那些简单的操作。我怎样才能用像 Julia 这样的编程语言组合这些案例?
我已经写了一些非通用的愚蠢代码,看看事情会如何发展,所以我将提供我的代码来应用最小可重现示例,但不要认真对待它,我想我只是在寻找线索或摆脱脑海中问号的路线图。
using Parameters
struct inf_matrix
mod_of :: Integer
mod_value :: Integer
i_coefficient :: Integer
j_coefficient :: Integer
value :: Integer
end
function single_demo(_mod_of :: Integer, _mod_value :: Integer, _i_coefficient :: Integer, _j_coefficient :: Integer, _value :: Integer)
test_matrix = inf_matrix(_mod_of, _mod_value, _i_coefficient, _j_coefficient, _value)
return test_matrix
end
function get_elem(st::inf_matrix ,i :: Integer, j :: Integer)
#This function is not completed yet
if (i % st.mod_of == st.mod_value) && (2 * st.i_coefficient == j)
return st.value;
else
return -1
end
end
demo_1 = single_demo(2, 0 ,1, 2, 1)
println(get_elem(demo_1, 1, 0))
如有任何帮助,我们将不胜感激。
这里是你如何做到这一点
import Base: getindex, +, *
abstract type InfiniteMatrix end
struct InfiniteIdentity <: InfiniteMatrix end
getindex(::InfiniteIdentity, i, j) = i .== j'
struct InfiniteConstant <: InfiniteMatrix
c
end
getindex(m::InfiniteConstant, i::Integer, j::Integer) = m.c
getindex(m::InfiniteConstant, i, j) = fill(m.c, size(i)..., size(j)...)
struct InfiniteMatrixFilter <: InfiniteMatrix
condition::Function
iftrue::InfiniteMatrix
iffalse::InfiniteMatrix
end
getindex(m::InfiniteMatrixFilter, i, j) = ifelse.(m.condition.(i,j'), m.iftrue[i,j], m.iffalse[i,j])
struct InfiniteMatrixFunction <: InfiniteMatrix
f::Function
args
end
getindex(m::InfiniteMatrixFunction, i, j) = m.f(getindex.(m.args, Ref(i), Ref(j))...)
+(m1::InfiniteMatrix, m2::InfiniteMatrix) = InfiniteMatrixFunction(+, (m1, m2))
*(n::Number, m::InfiniteMatrix) = InfiniteMatrixFunction(x -> n*x, (m,))
julia> i = InfiniteIdentity()
InfiniteIdentity()
julia> c1 = InfiniteConstant(1)
InfiniteConstant(1)
julia> (2i+3c1)[1:5, 1:5]
5×5 Array{Int64,2}:
5 3 3 3 3
3 5 3 3 3
3 3 5 3 3
3 3 3 5 3
3 3 3 3 5
julia> m = InfiniteMatrixFilter((i,j) -> i%2 == 0, c1, 0c1)
InfiniteMatrixFilter(var"#43#44"(), InfiniteConstant(1), InfiniteMatrixFunction(var"#41#42"{Int64}(0), (InfiniteConstant(1),)))
julia> m[1:5, 1:5]
5×5 Array{Int64,2}:
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0
(这只是概念验证,并未优化或无错误)