Thursday, September 8, 2016

Global warming as falling into the Sun

This summer in Spain has been so particularly hot that people came up with graphical jokes like this:
(Cáceres is my hometown; versions of this picture for many other Spanish populations swarm the net.) Pursuing this idea half-seriously, one can reason that an increase in global temperatures due to climate change might be journalistically equated with the Earth getting closer to the Sun and thus receiving more radiation, which analogy conjures up doomy visions of our planet falling into the blazing hell of the star: let us do the calculations.
Climate sensitivity, usually denoted by λ, links changes in global surface temperature with variations of received radiative power
ΔT = λ ΔW.
The mechanism by which radiative power changes (increased albedo, greenhouse effect) results in a different associated λ parameter. For the case of power variations due to changes in solar activity, Tung et. al have calculated λs to be in the range of 0.69 to 0.97 K/(W/m2) using data from observations of 11-year solar cycles, and estimate that the stationary sensitivity (i.e. if the change in power was permanent) would be 1.5 times higher, thus in the range of 1.03 to 1.45 K/(W/m2).
Now, the Earth is D0 = 1.496 × 108 km away from the Sun, and receives an average radiation of W0 = 1366 W/m2. Assuming far-field conditions, the radiative power received at the Earth as a function of the distance D to the Sun is then
W = w / D2,
w = 3.057 × 1025 W/sr,
which allows us to calculate ΔT = λs ΔW from ΔD = D0D, as shown in the graph for the minimum and maximum estimated values of λs. Although this cannot be checked visually, the lines are not straight but include a negligible (in these distance ranges) quadratic component.
So, the estimated increase of 0.75 °C in global temperature during the 20th century is equivalent to pushing the Earth between 30 and 40 thousand kilometers towards the Sun. Each extra °C brings us 38,000-54,000 km closer to the star. For those stuck with USCS, each °F is equivalent to 13,000-18,000 miles.
As an alarmist meme, the figure works poorly since no amount of global warming will translate to anything resembling "falling into the Sun": relative changes in distance measure in the permyriads. And, yes, the joke at the beginning of this article is definitely a gross exaggeration.

Tuesday, September 6, 2016

Compile-time checking the existence of a class template

(Updated after a suggestion from bluescarni.) I recently had to use C++14's std::is_final but wanted to downgrade to boost::is_final if the former was not available. Trusting __cplusplus implies overlooking the fact that compilers never provide 100% support for any version of the language, and  Boost.Config is usually helpful with these matters, but, as of this writing, it does not provide any macro to check for the existence of std::is_final. It turns out the matter can be investigated with some compile-time manipulations. We first set up some helping machinery in a namespace of our own:
namespace std_is_final_exists_detail{
    
template<typename> struct is_final{};

struct helper{};

}
std_is_final_exists_detail::is_final has the same signature as the (possibly existing) std::is_final homonym, but need not implement any of the functionality since it will be used for detection only. The class helper is now used to write code directly into namespace std, as the rules of the language allow (and, in some cases, encourage) us to specialize standard class templates for our own types, like for instance with std::hash:
namespace std{

template<>
struct hash<std_is_final_exists_detail::helper>
{
  std::size_t operator()(
    const std_is_final_exists_detail::helper&)const{return 0;}
      
  static constexpr bool check()
  {
    using helper=std_is_final_exists_detail::helper;
    using namespace std_is_final_exists_detail;
    
    return
      !std::is_same<
        is_final<helper>,
        std_is_final_exists_detail::is_final<helper>>::value;
  }
};

}
operator() is defined to nominally comply with the expected semantics of std::hash specialization; it is in check that the interesting work happens. By a non-obvious but totally sensible C++ rule, the directive
using namespace std_is_final_exists_detail;
makes all the symbols of the namespace (including is_final) visible as if they were declared in the nearest namespace containing both std_is_final_exists_detail and std, that is, at global namespace level. This means that the unqualified use of is_final in
!std::is_same<
  is_final<helper>,...
resolves to std::is_final if it exists (as it is within namespace std, i.e. closer than the global level), and to std_is_final_exists_detail::is_final otherwise. We can wrap everything up in a utility class:
using std_is_final_exists=std::integral_constant<
  bool,
  std::hash<std_is_final_exists_detail::helper>::check()
>;
and check with a program
#include <iostream>

int main()
{
  std::cout<<"std_is_final_exists: "
           <<std_is_final_exists::value<<"\n";
}
that dutifully ouputs
std_is_final_exists: 0
with GCC in -std=c+11 mode and
std_is_final_exists: 1
when with -std=c+14. Clang and Visual Studio also handle this code properly.
(Updated Sep 7, 2016.) The same technique can be used to walk the last mile and implement an is_final type trait class relying on std::final but falling back to boost::is_final if the former is not present. I've slightly changed naming and used std::is_void for the specialization trick as it involves a little less typing.
#include <boost/type_traits/is_final.hpp>
#include <type_traits>

namespace my_lib{
namespace is_final_fallback{

template<typename T> using is_final=boost::is_final<T>;

struct hook{};

}}

namespace std{

template<>
struct is_void<::my_lib::is_final_fallback::hook>:
  std::false_type
{      
  template<typename T>
  static constexpr bool is_final_f()
  {
    using namespace ::my_lib::is_final_fallback;
    return is_final<T>::value;
  }
};

} /* namespace std */

namespace my_lib{

template<typename T>
struct is_final:std::integral_constant<
  bool,
  std::is_void<is_final_fallback::hook>::template is_final_f<T>()
>{};

} /* namespace mylib */