// Norm computes the magnitude of the mesh. // Ord can be One, Two or Inf func (m mesh) Norm(ord norm) float64 { switch ord { case One: // vector to hold the columns v := vec.Zeros(m.r) // vector which holds the sums of the // columns sv := vec.Zeros(m.c) for j := 0; j < m.c; j++ { m.GetCol(v, j) sv.SetAt(j, v.AbsElemSum()) } _, n := sv.MaxElem() return n case Two: sum := 0. for _, v := range m.elems.Slice() { sum += v * v } return math.Sqrt(sum) case Inf: v := vec.Zeros(m.c) // vector which holds the absolute sums of // the rows of mesh, m sv := vec.Zeros(m.r) for i := 0; i < m.r; i++ { m.GetRow(v, i) sv.SetAt(i, v.AbsElemSum()) } _, n := sv.MaxElem() return n } return 0 }
// Sum computes the sum of meshes, m & n and puts // result in receiver. // m, n and o should have same dimensions. // a*m + n = o func (o *mesh) Sum(a float64, m, n Mesher) { _, mc, _ := m.Size() mv := vec.Zeros(mc) nv := vec.Zeros(mc) ov := vec.Zeros(mc) for j := 0; j < mc; j++ { m.GetCol(mv, j) n.GetCol(nv, j) ov.Sum(a, mv, nv) o.SetCol(ov, j) } }
// Det computes the determinant of a square mesh, m func (m mesh) Det() (d float64) { mc := m.c L := I(mc) U := Gen(nil, mc, mc) mut := make([]int, mc) m.LU(mut, L, U) d = 1. // check number of mutations // if number of mutations is // odd, then det is -det nmuts := func(det *float64) { cnt := 0 for _, val := range mut { if val != 0 { cnt++ } } if cnt%2 == 1 { *det = -*det } } dv := vec.Zeros(mc) m.GetDiag(dv) for _, v := range dv.Slice() { d *= v } nmuts(&d) return }
// Gen creates a new row oriented mesh // If nil vector is passed, then mesh // will be generated with all elements zeroed func Gen(v vec.Vectorer, r, c int) Mesher { hm := new(mesh) hm.r, hm.c, hm.off = r, c, c hm.elems = vec.Zeros(r * c) if v == nil { return hm } hm.elems.Clone(v) return hm }
// T transposes mesh, m and puts it into // the receiver func (n *mesh) T(m Mesher) { mr, mc, _ := m.Size() nr, _, _ := n.Size() if mc != nr { log.Fatalln("vec: T: Input meshes not equal in size.") } v := vec.Zeros(mr) for j := 0; j < mc; j++ { m.GetCol(v, j) n.SetRow(v, j) } }
func NewTwist(w, q vec.Vectorer) Twister { t := new(twist) t.w = w // set the axis of motion of joint t.q = q // set the position a point on the axis of joint t.v = vec.Zeros(AxisLength) t.v.Cross(q, w) // qxw t.t = mesh.Gen(nil, TwistLength, 1) tvec := t.t.Vec().Slice() copy(tvec[3:], w.Slice()) copy(tvec[:3], t.v.Slice()) return t }
/* Solve AX = B, for X if A, B are square, then X should be square if A is square, but B, X are rectangular, then A.R == B.R == X.R else Solve will panic */ func (X *mesh) Solve(A, B Mesher) { _, N, _ := A.Size() br, bc, _ := B.Size() mut := make([]int, N, N) b := vec.Zeros(br) L := I(N) U := Gen(nil, N, N) A.LU(mut, L, U) for j := 0; j < bc; j++ { B.GetCol(b, j) b.Permute(mut) L.SolveLy(b) U.SolveUx(b) X.SetCol(b, j) } }