or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

complex-construction.mdcubical-complexes.mdindex.mdpersistent-homology.mdpoint-cloud.mdrepresentations.mdwitness-complexes.md

witness-complexes.mddocs/

0

# Witness Complexes

1

2

Classes for constructing witness complexes, which provide memory-efficient approximations of complex topological structures using landmark points. Witness complexes are particularly useful for large datasets where full complex construction is computationally prohibitive.

3

4

## Capabilities

5

6

### WitnessComplex

7

8

Basic witness complex construction using abstract distance functions between landmarks and witnesses.

9

10

```python { .api }

11

class WitnessComplex:

12

def __init__(self, landmarks, witnesses):

13

"""

14

Initialize witness complex constructor.

15

16

Parameters:

17

- landmarks: List of landmark point indices or points

18

- witnesses: List of witness point indices or points

19

"""

20

21

def create_simplex_tree(self, max_alpha_square: float, limit_dimension: int = float('inf')):

22

"""

23

Create simplex tree from the witness complex.

24

25

Parameters:

26

- max_alpha_square: Maximum alpha square value for filtration

27

- limit_dimension: Maximum dimension of simplices to include

28

29

Returns:

30

SimplexTree: Filtered witness complex as simplex tree

31

"""

32

```

33

34

### StrongWitnessComplex

35

36

Strong witness complex variant that requires all faces of a simplex to be witnessed, providing more stable topological features.

37

38

```python { .api }

39

class StrongWitnessComplex:

40

def __init__(self, landmarks, witnesses):

41

"""

42

Initialize strong witness complex constructor.

43

44

Parameters:

45

- landmarks: List of landmark point indices or points

46

- witnesses: List of witness point indices or points

47

"""

48

49

def create_simplex_tree(self, max_alpha_square: float, limit_dimension: int = float('inf')):

50

"""

51

Create simplex tree from the strong witness complex.

52

53

Parameters:

54

- max_alpha_square: Maximum alpha square value for filtration

55

- limit_dimension: Maximum dimension of simplices to include

56

57

Returns:

58

SimplexTree: Filtered strong witness complex as simplex tree

59

"""

60

```

61

62

### EuclideanWitnessComplex

63

64

Witness complex optimized for point clouds embedded in Euclidean space, using efficient distance computations.

65

66

```python { .api }

67

class EuclideanWitnessComplex:

68

def __init__(self, landmarks, witnesses):

69

"""

70

Initialize Euclidean witness complex constructor.

71

72

Parameters:

73

- landmarks: List of landmark points in Euclidean space

74

- witnesses: List of witness points in Euclidean space

75

"""

76

77

def create_simplex_tree(self, max_alpha_square: float, limit_dimension: int = float('inf')):

78

"""

79

Create simplex tree from the Euclidean witness complex.

80

81

Parameters:

82

- max_alpha_square: Maximum alpha square value for filtration

83

- limit_dimension: Maximum dimension of simplices to include

84

85

Returns:

86

SimplexTree: Filtered Euclidean witness complex as simplex tree

87

"""

88

```

89

90

### EuclideanStrongWitnessComplex

91

92

Combination of Euclidean optimization and strong witness conditions, providing the most stable witness complex construction.

93

94

```python { .api }

95

class EuclideanStrongWitnessComplex:

96

def __init__(self, landmarks, witnesses):

97

"""

98

Initialize Euclidean strong witness complex constructor.

99

100

Parameters:

101

- landmarks: List of landmark points in Euclidean space

102

- witnesses: List of witness points in Euclidean space

103

"""

104

105

def create_simplex_tree(self, max_alpha_square: float, limit_dimension: int = float('inf')):

106

"""

107

Create simplex tree from the Euclidean strong witness complex.

108

109

Parameters:

110

- max_alpha_square: Maximum alpha square value for filtration

111

- limit_dimension: Maximum dimension of simplices to include

112

113

Returns:

114

SimplexTree: Filtered Euclidean strong witness complex as simplex tree

115

"""

116

```

117

118

## Usage Examples

119

120

### Basic Witness Complex Construction

121

122

```python

123

import gudhi

124

import numpy as np

125

126

# Generate large point cloud

127

all_points = np.random.random((1000, 3))

128

129

# Select landmarks using farthest point sampling

130

num_landmarks = 50

131

landmark_indices = gudhi.choose_n_farthest_points(all_points, num_landmarks)

132

landmarks = all_points[landmark_indices]

133

134

# Use all points as witnesses

135

witnesses = all_points

136

137

# Create Euclidean witness complex

138

witness_complex = gudhi.EuclideanWitnessComplex(landmarks, witnesses)

139

simplex_tree = witness_complex.create_simplex_tree(

140

max_alpha_square=0.1,

141

limit_dimension=2

142

)

143

144

# Compute persistence

145

persistence = simplex_tree.persistence()

146

147

print(f"Landmarks: {len(landmarks)}")

148

print(f"Witnesses: {len(witnesses)}")

149

print(f"Simplices: {simplex_tree.num_simplices()}")

150

print(f"Persistence pairs: {len(persistence)}")

151

```

152

153

### Comparing Witness Complex Variants

154

155

```python

156

import gudhi

157

import numpy as np

158

159

# Generate point cloud

160

points = np.random.random((500, 2))

161

162

# Select landmarks

163

num_landmarks = 30

164

landmark_indices = gudhi.choose_n_farthest_points(points, num_landmarks)

165

landmarks = points[landmark_indices]

166

witnesses = points

167

168

# Create different witness complex variants

169

complexes = {

170

'Witness': gudhi.EuclideanWitnessComplex(landmarks, witnesses),

171

'Strong Witness': gudhi.EuclideanStrongWitnessComplex(landmarks, witnesses)

172

}

173

174

max_alpha = 0.05

175

results = {}

176

177

for name, complex_obj in complexes.items():

178

simplex_tree = complex_obj.create_simplex_tree(

179

max_alpha_square=max_alpha,

180

limit_dimension=1

181

)

182

persistence = simplex_tree.persistence()

183

184

results[name] = {

185

'simplices': simplex_tree.num_simplices(),

186

'persistence_pairs': len(persistence),

187

'betti_0': len([p for p in persistence if p[0] == 0]),

188

'betti_1': len([p for p in persistence if p[0] == 1])

189

}

190

191

for name, stats in results.items():

192

print(f"{name}:")

193

print(f" Simplices: {stats['simplices']}")

194

print(f" Persistence pairs: {stats['persistence_pairs']}")

195

print(f" Betti numbers: β₀={stats['betti_0']}, β₁={stats['betti_1']}")

196

print()

197

```

198

199

### Memory-Efficient Large Dataset Analysis

200

201

```python

202

import gudhi

203

import numpy as np

204

205

# Simulate very large dataset

206

np.random.seed(42)

207

large_dataset = np.random.random((10000, 5)) # 10k points in 5D

208

209

# Use witness complex for memory efficiency

210

num_landmarks = 100 # Much smaller than full dataset

211

212

# Select diverse landmarks

213

landmark_indices = gudhi.choose_n_farthest_points(large_dataset, num_landmarks)

214

landmarks = large_dataset[landmark_indices]

215

216

# Subsample witnesses for computational efficiency

217

num_witnesses = 2000

218

witness_indices = gudhi.pick_n_random_points(large_dataset, num_witnesses)

219

witnesses = large_dataset[witness_indices]

220

221

# Create witness complex

222

witness_complex = gudhi.EuclideanStrongWitnessComplex(landmarks, witnesses)

223

simplex_tree = witness_complex.create_simplex_tree(

224

max_alpha_square=0.2,

225

limit_dimension=2

226

)

227

228

# Analyze topology

229

persistence = simplex_tree.persistence()

230

231

# Extract significant features

232

significant_features = [

233

(dim, (birth, death)) for dim, (birth, death) in persistence

234

if death - birth > 0.01 # Minimum persistence threshold

235

]

236

237

print(f"Original dataset: {len(large_dataset)} points")

238

print(f"Landmarks: {len(landmarks)} points")

239

print(f"Witnesses: {len(witnesses)} points")

240

print(f"Significant topological features: {len(significant_features)}")

241

242

# Visualize persistence diagram

243

gudhi.plot_persistence_diagram(persistence)

244

```

245

246

### Landmark Selection Strategies

247

248

```python

249

import gudhi

250

import numpy as np

251

from sklearn.cluster import KMeans

252

253

# Generate point cloud with clusters

254

np.random.seed(42)

255

cluster_centers = np.array([[0, 0], [3, 0], [1.5, 2.6]])

256

points = []

257

for center in cluster_centers:

258

cluster_points = np.random.normal(center, 0.3, (100, 2))

259

points.append(cluster_points)

260

all_points = np.vstack(points)

261

262

# Compare different landmark selection strategies

263

strategies = {

264

'Farthest Point': lambda pts, n: gudhi.choose_n_farthest_points(pts, n),

265

'Random': lambda pts, n: gudhi.pick_n_random_points(pts, n),

266

'K-means Centers': lambda pts, n: KMeans(n_clusters=n, random_state=42).fit(pts).cluster_centers_

267

}

268

269

num_landmarks = 15

270

results = {}

271

272

for strategy_name, strategy_func in strategies.items():

273

if strategy_name == 'K-means Centers':

274

landmarks = strategy_func(all_points, num_landmarks)

275

else:

276

landmark_indices = strategy_func(all_points, num_landmarks)

277

landmarks = all_points[landmark_indices]

278

279

# Create witness complex

280

witness_complex = gudhi.EuclideanWitnessComplex(landmarks, all_points)

281

simplex_tree = witness_complex.create_simplex_tree(

282

max_alpha_square=0.5,

283

limit_dimension=1

284

)

285

286

persistence = simplex_tree.persistence()

287

betti_1 = len([p for p in persistence if p[0] == 1 and p[1][1] != float('inf')])

288

289

results[strategy_name] = {

290

'simplices': simplex_tree.num_simplices(),

291

'holes_detected': betti_1

292

}

293

294

print("Landmark selection strategy comparison:")

295

for strategy, stats in results.items():

296

print(f"{strategy}: {stats['simplices']} simplices, {stats['holes_detected']} holes detected")

297

```