| // |
| // Copyright 2019 Google LLC |
| // |
| // 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. |
| // |
| |
| #ifndef DIFFERENTIAL_PRIVACY_ALGORITHMS_BOUNDED_STANDARD_DEVIATION_H_ |
| #define DIFFERENTIAL_PRIVACY_ALGORITHMS_BOUNDED_STANDARD_DEVIATION_H_ |
| |
| #include <cmath> |
| #include <memory> |
| #include <type_traits> |
| #include <utility> |
| |
| #include <cstdint> |
| #include "absl/memory/memory.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "algorithms/algorithm.h" |
| #include "algorithms/approx-bounds.h" |
| #include "algorithms/bounded-algorithm.h" |
| #include "algorithms/bounded-variance.h" |
| #include "algorithms/numerical-mechanisms.h" |
| #include "algorithms/util.h" |
| #include "proto/util.h" |
| #include "proto/data.pb.h" |
| #include "proto/summary.pb.h" |
| #include "base/status_macros.h" |
| |
| // Bounded Stddev is deprecated in favor of using variance and taking the sqrt |
| // of the result. |
| |
| namespace differential_privacy { |
| |
| // Incrementally provides a differentially private standard deviation for values |
| // in the range [lower..upper]. Values outside of this range will be clamped so |
| // they lie in the range. The output will also be clamped between 0 and (upper - |
| // lower). |
| // |
| // The implementation simply computes the bounded variance and takes the square |
| // root, which is differentially private by the post-processing theorem. It |
| // relies on the fact that the bounded variance algorithm guarantees that the |
| // output is non-negative. |
| template <typename T> |
| class ABSL_DEPRECATED( |
| "Use BoundedVariance instead and take the sqrt of the result") |
| BoundedStandardDeviation : public Algorithm<T> { |
| static_assert( |
| std::is_arithmetic<T>::value, |
| "BoundedStandardDeviation can only be used for arithmetic types"); |
| |
| public: |
| // Builder for BoundedStandardDeviation algorithm. |
| class ABSL_DEPRECATED( |
| "Use BoundedVariance instead and take the sqrt of the result") Builder; |
| |
| void AddEntry(const T& t) override { variance_->AddEntry(t); } |
| |
| // Returns a BoundedVarianceSummary. |
| Summary Serialize() const override { return variance_->Serialize(); } |
| |
| // Merges from BoundedVarianceSummary. |
| absl::Status Merge(const Summary& summary) override { |
| return variance_->Merge(summary); |
| } |
| |
| int64_t MemoryUsed() override { |
| int64_t memory = sizeof(BoundedStandardDeviation<T>); |
| if (variance_) { |
| memory += variance_->MemoryUsed(); |
| } |
| return memory; |
| } |
| |
| double GetEpsilon() const override { return variance_->GetEpsilon(); } |
| |
| // Returns the epsilon used to calculate approximate bounds. If approximate |
| // bounds are not used, returns 0. |
| double GetBoundingEpsilon() const { return variance_->GetBoundingEpsilon(); } |
| |
| // Returns the epsilon used to calculate the noisy mean. If bounds are |
| // specified explicitly, this will be the total epsilon used by the algorithm. |
| double GetAggregationEpsilon() const { |
| return variance_->GetAggregationEpsilon(); |
| } |
| |
| private: |
| BoundedStandardDeviation(const double epsilon, |
| std::unique_ptr<BoundedVariance<T>> variance) |
| : Algorithm<T>(epsilon), variance_(std::move(variance)) {} |
| |
| absl::StatusOr<Output> GenerateResult(double noise_interval_level) override { |
| ASSIGN_OR_RETURN(Output variance_output, |
| variance_->PartialResult(noise_interval_level)); |
| double stdev = std::sqrt(GetValue<double>(variance_output)); |
| SetValue<double>(variance_output.mutable_elements(0)->mutable_value(), |
| stdev); |
| return variance_output; |
| } |
| |
| void ResetState() override { variance_->Reset(); } |
| std::unique_ptr<BoundedVariance<T>> variance_; |
| }; |
| |
| template <typename T> |
| class BoundedStandardDeviation<T>::Builder { |
| public: |
| BoundedStandardDeviation<T>::Builder& SetEpsilon(double epsilon) { |
| variance_builder_.SetEpsilon(epsilon); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetDelta(double delta) { |
| variance_builder_.SetDelta(delta); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetMaxPartitionsContributed( |
| int max_partitions_contributed) { |
| variance_builder_.SetMaxPartitionsContributed(max_partitions_contributed); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetMaxContributionsPerPartition( |
| int max_contributions_per_partition) { |
| variance_builder_.SetMaxContributionsPerPartition( |
| max_contributions_per_partition); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetUpper(T upper) { |
| variance_builder_.SetUpper(upper); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetLower(T lower) { |
| variance_builder_.SetLower(lower); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetApproxBounds( |
| std::unique_ptr<ApproxBounds<T>> approx_bounds) { |
| variance_builder_.SetApproxBounds(std::move(approx_bounds)); |
| return *this; |
| } |
| |
| BoundedStandardDeviation<T>::Builder& SetLaplaceMechanism( |
| std::unique_ptr<NumericalMechanismBuilder> builder) { |
| variance_builder_.SetLaplaceMechanism(std::move(builder)); |
| return *this; |
| } |
| |
| absl::StatusOr<std::unique_ptr<BoundedStandardDeviation<T>>> Build() { |
| ASSIGN_OR_RETURN(std::unique_ptr<BoundedVariance<T>> variance, |
| variance_builder_.Build()); |
| const double epsilon = variance->GetEpsilon(); |
| return absl::WrapUnique( |
| new BoundedStandardDeviation(epsilon, std::move(variance))); |
| } |
| |
| private: |
| typename BoundedVariance<T>::Builder variance_builder_; |
| }; |
| |
| } // namespace differential_privacy |
| |
| #endif // DIFFERENTIAL_PRIVACY_ALGORITHMS_BOUNDED_STANDARD_DEVIATION_H_ |