def generateGeneCorrelationMatrix(n, maxAlphaBeta, normalizeWRows,
                                  networkStructure, powerLawExponent,
                                  networkSparsity, saveFolder):
    """Generate correlation matrix of gene regulatory network.

    Parameters
    ----------
    n : int

    maxAlphaBeta :

    normalizeWRows : logical

    networkStructure : string

    powerLawExponent : float

    networkSparsity :

    saveFolder : 

    Returns
    -------
    gc :

    transcriptionFactors : 

    """
    networkMatrix = np.zeros(shape=(n, n))

    #Generate the network structure
    if (networkStructure == "SimulatedPowerLaw"):
        #Generate number of in and out connections per gene
        inConnections = [
            int((1 / 2.0) * math.pow(1 - np.random.uniform(), -1 /
                                     (powerLawExponent - 1)) + 1 / (2.0))
            for i in range(n)
        ]
        outConnections = [
            int((1 / 2.0) * math.pow(1 - np.random.uniform(), -1 /
                                     (powerLawExponent - 1)) + 1 / (2.0))
            for i in range(n)
        ]

        #Make sure number of in and out connections is not greater than the number of genes
        for i in range(n):
            if (inConnections[i] > n):
                inConnections[i] = n
            if (outConnections[i] > n):
                outConnections[i] = n

        #Set up a multiset of the number of outconnections each gene has, then for each gene sample the inconnections from
        #the multiset of outconnections and remove duplicates
        outNodesSamplePool = []
        for col in range(n):
            numOutConnection = outConnections[col]
            outNodesSamplePool += [col] * numOutConnection

        for row in range(n):
            numInConnections = inConnections[row]
            connectionIndexes = random.sample(outNodesSamplePool,
                                              numInConnections)
            connectionIndexes = list(set(connectionIndexes))
            networkMatrix[row, connectionIndexes] = 1

    elif (networkStructure == "TRRUST"):
        #This file must be downloaded, or it can be generated by using the final AnalyzeTRRUST.py and the original file
        networkMatrix = np.load("TRRUST_Network.npy")

    elif (networkStructure == "Random"):
        #Randomly generate network using sparsity and binomial distribution for the number of in connections per gene
        for row in range(n):
            numInConnections = np.random.binomial(n, (1 - networkSparsity))
            connectionIndexes = random.sample(range(n), numInConnections)
            networkMatrix[row, connectionIndexes] = 1

    else:
        raise Exception('Invalid Network Structure')

    analyzeNetworkStructure(n, networkMatrix, networkStructure, saveFolder)

    valueMatrix = np.zeros(shape=(n, n))

    #Generate values for matrix from a Beta distribution using randomly generated alpha and beta in the range [0, 1, 2, ... , maxAlphaBeta]
    #Then transform the actual values from the (0, 1) range to the (-1, 1) range
    for col in range(n):
        alpha = int(maxAlphaBeta * np.random.uniform() + 1)
        beta = int(maxAlphaBeta * np.random.uniform() + 1)
        valueMatrix[col, :] = (
            2 * np.random.randint(0, 2) - 1) * np.random.beta(
                a=alpha, b=beta, size=n)

    #Element-wise multiply network structure matrix and value matrix
    gc = np.multiply(networkMatrix, valueMatrix)

    #If set to true, will divide each value of each row (in connections) by the number of connections
    if (normalizeWRows):
        for row in range(n):
            if (np.count_nonzero(gc[row, :]) != 0):
                gc[row, :] = gc[row, :] / np.count_nonzero(
                    gc[row, :])  #Normalize by number of connections per row

    #Transcription Factors are defined as genes with a nonzero outdegree
    outDegrees = np.sum(networkMatrix, axis=0)
    transcriptionFactors = np.nonzero(outDegrees)[0]

    return (gc, transcriptionFactors)
