4 Fold Definition

0 views
Skip to first unread message

Sebastian Thorndike

unread,
Aug 4, 2024, 7:31:50 PM8/4/24
to stafasroossa
Giveyour bowl a quarter turn and continue thusly, until the lighter mixture is almost fully incorporated. If you were folding in batches, add the second or third batch and continue folding until the batter is thick, airy, and uniform in color with no large streaks of the lighter ingredient (some small lumps or light streaks are okay; overfolding could deflate the batter).

Fold change is a measure describing how much a quantity changes between an original and a subsequent measurement. It is defined as the ratio between the two quantities; for quantities A and B the fold change of B with respect to A is B/A. In other words, a change from 30 to 60 is defined as a fold-change of 2. This is also referred to as a "one fold increase". Similarly, a change from 30 to 15 is referred to as a "0.5-fold decrease". Fold change is often used when analysing multiple measurements of a biological system taken at different times as the change described by the ratio between the time points is easier to interpret than the difference.


Fold change is so called because it is common to describe an increase of multiple X as an "X-fold increase". As such, several dictionaries, including the Oxford English Dictionary[1] and Merriam-Webster Dictionary,[2] as well as Collins's Dictionary of Mathematics, define "-fold" to mean "times", as in "2-fold" = "2 times" = "double". Likely because of this definition, many scientists use not only "fold", but also "fold change" to be synonymous with "times", as in "3-fold larger" = "3 times larger".[3][4][5]


In functional programming, fold (or reduce) is a family of higher order functions that process a data structure in some order and build a return value. This is as opposed to the family of unfold functions which take a starting value and apply it to a function to generate a data structure.


Typically, a fold deals with two things: a combining function, and a data structure, typically a list of elements. The fold then proceeds to combine elements of the data structure using the function in some systematic way. For instance, we might want to use a hypothetical function fold to write


However, in the general case, functions of two parameters are not associative, so the order in which one carries out the combination of the elements matters. On lists, there are two obvious ways to carry this out: either by recursively combining the first element with the results of combining the rest (called a right fold) or by recursively combining the results of combining all but the last element with the last one, (called a left fold). Also, in practice, it is convenient and natural to have an initial value which in the case of a right fold, is used when one reaches the end of the list, and in the case of a left fold, is what is initially combined with the first element of the list. This is perhaps clearer to see in the equations defining foldr and foldl in Haskell. Note that in Haskell, [] represents the empty list, and (x:xs) represents the list starting with x and where the rest of the list is xs.


One important thing to note in the presence of lazy, or normal-order evaluation, is that foldr will immediately return the application of f to the recursive case of folding over the rest of the list. Thus, if f is able to produce some part of its result without reference to the recursive case, and the rest of the result is never demanded, then the recursion will stop. This allows right folds to operate on infinite lists. By contrast, foldl will immediately call itself with new parameters until it reaches the end of the list. This tail recursion can be efficiently compiled as a loop, but can't deal with infinite lists at all -- it will recurse forever in an infinite loop. Another technical point to be aware of in the case of left folds in a normal-order evaluation language is that the new initial parameter is not being evaluated before the recursive call is made. This can lead to stack overflows when one reaches the end of the list and tries to evaluate the resulting gigantic expression. For this reason, such languages often provide a stricter variant of left folding which forces the evaluation of the initial parameter before making the recursive call, in Haskell, this is the foldl' (note the apostrophe) function in the Data.List library. Combined with the speed of tail recursion, such folds are very efficient when lazy evaluation of the final result is impossible or undesirable.


One often wants to choose the identity element of the operation f as the initial value z. When no initial value seems appropriate, for example, when one wants to fold the function which computes the maximum of its two parameters over a list in order to get the maximum element of the list, there are variants of foldr and foldl which use the last and first element of the list respectively as the initial value. In Haskell and several other languages, these are called foldr1 and foldl1, the 1 making reference to the automatic provision of an initial element, and the fact that the lists they are applied to must have at least one element.


These folds use type-symmetrical binary operation: the types of both its arguments, and its result, must be the same. Richard Bird in his 2010 book "Pearls of Functional Algorithm Design" (Cambridge University Press 2010, ISBN 978-0-521-51338-8, p. 42) proposes "a general fold function on non-empty lists" foldrn which transforms its last element, by applying an additional argument function to it, into a value of the result type before starting the folding itself, and is thus able to use type-asymmetrical binary operation like the regular foldr to produce a result of type different from the list's elements type.


The use of initial value is mandatory when the combining function is asymmetrical in its types, i.e. when the type of its result is different from the type of list's elements. Then an initial value must be used, with the same type as that of the function's result, for a linear chain of applications to be possible, whether left- or right-oriented.


In the case of foldi function, to avoid its runaway evaluation on indefinitely defined lists the function f must not always demand its second argument's value, at least not all of it, and/or not immediately (example below).


One way in which it is perhaps natural to view folds is as a mechanism for replacing the structural components of a data structure with other functions and values in some regular way. In many languages, lists are built up from two primitives: either the list is the empty list, commonly called nil, or it is a list constructed by appending an element to the start of some other list, which we call a cons. In Haskell, the cons operation is written as a colon (:), and in scheme and other lisps, it is called cons. One can view a right fold as replacing the nil at the end of the list with a specific value, and each cons with a specific other function. Hence, one gets a diagram which looks something like this:


These pictures do a rather nice job of motivating the names left and right fold visually. It also makes obvious the fact that foldr (:) [] is the identity function on lists, as replacing cons with cons and nil with nil will not change anything. The left fold diagram suggests an easy way to reverse a list, foldl (flip (:)) []. Note that the parameters to cons must be flipped, because the element to add is now the right hand parameter of the combining function. Another easy result to see from this vantage-point is to write the higher-order map function in terms of foldr, by composing the function to act on the elements with cons, as:


This way of looking at things provides a simple route to designing fold-like functions on other algebraic data structures, like various sorts of trees. One writes a function which recursively replaces the constructors of the datatype with provided functions, and any constant values of the type with provided values. Such functions are generally referred to as Catamorphisms.


where the function union operates on ordered lists in a local manner to efficiently produce their union, and minus their set difference, defined at Data.List.Ordered package or here at Prime numbers page.


Click 'Accept all cookies' to agree to all cookies that collect anonymous data. To only allow the cookies that make the site work, click 'Use essential cookies only.' Visit 'Set cookie preferences' to control specific cookies.


The Scottish Government Urban Rural Classification provides a consistent way of defining urban and rural areas across Scotland. The classification is based upon two main criteria: (i) population, as defined by the National Records of Scotland (NRS), and (ii) accessibility, based on drive time analysis to differentiate between accessible and remote areas in Scotland. The classification is available in multiple forms, including a 6-fold classification which distinguishes between urban, rural, and remote areas through six categories, and an 8-fold classification which further distinguishes between remote and very remote regions.


The population criteria is derived from the Settlements dataset produced by NRS, which defines areas of contiguous high density postcodes that make up a Settlement. Using the population thresholds of 125,000, 10,000 and 3,000 people, Settlements can be grouped into the following categories:


Accessibility is measured in terms of drive times to an urban area. This is done by calculating 30 and 60 minute drive times from the population weighted centroids of Settlements with a population of 10,000 or more (i.e. Large and Other Urban Areas). The results allow areas to be classified in terms of accessibility by the following categories:


By combining both the population and accessibility measures, a Scotland-wide Urban Rural Classification is defined. Categories of the 6- and 8-fold classifications are shown in Tables 2.1 and 2.2 below.

3a8082e126
Reply all
Reply to author
Forward
0 new messages