-- Generating zopts

-- zLongActiv & opposed must be booleans (not 0/1)
-- rename latitudes with "gradient"?
local function make(latitudes, Es, initTotVa, Kzopt, opposed)
    --print("ID CONTROL:"..#latitudes.." "..#Es.." "..initTotVa.." "..Kzopt)
    local nLines = #latitudes
    local nCols = #latitudes[1]
    --print("NC "..nLines.." "..nCols)
    local zopts = {}


    -- Zopt

    --[[ NOT THIS WAY
    nInterv = nLines
    if nCols > nLines then nInterv = nCols end
    local delta = Kzopt/(nInterv-1)--math.sqrt(Kzopt * totVarPheno / varLat)

    local coefInv = 1
    if opposed then coefInv = -1 end

    for i = 1, nLines do
        if nLines >= nCols then
            coefL = 1
        else
            coefL = 0
        end
        zopts[i] = {}
        for j = 1, nCols do
            zopts[i][j] = coefInv*(-Kzopt/2+(i-1)*coefL*delta+(j-1)*(1-coefL)*delta)
        end
    end--]]

    -- Zopt
    --Logitgudinal zopt
     local zoptLong = rep(0, nCols)
     local totVarPheno = initTotVa + 1
     local varLat = stats.variance_matrix(latitudes)
     local const = math.sqrt(Kzopt * totVarPheno / varLat)

     --[[local mode = "List of list"
     if #Es == nLines*nCols
     then mode = "List"
     end--]]

     for i = 1, nLines do
         zopts[i] = {}
         for j = 1, nCols do
           --[[print(latitudes[i][j])
             local Esij = 0
             if mode == "List"
             then
                 Esij = Es[(i-1)*nCols+j]
                 print("Esij", (i-1)*nCols+j)
             else Esij = Es[i][j]
             end
             print(i.." "..j.. " "..Esij)--]]
             Esij = Es[i][j]
             zopts[i][j] = const * latitudes[i][j] + Esij + zoptLong[j]
         end
     end

       -- If opposed we revert all the lines of the matrix
       if opposed then reverse_vector(zopts) end

    -- If opposed we revert all the lines of the matrix
    if opposed then reverse_vector(zopts) end

    return zopts
end

-------------------------------     Packing        -----------------------------

local zopt = {}
zopt.make = make
return zopt
