| 赞 | 15 |
| VIP | |
| 好人卡 | |
| 积分 | 19 |
| 经验 | |
| 最后登录 | 2026-5-25 |
| 在线时间 | 404 小时 |
- 梦石
- 0
- 星屑
- 1944
- 在线时间
- 404 小时
- 注册时间
- 2015-8-30
- 回帖
- 322
|
楼主 |
发表于 2016-8-29 21:16:09
|
显示全部楼层
为了做这个,我花了一天时间把行列式研究了个透。我还找讲量子的理论物理书,看一下矩阵的性质。其实矩阵跟行列式几乎不着关系……
那天下午,我作为一个普通的七年级学生,做了很多额外的行列式的题目——本来初中阶段就不应该学这个。
补了一天的姿势之后,我终于总结出了把行列式变成三角形的一般方法(从1开始数而非从0,为了适合一般的数学意义;r表示行矢量,c表示列矢量,a表示元素,n表示阶数):
先用第1行减第2行的对应元素乘第2行第1个元素除以第1行第1个元素的商的积。即:r(2) -= r(1) * (a(2,1) / a(1,1))。根据行列式性质5,行列式的值不变。
再r(3) -= r(1) * (a(3,1) / a(1,1))。再r(4) -= r(1) * (a(4,1) / a(1,1))。以此类推,到r(n) -= r(1) * (a(n,1) / a(1,1))。
然后r(3) -= r(2) * (a(3,2) / a(2,2))。再r(4) -= r(2) * (a(4,2) / a(2,2))。以此类推。这个式子现在很常用,我们用函数d(a,b)来表示。
像上面这样以此类推,我们得到d(n,n-1)是最后一个式子。我们总结一下:
d(2,1);d(3,1);d(4,1);...;d(n,1)
d(3,2);d(4,2);d(5,2);...;d(n,2)
d(4,3);d(5,3);......
......
d(n-1,n-2);d(n,n-2)
d(n,n-1)
好,现在从0开始数,再用上ruby语言,再进一步总结:
for i in 0...n
for j in 0...i
d(i,j)
end
end
看上去简单的很是吧?
但是这么简单的东西榨干了我那么多时间!后来,我用一个行列式
| 1 2 3 |
| 9 8 7 |
| 6 6 5 |
测试了一下,得到了正确结果。正确结果是6678还是6687来着,反正我的代码算对了。
后来你说,我的代码有问题,我就把代码复制回来,又试了一次这个6678行列式,结果得到了-20……我严重怀疑我的iPad被黑客袭击了。这真是奇妙的很啊。
现在我陷入了瓶颈,不知道怎么修复了……
下面是我在你提出bug时未完更新。发现有一处非常奇怪的ArgErr,说我多了一个参数。
- #----------------------------------------------------------------
- # ### Determinant
- #----------------------------------------------------------------
- # 行列式类。用于计算、处理、表达行列式的类。
- #----------------------------------------------------------------
- class Determinant <
- #----------------------------------------------------------------
- # ## 超类
- #----------------------------------------------------------------
- # Object
- #----------------------------------------------------------------
- Object
- #----------------------------------------------------------------
- # ## 包含的模块
- #----------------------------------------------------------------
- # Comparable
- #----------------------------------------------------------------
- include(Comparable)
- #----------------------------------------------------------------
- # ## 类方法
- #----------------------------------------------------------------
- class << self
- #----------------------------------------------------------------
- # # Determinant[row1, row2, ...]
- #----------------------------------------------------------------
- # 基本同Determinant.new。不同之处在于此方法的参数是多个长度相等的数组,
- # 而Determinant.new的参数是嵌套数组。
- #----------------------------------------------------------------
- def [](*rows)
- return(new(rows))
- end
- #----------------------------------------------------------------
- # # Determinant.new(rows)
- #----------------------------------------------------------------
- # 生成一个与rows内容相同的行列式。
- # rows是一个嵌套数组,且rows内的数组的长度应与rows的长度相等,否则会引
- # 发TypeError。
- #----------------------------------------------------------------
- def new(rows)
- super(rows)
- end
- #----------------------------------------------------------------
- # # Determinant.rows(rows, copy = true)
- #----------------------------------------------------------------
- # 基本同Determinant.new。copy为true时使用rows.dup,否则直接使用
- # rows。
- # 请参考Determinant.columns。
- #----------------------------------------------------------------
- def rows(rows, copy = true)
- return(new(rows.dup)) if copy
- return(new(rows))
- end
- #----------------------------------------------------------------
- # # Determinant.columns(columns, copy = true)
- #----------------------------------------------------------------
- # 生成一个与columns内容相同的行列式。相当于Determinant.rows
- # (columns, copy).transpose!。copy为true时使用columns.dup,否则直接使
- # 用columns。
- # 请参考Determinant.rows。
- #----------------------------------------------------------------
- def columns(columns, copy = true)
- return(rows(columns, copy).transpose!)
- end
- #----------------------------------------------------------------
- # # Determinant.diagonal(value1, value2, ...)
- # Determinant.diagonal(values)
- #----------------------------------------------------------------
- # 生成一个对角线内容分别是value1、value2等或数组values的元素的行列式。
- # 其他元素都为0。
- #----------------------------------------------------------------
- def diagonal(*values)
- ary = (values.size == 1 and values[0].is_a?(Array)) ? values[0] : values
- j = 0
- det = zero(size)
- for i in ary
- det[j, j] = i
- j += 1
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # Determinant.scalar(size, value)
- #----------------------------------------------------------------
- # 生成一个对角线元素全部为value的size阶行列式。其他元素都为0。
- #----------------------------------------------------------------
- def scalar(size, value)
- det = zero(size)
- for i in 0...size
- det[i, i] = value
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # Determinant.identity(size)
- #----------------------------------------------------------------
- # 生成一个对角线元素全为1的size阶行列式。其他元素都为0。
- #----------------------------------------------------------------
- def identity(size)
- return(scalac(size, 1))
- end
- #----------------------------------------------------------------
- # # Determinant.unit(size)
- #----------------------------------------------------------------
- # 同Determinant.identity。
- #----------------------------------------------------------------
- def unit(size)
- return(identity(size))
- end
- #----------------------------------------------------------------
- # # Determinant.I(size)
- #----------------------------------------------------------------
- # 同Determinant.identity。
- #----------------------------------------------------------------
- def I(size)
- return(identity(size))
- end
- #----------------------------------------------------------------
- # # Determinant.zero(size)
- #----------------------------------------------------------------
- # 生成一个元素全为0的size阶行列式。
- #----------------------------------------------------------------
- def zero(size)
- det = new(Array.new(size) { Array.new(size) })
- for i in 0...size
- det[i, i] = 0
- end
- return(det)
- end
- end
- #----------------------------------------------------------------
- # ## 方法
- #----------------------------------------------------------------
- #----------------------------------------------------------------
- # # size
- #----------------------------------------------------------------
- # 返回行列式的阶数。相当于rows.size。
- #----------------------------------------------------------------
- def size
- return(rows.size)
- end
- #----------------------------------------------------------------
- # # order
- #----------------------------------------------------------------
- # 同size。
- #----------------------------------------------------------------
- def order
- return(size)
- end
- #----------------------------------------------------------------
- # # cofactor(x, y)
- #----------------------------------------------------------------
- # 返回在x、y位置的余子式。
- #----------------------------------------------------------------
- def cofactor(x, y)
- raise(TypeError) if x >= size or y >= size
- ary = rows.dup
- ary.delete_at(x)
- for i in 0...(order - 1)
- ary[i] = i >= x ? rows[i].clone : rows[i + 1].clone
- ary[i].delete_at(y)
- end
- return(Determinant.new(ary))
- end
- #----------------------------------------------------------------
- # # cof(x, y)
- #----------------------------------------------------------------
- # 同cofactor。
- #----------------------------------------------------------------
- def cof(x, y)
- return(cofactor(x, y))
- end
- #----------------------------------------------------------------
- # # algebraic_cofactor(x, y)
- #----------------------------------------------------------------
- # 返回在x、y位置的代数余子式。
- #----------------------------------------------------------------
- def algebraic_cofactor(x, y)
- raise(TypeError) if x >= size or y >= size
- return((-1) ** (x + y) * cofactor(x, y).value)
- end
- #----------------------------------------------------------------
- # # alc(x, y)
- #----------------------------------------------------------------
- # 同algebraic_cofactor。
- #----------------------------------------------------------------
- def alc(x, y)
- return(algebraic_cofactor(x, y))
- end
- #----------------------------------------------------------------
- # # at(x, y)
- #----------------------------------------------------------------
- # 返回在x、y位置的元素。
- #----------------------------------------------------------------
- def at(x, y)
- return(nil) if x >= size or y >= size
- return(rows[x][y])
- end
- #----------------------------------------------------------------
- # # self[x, y]
- #----------------------------------------------------------------
- # 同at。
- #----------------------------------------------------------------
- def [](x, y)
- return(nil) if x >= size or y >= size
- return(at(x, y))
- end
- #----------------------------------------------------------------
- # # self[x, y] = val
- #----------------------------------------------------------------
- # 为在x、y位置的元素赋值代入val。
- # 返回val。
- #----------------------------------------------------------------
- def []=(x, y, val)
- raise(TypeError) if x >= size or y >= size
- return(rows[x][y] = val)
- end
- #----------------------------------------------------------------
- # # rows = val
- #----------------------------------------------------------------
- # 为rows赋值代入val。
- # 返回val。
- #----------------------------------------------------------------
- def rows=(val)
- raise(TypeError) if !val.is_a?(Array)
- for i in val
- raise(TypeError) if !i.is_a?(Array) or i.size != val.size
- end
- return(@rows = val)
- end
- #----------------------------------------------------------------
- # # row(x)
- #----------------------------------------------------------------
- # 返回与第x行内容相同的数组。
- # 请参考column。
- #----------------------------------------------------------------
- def row(x)
- raise(TypeError) if x >= size
- return(rows[x])
- end
- #----------------------------------------------------------------
- # # column(y)
- #----------------------------------------------------------------
- # 返回与第y列内容相同的数组。
- # 请参考row。
- #----------------------------------------------------------------
- def column(y)
- raise(TypeError) if y >= size
- ary = []
- for i in rows
- ary += i[y].to_a
- end
- return(ary)
- end
- #----------------------------------------------------------------
- # # change_row(x, ary)
- #----------------------------------------------------------------
- # 返回把第x行的内容代替为数组ary的内容后的行列式。
- # ary的元素的数量必须与行列式的阶数相等,否则会引发TypeError。
- # 请参考change_column。
- #----------------------------------------------------------------
- def change_row(x, ary)
- raise(TypeError) if ary.size != size or x >= size
- det = dup
- det.rows[x] = ary
- return(det)
- end
- #----------------------------------------------------------------
- # # change_row!(x, ary)
- #----------------------------------------------------------------
- # 基本同change_row,不同之处在于change_row!有破坏性。
- # 请参考change_column!。
- #----------------------------------------------------------------
- def change_row!(x, ary)
- raise(TypeError) if ary.size != size or x >= size
- rows[x] = ary
- return(self)
- end
- #----------------------------------------------------------------
- # # change_column(y, ary)
- #----------------------------------------------------------------
- # 返回把第y列的内容代替为数组ary的内容后的行列式。
- # ary的元素的数量必须与行列式的阶数相等,否则会引发TypeError。
- # 请参考change_row。
- #----------------------------------------------------------------
- def change_column(y, ary)
- raise(TypeError) if ary.size != size or y >= size
- det = dup
- for i in 0...size
- det[i, y] = ary[i]
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # change_column!(y, ary)
- #----------------------------------------------------------------
- # 基本同change_column,不同之处在于change_column!有破坏性。
- # 请参考change_row!。
- #----------------------------------------------------------------
- def change_column!(y, ary)
- raise(TypeError) if ary.size != size or y >= size
- for i in 0...size
- self[i, y] = ary[i]
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # collect { |item| ... }
- #----------------------------------------------------------------
- # 为行列式中的每个元素分别进行块的迭代操作,并以行列式的形式返回迭代操作
- # 的结果。
- #----------------------------------------------------------------
- def collect
- det = Determinant.zero(size)
- for i in 0...size
- for j in 0...size
- det[i, j] = yield(at(i, j))
- end
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # map
- #----------------------------------------------------------------
- # 同collect。
- #----------------------------------------------------------------
- def map
- return(collect)
- end
- #----------------------------------------------------------------
- # # collect! { |item| ... }
- #----------------------------------------------------------------
- # 基本同collect,不同之处在于collect!有破坏性。
- #----------------------------------------------------------------
- def collect!
- for i in 0...size
- for j in 0...size
- self[i, j] = yield(at(i, j))
- end
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # map!
- #----------------------------------------------------------------
- # 同collect!。
- #----------------------------------------------------------------
- def map!
- return(collect!)
- end
- #----------------------------------------------------------------
- # # transpose
- #----------------------------------------------------------------
- # 转置变换。指把行列式逆时针旋转1/4圈。返回变换后的行列式。
- # 行列式的性质1:行列式转置后,其值不变(请参考value)。
- #----------------------------------------------------------------
- def transpose
- det = dup
- for i in 0...size
- det.change_column(i, row(i))
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # transpose!
- #----------------------------------------------------------------
- # 基本同transpose,不同之处在于transpose!有破坏性。
- #----------------------------------------------------------------
- def transpose!
- det = dup
- for i in 0...size
- change_column(i, det.row(i))
- end
- return(self)
- end
- end
- #----------------------------------------------------------------
- # # exchange_row(x, x_ed)
- #----------------------------------------------------------------
- # 换法变换。指把第x行与第x_ed行的位置互换。返回变换后的行列式。
- # 行列式的性质2:互换行列式的两行(列),行列式变号(请参考value)。
- # 请参考exchange_column。
- #----------------------------------------------------------------
- def exchange_row(x, x_ed)
- raise(TypeError) if x >= size or x_ed >= size
- det = dup
- a = row(x)
- b = row(x_ed)
- det.change_row!(x, b)
- det.change_row!(x_ed, a)
- return(det)
- end
- #----------------------------------------------------------------
- # # exchange_row!
- #----------------------------------------------------------------
- # 基本同exchange_row,不同之处在于exchange_row!有破坏性。
- # 请参考exchange_column!。
- #----------------------------------------------------------------
- def exchange_row!(x, x_ed)
- raise(TypeError) if x >= size or x_ed >= size
- a = row(x)
- b = row(x_ed)
- change_row!(x, b)
- change_row!(x_ed, a)
- return(self)
- end
- #----------------------------------------------------------------
- # # exchange_column(y, y_ed)
- #----------------------------------------------------------------
- # 换法变换。指把第y列与第y_ed列的位置互换。返回变换后的行列式。
- # 请参考exchange_row。
- #----------------------------------------------------------------
- def exchange_column(y, y_ed)
- raise(TypeError) if y >= size or y_ed >= size
- det = dup
- a = column(y)
- b = column(y_ed)
- det.change_column!(y, b)
- det.change_column!(y_ed, a)
- return(det)
- end
- #----------------------------------------------------------------
- # # exchange_column!
- #----------------------------------------------------------------
- # 基本同exchange_column,不同之处在于exchange_column!有破坏性。
- #----------------------------------------------------------------
- def exchange_column!(y, y_ed)
- raise(TypeError) if y >= size or y_ed >= size
- a = column(y)
- b = column(y_ed)
- change_column!(y, b)
- change_column!(y_ed, a)
- return(self)
- end
- #----------------------------------------------------------------
- # # multiply_row(x, num)
- #----------------------------------------------------------------
- # 倍法变换。指把第x行的每一个元素都乘num。返回变换后的行列式。
- # 行列式的性质3:行列式的某一行(列)的所有元素都乘k,等同于用k乘这个行
- # 列式(请参考value)。
- # 请参考multiply_column。
- #----------------------------------------------------------------
- def multiply_row(x, num)
- raise(TypeError) if x >= size
- det = dup
- for i in 0...size
- det[x, i] *= num
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # multiply_row!
- #----------------------------------------------------------------
- # 基本同multiply_row,不同之处在于multiply_row!有破坏性。
- # 请参考multilpy_column!。
- #----------------------------------------------------------------
- def multiply_row!(x, num)
- raise(TypeError) if x >= size
- for i in 0...size
- self[x, i] *= num
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # multiply_column(y, num)
- #----------------------------------------------------------------
- # 倍法变换。指把第y列的每一个元素都乘num。返回变换后的行列式。
- # 请参考multiply_row。
- #----------------------------------------------------------------
- def multiply_column(y, num)
- raise(TypeError) if y >= size
- det = dup
- for i in 0...size
- det[i, y] *= num
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # multiply_column!
- #----------------------------------------------------------------
- # 基本同multiply_column,不同之处在于multiply_column!有破坏性。
- # 请参考multiply_row!。
- #----------------------------------------------------------------
- def multiply_column!(y, num)
- raise(TypeError) if y >= size
- for i in 0...size
- self[i, y] *= num
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # transform_row(x, x_ed, num)
- #----------------------------------------------------------------
- # 消法变换。指把第x行的每一个元素都加上第x_ed行的对应元素乘num的积。返
- # 回变换后的行列式。
- # 行列式的性质5:把行列式的某一行(列)的元素都乘k后加到另一行(列)的对
- # 应元素上去,行列式的值不变(请参考value)。
- # (行列式的性质4:如果行列式的某一行(列)的元素都是多项式,就可以把该
- # 行列式拆成多个行列式的和(请参考value)。)
- # 请参考transform_column。
- #----------------------------------------------------------------
- def transform_row(x, x_ed, num)
- raise(TypeError) if x == x_ed or x >= size or x_ed >= size
- det = dup
- for i in 0...size
- det[x, i] += row(x_ed)[i] * num
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # transform_row!
- #----------------------------------------------------------------
- # 基本同transform_row,不同之处在于transform_row!有破坏性。
- # 请参考transform_column!。
- #----------------------------------------------------------------
- def transform_row!(x, x_ed, num)
- raise(TypeError) if x == x_ed or x >= size or x_ed >= size
- for i in 0...size
- self[x, i] += row(x_ed)[i] * num
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # transform_column(y, y_ed, num)
- #----------------------------------------------------------------
- # 消法变换。指把第y列的每一个元素都加上第y_ed列的对应元素乘num的积。返
- # 回变换后的行列式。
- # 请参考transform_row。
- #----------------------------------------------------------------
- def transform_column(y, y_ed, num)
- raise(TypeError) if y == y_ed or y >= size or y_ed >= size
- det = dup
- for i in 0...size
- det[i, y] += y(y_ed)[i] * num
- end
- return(det)
- end
- #----------------------------------------------------------------
- # # transform_column!
- #----------------------------------------------------------------
- # 基本同transform_column,不同之处在于transform_column!有破坏性。
- # 请参考transform_row!。
- #----------------------------------------------------------------
- def transform_column!(y, y_ed, num)
- raise(TypeError) if y == y_ed or y >= size or y_ed >= size
- for i in 0...size
- self[i, y] += y(y_ed)[i] * num
- end
- return(self)
- end
- #----------------------------------------------------------------
- # # value(expand_calculate = false)
- #----------------------------------------------------------------
- # 返回行列式的值。当expand_calculate为true时计算时间较长但没有任何误
- # 差,为false时计算时间较短但在阶数较大时会有细微误差。
- # 若行列式中没有浮点数则返回整数,否则返回浮点数。
- #----------------------------------------------------------------
- def value(expand_calculate = false)
- f = false
- for i in 0...size
- for j in 0...size
- if at(i, j).is_a?(Float)
- f = true
- break
- end
- end
- break if f == true
- end
- if expand_calculate
- if order == 1
- return at(0, 0)
- else
- val = 0
- for i in 0...order
- val += at(0, i) * algebraic_cofactor(0, i)
- end
- end
- else
- det = dup
- for i in 0...size
- j = 0
- i.times do
- if at(j, j) == 0
- return 0.0 if f
- return 0
- end
- det.transform_row!(i, j, -(at(i, j) / at(j, j).to_f))
- j += 1
- end
- end
- val = 1
- for i in 0...size
- val *= det[i, i]
- end
- end
- return val.to_i unless f
- return val
- end
- #----------------------------------------------------------------
- # # inspect
- #----------------------------------------------------------------
- # 返回表达行列式的字符串。
- #----------------------------------------------------------------
- def inspect
- l = []
- for i in 0...size
- l[i] = 0
- for j in 0...size
- l[i] = at(j, i).size if at(j, i).size > l[i]
- end
- end
- str = ""
- for i in rows
- str += "| "
- k = 0
- for j in i
- k += 1
- str += j.inspect
- str += ", " if k < size
- str += " " * (l[k - 1] - j.inspect.size)
- end
- str += " |\n"
- end
- return str
- end
- #----------------------------------------------------------------
- # # to_s
- #----------------------------------------------------------------
- # 同inspect。
- #----------------------------------------------------------------
- def to_s
- return inspect
- end
- #----------------------------------------------------------------
- # # to_a
- #----------------------------------------------------------------
- # 同rows。
- #----------------------------------------------------------------
- def to_a
- return rows
- end
- #----------------------------------------------------------------
- # # to_f
- #----------------------------------------------------------------
- # 同value.to_f。
- #----------------------------------------------------------------
- def to_f
- return value.to_f
- end
- #----------------------------------------------------------------
- # # to_i
- #----------------------------------------------------------------
- # 同value.to_i。
- #----------------------------------------------------------------
- def to_i
- return value.to_i
- end
- #----------------------------------------------------------------
- # # self <=> other
- #----------------------------------------------------------------
- # 对self和other进行比较。若self.value较大时返回正数,若相等时返回0,
- # 若较小时返回负数。
- #----------------------------------------------------------------
- def <=>(other)
- if other.is_a?(Determinant)
- return value <=> other.value
- else
- return value <=> other
- end
- end
- #----------------------------------------------------------------
- # # eql?(other)
- #----------------------------------------------------------------
- # 若rows与other的rows用eql?比较为true则返回true,否则返回false。
- #----------------------------------------------------------------
- def eql?(other)
- if other.is_a?(Determinant)
- return rows.eql?(other.rows)
- else
- return false
- end
- end
- #----------------------------------------------------------------
- # ## 属性
- #----------------------------------------------------------------
- #----------------------------------------------------------------
- # # rows
- #----------------------------------------------------------------
- # 返回与行列式的内容一样的嵌套数组。
- # 请参考Determinant.new
- #----------------------------------------------------------------
- attr_accessor(:rows)
- #----------------------------------------------------------------
- # ## 私有方法
- #----------------------------------------------------------------
- #----------------------------------------------------------------
- # # initialiaze(rows)
- #----------------------------------------------------------------
- # 行列式对象被建立之后初始化的方法,该方法的参数会全部传递给Determinant
- # .new。这里定义了rows属性的初始值。
- #----------------------------------------------------------------
- def initialize(rows)
- raise(TypeError) unless rows.is_a?(Array)
- for i in rows
- raise(TypeError) unless i.is_a?(Array) and i.size == rows.size
- end
- @rows = rows
- end
- #----------------------------------------------------------------
- # # initialiaze_copy(det)
- #----------------------------------------------------------------
- # 行列式对象被复制之后初始化的方法。
- # 行列式的克隆中,它的rows和rows内部的数组都是原行列式对象的rows和rows
- # 内部的数组的克隆。其余信息的克隆都和一般的对象相同,即Object类内的定义。
- #----------------------------------------------------------------
- def initialize_copy(det)
- det.rows = rows.dup
- for i in 0...size
- det.rows[i] = rows[i].dup
- end
- end
- end
复制代码 |
|