-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
14 experiments with alternative implementations (#15)
* experiments * experiments
- Loading branch information
Showing
7 changed files
with
175 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Copyright 2025 Stanford University Convex Optimization Group | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import cvxpy as cp | ||
|
||
from cvx.ball.utils.circle import Center, Circle | ||
|
||
|
||
def min_circle_cvx(points, **kwargs): | ||
# Use con_1 if no constraint construction is defined | ||
# cvxpy variable for the radius | ||
r = cp.Variable(name="Radius") | ||
# cvxpy variable for the midpoint | ||
x = cp.Variable(points.shape[1], name="Midpoint") | ||
objective = cp.Minimize(r) | ||
constraints = [cp.SOC(r, point - x) for point in points] | ||
# * #np.ones(points.shape[0]), | ||
# points - cp.outer(np.ones(points.shape[0]), x), | ||
# axis=1, | ||
# ) | ||
# ] | ||
|
||
problem = cp.Problem(objective=objective, constraints=constraints) | ||
problem.solve(**kwargs) | ||
|
||
return Circle(radius=float(r.value), center=Center(x.value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import cvxpy as cp | ||
|
||
from cvx.ball.utils.circle import Center, Circle | ||
|
||
|
||
def min_circle_cvx(points, **kwargs): | ||
# Use con_1 if no constraint construction is defined | ||
# cvxpy variable for the radius | ||
r = cp.Variable(name="Radius") | ||
# cvxpy variable for the midpoint | ||
x = cp.Variable(points.shape[1], name="Midpoint") | ||
objective = cp.Minimize(r) | ||
constraints = [cp.norm2(x - point) <= r for point in points] | ||
# * #np.ones(points.shape[0]), | ||
# points - cp.outer(np.ones(points.shape[0]), x), | ||
# axis=1, | ||
# ) | ||
# ] | ||
|
||
problem = cp.Problem(objective=objective, constraints=constraints) | ||
problem.solve(**kwargs) | ||
|
||
return Circle(radius=float(r.value), center=Center(x.value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import time | ||
from typing import List, Tuple | ||
|
||
import numpy as np | ||
import plotly.graph_objects as go | ||
from plotly.subplots import make_subplots | ||
|
||
from cvx.ball.solver import min_circle_cvx | ||
|
||
|
||
def cvx(n: int) -> float: | ||
points = np.random.rand(n, 5) | ||
return min_circle_cvx(points, solver="CLARABEL") | ||
|
||
|
||
def measure_execution_time(func, n: int, num_trials: int = 3) -> float: | ||
"""Run multiple trials and return average execution time""" | ||
times = [] | ||
for _ in range(num_trials): | ||
start = time.time() | ||
func(n) | ||
times.append(time.time() - start) | ||
return np.mean(times) | ||
|
||
|
||
def run_analysis() -> Tuple[List[int], List[float]]: | ||
# Test for different values of n (powers of 2) | ||
sequence = np.array([2**n for n in range(4, 20)]) | ||
execution_times = [] | ||
|
||
for n in sequence: | ||
avg_time = measure_execution_time(cvx, int(n)) | ||
execution_times.append(avg_time) | ||
print(f"n={n}: {avg_time:.4f} seconds") | ||
|
||
return sequence, execution_times | ||
|
||
|
||
def plot_results(sizes: List[int], times: List[float]) -> None: | ||
# Create figure | ||
fig = make_subplots(specs=[[{"secondary_y": True}]]) | ||
|
||
# Add actual execution times | ||
fig.add_trace( | ||
go.Scatter( | ||
x=sizes, y=times, name="Actual Time", mode="lines+markers", line=dict(color="blue"), marker=dict(size=8) | ||
) | ||
) | ||
|
||
# Add theoretical O(n) complexity line | ||
normalized_n = np.array(sizes) / sizes[0] | ||
fig.add_trace( | ||
go.Scatter(x=sizes, y=normalized_n * times[0], name="O(n)", line=dict(color="red", dash="dash"), mode="lines") | ||
) | ||
|
||
# Update layout with log scales | ||
fig.update_layout( | ||
title="Algorithm Performance Analysis", | ||
xaxis=dict( | ||
title="Input Size (n)", | ||
type="log", | ||
dtick="D1", # Show ticks for each power of 10 | ||
), | ||
yaxis=dict(title="Execution Time (seconds)", type="log", dtick="D1"), | ||
hovermode="x unified", | ||
showlegend=True, | ||
legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.99), | ||
plot_bgcolor="white", | ||
) | ||
|
||
# Add grid lines | ||
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="LightGray") | ||
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="LightGray") | ||
|
||
# Show the plot | ||
fig.show() | ||
|
||
|
||
if __name__ == "__main__": | ||
# Run the analysis | ||
sizes, times = run_analysis() | ||
plot_results(sizes, times) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import statistics | ||
import timeit as tt | ||
|
||
import numpy as np | ||
|
||
from cvx.ball.solver import min_circle_cvx | ||
from experiments.alter1 import min_circle_cvx as alter1 | ||
from experiments.alter2 import min_circle_cvx as alter2 | ||
|
||
if __name__ == "__main__": | ||
points = np.random.randn(10000, 5) | ||
|
||
def cvx(): | ||
min_circle_cvx(points, solver="CLARABEL") | ||
|
||
def alter_a(): | ||
alter1(points, solver="CLARABEL") | ||
|
||
def alter_b(): | ||
alter2(points, solver="CLARABEL") | ||
|
||
times_clarabel = tt.repeat(cvx, number=1, repeat=5) | ||
print(times_clarabel) | ||
print(statistics.mean(times_clarabel)) | ||
|
||
times_alter1 = tt.repeat(alter_a, number=1, repeat=5) | ||
print(times_alter1) | ||
print(statistics.mean(times_alter1)) | ||
|
||
times_alter2 = tt.repeat(alter_b, number=1, repeat=5) | ||
print(times_alter2) | ||
print(statistics.mean(times_alter2)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters