-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmves1.py
75 lines (53 loc) · 1.74 KB
/
mves1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from __future__ import print_function, division
import scipy.optimize, numpy
def MVES( pts ):
## pts should be a sequence of n-dimensional points.
pts = numpy.asarray( pts )
n = pts.shape[1]
assert len( pts.shape ) == 2
## Make an empty array where the points are the columns with a 1 appended.
data = numpy.ones( ( n+1, len( pts ) ) )
data[:-1] = pts.T
## Our solution is n+1 points, each of which is an n-dimensional points with a 1 appended.
shape = ( n+1, n+1 )
def unpack( x ):
V = numpy.ones( shape )
V[:-1] = x.reshape( n, n+1 )
return V
def f( x ):
V = unpack( x )
vol = abs( numpy.linalg.det( V ) )
return vol
constraints = []
'''
def g( x ):
V = unpack( x )
# print( V )
Vinv = numpy.linalg.inv( V )
bary = numpy.dot( Vinv, data )
return abs( bary ).sum()
constraints.append( { 'type': 'ineq', 'fun': g } )
'''
## Constrain the barycentric coordinates to be positive.
def gen_g_positive( constraints ):
for i in range( len( pts ) ):
def gen_g_positive_i( i ):
def g_positive( x ):
V = unpack( x )
Vinv = numpy.linalg.inv( V )
# print( Vinv )
bary = numpy.dot( Vinv, data[:,i] )
return bary
return g_positive
constraints.append( { 'type': 'ineq', 'fun': gen_g_positive_i(i) } )
gen_g_positive( constraints )
x0 = numpy.identity(n+1)[:-1].ravel()
solution = scipy.optimize.minimize( f, x0, method='SLSQP', constraints = constraints )
solution.x = unpack( solution.x )
return solution
# pts = [ [ 0,1 ], [ 1,0 ], [ -2,0 ], [ 0,0 ] ]
pts = [ [ 0,.9, 0., 1 ], [ .1, .9, 0.5, -0.5 ], [ 1,0, -.2, 0.8 ], [ 0, 0, -0.7, 0.3 ] ]
pts = numpy.random.random_sample((20, 8))
solution = MVES( pts )
print( solution )
print( solution.x.round(2) )