Difference between revisions of "First Page"

From Dirks Personal WiKi
m
m (Undo revision 167 by DirkMittler (talk))
Tag: Undo
Line 1: Line 1:
 
== Some Experimentation with MediaWiKi ==
 
== Some Experimentation with MediaWiKi ==
  +
 
[[Category:Programming]]
   
 
=== Basics ===
 
=== Basics ===
Line 104: Line 106:
   
 
== Notes ==
 
== Notes ==
 
: ([[Category:Programming|Programming]])
 
   
 
<references />
 
<references />

Revision as of 05:23, 2 September 2024

Some Experimentation with MediaWiKi

Basics

Eq 1:    [math]\displaystyle{ y=\pm\sqrt{1-x^{2}} }[/math]    (Equation for circle.)

Drop-Down Menu

Inter-WiKi Links

The following is a hypothetical exercise...

A cartoon centipede reads books and types on a laptop.
The Wikipede edits wikipedia:Myriapoda.

This example is supposed to show how thumbnails can be made to display by default, as well as how inter-WiKi links work.

Some of the links which follow, will not be prefixed with an obvious 'wikipedia:', but are also not of my own origin, as they will point to the English-speaking WiKiPedia.


A Real Coding Issue

The following is some reinvented (C++) code which was first suggested in 1999, to compute the reciprocal square root using a trick. It may not be helpful, because this code requires that the language implementation can already perform multiplication and subtraction in double-precision, floating-point representation, as well as to access such numbers as though they were integers. The fact that so-called 'doubles' have 11 most significant bits that state their power of 2 means that for most purposes, this sort of type-punning computes their logarithm very quickly, which, in turn, is useful to produce a first approximation of their reciprocal square root, of the form...

Eq 2:    [math]\displaystyle{ \ln\left(\frac{1}{\sqrt{x}}\right)-\frac{1}{2}\ln\left(x\right) }[/math]

Why, exactly, the constants are used as starting values, from which half the punned value of (x) is to be subtracted, is not clear to most people, including This Author. This may have more to do with the binary floating-point format than with the square root of (x). Yet, the fact that Matthew Robertson was able to derive the double-precision version [1] suggests that he knows. What's being computed more closely resembles...

Eq 3:    [math]\displaystyle{ C-\frac{1}{2}\ln\left(x\right) }[/math]

What the reader may already have noticed is, that if he or she tries to implement this with C++2020, the standard method of type-punning no longer works, or produces some type of error message from the compiler[2]... What this did for me was create a conflict, about whether I should code for the C++2017 installed on most of my boxes, or for C++2020, which I only have installed on one machine. I had the theoretical demand for code that was valid either way.

The Legacy Method

float64_t Q_rsqrt_pun(const float64_t number) noexcept {
	uint64_t *temp1 = (uint64_t *) &number;
	uint64_t temp2 = 0x5FE6EB50C7B537A9 - (*temp1 >> 1);
	float64_t *out = (float64_t *) &temp2;
	return *out;
}

Notably, this code still works on GNU-C++17 compilers, and there is no compelling reason to think that it would not work under C++2020, except for the possibility that the compiler blocks it, just because it offends some aesthetic standard. As long as the floating-point number still conforms to the IEEE 754 standard, both methods shown in this article should work.

Another reason why devs might deprecate it at some point in the future, could have to do with forms of optimization which the compilers will carry out, based on unspecified principles.

However, there is the very real fact that on certain hardware architectures, the IEEE 754 standard may no longer define how 'double' floating-point numbers are formatted, and this could be the real reason to drop such practices. In that case, neither of the code versions in this article will work.

Replacement Code for C++2017

The rest of the (working) computation applies Newton's Method 4 extra times, resulting in precision which reaches the limit of the double-precision floating-point format.

/*  Fast Inverse Square Root, using Matthew Robertson's
 * Magic Number for double-precision floating-point.
 * 
 * Implemented August 2, 2024
 * by Dirk Mittler
 * 
 */

#include <cstring>
#include <cstdint>

typedef double float64_t;

float64_t Q_rsqrt(const float64_t number) noexcept {
	const float64_t threehalfs = 1.5;
	const float64_t halfnum = 0.5 * number;
	uint64_t temp;
	float64_t y;
	static_assert(sizeof(uint64_t) == sizeof(number),
					"`double` has a weird size.");
	memcpy(&temp, &number, sizeof(float64_t));
//	temp = 0x5f3759df - (temp >> 1);	// Original 32-bit fr Quake III
	temp = 0x5FE6EB50C7B537A9 - (temp >> 1);	// Matthew Robertson's
	memcpy(&y, &temp, sizeof(float64_t));
	y *= (threehalfs - (halfnum * y * y));
	y *= (threehalfs - (halfnum * y * y));
	y *= (threehalfs - (halfnum * y * y));
	return y * (threehalfs - (halfnum * y * y));
}

Reason Such Code Was Invented

Of course, the original hack had as context that in early 3D games, texture maps were also associated with normal-maps [3] that only had 8 bits of (signed) precision per coordinate (fetched as R, G and B components of a specially-prepared texture image, at 8 bits per channel), so that even 32-bit, single-precision floating point numbers were overkill for certain parts of the rendering. The game in which this was first exploited was a Quake III Arena version that ran on early PCs, but it can still be played today on Steam [4]. And so, a real speed improvement can be achieved over accurate computations, by reducing the number of passes of Newton's Method, to 1 or even 0. In this case, precision is truly not equivalent to accuracy.

Although Quake III was surely programmed using some version of DirectX, the practice of normal-mapping is also standard with OpenGL.

In general, Normal Vectors need to be Unit Vectors, which can be derived from arbitrary vectors, such as the per-texel vectors of a normal-map, using the following equation, but requiring that a square root be divided by, which really means that the reciprocal of a square root frequently needs to be scalar-multiplied by...

Eq 4:    [math]\displaystyle{ \widehat{N}=\frac{1}{\left\Vert N\right\Vert }N,\;\left\Vert N\right\Vert =\sqrt{N_{x}^{2}+N_{y}^{2}+N_{z}^{2}} }[/math]

Notes

  1. Matthew Robertson (2012-04-24). "A Brief History of InvSqrt" X
  2. GitHub Advice. "Don't use unions or pointer casts..." X
  3. LearnOpenGL - Normal Mapping X
  4. Quake III Arena on Steam (2024-08-31). X