Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Measurement statistics module #896

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft

Conversation

nitbharambe
Copy link
Member

Implements variance related calculations mentioned in # #547

Changes proposed in this PR include:

A generic module for handling different types of variances in state estimation.

Could you please pay extra attention to the points below when reviewing the PR:

mgovers and others added 8 commits February 4, 2025 15:56
Signed-off-by: Martijn Govers <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Comment on lines +108 to +110
explicit operator UniformComplexRDV<sym>() const {
return UniformComplexRDV<sym>{.value = value, .variance = sum_val(variance)};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and elsewhere: please double-check whether additional conversion operators are required

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added tests without checking implementations. Also it would be nice to now add additional conversion operators if there is a need for it during implementation. The base for the operators are ready and available in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so do you want me to review as is? i would be reviewing my own code though 😬

Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
Signed-off-by: Nitish Bharambe <[email protected]>
@nitbharambe nitbharambe marked this pull request as ready for review February 17, 2025 14:28
Copy link
Member

@mgovers mgovers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from a very quick look it seems OK to me, but maybe it's good to let someone else review, as i've written a significant part of the code

Comment on lines +108 to +110
explicit operator UniformComplexRDV<sym>() const {
return UniformComplexRDV<sym>{.value = value, .variance = sum_val(variance)};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so do you want me to review as is? i would be reviewing my own code though 😬

@nitbharambe
Copy link
Member Author

from a very quick look it seems OK to me, but maybe it's good to let someone else review, as i've written a significant part of the code

True, asked @Jerry-Jinfeng-Guo .

Copy link
Contributor

@Jerry-Jinfeng-Guo Jerry-Jinfeng-Guo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple comments on the file statistics.hpp in general before proceeding to the test file:

  • Please rename RDV to RandVar
  • Please rename Uniform to Unified
  • Is the symmetric member variable actually useful?
  • Shall we add some simple equations as reference to the conversions between the forms?

/**
* @file statistics.hpp
* @brief This file contains various structures and functions for handling statistical representations of
* randomly distributed variables(RDV) used in the Power Grid Model, like in the State Estimation algorithms to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

randomly distributed variable is quite a strange expression. For this specific context, 'random variable' is accurate and comcise enough.

Suggested change
* randomly distributed variables(RDV) used in the Power Grid Model, like in the State Estimation algorithms to
* random variables (RandVar) used in the Power Grid Model, like in the State Estimation algorithms to

or

Suggested change
* randomly distributed variables(RDV) used in the Power Grid Model, like in the State Estimation algorithms to
* random variables (RV) used in the Power Grid Model, like in the State Estimation algorithms to

* with different types of variances. These structures support both symmetric and asymmetric representations and
* provide conversion operators to transform between these representations.
*
* A Randomly distributed variable in PGM can have following characteristics:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* A Randomly distributed variable in PGM can have following characteristics:
* A random variable in PGM can have following characteristics:

Comment on lines +21 to +24
* - Uniform: Single Variance for all phases
* - Independent: Unique Variance for each phase
* - Real: The Real value without direction, eg. real axis: RealValue (* 1), imaginary axis: RealValue (* 1i).
* - Complex: A combined complex value in `a + bi` notation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* - Uniform: Single Variance for all phases
* - Independent: Unique Variance for each phase
* - Real: The Real value without direction, eg. real axis: RealValue (* 1), imaginary axis: RealValue (* 1i).
* - Complex: A combined complex value in `a + bi` notation.
* - Unified: total variance for all phases
* - Independent: all phases are independent from each other
* - Scalar: a scalar value `RealValue`, eg. real axis: RealValue (* 1), imaginary axis: RealValue (* i).
* - Complex: a complex value with real and imaginary parts.

Comment on lines +26 to +29
* Based on these, we use combine variables in Polar/Decomposed forms:
* - Decomposed: Treat RDV individually as in cartesian co-ordinates with a separate variance for both real and
* complex component.
* - Polar: RDV is in polar co-ordinates, with magnitude and angle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is a bit hard to flow from the above, perhaps some inbetween liaison?

Suggested change
* Based on these, we use combine variables in Polar/Decomposed forms:
* - Decomposed: Treat RDV individually as in cartesian co-ordinates with a separate variance for both real and
* complex component.
* - Polar: RDV is in polar co-ordinates, with magnitude and angle.
* [liaison]
* Based on these, we use combined variables in Decomposed/Polar forms:
* - Decomposed: treat random variables individually as in cartesian co-ordinates with separated variances for both real and
* imaginary part.
* - Polar: random variables are in polar co-ordinates, with magnitudes and angles.

Comment on lines +42 to +51
explicit operator UniformRealRDV<asymmetric_t>() const
requires(is_symmetric_v<sym>)
{
return {.value = RealValue<asymmetric_t>{std::piecewise_construct, value}, .variance = variance};
}
explicit operator UniformRealRDV<symmetric_t>() const
requires(is_asymmetric_v<sym>)
{
return {.value = mean_val(value), .variance = variance / 3.0};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the division by 3 enough? If I convert one sym rand var to asym rand var and back, would I still get the same result?

Comment on lines +172 to +179
return DecomposedComplexRDV<sym>{
.real_component = {.value = real_component,
.variance = magnitude.variance * cos_theta * cos_theta +
imag_component * imag_component * angle.variance},
.imag_component = {.value = imag_component,
.variance = magnitude.variance * sin_theta * sin_theta +
real_component * real_component * angle.variance}};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add the exact equations in, especially here, to make it easier to follow?


// Complex measured value of a sensor in p.u. with a uniform variance across all phases and axes of the complex plane
// (rotationally symmetric)
template <symmetry_tag sym_type> struct UniformComplexRDV {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
template <symmetry_tag sym_type> struct UniformComplexRDV {
template <symmetry_tag sym_type> struct UnifiedComplexRandVar {

#pragma once

#include "common.hpp"
#include "three_phase_tensor.hpp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one again ...

Copy link
Contributor

@Jerry-Jinfeng-Guo Jerry-Jinfeng-Guo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No major comments, except:

  • Please rename RDV to RandVar
  • Please rename U(u)niform to U(u)nified
  • Is it possible to add additional test for the conversion back and forth? I.e., original = Convert_to_a(Convert_to_b(original))
  • I understant that most (first level) subcases are now adopting the function/struct name directly, is it desirable? I.e., PolarComplexRDV<asymmetric_t> or Polar complex random variable - asymmetric

Comment on lines +13 to +14
using std::numbers::sqrt2;
constexpr auto inv_sqrt2 = sqrt2 / 2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
using std::numbers::sqrt2;
constexpr auto inv_sqrt2 = sqrt2 / 2;
constexpr auto inv_sqrt2 = std::numbers::sqrt2 * 0.5;
constexpr auto sqrt3_2 = std::numbers::sqrt3 * 0.5;


using std::numbers::sqrt2;
constexpr auto inv_sqrt2 = sqrt2 / 2;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These folks are used often enough:

Suggested change
constexpr pi_2 = pi * 0.5;
constexpr pi_3 = pi / 3.0;
constexpr pi_4 = pi * 0.25;
constexpr pi_6 = pi_3 * 0.5;

CHECK(imag(decomposed.value()) == doctest::Approx(imag(polar.value())));
}

SUBCASE("Perpendicular phase shift") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perpendicular would be matching a rotation.

Suggested change
SUBCASE("Perpendicular phase shift") {
SUBCASE("90deg phase shift") {

@nitbharambe nitbharambe marked this pull request as draft February 20, 2025 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants