# CosineSimilarity

Calculates the cosine similarity between two embedding vectors. Returns a value between -1 (opposite) and 1 (identical).

## Signature

```go
func CosineSimilarity(a, b []float64) (float64, error)
```

## Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| a | []float64 | First embedding vector |
| b | []float64 | Second embedding vector |

## Return Value

Returns a float64 between -1 and 1:
- 1.0: Vectors are identical
- 0.0: Vectors are orthogonal (no similarity)
- -1.0: Vectors are opposite

### Zero and empty vectors

A zero vector (all-zero components) or an empty (`len == 0`) vector on either
side returns `(0, nil)` — not an error — matching the TypeScript AI SDK. Only
a length mismatch between `a` and `b` returns an error, a typed
`*errors.InvalidArgumentError` with message
`"Vectors must have the same length (vector1Length=…, vector2Length=…)"`.

## Examples

### Basic Similarity Calculation

```go
package main

import (
    "context"
    "fmt"
    "log"

    "github.com/digitallysavvy/go-ai/pkg/ai"
    "github.com/digitallysavvy/go-ai/pkg/providers/openai"
)

func main() {
    provider := openai.New(openai.Config{
        APIKey: "your-api-key",
    })
    model, _ := provider.EmbeddingModel("text-embedding-3-small")

    // Embed two texts
    result1, _ := ai.Embed(context.Background(), ai.EmbedOptions{
        Model: model,
        Input: "machine learning",
    })

    result2, _ := ai.Embed(context.Background(), ai.EmbedOptions{
        Model: model,
        Input: "artificial intelligence",
    })

    // Calculate similarity
    similarity, err := ai.CosineSimilarity(result1.Embedding, result2.Embedding)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Similarity: %.4f\n", similarity)
}
```

### Semantic Search

```go
// Query embedding
queryResult, _ := ai.Embed(ctx, ai.EmbedOptions{
    Model: model,
    Input: "neural networks",
})

// Document embeddings
documents := []string{
    "Deep learning uses neural networks",
    "The weather is sunny today",
    "Artificial neural networks are computational models",
}

// Find most similar
var bestMatch string
var bestScore float64

for _, doc := range documents {
    docResult, _ := ai.Embed(ctx, ai.EmbedOptions{
        Model: model,
        Input: doc,
    })

    similarity, _ := ai.CosineSimilarity(queryResult.Embedding, docResult.Embedding)

    if similarity > bestScore {
        bestScore = similarity
        bestMatch = doc
    }
}

fmt.Printf("Best match (%.4f): %s\n", bestScore, bestMatch)
```

### Similarity Threshold

```go
similarity, err := ai.CosineSimilarity(embedding1, embedding2)
if err != nil {
    log.Fatal(err)
}

switch {
case similarity > 0.9:
    fmt.Println("Highly similar")
case similarity > 0.7:
    fmt.Println("Moderately similar")
case similarity > 0.5:
    fmt.Println("Somewhat similar")
default:
    fmt.Println("Not similar")
}
```

### Pairwise Similarity Matrix

```go
embeddings := [][]float64{
    embedding1,
    embedding2,
    embedding3,
}

fmt.Println("Similarity Matrix:")
for i := 0; i < len(embeddings); i++ {
    for j := 0; j < len(embeddings); j++ {
        sim, _ := ai.CosineSimilarity(embeddings[i], embeddings[j])
        fmt.Printf("%.3f ", sim)
    }
    fmt.Println()
}
```

## Error Handling

`CosineSimilarity` only returns an error for a length mismatch; a zero or
empty vector is not an error condition.

```go
similarity, err := ai.CosineSimilarity(a, b)
if err != nil {
    var invalidArg *providererrors.InvalidArgumentError
    if errors.As(err, &invalidArg) {
        log.Printf("Dimension mismatch: %v", invalidArg)
    } else {
        log.Println("Unknown error:", err)
    }
    return
}
// similarity is 0 (not an error) if either vector is all-zero or empty.
```

## See Also

- [Embed](https://goaisdk.com/docs/reference/ai/embed.md) - Generate embeddings
- [EmbedMany](https://goaisdk.com/docs/reference/ai/embed-many.md) - Batch embeddings
- EuclideanDistance - Alternative distance metric
- DotProduct - Dot product similarity
- [RAG Guide](https://goaisdk.com/docs/ai-sdk-core/embeddings.md)
