package alg

import (
	"sync"
	"zhimolostnova_anna_lab_6/util"
)

func DeterminantParallel(matrix [][]float64, workers int) float64 {
	size := len(matrix)

	if size == 1 {
		return matrix[0][0]
	}

	if size == 2 {
		return matrix[0][0]*matrix[1][1] - matrix[0][1]*matrix[1][0]
	}

	det := 0.0
	wg := sync.WaitGroup{}
	mu := sync.Mutex{}
	chunks := size / workers
	if chunks == 0 {
		chunks = 1
	}
	for j := 0; j < size; j += chunks {
		wg.Add(1)
		go func(jStart int) {
			defer wg.Done()
			localDet := 0.0
			for jj := jStart; jj < jStart+chunks && jj < size; jj++ {
				subMatrix := util.GetMinor(matrix, jj)
				sign := 1
				if jj%2 != 0 {
					sign = -1
				}
				localDet += float64(sign) * matrix[0][jj] * DeterminantParallel(subMatrix, workers)
			}
			mu.Lock()
			det += localDet
			mu.Unlock()
		}(j)
	}

	wg.Wait()
	return det
}