Banana-Leopard/TASTY huggingface dataset:
# Python3 program for finding orientation of the pattern
# using KMP pattern searching algorithm
N = 5
 
# Used in KMP Search for preprocessing the pattern
def computeLPSArray(pat, M, lps):
     
    # length of the previous longest prefix suffix
    lenl = 0
    i = 1
 
    lps[0] = 0 # lps[0] is always 0
 
    # the loop calculates lps[i] for i = 1 to M-1
    while (i < M):
        if (pat[i] == pat[lenl]):
            lenl += 1
            lps[i] = lenl
            i += 1
        else: # (pat[i] != pat[lenl])
            if (lenl != 0) :
                 
                # This is tricky. Consider the example
                # AAACAAAA and i = 7.
                lenl = lps[lenl - 1]
 
                # Also, note that we do not increment i here
             
            # if (lenl == 0)
            else:
                lps[i] = 0
                i += 1
 
def KMPSearch(pat, txt):
    M = len(pat)
 
    # create lps[] that will hold the longest
    # prefix suffix values for pattern
    lps = [0] * M
    j = 0 # index for pat[]
 
    # Preprocess the pattern (calculate lps[] array)
    computeLPSArray(pat, M, lps)
 
    # index for txt[]
    i = 0
    while (i < N):
        if (pat[j] == txt[i]):
            j += 1
            i += 1
        if (j == M):
             
            # return 1 is pattern is found
            return 1
 
        # mismatch after j matches
        elif (i < N and pat[j] != txt[i]):
             
            # Do not match lps[0..lps[j-1]] characters,
            # they will match anyway
            if (j != 0):
                j = lps[j - 1]
            else:
                i = i + 1
 
    # to amemory leak
 
    # return 0 is pattern is not found
    return 0
 
# Function to find orientation of pattern in the matrix
# It uses KMP pattern searching algorithm
def findOrientation(mat, pat):
     
    # allocate memory for string containing cols
    col = ['a'] * (N)
 
    for i in range(N):
         
        # search in row i
        if (KMPSearch(pat, mat[i])):
            print("Horizontal")
            return
 
        # Construct an array to store i'th column
        for j in range(N):
            col[j] = mat[j][i]
 
        # Search in column i
        if (KMPSearch(pat, col)):
            print("Vertical")
 
# Driver Code
mat=[['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h', 'i', 'j'],
    ['k', 'l', 'm', 'n', 'o'],
    ['p', 'q', 'r', 's', 't'],
    ['u', 'v', 'w', 'x', 'y']]
pat= "pqrs"
 
findOrientation(mat, pat)
 
# This code is contributed by Mohit kumar 29

Time complexity: quadratic
Space complexity: linear
# A Naive method to find maximum
# value of mat[d][e] - mat[a][b]
# such that d > a and e > b
N = 5
 
# The function returns maximum
# value A(d,e) - A(a,b) over
# all choices of indexes such
# that both d > a and e > b.
def findMaxValue(mat):
     
    # stores maximum value
    maxValue = 0
 
    # Consider all possible pairs
    # mat[a][b] and mat[d][e]
    for a in range(N - 1):
        for b in range(N - 1):
            for d in range(a + 1, N):
                for e in range(b + 1, N):
                    if maxValue < int (mat[d][e] -
                                       mat[a][b]):
                        maxValue = int(mat[d][e] -
                                       mat[a][b]);
 
    return maxValue;
 
# Driver Code
mat = [[ 1, 2, -1, -4, -20 ],
       [ -8, -3, 4, 2, 1 ],
       [ 3, 8, 6, 1, 3 ],
       [ -4, -1, 1, 7, -6 ],
       [ 0, -4, 10, -5, 1 ]];
        
print("Maximum Value is " +
       str(findMaxValue(mat)))
       
# This code is contributed
# by ChitraNayal

Time complexity: np
Space complexity: constant
# An efficient method to find maximum value
# of mat[d] - ma[a][b] such that c > a and d > b
 
import sys
N = 5
 
# The function returns maximum value
# A(c,d) - A(a,b) over all choices of
# indexes such that both c > a and d > b.
def findMaxValue(mat):
 
    # stores maximum value
    maxValue = -sys.maxsize -1
 
    # maxArr[i][j] stores max of elements
    # in matrix from (i, j) to (N-1, N-1)
    maxArr = [[0 for x in range(N)]
                 for y in range(N)]
 
    # last element of maxArr will be
    # same's as of the input matrix
    maxArr[N - 1][N - 1] = mat[N - 1][N - 1]
 
    # preprocess last row
    maxv = mat[N - 1][N - 1]; # Initialize max
    for j in range (N - 2, -1, -1):
     
        if (mat[N - 1][j] > maxv):
            maxv = mat[N - 1][j]
        maxArr[N - 1][j] = maxv
     
    # preprocess last column
    maxv = mat[N - 1][N - 1] # Initialize max
    for i in range (N - 2, -1, -1):
     
        if (mat[i][N - 1] > maxv):
            maxv = mat[i][N - 1]
        maxArr[i][N - 1] = maxv
 
    # preprocess rest of the matrix
    # from bottom
    for i in range (N - 2, -1, -1):
     
        for j in range (N - 2, -1, -1):
         
            # Update maxValue
            if (maxArr[i + 1][j + 1] -
                mat[i][j] > maxValue):
                maxValue = (maxArr[i + 1][j + 1] -
                                       mat[i][j])
 
            # set maxArr (i, j)
            maxArr[i][j] = max(mat[i][j],
                           max(maxArr[i][j + 1],
                               maxArr[i + 1][j]))
         
    return maxValue
 
# Driver Code
mat = [[ 1, 2, -1, -4, -20 ],
       [-8, -3, 4, 2, 1 ],
       [ 3, 8, 6, 1, 3 ],
       [ -4, -1, 1, 7, -6] ,
       [0, -4, 10, -5, 1 ]]
                     
print ("Maximum Value is",
        findMaxValue(mat))
 
# This code is contributed by iAyushRaj

Time complexity: quadratic
Space complexity: quadratic
# An efficient Python3 program to find maximum sum
# sub-square matrix
 
# Size of given matrix
N = 5
 
# A O(n^2) function to the maximum sum sub-
# squares of size k x k in a given square
# matrix of size n x n
def printMaxSumSub(mat, k):
 
    # k must be smaller than or equal to n
    if (k > N):
        return;
 
    # 1: PREPROCESSING
    # To store sums of all strips of size k x 1
    stripSum = [[0 for j in range(N)] for i in range(N)];
 
    # Go column by column
    for j in range(N):
         
        # Calculate sum of first k x 1 rectangle
        # in this column
        sum = 0;
        for i in range(k):
            sum += mat[i][j];
        stripSum[0][j] = sum;
 
        # Calculate sum of remaining rectangles
        for i in range(1,N-k+1):
            sum += (mat[i+k-1][j] - mat[i-1][j]);
            stripSum[i][j] = sum;
 
    # max_sum stores maximum sum and its
    # position in matrix
    max_sum = -1000000000
    i_ind = 0
    j_ind = 0
 
    # 2: CALCULATE SUM of Sub-Squares using stripSum[][]
    for i in range(N-k+1):
         
        # Calculate and print sum of first subsquare
        # in this row
        sum = 0;
        for j in range(k):
            sum += stripSum[i][j];
 
        # Update max_sum and position of result
        if (sum > max_sum):
            max_sum = sum;
            i_ind = i
            j_ind = 0
 
 
        # Calculate sum of remaining squares in
        # current row by removing the leftmost
        # strip of previous sub-square and adding
        # a new strip
        for j in range(1,N-k+1):
            sum += (stripSum[i][j+k-1] - stripSum[i][j-1]);
 
            # Update max_sum and position of result
            if (sum > max_sum):
                max_sum = sum;
                i_ind = i
                j_ind = j
 
    # Print the result matrix
    for i in range(k):
        for j in range(k):
            print(mat[i+i_ind][j+j_ind], end = ' ')
        print()
 
# Driver program to test above function
mat = [[1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2],
        [3, 8, 6, 7, 3],
        [4, 4, 4, 4, 4],
        [5, 5, 5, 5, 5],
    ];
k = 3;
print("Maximum sum 3 x 3 matrix is");
printMaxSumSub(mat, k);
 
# This code is contributed by rutvik_56.

Time complexity: quadratic
Space complexity: quadratic
# Python3 Code For A Boolean Matrix Question
R = 3
C = 4
 
 
def modifyMatrix(mat):
    row = [0] * R
    col = [0] * C
 
    # Initialize all values of row[] as 0
    for i in range(0, R):
        row[i] = 0
 
    # Initialize all values of col[] as 0
    for i in range(0, C):
        col[i] = 0
 
    # Store the rows and columns to be marked
    # as 1 in row[] and col[] arrays respectively
    for i in range(0, R):
 
        for j in range(0, C):
            if (mat[i][j] == 1):
                row[i] = 1
                col[j] = 1
 
    # Modify the input matrix mat[] using the
    # above constructed row[] and col[] arrays
    for i in range(0, R):
 
        for j in range(0, C):
            if (row[i] == 1 or col[j] == 1):
                mat[i][j] = 1
 
# A utility function to print a 2D matrix
 
 
def printMatrix(mat):
    for i in range(0, R):
 
        for j in range(0, C):
            print(mat[i][j], end=" ")
        print()
 
 
# Driver Code
mat = [[1, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 0, 0, 0]]
 
print("Input Matrix")
printMatrix(mat)
 
modifyMatrix(mat)
 
print("Matrix after modification")
printMatrix(mat)
 
# This code is contributed by Nikita Tiwari.

Time complexity: quadratic
Space complexity: linear
# Python3 Code For A Boolean Matrix Question
def modifyMatrix(mat):
 
    # variables to check if there are any 1
    # in first row and column
    row_flag = False
    col_flag = False
 
    # updating the first row and col
    # if 1 is encountered
    for i in range(0, len(mat)):
 
        for j in range(0, len(mat)):
            if (i == 0 and mat[i][j] == 1):
                row_flag = True
 
            if (j == 0 and mat[i][j] == 1):
                col_flag = True
 
            if (mat[i][j] == 1):
                mat[0][j] = 1
                mat[i][0] = 1
 
    # Modify the input matrix mat[] using the
    # first row and first column of Matrix mat
    for i in range(1, len(mat)):
 
        for j in range(1, len(mat) + 1):
            if (mat[0][j] == 1 or mat[i][0] == 1):
                mat[i][j] = 1
 
    # modify first row if there was any 1
    if (row_flag == True):
        for i in range(0, len(mat)):
            mat[0][i] = 1
 
    # modify first col if there was any 1
    if (col_flag == True):
        for i in range(0, len(mat)):
            mat[i][0] = 1
 
# A utility function to print a 2D matrix
 
 
def printMatrix(mat):
 
    for i in range(0, len(mat)):
        for j in range(0, len(mat) + 1):
            print(mat[i][j], end="")
 
        print()
 
 
# Driver Code
mat = [[1, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 0, 0, 0]]
 
print("Input Matrix :")
printMatrix(mat)
 
modifyMatrix(mat)
 
print("Matrix After Modification :")
printMatrix(mat)
 
# This code is contributed by Nikita tiwari.

Time complexity: quadratic
Space complexity: constant
''' Python program to find k such that all elements in k'th row
    are 0 and k'th column are 1'''
 
def find(arr):
 
    # store length of the array
    n = len(arr)
 
    # start from top right-most corner
    i = 0
    j = n - 1
     
    # initialise result
    res = -1
 
    # find the index (This loop runs at most 2n times, we
    # either increment row number or decrement column number)
    while i < n and j >= 0:
 
        # if the current element is 0, then this row may be a solution
        if arr[i][j] == 0:
 
            # check for all the elements in this row
            while j >= 0 and (arr[i][j] == 0 or i == j):
                j -= 1
 
            # if all values are 0, update result as row number   
            if j == -1:
                res = i
                break
 
            # if found a 1 in current row, the row can't be a
            # solution, increment row number
            else: i += 1
 
        # if the current element is 1
        else:
 
            #check for all the elements in this column
            while i < n and (arr[i][j] == 1 or i == j):
                i +=1
 
            # if all elements are 1, update result as col number
            if i == n:
                res = j
                break
 
            # if found a 0 in current column, the column can't be a
            # solution, decrement column number
            else: j -= 1
 
    # if we couldn't find result in above loop, result doesn't exist
    if res == -1:
        return res
 
    # check if the above computed res value is valid
    for i in range(0, n):
        if res != i and arr[i][res] != 1:
            return -1
    for j in range(0, j):
        if res != j and arr[res][j] != 0:
            return -1;
  
    return res;
 
# test find(arr) function
arr = [ [0,0,1,1,0],
         [0,0,0,1,0],
         [1,1,1,1,0],
         [0,0,0,0,0],
         [1,1,1,1,1] ]
 
print (find(arr))

Time complexity: linear
Space complexity: constant
# Python3 program to check whether a given tic tac toe
# board is valid or not
 
# Returns true if char wins. Char can be either
# 'X' or 'O'
def win_check(arr, char):
    # Check all possible winning combinations
    matches = [[0, 1, 2], [3, 4, 5],
               [6, 7, 8], [0, 3, 6],
               [1, 4, 7], [2, 5, 8],
               [0, 4, 8], [2, 4, 6]]
 
    for i in range(8):
        if(arr[matches[i][0]] == char and
            arr[matches[i][1]] == char and
            arr[matches[i][2]] == char):
            return True
    return False
 
def is_valid(arr):
    # Count number of 'X' and 'O' in the given board
    xcount = arr.count('X')
    ocount = arr.count('O')
     
    # Board can be valid only if either xcount and ocount
    # is same or count is one more than oCount
    if(xcount == ocount+1 or xcount == ocount):
        # Check if O wins
        if win_check(arr, 'O'):
            # Check if X wins, At a given point only one can win,
            # if X also wins then return Invalid
            if win_check(arr, 'X'):
                return "Invalid"
 
            # O can only win if xcount == ocount in case where whole
            # board has values in each position.
            if xcount == ocount:
                return "Valid"
 
        # If X wins then it should be xc == oc + 1,
        # If not return Invalid    
        if win_check(arr, 'X') and xcount != ocount+1:
            return "Invalid"
         
        # if O is not the winner return Valid
        if not win_check(arr, 'O'):
            return "Valid"
         
    # If nothing above matches return invalid
    return "Invalid"
 
 
# Driver Code
arr = ['X', 'X', 'O',
       'O', 'O', 'X',
       'X', 'O', 'X']
print("Given board is " + is_valid(arr))

Time complexity: constant
Space complexity: constant
# Python 3 program to compute submatrix
# query sum in O(1) time
 
M = 4
N = 5
 
# Function to preprocess input mat[M][N].
# This function mainly fills aux[M][N]
# such that aux[i][j] stores sum
# of elements from (0,0) to (i,j)
def preProcess(mat, aux):
     
    # Copy first row of mat[][] to aux[][]
    for i in range(0, N, 1):
        aux[0][i] = mat[0][i]
 
    # Do column wise sum
    for i in range(1, M, 1):
        for j in range(0, N, 1):
            aux[i][j] = mat[i][j] + aux[i - 1][j]
 
    # Do row wise sum
    for i in range(0, M, 1):
        for j in range(1, N, 1):
            aux[i][j] += aux[i][j - 1]
 
# A O(1) time function to compute sum of submatrix
# between (tli, tlj) and (rbi, rbj) using aux[][]
# which is built by the preprocess function
def sumQuery(aux, tli, tlj, rbi, rbj):
     
    # result is now sum of elements
    # between (0, 0) and (rbi, rbj)
    res = aux[rbi][rbj]
 
    # Remove elements between (0, 0)
    # and (tli-1, rbj)
    if (tli > 0):
        res = res - aux[tli - 1][rbj]
 
    # Remove elements between (0, 0)
    # and (rbi, tlj-1)
    if (tlj > 0):
        res = res - aux[rbi][tlj - 1]
 
    # Add aux[tli-1][tlj-1] as elements
    # between (0, 0) and (tli-1, tlj-1)
    # are subtracted twice
    if (tli > 0 and tlj > 0):
        res = res + aux[tli - 1][tlj - 1]
 
    return res
 
# Driver Code
if __name__ == '__main__':
    mat = [[1, 2, 3, 4, 6],
           [5, 3, 8, 1, 2],
           [4, 6, 7, 5, 5],
           [2, 4, 8, 9, 4]]
aux = [[0 for i in range(N)]
          for j in range(M)]
 
preProcess(mat, aux)
 
tli = 2
tlj = 2
rbi = 3
rbj = 4
print("Query1:", sumQuery(aux, tli, tlj, rbi, rbj))
 
tli = 0
tlj = 0
rbi = 1
rbj = 1
print("Query2:", sumQuery(aux, tli, tlj, rbi, rbj))
 
tli = 1
tlj = 2
rbi = 3
rbj = 3
print("Query3:", sumQuery(aux, tli, tlj, rbi, rbj))
 
# This code is contributed by
# Shashank_Sharma

Time complexity: quadratic
Space complexity: quadratic
# Python3 program to find largest rectangle
# with all 1s in a binary matrix
 
# Finds the maximum area under the
# histogram represented
# by histogram. See below article for details.
 
 
class Solution():
    def maxHist(self, row):
        # Create an empty stack. The stack holds
        # indexes of hist array / The bars stored
        # in stack are always in increasing order
        # of their heights.
        result = []
 
        # Top of stack
        top_val = 0
 
        # Initialize max area in current
        max_area = 0
        # row (or histogram)
 
        area = 0  # Initialize area with current top
 
        # Run through all bars of given
        # histogram (or row)
        i = 0
        while (i < len(row)):
 
            # If this bar is higher than the
            # bar on top stack, push it to stack
            if (len(result) == 0) or (row[result[-1]] <= row[i]):
                result.append(i)
                i += 1
            else:
 
                # If this bar is lower than top of stack,
                # then calculate area of rectangle with
                # stack top as the smallest (or minimum
                # height) bar. 'i' is 'right index' for
                # the top and element before top in stack
                # is 'left index'
                top_val = row[result.pop()]
                area = top_val * i
 
                if (len(result)):
                    area = top_val * (i - result[-1] - 1)
                max_area = max(area, max_area)
 
        # Now pop the remaining bars from stack
        # and calculate area with every popped
        # bar as the smallest bar
        while (len(result)):
            top_val = row[result.pop()]
            area = top_val * i
            if (len(result)):
                area = top_val * (i - result[-1] - 1)
 
            max_area = max(area, max_area)
 
        return max_area
 
    # Returns area of the largest rectangle
    # with all 1s in A
    def maxRectangle(self, A):
 
        # Calculate area for first row and
        # initialize it as result
        result = self.maxHist(A[0])
 
        # iterate over row to find maximum rectangular
        # area considering each row as histogram
        for i in range(1, len(A)):
 
            for j in range(len(A[i])):
 
                # if A[i][j] is 1 then add A[i -1][j]
                if (A[i][j]):
                    A[i][j] += A[i - 1][j]
 
            # Update result if area with current
            # row (as last row) of rectangle) is more
            result = max(result, self.maxHist(A[i]))
 
        return result
 
 
# Driver Code
if __name__ == '__main__':
    A = [[0, 1, 1, 0],
         [1, 1, 1, 1],
         [1, 1, 1, 1],
         [1, 1, 0, 0]]
    ans = Solution()
 
    print("Area of maximum rectangle is",
          ans.maxRectangle(A))
 
# This code is contributed
# by Aaryaman Sharma

Time complexity: quadratic
Space complexity: linear
# Python3 code for Maximum size
# square sub-matrix with all 1s
 
def printMaxSubSquare(M):
    R = len(M)  # no. of rows in M[][]
    C = len(M[0])  # no. of columns in M[][]
 
    S = []
    for i in range(R):
        temp = []
        for j in range(C):
            if i == 0 or j == 0:
                temp += M[i][j],
            else:
                temp += 0,
        S += temp,
    # here we have set the first row and first column of S same as input matrix, other entries are set to 0
 
    # Update other entries
    for i in range(1, R):
        for j in range(1, C):
            if (M[i][j] == 1):
                S[i][j] = min(S[i][j-1], S[i-1][j],
                              S[i-1][j-1]) + 1
            else:
                S[i][j] = 0
 
    # Find the maximum entry and
    # indices of maximum entry in S[][]
    max_of_s = S[0][0]
    max_i = 0
    max_j = 0
    for i in range(R):
        for j in range(C):
            if (max_of_s < S[i][j]):
                max_of_s = S[i][j]
                max_i = i
                max_j = j
 
    print("Maximum size sub-matrix is: ")
    for i in range(max_i, max_i - max_of_s, -1):
        for j in range(max_j, max_j - max_of_s, -1):
            print(M[i][j], end=" ")
        print("")
 
 
# Driver Program
M = [[0, 1, 1, 0, 1],
     [1, 1, 0, 1, 0],
     [0, 1, 1, 1, 0],
     [1, 1, 1, 1, 0],
     [1, 1, 1, 1, 1],
     [0, 0, 0, 0, 0]]
 
printMaxSubSquare(M)
 
# This code is contributed by Soumen Ghosh

Time complexity: quadratic
Space complexity: quadratic
# Python code for Maximum size square
# sub-matrix with all 1s
# (space optimized solution)
 
R = 6
C = 5
 
 
def printMaxSubSquare(M):
 
    global R, C
    Max = 0
 
    # set all elements of S to 0 first
    S = [[0 for col in range(C)]for row in range(2)]
 
    # Construct the entries
    for i in range(R):
        for j in range(C):
 
            # Compute the entrie at the current position
            Entrie = M[i][j]
            if(Entrie):
                if(j):
                    Entrie = 1 + min(S[1][j - 1], min(S[0][j - 1], S[1][j]))
 
            # Save the last entrie and add the new one
            S[0][j] = S[1][j]
            S[1][j] = Entrie
 
            # Keep track of the max square length
            Max = max(Max, Entrie)
 
    # Print the square
    print("Maximum size sub-matrix is: ")
    for i in range(Max):
        for j in range(Max):
            print("1", end=" ")
        print()
 
 
# Driver code
M = [[0, 1, 1, 0, 1],
     [1, 1, 0, 1, 0],
     [0, 1, 1, 1, 0],
     [1, 1, 1, 1, 0],
     [1, 1, 1, 1, 1],
     [0, 0, 0, 0, 0]]
 
printMaxSubSquare(M)
 
# This code is contributed by shinjanpatra

Time complexity: quadratic
Space complexity: linear
# Python3 implementation of the approach
 
# A structure to represent a cell index
class Cell:
 
    def __init__(self, r, c):
        self.r = r # r is row, varies from 0 to R-1
        self.c = c # c is column, varies from 0 to C-1
 
# A simple solution to find sums
# for a given array of cell indexes
def printSums(mat, arr, n):
 
    # Iterate through all cell indexes
    for i in range(0, n):
     
        Sum = 0; r = arr[i].r; c = arr[i].c
 
        # Compute sum for current cell index
        for j in range(0, R):
            for k in range(0, C):
                if j != r and k != c:
                    Sum += mat[j][k]
        print(Sum)
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 1, 2], [3, 4, 6], [5, 3, 2]]
    R = C = 3
    arr = [Cell(0, 0), Cell(1, 1), Cell(0, 1)]
    n = len(arr)
    printSums(mat, arr, n)
     
# This code is contributed by Rituraj Jain

Time complexity: cubic
Space complexity: constant
# Python3 implementation of the approach
 
# A structure to represent a cell index
class Cell:
 
    def __init__(self, r, c):
        self.r = r # r is row, varies from 0 to R-1
        self.c = c # c is column, varies from 0 to C-1
 
# A simple solution to find sums
# for a given array of cell indexes
def printSums(mat, arr, n):
 
    Sum = 0
    row, col = [0] * R, [0] * C
 
    # Compute sum of all elements,
    # sum of every row and sum every column
    for i in range(0, R):
        for j in range(0, C):
            Sum += mat[i][j]
            row[i] += mat[i][j]
            col[j] += mat[i][j]
 
    # Compute the desired sum
    # for all given cell indexes
    for i in range(0, n):
        r0, c0 = arr[i].r, arr[i].c
        print(Sum - row[r0] - col[c0] + mat[r0][c0])
 
# Driver Code
if __name__ == "__main__":
 
    mat = [[1, 1, 2], [3, 4, 6], [5, 3, 2]]
    R = C = 3
    arr = [Cell(0, 0), Cell(1, 1), Cell(0, 1)]
    n = len(arr)
    printSums(mat, arr, n)
 
# This code is contributed by Rituraj Jain

Time complexity: quadratic
Space complexity: linear