// Determinant returns the determinant of the matrix.
346863
func (mat *T) Determinant() float32 {
	return mat[0][0]*mat[1][1]*mat[2][2] +
		mat[1][0]*mat[2][1]*mat[0][2] +
		mat[2][0]*mat[0][1]*mat[1][2] -
		mat[2][0]*mat[1][1]*mat[0][2] -
		mat[1][0]*mat[0][1]*mat[2][2] -
		mat[0][0]*mat[2][1]*mat[1][2]
}
1246317
func (mat *T) Determinant3x3() float64 {
	return mat[0][0]*mat[1][1]*mat[2][2] +
		mat[1][0]*mat[2][1]*mat[0][2] +
		mat[2][0]*mat[0][1]*mat[1][2] -
		mat[2][0]*mat[1][1]*mat[0][2] -
		mat[1][0]*mat[0][1]*mat[2][2] -
		mat[0][0]*mat[2][1]*mat[1][2]
}
329767
func (m Mat2x3) Col(col int) Vec2 {
	return Vec2{m[col*2+0], m[col*2+1]}
}
553053
func determinize(a *Automaton) *Automaton {
	if a.deterministic || a.numStates() <= 1 {
		return a
	}

	// subset construction
	b := newAutomatonBuilder()

	// fmt.Println("DET:")

	initialset := newFrozenIntSetOf(0, 0)

	// craete state 0:
	b.createState()

	worklist := list.New()
	newstate := make(map[string]int)
	hash := func(s *FrozenIntSet) string {
		return s.String()
	}

	worklist.PushBack(initialset)

	b.setAccept(0, a.IsAccept(0))
	newstate[hash(initialset)] = 0

	// like map[int]*PointTransitions
	points := newPointTransitionSet()

	// like sorted map[int]int
	statesSet := newSortedIntSet(5)

	t := newTransition()

	for worklist.Len() > 0 {
		s := worklist.Remove(worklist.Front()).(*FrozenIntSet)
		// fmt.Printf("det: pop set=%v\n", s)

		// Collate all outgoing transitions by min/1+max
		for _, s0 := range s.values {
			numTransitions := a.numTransitions(s0)
			a.initTransition(s0, t)
			for j := 0; j < numTransitions; j++ {
				a.nextTransition(t)
				points.add(t)
			}
		}

		if len(points.points) == 0 {
			// No outgoing transitions -- skip it
			continue
		}

		points.sort()

		lastPoint := -1
		accCount := 0

		r := s.state
		for _, v := range points.points {
			point := v.point

			if len(statesSet.values) > 0 {
				assert(lastPoint != -1)

				hashKey := statesSet.computeHash().String()

				q, ok := newstate[hashKey]
				if !ok {
					q = b.createState()
					p := statesSet.freeze(q)
					// fmt.Printf("  make new state=%v -> %v accCount=%v\n", q, p, accCount)
					worklist.PushBack(p)
					b.setAccept(q, accCount > 0)
					newstate[hash(p)] = q
				} else {
					assert2(b.isAccept(q) == (accCount > 0),
						"accCount=%v vs existing accept=%v states=%v",
						accCount, b.isAccept(q), statesSet)
				}

				// fmt.Printf("  add trans src=%v dest=%v min=%v max=%v\n",
				// 	r, q, lastPoint, point-1)
				b.addTransitionRange(r, q, lastPoint, point-1)
			}

			// process transitions that end on this point
			// (closes an overlapping interval)
			for j, limit := 0, len(v.ends.transitions); j < limit; j += 3 {
				dest := v.ends.transitions[j]
				statesSet.decr(dest)
				if a.IsAccept(dest) {
					accCount--
				}
			}
			v.ends.transitions = v.ends.transitions[:0] // reuse slice

			// process transitions that start on this point
			// (opens a new interval)
			for j, limit := 0, len(v.starts.transitions); j < limit; j += 3 {
				dest := v.starts.transitions[j]
				statesSet.incr(dest)
				if a.IsAccept(dest) {
					accCount++
				}
			}
			v.starts.transitions = v.starts.transitions[:0] // reuse slice

			lastPoint = point
		}
		points.reset()
		assert2(len(statesSet.values) == 0, "upto=%v", len(statesSet.values))
	}

	ans := b.finish()
	assert(ans.deterministic)
	return ans
}
891489
func (mat *T) Determinant3x3() float32 {
	return mat[0][0]*mat[1][1]*mat[2][2] +
		mat[1][0]*mat[2][1]*mat[0][2] +
		mat[2][0]*mat[0][1]*mat[1][2] -
		mat[2][0]*mat[1][1]*mat[0][2] -
		mat[1][0]*mat[0][1]*mat[2][2] -
		mat[0][0]*mat[2][1]*mat[1][2]
}
1287447
func (mat *T) Transpose() *T {
	temp := mat[0][1]
	mat[0][1] = mat[1][0]
	mat[1][0] = temp
	return mat
}
26995
func (m *Matrix) Dimensions() []int {
	r := make([]int, len(m.dims))
	copy(r, m.dims)
	return r
}
597778
func (m matrix) Invert() (matrix, error) {
	if !m.IsSquare() {
		return nil, errNotSquare
	}

	size := len(m)
	work, _ := identityMatrix(size)
	work, _ = m.Augment(work)

	err := work.gaussianElimination()
	if err != nil {
		return nil, err
	}

	return work.SubMatrix(0, size, size, size*2)
}
1213618
func Dot(a, b *T) float32 {
	return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]
}
1028163
func Zeros(r, c uint) *Matrix {
	res := make([][]float32, r)
	for y := 0; y < int(r); y++ {
		res[y] = make([]float32, c)
	}
	return NewMatrix(res)
}
811229
func (m *Matrix) Multiply(m2 *Matrix) *Matrix {
	multiplyMatricies(m.Val[:], m2.Val[:])
	return m
}
454107
func (m Mat3x4) Col(col int) Vec3 {
	return Vec3{m[col*3+0], m[col*3+1], m[col*3+2]}
}
1314970
func (m *Matrix) T() *Matrix {
	newMat := make([][]float32, m.Cols)
	var wg sync.WaitGroup
	for y := 0; y < int(m.Cols); y++ {
		wg.Add(1)
		go m.t(newMat, y, &wg)
	}
	wg.Wait()
	return NewMatrix(newMat)
}
1011832
public double determinant() {
        if (rows != columns) {
            throw new IllegalStateException("Can not compute determinant of non-square matrix.");
        }

        if (rows == 0) {
            return 0.0;
        } else if (rows == 1) {
            return get(0, 0);
        } else if (rows == 2) {
            return get(0, 0) * get(1, 1) -
                    get(0, 1) * get(1, 0);
        } else if (rows == 3) {
            return get(0, 0) * get(1, 1) * get(2, 2) +
                    get(0, 1) * get(1, 2) * get(2, 0) +
                    get(0, 2) * get(1, 0) * get(2, 1) -
                    get(0, 2) * get(1, 1) * get(2, 0) -
                    get(0, 1) * get(1, 0) * get(2, 2) -
                    get(0, 0) * get(1, 2) * get(2, 1);
        }

        MatrixDecompositor decompositor = withDecompositor(LinearAlgebra.LU);
        Matrix[] lup = decompositor.decompose();
        // TODO: Why Java doesn't support pattern matching?
        Matrix u = lup[1];
        Matrix p = lup[2];

        double result = u.diagonalProduct();

        // TODO: we can do that in O(n log n)
        //       just google: "counting inversions divide and conqueror"
        int[] permutations = new int[p.rows()];
        for (int i = 0; i < p.rows(); i++) {
            for (int j = 0; j < p.columns(); j++) {
                if (p.get(i, j) > 0.0) {
                    permutations[i] = j;
                    break;
                }
            }
        }

        int sign = 1;
        for (int i = 0; i < permutations.length; i++) {
            for (int j = i + 1; j < permutations.length; j++) {
                if (permutations[j] < permutations[i]) {
                    sign *= -1;
                }
            }
        }

        return sign * result;
    }
890862
func (m *Matrix) Get(row, col int) float64 {
	index := (m.stride * row) + col
	return m.elements[index]
}
905600
func (v PreciseVector) Dot(ov PreciseVector) *big.Float {
	return precAdd(precMul(v.X, ov.X), precAdd(precMul(v.Y, ov.Y), precMul(v.Z, ov.Z)))
}
1235570
func (m *matrix3x3) row(row int) Point {
	return Point{r3.Vector{m[row][0], m[row][1], m[row][2]}}
}