"""Owned real Cholesky loop with explicit symmetry check and two triangular solves."""
import math,json
def chol(A):
    n=len(A)
    if not n or any(len(r)!=n for r in A):raise ValueError('square required')
    if not all(math.isfinite(x) for r in A for x in r):raise ValueError('finite required')
    if any(abs(A[i][j]-A[j][i])>1e-12 for i in range(n) for j in range(n)):raise ValueError('own explicit symmetry check')
    L=[[0.]*n for _ in range(n)];pivots=[]
    for i in range(n):
        for j in range(i+1):
            t=A[i][j]-sum(L[i][k]*L[j][k] for k in range(j))
            if i==j:
                if t<=0:raise ValueError('nonpositive pivot')
                pivots.append(t);L[i][j]=math.sqrt(t)
            else:L[i][j]=t/L[j][j]
    return L,pivots
def solve(L,b):
    n=len(L);y=[0.]*n;x=[0.]*n
    for i in range(n):y[i]=(b[i]-sum(L[i][j]*y[j] for j in range(i)))/L[i][i]
    for i in reversed(range(n)):x[i]=(y[i]-sum(L[j][i]*x[j] for j in range(i+1,n)))/L[i][i]
    return y,x
def demo():
    A=[[4.,2.,2.],[2.,10.,-2.],[2.,-2.,6.]];b=[6.,24.,-8.];L,p=chol(A);y,x=solve(L,b)
    LLt=[[sum(L[i][k]*L[j][k] for k in range(3)) for j in range(3)] for i in range(3)]
    assert LLt==A and p==[4.,9.,4.] and x==[1.,2.,-1.]
    residual=[sum(a*v for a,v in zip(row,x))-rhs for row,rhs in zip(A,b)];assert residual==[0.,0.,0.]
    rejected=[]
    for name,B in [('nonsymmetric',[[2.,1.],[0.,2.]]),('positive_semidefinite',[[1.,1.],[1.,1.]]),('indefinite',[[1.,2.],[2.,1.]])]:
        try:chol(B)
        except ValueError as e:rejected.append({'case':name,'reason':str(e)})
        else:raise AssertionError(name)
    return {'A':A,'b':b,'lower_L':L,'diagonal_pivots_before_square_root':p,'L_times_L_transpose':LLt,'forward_y':y,'backward_x':x,'Ax_minus_b':residual,'own_explicit_contract_rejections':rejected,'NumPy_executed':False}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
