Skip to content

Commit f9399d4

Browse files
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
1 parent 2021699 commit f9399d4

2 files changed

Lines changed: 38 additions & 32 deletions

File tree

benchmark/benchmark_auto_mask.py

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import numpy as np
2121
import pandas as pd
2222

23-
from linopy import GREATER_EQUAL, LESS_EQUAL, Model
23+
from linopy import GREATER_EQUAL, Model
2424

2525

2626
def create_nan_data(
@@ -269,7 +269,7 @@ def benchmark(
269269
print("=" * 70)
270270
print("BENCHMARK: No Masking vs Manual Masking vs Auto-Masking")
271271
print("=" * 70)
272-
print(f"\nModel size:")
272+
print("\nModel size:")
273273
print(f" - Generators: {n_generators}")
274274
print(f" - Time periods: {n_periods}")
275275
print(f" - Regions: {n_regions}")
@@ -290,14 +290,14 @@ def benchmark(
290290
line_nan_count = data["line_capacity"].isna().sum().sum()
291291
line_total = data["line_capacity"].size
292292

293-
print(f"NaN statistics:")
293+
print("NaN statistics:")
294294
print(
295295
f" - Generator capacity: {gen_nan_count:,}/{gen_total:,} "
296-
f"({100*gen_nan_count/gen_total:.1f}% NaN)"
296+
f"({100 * gen_nan_count / gen_total:.1f}% NaN)"
297297
)
298298
print(
299299
f" - Line capacity: {line_nan_count:,}/{line_total:,} "
300-
f"({100*line_nan_count/line_total:.1f}% NaN)"
300+
f"({100 * line_nan_count / line_total:.1f}% NaN)"
301301
)
302302
print()
303303

@@ -343,37 +343,37 @@ def benchmark(
343343
print("RESULTS: Model Building Time")
344344
print("-" * 70)
345345

346-
print(f"\nNo masking (baseline):")
346+
print("\nNo masking (baseline):")
347347
print(f" - Mean time: {np.mean(no_mask_times):.3f}s")
348348
print(f" - Variables: {no_mask_nvars:,} (includes NaN-bounded vars)")
349349
print(f" - Constraints: {no_mask_ncons:,}")
350350

351-
print(f"\nManual masking:")
351+
print("\nManual masking:")
352352
print(f" - Mean time: {np.mean(manual_times):.3f}s")
353353
print(f" - Variables: {manual_nvars:,}")
354354
print(f" - Constraints: {manual_ncons:,}")
355355
manual_overhead = np.mean(manual_times) - np.mean(no_mask_times)
356-
print(f" - Overhead vs no-mask: {manual_overhead*1000:+.1f}ms")
356+
print(f" - Overhead vs no-mask: {manual_overhead * 1000:+.1f}ms")
357357

358-
print(f"\nAuto masking:")
358+
print("\nAuto masking:")
359359
print(f" - Mean time: {np.mean(auto_times):.3f}s")
360360
print(f" - Variables: {auto_nvars:,}")
361361
print(f" - Constraints: {auto_ncons:,}")
362362
auto_overhead = np.mean(auto_times) - np.mean(no_mask_times)
363-
print(f" - Overhead vs no-mask: {auto_overhead*1000:+.1f}ms")
363+
print(f" - Overhead vs no-mask: {auto_overhead * 1000:+.1f}ms")
364364

365365
# Comparison
366-
print(f"\nComparison (Auto vs Manual):")
366+
print("\nComparison (Auto vs Manual):")
367367
speedup = np.mean(manual_times) / np.mean(auto_times)
368368
diff = np.mean(auto_times) - np.mean(manual_times)
369369
if speedup > 1:
370370
print(f" - Auto-mask is {speedup:.2f}x FASTER than manual")
371371
else:
372-
print(f" - Auto-mask is {1/speedup:.2f}x SLOWER than manual")
373-
print(f" - Time difference: {diff*1000:+.1f}ms")
372+
print(f" - Auto-mask is {1 / speedup:.2f}x SLOWER than manual")
373+
print(f" - Time difference: {diff * 1000:+.1f}ms")
374374

375375
# Verify models are equivalent
376-
print(f"\nVerification:")
376+
print("\nVerification:")
377377
print(f" - Manual == Auto variables: {manual_nvars == auto_nvars}")
378378
print(f" - Manual == Auto constraints: {manual_ncons == auto_ncons}")
379379
print(f" - Variables masked out: {no_mask_nvars - manual_nvars:,}")
@@ -394,8 +394,8 @@ def benchmark(
394394
print("RESULTS: LP File Write Time & Size")
395395
print("-" * 70)
396396

397-
import tempfile
398397
import os
398+
import tempfile
399399

400400
# Write LP file for manual masked model
401401
with tempfile.NamedTemporaryFile(suffix=".lp", delete=False) as f:
@@ -415,11 +415,11 @@ def benchmark(
415415
auto_lp_size = os.path.getsize(auto_lp_path) / (1024 * 1024) # MB
416416
os.unlink(auto_lp_path)
417417

418-
print(f"\nManual masking:")
418+
print("\nManual masking:")
419419
print(f" - Write time: {manual_write_time:.3f}s")
420420
print(f" - File size: {manual_lp_size:.2f} MB")
421421

422-
print(f"\nAuto masking:")
422+
print("\nAuto masking:")
423423
print(f" - Write time: {auto_write_time:.3f}s")
424424
print(f" - File size: {auto_lp_size:.2f} MB")
425425

@@ -463,7 +463,7 @@ def benchmark_code_simplicity() -> None:
463463
print("CODE COMPARISON: Manual vs Auto-Mask")
464464
print("=" * 70)
465465

466-
manual_code = '''
466+
manual_code = """
467467
# Manual masking - must create mask explicitly
468468
gen_mask = gen_capacity.notnull()
469469
dispatch = m.add_variables(
@@ -473,9 +473,9 @@ def benchmark_code_simplicity() -> None:
473473
name="dispatch",
474474
mask=gen_mask, # Extra step required
475475
)
476-
'''
476+
"""
477477

478-
auto_code = '''
478+
auto_code = """
479479
# Auto masking - just pass the data with NaN
480480
m = Model(auto_mask=True)
481481
dispatch = m.add_variables(
@@ -484,7 +484,7 @@ def benchmark_code_simplicity() -> None:
484484
coords=[generators, periods],
485485
name="dispatch",
486486
)
487-
'''
487+
"""
488488

489489
print("\nManual masking approach:")
490490
print(manual_code)
@@ -516,10 +516,10 @@ def benchmark_constraint_masking(n_runs: int = 3) -> None:
516516
nan_mask = rng.random(n_constraints) < nan_fraction
517517
rhs.values[nan_mask] = np.nan
518518

519-
print(f"\nModel size:")
519+
print("\nModel size:")
520520
print(f" - Variables: {n_vars}")
521521
print(f" - Potential constraints: {n_constraints}")
522-
print(f" - NaN in RHS: {nan_mask.sum()} ({100*nan_fraction:.0f}%)")
522+
print(f" - NaN in RHS: {nan_mask.sum()} ({100 * nan_fraction:.0f}%)")
523523
print(f"\nRunning {n_runs} iterations each...\n")
524524

525525
# Manual masking
@@ -558,16 +558,16 @@ def benchmark_constraint_masking(n_runs: int = 3) -> None:
558558
print("-" * 70)
559559
print("RESULTS: Constraint Building Time")
560560
print("-" * 70)
561-
print(f"\nManual masking:")
561+
print("\nManual masking:")
562562
print(f" - Mean time: {np.mean(manual_times):.3f}s")
563563
print(f" - Active constraints: {manual_ncons:,}")
564564

565-
print(f"\nAuto masking:")
565+
print("\nAuto masking:")
566566
print(f" - Mean time: {np.mean(auto_times):.3f}s")
567567
print(f" - Active constraints: {auto_ncons:,}")
568568

569569
overhead = np.mean(auto_times) - np.mean(manual_times)
570-
print(f"\nOverhead: {overhead*1000:.1f}ms")
570+
print(f"\nOverhead: {overhead * 1000:.1f}ms")
571571
print(f"Same constraint count: {manual_ncons == auto_ncons}")
572572

573573

@@ -588,9 +588,9 @@ def print_summary_table(results: list[dict[str, Any]]) -> None:
588588
lp_size = r.get("lp_size_mb", 0)
589589
print(
590590
f"{name:<12} {r['potential_vars']:>10,} {r['nvars']:>10,} "
591-
f"{r['masked_out']:>8,} {r['no_mask_time']*1000:>8.0f}ms "
592-
f"{r['manual_time']*1000:>8.0f}ms {r['auto_time']*1000:>8.0f}ms "
593-
f"{(r['auto_time']-r['manual_time'])*1000:>+7.0f}ms "
591+
f"{r['masked_out']:>8,} {r['no_mask_time'] * 1000:>8.0f}ms "
592+
f"{r['manual_time'] * 1000:>8.0f}ms {r['auto_time'] * 1000:>8.0f}ms "
593+
f"{(r['auto_time'] - r['manual_time']) * 1000:>+7.0f}ms "
594594
f"{lp_write:>8.0f}ms {lp_size:>8.1f}MB"
595595
)
596596
print("-" * 110)

linopy/model.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,12 @@ def add_variables(
554554

555555
# Auto-mask based on NaN in bounds (use numpy for speed)
556556
if self.auto_mask:
557-
auto_mask_values = ~np.isnan(data.lower.values) & ~np.isnan(data.upper.values)
558-
auto_mask_arr = DataArray(auto_mask_values, coords=data.coords, dims=data.dims)
557+
auto_mask_values = ~np.isnan(data.lower.values) & ~np.isnan(
558+
data.upper.values
559+
)
560+
auto_mask_arr = DataArray(
561+
auto_mask_values, coords=data.coords, dims=data.dims
562+
)
559563
if mask is not None:
560564
mask = mask & auto_mask_arr
561565
else:
@@ -760,7 +764,9 @@ def add_constraints(
760764
rhs_da, _ = xr.broadcast(rhs_da, data.labels)
761765
rhs_notnull = rhs_da.values
762766
auto_mask_values = auto_mask_values & rhs_notnull
763-
auto_mask_arr = DataArray(auto_mask_values, coords=data.labels.coords, dims=data.labels.dims)
767+
auto_mask_arr = DataArray(
768+
auto_mask_values, coords=data.labels.coords, dims=data.labels.dims
769+
)
764770
if mask is not None:
765771
mask = mask & auto_mask_arr
766772
else:

0 commit comments

Comments
 (0)