# Example for a QCQP problem (linear objective, convex quadratic constraints). # # This model finds the shape of a hanging chain by # minimizing its potential energy. # # Based on AMPL model catenary.mod: # (Source: https://vanderbei.princeton.edu/ampl/nlmodels/catenary/) # # (C) 2018-2025 Fair Isaac Corporation import xpress as xp N = 100 # Number of chainlinks. L = 1 # Difference in x-coordinates of endlinks. H = 2*L/N # Length of each link. RN = range(N+1) p = xp.problem() x = p.addVariables(N+1, lb=-xp.infinity, name="x") y = p.addVariables(N+1, lb=-xp.infinity, name="y") # Objective: minimise the potential energy. p.setObjective(xp.Sum((y[j-1] + y[j]) / 2 for j in range(1, N+1))) # Bounds: positions of endpoints. # Left anchor. p.addConstraint(x[0] == 0) p.addConstraint(y[0] == 0) # Right anchor. p.addConstraint(x[N] == L) p.addConstraint(y[N] == 0) # Constraints: positions of chainlinks. p.addConstraint((x[j] - x[j-1])**2 + (y[j] - y[j-1])**2 <= H**2 for j in range(1, N+1)) # Uncomment to export the matrix file. # p.writeProb('catenary.mat', 'l') p.optimize() print("Solution: ", p.attributes.objval) xsol, ysol = p.getSolution(x), p.getSolution(y) for j in RN: print("{0:10,5f} {1:10,5f}".format(xsol[j], ysol[j]))