> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/itsubaki/reval/llms.txt
> Use this file to discover all available pages before exploring further.

# NDCG

> Normalized Discounted Cumulative Gain with graded relevance

NDCG (Normalized Discounted Cumulative Gain) is a ranking quality metric that handles **graded** relevance — items can be highly relevant, somewhat relevant, or not relevant at all, rather than just relevant or not. It also applies a logarithmic discount so that items ranked higher contribute more to the score than items ranked lower.

## Constants

```go theme={null}
const (
    AbsTol = 1e-08
    RelTol = 1e-05
)
```

These tolerances are used by `IsClose` and `IsZero` for floating-point comparisons throughout the library.

| Constant | Value   | Description                             |
| -------- | ------- | --------------------------------------- |
| `AbsTol` | `1e-08` | Absolute tolerance for float comparison |
| `RelTol` | `1e-05` | Relative tolerance for float comparison |

***

## `NDCG`

```go theme={null}
func NDCG(predicted []string, relevance map[string]int, k int) float64
```

Returns the Normalized Discounted Cumulative Gain at cutoff K. NDCG compares the `DCG` of the actual ranked list against the ideal `DCG` (the best possible ordering of the same items). A score of 1.0 indicates a perfect ranking; 0.0 means no relevant items were retrieved. Returns `0.0` when the ideal DCG is zero.

<ParamField path="predicted" type="[]string" required>
  The ranked list of item identifiers returned by the system, ordered from most to least relevant.
</ParamField>

<ParamField path="relevance" type="map[string]int" required>
  A map of item identifier to integer relevance grade. Higher grades indicate greater relevance. Items not present in the map are treated as grade 0.
</ParamField>

<ParamField path="k" type="int" required>
  The cutoff depth. Only the first `k` positions are evaluated.
</ParamField>

**Returns** `float64` — DCG of the predicted ranking divided by the ideal DCG, in the range \[0, 1].

### Example

```go theme={null}
func ExampleNDCG() {
	predicted := []string{"A", "B", "C", "D"}
	relevance := map[string]int{
		"A": 3,
		"B": 2,
		"C": 1,
		"D": 0,
		"E": 3,
	}

	s := reval.NDCG(predicted, relevance, 3)
	fmt.Println("NDCG@3:", s)

	// Output:
	// NDCG@3: 0.7271926019583822
}
```

<Note>
  The ideal top-3 ranking would be "A" (grade 3), "E" (grade 3), "B" (grade 2). The actual top-3 is "A" (3), "B" (2), "C" (1). The actual DCG is lower because "E" was not retrieved at rank 2, giving NDCG ≈ 0.727.
</Note>

***

## `DCG`

```go theme={null}
func DCG(relevance []int) float64
```

Computes the Discounted Cumulative Gain for a sequence of relevance grades. Grades are discounted by the logarithm of their rank position so that higher-ranked items contribute more to the total.

The formula applied at each position `i` (0-indexed) is:

```
DCG = Σ (2^rel_i - 1) / log2(i + 2)
```

<ParamField path="relevance" type="[]int" required>
  A slice of integer relevance grades in rank order. The first element is rank 1, the second is rank 2, and so on.
</ParamField>

**Returns** `float64` — the summed discounted gain across all positions.

***

## `IsClose`

```go theme={null}
func IsClose(a, b float64) bool
```

Reports whether two float64 values are approximately equal, using both absolute and relative tolerances defined by `AbsTol` and `RelTol`. The comparison uses the formula:

```
|a - b| ≤ AbsTol + RelTol × max(|a|, |b|)
```

<ParamField path="a" type="float64" required>
  The first value to compare.
</ParamField>

<ParamField path="b" type="float64" required>
  The second value to compare.
</ParamField>

**Returns** `bool` — `true` if `a` and `b` are within tolerance of each other.

***

## `IsZero`

```go theme={null}
func IsZero(a float64) bool
```

Reports whether a float64 value is approximately zero. Equivalent to calling `IsClose(a, 0.0)`.

<ParamField path="a" type="float64" required>
  The value to test.
</ParamField>

**Returns** `bool` — `true` if `a` is within tolerance of 0.0.
