# [Serialization](#Serialization)
Provides serialization of Julia objects.
```julia
serialize(stream::IO, value)
```
Write an arbitrary value to a stream in an opaque format, such that it can be read back by [`deserialize`](#Serialization.deserialize). The read-back value will be as identical as possible to the original, but note that `Ptr` values are serialized as all-zero bit patterns (`NULL`).
An 8-byte identifying header is written to the stream first. To avoid writing the header, construct a `Serializer` and use it as the first argument to `serialize` instead. See also [`Serialization.writeheader`](#Serialization.writeheader).
The data format can change in minor (1.x) Julia releases, but files written by prior 1.x versions will remain readable. The main exception to this is when the definition of a type in an external package changes. If that occurs, it may be necessary to specify an explicit compatible version of the affected package in your environment. Renaming functions, even private functions, inside packages can also put existing files out of sync. Anonymous functions require special care: because their names are automatically generated, minor code changes can cause them to be renamed. Serializing anonymous functions should be avoided in files intended for long-term storage.
In some cases, the word size (32- or 64-bit) of the reading and writing machines must match. In rarer cases the OS or architecture must also match, for example when using packages that contain platform-dependent code.
```julia
serialize(filename::AbstractString, value)
```


# [Serialization](#Serialization)
Open a file and serialize the given value to it.
This method is available as of Julia 1.1.
```julia
deserialize(stream)
```
Read a value written by [`serialize`](#Serialization.serialize). `deserialize` assumes the binary data read from `stream` is correct and has been serialized by a compatible implementation of [`serialize`](#Serialization.serialize). `deserialize` is designed for simplicity and performance, and so does not validate the data read. Malformed data can result in process termination. The caller must ensure the integrity and correctness of data read from `stream`.
```julia
deserialize(filename::AbstractString)
```
Open a file and deserialize its contents.
This method is available as of Julia 1.1.
```julia
Serialization.writeheader(s::AbstractSerializer)
```
Write an identifying header to the specified serializer. The header consists of 8 bytes as follows:
| Offset | Description                                |
|:-------|:-------------------------------------------|
| 0      | tag byte (0x37)                            |
| 1-2    | signature bytes "JL"                       |
| 3      | protocol version                           |
| 4      | bits 0-1: endianness: 0 = little, 1 = big  |
| 4      | bits 2-3: platform: 0 = 32-bit, 1 = 64-bit |
| 5-7    | reserved                                   |
------------------------------------------------------------------------


# Shared Arrays · The Julia Language
Source: https://docs.julialang.org/en/v1/stdlib/SharedArrays/


# [Shared Arrays](#Shared-Arrays)
`SharedArray` represents an array, which is shared across multiple processes, on a single machine.
```julia
SharedArray{T}(dims::NTuple; init=false, pids=Int[])
SharedArray{T,N}(...)
```
Construct a `SharedArray` of a bits type `T` and size `dims` across the processes specified by `pids` - all of which have to be on the same host. If `N` is specified by calling `SharedArray{T,N}(dims)`, then `N` must match the length of `dims`.
If `pids` is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, `localindices` and `indexpids` will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.
If an `init` function of the type `initfn(S::SharedArray)` is specified, it is called on all the participating workers.
The shared array is valid as long as a reference to the `SharedArray` object exists on the node which created the mapping.
```julia
SharedArray{T}(filename::AbstractString, dims::NTuple, [offset=0]; mode=nothing, init=false, pids=Int[])
SharedArray{T,N}(...)
```
Construct a `SharedArray` backed by the file `filename`, with element type `T` (must be a bits type) and size `dims`, across the processes specified by `pids` - all of which have to be on the same host. This file is mmapped into the host memory, with the following consequences:
-   The array data must be represented in binary format (e.g., an ASCII format like CSV cannot be supported)


# [Shared Arrays](#Shared-Arrays)
-   Any changes you make to the array values (e.g., `A[3] = 0`) will also change the values on disk
If `pids` is left unspecified, the shared array will be mapped across all processes on the current host, including the master. But, `localindices` and `indexpids` will only refer to worker processes. This facilitates work distribution code to use workers for actual computation with the master process acting as a driver.
`mode` must be one of `"r"`, `"r+"`, `"w+"`, or `"a+"`, and defaults to `"r+"` if the file specified by `filename` already exists, or `"w+"` if not. If an `init` function of the type `initfn(S::SharedArray)` is specified, it is called on all the participating workers. You cannot specify an `init` function if the file is not writable.
`offset` allows you to skip the specified number of bytes at the beginning of the file.
```julia
SharedVector
```
A one-dimensional [`SharedArray`](#SharedArrays.SharedArray).
```julia
SharedMatrix
```
A two-dimensional [`SharedArray`](#SharedArrays.SharedArray).
```julia
procs(S::SharedArray)
```
Get the vector of processes mapping the shared array.
```julia
sdata(S::SharedArray)
```
Return the actual `Array` object backing `S`.
```julia
indexpids(S::SharedArray)
```
Return the current worker's index in the list of workers mapping the `SharedArray` (i.e. in the same list returned by `procs(S)`), or 0 if the `SharedArray` is not mapped locally.
```julia
localindices(S::SharedArray)
```


# [Shared Arrays](#Shared-Arrays)
Return a range describing the "default" indices to be handled by the current process. This range should be interpreted in the sense of linear indexing, i.e., as a sub-range of `1:length(S)`. In multi-process contexts, returns an empty range in the parent process (or any process for which [`indexpids`](#SharedArrays.indexpids) returns 0).
It's worth emphasizing that `localindices` exists purely as a convenience, and you can partition work on the array among workers any way you wish. For a `SharedArray`, all indices should be equally fast for each worker process.
------------------------------------------------------------------------


# Sockets · The Julia Language
Source: https://docs.julialang.org/en/v1/stdlib/Sockets/


# [Sockets](#Sockets)
Support for sockets. Provides [`IPAddr`](#Sockets.IPAddr) and subtypes, [`TCPSocket`](#Sockets.TCPSocket), and [`UDPSocket`](#Sockets.UDPSocket).
```julia
connect([host], port::Integer) -> TCPSocket
```
Connect to the host `host` on port `port`.
```julia
connect(path::AbstractString) -> PipeEndpoint
```
Connect to the named pipe / UNIX domain socket at `path`.
Path length on Unix is limited to somewhere between 92 and 108 bytes (cf. `man unix`).
```julia
listen([addr, ]port::Integer; backlog::Integer=BACKLOG_DEFAULT) -> TCPServer
```
Listen on port on the address specified by `addr`. By default this listens on `localhost` only. To listen on all interfaces pass `IPv4(0)` or `IPv6(0)` as appropriate. `backlog` determines how many connections can be pending (not having called [`accept`](#Sockets.accept)) before the server will begin to reject them. The default value of `backlog` is 511.
```julia
listen(path::AbstractString) -> PipeServer
```
Create and listen on a named pipe / UNIX domain socket.
Path length on Unix is limited to somewhere between 92 and 108 bytes (cf. `man unix`).
```julia
getaddrinfo(host::AbstractString, IPAddr) -> IPAddr
```
Gets the first IP address of the `host` of the specified `IPAddr` type. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.
**Examples**
```julia-repl
julia> getaddrinfo("localhost", IPv6)
ip"::1"

julia> getaddrinfo("localhost", IPv4)
ip"127.0.0.1"
```
```julia
getaddrinfo(host::AbstractString) -> IPAddr
```


# [Sockets](#Sockets)
Gets the first available IP address of `host`, which may be either an `IPv4` or `IPv6` address. Uses the operating system's underlying getaddrinfo implementation, which may do a DNS lookup.
```julia
getipaddr() -> IPAddr
```
Get an IP address of the local machine, preferring IPv4 over IPv6. Throws if no addresses are available.
```julia
getipaddr(addr_type::Type{T}) where T<:IPAddr -> T
```
Get an IP address of the local machine of the specified type. Throws if no addresses of the specified type are available.
This function is a backwards-compatibility wrapper around [`getipaddrs`](#Sockets.getipaddrs). New applications should use [`getipaddrs`](#Sockets.getipaddrs) instead.
**Examples**
```julia-repl
julia> getipaddr()
ip"192.168.1.28"

julia> getipaddr(IPv6)
ip"fe80::9731:35af:e1c5:6e49"
```
See also [`getipaddrs`](#Sockets.getipaddrs).
```julia
getipaddrs(addr_type::Type{T}=IPAddr; loopback::Bool=false) where T<:IPAddr -> Vector{T}
```
Get the IP addresses of the local machine.
Setting the optional `addr_type` parameter to `IPv4` or `IPv6` causes only addresses of that type to be returned.
The `loopback` keyword argument dictates whether loopback addresses (e.g. `ip"127.0.0.1"`, `ip"::1"`) are included.
This function is available as of Julia 1.2.
**Examples**


# [Sockets](#Sockets)
```julia-repl
julia> getipaddrs()
5-element Array{IPAddr,1}:
 ip"198.51.100.17"
 ip"203.0.113.2"
 ip"2001:db8:8:4:445e:5fff:fe5d:5500"
 ip"2001:db8:8:4:c164:402e:7e3c:3668"
 ip"fe80::445e:5fff:fe5d:5500"

julia> getipaddrs(IPv6)
3-element Array{IPv6,1}:
 ip"2001:db8:8:4:445e:5fff:fe5d:5500"
 ip"2001:db8:8:4:c164:402e:7e3c:3668"
 ip"fe80::445e:5fff:fe5d:5500"
```
See also [`islinklocaladdr`](#Sockets.islinklocaladdr).
```julia
islinklocaladdr(addr::IPAddr)
```
Tests if an IP address is a link-local address. Link-local addresses are not guaranteed to be unique beyond their network segment, therefore routers do not forward them. Link-local addresses are from the address blocks `169.254.0.0/16` or `fe80::/10`.
**Examples**
```julia
filter(!islinklocaladdr, getipaddrs())
```
```julia
getalladdrinfo(host::AbstractString) -> Vector{IPAddr}
```
Gets all of the IP addresses of the `host`. Uses the operating system's underlying `getaddrinfo` implementation, which may do a DNS lookup.
**Examples**
```julia-repl
julia> getalladdrinfo("google.com")
2-element Array{IPAddr,1}:
 ip"172.217.6.174"
 ip"2607:f8b0:4000:804::200e"
```
```julia
DNSError
```
The type of exception thrown when an error occurs in DNS lookup. The `host` field indicates the host URL string. The `code` field indicates the error code based on libuv.
```julia
getnameinfo(host::IPAddr) -> String
```
Performs a reverse-lookup for IP address to return a hostname and service using the operating system's underlying `getnameinfo` implementation.
**Examples**


# [Sockets](#Sockets)
```julia-repl
julia> getnameinfo(IPv4("8.8.8.8"))
"google-public-dns-a.google.com"
```
```julia
getsockname(sock::Union{TCPServer, TCPSocket}) -> (IPAddr, UInt16)
```
Get the IP address and port that the given socket is bound to.
```julia
getpeername(sock::TCPSocket) -> (IPAddr, UInt16)
```
Get the IP address and port of the remote endpoint that the given socket is connected to. Valid only for connected TCP sockets.
```julia
IPAddr
```
Abstract supertype for IP addresses. [`IPv4`](#Sockets.IPv4) and [`IPv6`](#Sockets.IPv6) are subtypes of this.
```julia
IPv4(host::Integer) -> IPv4
```
Return an IPv4 object from IP address `host` formatted as an [`Integer`](../../base/numbers/#Core.Integer).
**Examples**
```julia-repl
julia> IPv4(3223256218)
ip"192.30.252.154"
```
```julia
IPv4(str::AbstractString) -> IPv4
```
Parse an IPv4 address string into an `IPv4` object.
**Examples**
```julia-repl
julia> IPv4("127.0.0.1")
ip"127.0.0.1"
```
```julia
IPv6(host::Integer) -> IPv6
```
Return an IPv6 object from IP address `host` formatted as an [`Integer`](../../base/numbers/#Core.Integer).
**Examples**
```julia-repl
julia> IPv6(3223256218)
ip"::c01e:fc9a"
```
```julia
IPv6(str::AbstractString) -> IPv6
```
Parse an IPv6 address string into an `IPv6` object.
**Examples**
```julia-repl
julia> IPv6("::1")
ip"::1"
```
```julia
@ip_str str -> IPAddr
```
Parse `str` as an IP address.
**Examples**
```julia-repl
julia> ip"127.0.0.1"
ip"127.0.0.1"

julia> @ip_str "2001:db8:0:0:0:0:2:1"
ip"2001:db8::2:1"
```
```julia
TCPSocket(; delay=true)
```


# [Sockets](#Sockets)
Open a TCP socket using libuv. If `delay` is true, libuv delays creation of the socket's file descriptor till the first [`bind`](#Base.bind) call. `TCPSocket` has various fields to denote the state of the socket as well as its send/receive buffers.
```julia
UDPSocket()
```
Open a UDP socket using libuv. `UDPSocket` has various fields to denote the state of the socket.
```julia
accept(server[, client])
```
Accepts a connection on the given server and returns a connection to the client. An uninitialized client stream may be provided, in which case it will be used instead of creating a new stream.
```julia
listenany([host::IPAddr,] port_hint; backlog::Integer=BACKLOG_DEFAULT) -> (UInt16, TCPServer)
```
Create a `TCPServer` on any port, using hint as a starting point. Returns a tuple of the actual port that the server was created on and the server itself. The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow.
```julia
bind(socket::Union{TCPServer, UDPSocket, TCPSocket}, host::IPAddr, port::Integer; ipv6only=false, reuseaddr=false, kws...)
```
Bind `socket` to the given `host:port`. Note that `0.0.0.0` will listen on all devices.
-   The `ipv6only` parameter disables dual stack mode. If `ipv6only=true`, only an IPv6 stack is created.
-   If `reuseaddr=true`, multiple threads or processes can bind to the same address without error if they all set `reuseaddr=true`, but only the last to bind will receive any traffic.
```julia
bind(chnl::Channel, task::Task)
```


# [Sockets](#Sockets)
Associate the lifetime of `chnl` with a task. `Channel` `chnl` is automatically closed when the task terminates. Any uncaught exception in the task is propagated to all waiters on `chnl`.
The `chnl` object can be explicitly closed independent of task termination. Terminating tasks have no effect on already closed `Channel` objects.
When a channel is bound to multiple tasks, the first task to terminate will close the channel. When multiple channels are bound to the same task, termination of the task will close all of the bound channels.
**Examples**
```julia-repl
julia> c = Channel(0);

julia> task = @async foreach(i->put!(c, i), 1:4);

julia> bind(c,task);

julia> for i in c
           @show i
       end;
i = 1
i = 2
i = 3
i = 4

julia> isopen(c)
false
```
```julia-repl
julia> c = Channel(0);

julia> task = @async (put!(c, 1); error("foo"));

julia> bind(c, task);

julia> take!(c)
1

julia> put!(c, 1);
ERROR: TaskFailedException
Stacktrace:
[...]
    nested task error: foo
[...]
```
[source](https://github.com/JuliaLang/julia/blob/9615af0f269df4d371b8010e9507ed5bae86103b/base/channels.jl#L237-L288)
```julia
send(socket::UDPSocket, host::IPAddr, port::Integer, msg)
```
Send `msg` over `socket` to `host:port`.
```julia
recv(socket::UDPSocket)
```
Read a UDP packet from the specified socket, and return the bytes received. This call blocks.
```julia
recvfrom(socket::UDPSocket) -> (host_port, data)
```


# [Sockets](#Sockets)
Read a UDP packet from the specified socket, returning a tuple of `(host_port, data)`, where `host_port` will be an InetAddr{IPv4} or InetAddr{IPv6}, as appropriate.
Prior to Julia version 1.3, the first returned value was an address (`IPAddr`). In version 1.3 it was changed to an `InetAddr`.
```julia
setopt(sock::UDPSocket; multicast_loop=nothing, multicast_ttl=nothing, enable_broadcast=nothing, ttl=nothing)
```
Set UDP socket options.
-   `multicast_loop`: loopback for multicast packets (default: `true`).
-   `multicast_ttl`: TTL for multicast packets (default: `nothing`).
-   `enable_broadcast`: flag must be set to `true` if socket will be used for broadcast messages, or else the UDP system will return an access error (default: `false`).
-   `ttl`: Time-to-live of packets sent on the socket (default: `nothing`).
```julia
nagle(socket::Union{TCPServer, TCPSocket}, enable::Bool)
```
Nagle's algorithm batches multiple small TCP packets into larger ones. This can improve throughput but worsen latency. Nagle's algorithm is enabled by default. This function sets whether Nagle's algorithm is active on a given TCP server or socket. The opposite option is called `TCP_NODELAY` in other languages.
This function requires Julia 1.3 or later.
```julia
quickack(socket::Union{TCPServer, TCPSocket}, enable::Bool)
```
On Linux systems, the TCP_QUICKACK is disabled or enabled on `socket`.
------------------------------------------------------------------------


# Sparse Arrays · The Julia Language
Source: https://docs.julialang.org/en/v1/stdlib/SparseArrays/


# [Sparse Arrays](#Sparse-Arrays)
Julia has support for sparse vectors and [sparse matrices](https://en.wikipedia.org/wiki/Sparse_matrix) in the `SparseArrays` stdlib module. Sparse arrays are arrays that contain enough zeros that storing them in a special data structure leads to savings in space and execution time, compared to dense arrays.
External packages which implement different sparse storage types, multidimensional sparse arrays, and more can be found in [Noteworthy External Sparse Packages](#Noteworthy-External-Sparse-Packages)


## [Compressed Sparse Column (CSC) Sparse Matrix Storage](#man-csc)
In Julia, sparse matrices are stored in the [Compressed Sparse Column (CSC) format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_column_.28CSC_or_CCS.29). Julia sparse matrices have the type [`SparseMatrixCSC{Tv,Ti}`](#SparseArrays.SparseMatrixCSC), where `Tv` is the type of the stored values, and `Ti` is the integer type for storing column pointers and row indices. The internal representation of `SparseMatrixCSC` is as follows:
```julia
struct SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
    m::Int                  # Number of rows
    n::Int                  # Number of columns
    colptr::Vector{Ti}      # Column j is in colptr[j]:(colptr[j+1]-1)
    rowval::Vector{Ti}      # Row indices of stored values
    nzval::Vector{Tv}       # Stored values, typically nonzeros
end
```
The compressed sparse column storage makes it easy and quick to access the elements in the column of a sparse matrix, whereas accessing the sparse matrix by rows is considerably slower. Operations such as insertion of previously unstored entries one at a time in the CSC structure tend to be slow. This is because all elements of the sparse matrix that are beyond the point of insertion have to be moved one place over.
All operations on sparse matrices are carefully implemented to exploit the CSC data structure for performance, and to avoid expensive operations.


## [Compressed Sparse Column (CSC) Sparse Matrix Storage](#man-csc)
If you have data in CSC format from a different application or library, and wish to import it in Julia, make sure that you use 1-based indexing. The row indices in every column need to be sorted, and if they are not, the matrix will display incorrectly. If your `SparseMatrixCSC` object contains unsorted row indices, one quick way to sort them is by doing a double transpose. Since the transpose operation is lazy, make a copy to materialize each transpose.
In some applications, it is convenient to store explicit zero values in a `SparseMatrixCSC`. These *are* accepted by functions in `Base` (but there is no guarantee that they will be preserved in mutating operations). Such explicitly stored zeros are treated as structural nonzeros by many routines. The [`nnz`](#SparseArrays.nnz) function returns the number of elements explicitly stored in the sparse data structure, including non-structural zeros. In order to count the exact number of numerical nonzeros, use [`count(!iszero, x)`](../../base/collections/#Base.count), which inspects every stored element of a sparse matrix. [`dropzeros`](#SparseArrays.dropzeros), and the in-place [`dropzeros!`](#SparseArrays.dropzeros!), can be used to remove stored zeros from the sparse matrix.
```julia-repl
julia> A = sparse([1, 1, 2, 3], [1, 3, 2, 3], [0, 1, 2, 0])
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
 0  ⋅  1
 ⋅  2  ⋅
 ⋅  ⋅  0

julia> dropzeros(A)
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
 ⋅  ⋅  1
 ⋅  2  ⋅
 ⋅  ⋅  ⋅
```


## [Sparse Vector Storage](#Sparse-Vector-Storage)
Sparse vectors are stored in a close analog to compressed sparse column format for sparse matrices. In Julia, sparse vectors have the type [`SparseVector{Tv,Ti}`](#SparseArrays.SparseVector) where `Tv` is the type of the stored values and `Ti` the integer type for the indices. The internal representation is as follows:
```julia
struct SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
    n::Int              # Length of the sparse vector
    nzind::Vector{Ti}   # Indices of stored values
    nzval::Vector{Tv}   # Stored values, typically nonzeros
end
```
As for [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC), the `SparseVector` type can also contain explicitly stored zeros. (See [Sparse Matrix Storage](#man-csc).).


## [Sparse Vector and Matrix Constructors](#Sparse-Vector-and-Matrix-Constructors)
The simplest way to create a sparse array is to use a function equivalent to the [`zeros`](../../base/arrays/#Base.zeros) function that Julia provides for working with dense arrays. To produce a sparse array instead, you can use the same name with an `sp` prefix:
```julia-repl
julia> spzeros(3)
3-element SparseVector{Float64, Int64} with 0 stored entries
```
The [`sparse`](#SparseArrays.sparse) function is often a handy way to construct sparse arrays. For example, to construct a sparse matrix we can input a vector `I` of row indices, a vector `J` of column indices, and a vector `V` of stored values (this is also known as the [COO (coordinate) format](https://en.wikipedia.org/wiki/Sparse_matrix#Coordinate_list_.28COO.29)). `sparse(I,J,V)` then constructs a sparse matrix such that `S[I[k], J[k]] = V[k]`. The equivalent sparse vector constructor is [`sparsevec`](#SparseArrays.sparsevec), which takes the (row) index vector `I` and the vector `V` with the stored values and constructs a sparse vector `R` such that `R[I[k]] = V[k]`.
```julia-repl
julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];

julia> S = sparse(I,J,V)
5×18 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
⎡⠀⠈⠀⠀⠀⠀⠀⠀⢀⎤
⎣⠀⠀⠀⠂⡀⠀⠀⠀⠀⎦

julia> R = sparsevec(I,V)
5-element SparseVector{Int64, Int64} with 4 stored entries:
  [1]  =  1
  [3]  =  -5
  [4]  =  2
  [5]  =  3
```


## [Sparse Vector and Matrix Constructors](#Sparse-Vector-and-Matrix-Constructors)
The inverse of the [`sparse`](#SparseArrays.sparse) and [`sparsevec`](#SparseArrays.sparsevec) functions is [`findnz`](#SparseArrays.findnz), which retrieves the inputs used to create the sparse array (including stored entries equal to zero). [`findall(!iszero, x)`](../../base/arrays/#Base.findall-Tuple%7BAny%7D) returns the Cartesian indices of non-zero entries in `x` (not including stored entries equal to zero).
```julia-repl
julia> findnz(S)
([1, 4, 5, 3], [4, 7, 9, 18], [1, 2, 3, -5])

julia> findall(!iszero, S)
4-element Vector{CartesianIndex{2}}:
 CartesianIndex(1, 4)
 CartesianIndex(4, 7)
 CartesianIndex(5, 9)
 CartesianIndex(3, 18)

julia> findnz(R)
([1, 3, 4, 5], [1, -5, 2, 3])

julia> findall(!iszero, R)
4-element Vector{Int64}:
 1
 3
 4
 5
```
Another way to create a sparse array is to convert a dense array into a sparse array using the [`sparse`](#SparseArrays.sparse) function:
```julia-repl
julia> sparse(Matrix(1.0I, 5, 5))
5×5 SparseMatrixCSC{Float64, Int64} with 5 stored entries:
 1.0   ⋅    ⋅    ⋅    ⋅
  ⋅   1.0   ⋅    ⋅    ⋅
  ⋅    ⋅   1.0   ⋅    ⋅
  ⋅    ⋅    ⋅   1.0   ⋅
  ⋅    ⋅    ⋅    ⋅   1.0

julia> sparse([1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 2 stored entries:
  [1]  =  1.0
  [3]  =  1.0
```
You can go in the other direction using the [`Array`](../../base/arrays/#Core.Array) constructor. The [`issparse`](#SparseArrays.issparse) function can be used to query if a matrix is sparse.
```julia-repl
julia> issparse(spzeros(5))
true
```


## [Sparse matrix operations](#Sparse-matrix-operations)
Arithmetic operations on sparse matrices also work as they do on dense matrices. Indexing of, assignment into, and concatenation of sparse matrices work in the same way as dense matrices. Indexing operations, especially assignment, are expensive, when carried out one element at a time. In many cases it may be better to convert the sparse matrix into `(I,J,V)` format using [`findnz`](#SparseArrays.findnz), manipulate the values or the structure in the dense vectors `(I,J,V)`, and then reconstruct the sparse matrix.


## [Correspondence of dense and sparse methods](#Correspondence-of-dense-and-sparse-methods)
The following table gives a correspondence between built-in methods on sparse matrices and their corresponding methods on dense matrix types. In general, methods that generate sparse matrices differ from their dense counterparts in that the resulting matrix follows the same sparsity pattern as a given sparse matrix `S`, or that the resulting sparse matrix has density `d`, i.e. each matrix element has a probability `d` of being non-zero.
Details can be found in the [Sparse Vectors and Matrices](#stdlib-sparse-arrays) section of the standard library reference.


## [Correspondence of dense and sparse methods](#Correspondence-of-dense-and-sparse-methods)
| Sparse                                        | Dense                                             | Description                                                                                |
|:----------------------------------------------|:--------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------|
| [`spzeros(m,n)`](#SparseArrays.spzeros)       | [`zeros(m,n)`](../../base/arrays/#Base.zeros)     | Creates a *m*-by-*n* matrix of zeros. ([`spzeros(m,n)`](#SparseArrays.spzeros) is empty.)                                                            |
| [`sparse(I,n,n)`](#SparseArrays.sparse)       | [`Matrix(I,n,n)`](../../base/arrays/#Base.Matrix) | Creates a *n*-by-*n* identity matrix.                                                                                |
| [`sparse(A)`](#SparseArrays.sparse)           | [`Array(S)`](../../base/arrays/#Core.Array)       | Interconverts between dense and sparse formats.                                                                                |
| [`sprand(m,n,d)`](#SparseArrays.sprand)       | [`rand(m,n)`](../Random/#Base.rand)               | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed uniformly on the half-open interval $\[0, 1)$.            |
| [`sprandn(m,n,d)`](#SparseArrays.sprandn)     | [`randn(m,n)`](../Random/#Base.randn)             | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements distributed according to the standard normal (Gaussian) distribution. |
| [`sprandn(rng,m,n,d)`](#SparseArrays.sprandn) | [`randn(rng,m,n)`](../Random/#Base.randn)         | Creates a *m*-by-*n* random matrix (of density *d*) with iid non-zero elements generated with the `rng` random number generator                      |


## [Sparse Linear Algebra](#stdlib-sparse-linalg)
Sparse matrix solvers call functions from [SuiteSparse](http://suitesparse.com). The following factorizations are available:
| Type                | Description                      |
|:--------------------|:---------------------------------|
| `CHOLMOD.Factor`    | Cholesky and LDLt factorizations |
| `UMFPACK.UmfpackLU` | LU factorization                 |
| `SPQR.QRSparse`     | QR factorization                 |
These factorizations are described in more detail in the [Sparse Linear Algebra API section](#stdlib-sparse-linalg-api):
1.  [`cholesky`](../LinearAlgebra/#LinearAlgebra.cholesky)
2.  [`ldlt`](../LinearAlgebra/#LinearAlgebra.ldlt)
3.  [`lu`](../LinearAlgebra/#LinearAlgebra.lu)
4.  [`qr`](../LinearAlgebra/#LinearAlgebra.qr)


# [SparseArrays API](#stdlib-sparse-arrays)
```julia
AbstractSparseArray{Tv,Ti,N}
```
Supertype for `N`-dimensional sparse arrays (or array-like types) with elements of type `Tv` and index type `Ti`. [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC), [`SparseVector`](#SparseArrays.SparseVector) and `SuiteSparse.CHOLMOD.Sparse` are subtypes of this.
```julia
AbstractSparseVector{Tv,Ti}
```
Supertype for one-dimensional sparse arrays (or array-like types) with elements of type `Tv` and index type `Ti`. Alias for `AbstractSparseArray{Tv,Ti,1}`.
```julia
AbstractSparseMatrix{Tv,Ti}
```
Supertype for two-dimensional sparse arrays (or array-like types) with elements of type `Tv` and index type `Ti`. Alias for `AbstractSparseArray{Tv,Ti,2}`.
```julia
SparseVector{Tv,Ti<:Integer} <: AbstractSparseVector{Tv,Ti}
```
Vector type for storing sparse vectors. Can be created by passing the length of the vector, a *sorted* vector of non-zero indices, and a vector of non-zero values.
For instance, the vector `[5, 6, 0, 7]` can be represented as
```julia
SparseVector(4, [1, 2, 4], [5, 6, 7])
```
This indicates that the element at index 1 is 5, at index 2 is 6, at index 3 is `zero(Int)`, and at index 4 is 7.
It may be more convenient to create sparse vectors directly from dense vectors using `sparse` as
```julia
sparse([5, 6, 0, 7])
```
yields the same sparse vector.
```julia
SparseMatrixCSC{Tv,Ti<:Integer} <: AbstractSparseMatrixCSC{Tv,Ti}
```


# [SparseArrays API](#stdlib-sparse-arrays)
Matrix type for storing sparse matrices in the [Compressed Sparse Column](#man-csc) format. The standard way of constructing SparseMatrixCSC is through the [`sparse`](#SparseArrays.sparse) function. See also [`spzeros`](#SparseArrays.spzeros), [`spdiagm`](#SparseArrays.spdiagm) and [`sprand`](#SparseArrays.sprand).
```julia
sparse(A)
```
Convert an AbstractMatrix `A` into a sparse matrix.
**Examples**
```julia-repl
julia> A = Matrix(1.0I, 3, 3)
3×3 Matrix{Float64}:
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

julia> sparse(A)
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 1.0   ⋅    ⋅
  ⋅   1.0   ⋅
  ⋅    ⋅   1.0
```
```julia
sparse(I, J, V,[ m, n, combine])
```
Create a sparse matrix `S` of dimensions `m x n` such that `S[I[k], J[k]] = V[k]`. The `combine` function is used to combine duplicates. If `m` and `n` are not specified, they are set to `maximum(I)` and `maximum(J)` respectively. If the `combine` function is not supplied, `combine` defaults to `+` unless the elements of `V` are Booleans in which case `combine` defaults to `|`. All elements of `I` must satisfy `1 <= I[k] <= m`, and all elements of `J` must satisfy `1 <= J[k] <= n`. Numerical zeros in (`I`, `J`, `V`) are retained as structural nonzeros; to drop numerical zeros, use [`dropzeros!`](#SparseArrays.dropzeros!).
For additional documentation and an expert driver, see `SparseArrays.sparse!`.
**Examples**


# [SparseArrays API](#stdlib-sparse-arrays)
```julia-repl
julia> Is = [1; 2; 3];

julia> Js = [1; 2; 3];

julia> Vs = [1; 2; 3];

julia> sparse(Is, Js, Vs)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 1  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  3
```
```julia
sparse!(I::AbstractVector{Ti}, J::AbstractVector{Ti}, V::AbstractVector{Tv},
        m::Integer, n::Integer, combine, klasttouch::Vector{Ti},
        csrrowptr::Vector{Ti}, csrcolval::Vector{Ti}, csrnzval::Vector{Tv},
        [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}] ) where {Tv,Ti<:Integer}
```
Parent of and expert driver for [`sparse`](#SparseArrays.sparse); see [`sparse`](#SparseArrays.sparse) for basic usage. This method allows the user to provide preallocated storage for `sparse`'s intermediate objects and result as described below. This capability enables more efficient successive construction of [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC)s from coordinate representations, and also enables extraction of an unsorted-column representation of the result's transpose at no additional cost.


# [SparseArrays API](#stdlib-sparse-arrays)
This method consists of three major steps: (1) Counting-sort the provided coordinate representation into an unsorted-row CSR form including repeated entries. (2) Sweep through the CSR form, simultaneously calculating the desired CSC form's column-pointer array, detecting repeated entries, and repacking the CSR form with repeated entries combined; this stage yields an unsorted-row CSR form with no repeated entries. (3) Counting-sort the preceding CSR form into a fully-sorted CSC form with no repeated entries.
Input arrays `csrrowptr`, `csrcolval`, and `csrnzval` constitute storage for the intermediate CSR forms and require `length(csrrowptr) >= m + 1`, `length(csrcolval) >= length(I)`, and `length(csrnzval >= length(I))`. Input array `klasttouch`, workspace for the second stage, requires `length(klasttouch) >= n`. Optional input arrays `csccolptr`, `cscrowval`, and `cscnzval` constitute storage for the returned CSC form `S`. If necessary, these are resized automatically to satisfy `length(csccolptr) = n + 1`, `length(cscrowval) = nnz(S)` and `length(cscnzval) = nnz(S)`; hence, if `nnz(S)` is unknown at the outset, passing in empty vectors of the appropriate type (`Vector{Ti}()` and `Vector{Tv}()` respectively) suffices, or calling the `sparse!` method neglecting `cscrowval` and `cscnzval`.
On return, `csrrowptr`, `csrcolval`, and `csrnzval` contain an unsorted-column representation of the result's transpose.


# [SparseArrays API](#stdlib-sparse-arrays)
You may reuse the input arrays' storage (`I`, `J`, `V`) for the output arrays (`csccolptr`, `cscrowval`, `cscnzval`). For example, you may call `sparse!(I, J, V, csrrowptr, csrcolval, csrnzval, I, J, V)`. Note that they will be resized to satisfy the conditions above.
For the sake of efficiency, this method performs no argument checking beyond `1 <= I[k] <= m` and `1 <= J[k] <= n`. Use with care. Testing with `--check-bounds=yes` is wise.
This method runs in `O(m, n, length(I))` time. The HALFPERM algorithm described in F. Gustavson, "Two fast algorithms for sparse matrices: multiplication and permuted transposition," ACM TOMS 4(3), 250-269 (1978) inspired this method's use of a pair of counting sorts.
```julia
SparseArrays.sparse!(I, J, V, [m, n, combine]) -> SparseMatrixCSC
```
Variant of `sparse!` that re-uses the input vectors (`I`, `J`, `V`) for the final matrix storage. After construction the input vectors will alias the matrix buffers; `S.colptr === I`, `S.rowval === J`, and `S.nzval === V` holds, and they will be `resize!`d as necessary.
Note that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around `sparse!(I, J, V, m, n, combine, klasttouch, csrrowptr, csrcolval, csrnzval, csccolptr, cscrowval, cscnzval)` where this method allocates `klasttouch`, `csrrowptr`, `csrcolval`, and `csrnzval` of appropriate size, but reuses `I`, `J`, and `V` for `csccolptr`, `cscrowval`, and `cscnzval`.


# [SparseArrays API](#stdlib-sparse-arrays)
Arguments `m`, `n`, and `combine` defaults to `maximum(I)`, `maximum(J)`, and `+`, respectively.
This method requires Julia version 1.10 or later.
```julia
sparsevec(I, V, [m, combine])
```
Create a sparse vector `S` of length `m` such that `S[I[k]] = V[k]`. Duplicates are combined using the `combine` function, which defaults to `+` if no `combine` argument is provided, unless the elements of `V` are Booleans in which case `combine` defaults to `|`.
**Examples**
```julia-repl
julia> II = [1, 3, 3, 5]; V = [0.1, 0.2, 0.3, 0.2];

julia> sparsevec(II, V)
5-element SparseVector{Float64, Int64} with 3 stored entries:
  [1]  =  0.1
  [3]  =  0.5
  [5]  =  0.2

julia> sparsevec(II, V, 8, -)
8-element SparseVector{Float64, Int64} with 3 stored entries:
  [1]  =  0.1
  [3]  =  -0.1
  [5]  =  0.2

julia> sparsevec([1, 3, 1, 2, 2], [true, true, false, false, false])
3-element SparseVector{Bool, Int64} with 3 stored entries:
  [1]  =  1
  [2]  =  0
  [3]  =  1
```
```julia
sparsevec(d::Dict, [m])
```
Create a sparse vector of length `m` where the nonzero indices are keys from the dictionary, and the nonzero values are the values from the dictionary.
**Examples**
```julia-repl
julia> sparsevec(Dict(1 => 3, 2 => 2))
2-element SparseVector{Int64, Int64} with 2 stored entries:
  [1]  =  3
  [2]  =  2
```
```julia
sparsevec(A)
```
Convert a vector `A` into a sparse vector of length `m`.
**Examples**


# [SparseArrays API](#stdlib-sparse-arrays)
```julia-repl
julia> sparsevec([1.0, 2.0, 0.0, 0.0, 3.0, 0.0])
6-element SparseVector{Float64, Int64} with 3 stored entries:
  [1]  =  1.0
  [2]  =  2.0
  [5]  =  3.0
```
```julia
similar(A::AbstractSparseMatrixCSC{Tv,Ti}, [::Type{TvNew}, ::Type{TiNew}, m::Integer, n::Integer]) where {Tv,Ti}
```
Create an uninitialized mutable array with the given element type, index type, and size, based upon the given source `SparseMatrixCSC`. The new sparse matrix maintains the structure of the original sparse matrix, except in the case where dimensions of the output matrix are different from the output.
The output matrix has zeros in the same locations as the input, but uninitialized values for the nonzero locations.
```julia
issparse(S)
```
Returns `true` if `S` is sparse, and `false` otherwise.
**Examples**
```julia-repl
julia> sv = sparsevec([1, 4], [2.3, 2.2], 10)
10-element SparseVector{Float64, Int64} with 2 stored entries:
  [1]  =  2.3
  [4]  =  2.2

julia> issparse(sv)
true

julia> issparse(Array(sv))
false
```
```julia
nnz(A)
```
Returns the number of stored (filled) elements in a sparse array.
**Examples**
```julia-repl
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 2  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  2

julia> nnz(A)
3
```
```julia
findnz(A::SparseMatrixCSC)
```
Return a tuple `(I, J, V)` where `I` and `J` are the row and column indices of the stored ("structurally non-zero") values in sparse matrix `A`, and `V` is a vector of the values.
**Examples**


# [SparseArrays API](#stdlib-sparse-arrays)
```julia-repl
julia> A = sparse([1 2 0; 0 0 3; 0 4 0])
3×3 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
 1  2  ⋅
 ⋅  ⋅  3
 ⋅  4  ⋅

julia> findnz(A)
([1, 1, 3, 2], [1, 2, 2, 3], [1, 2, 4, 3])
```
```julia
spzeros([type,]m[,n])
```
Create a sparse vector of length `m` or sparse matrix of size `m x n`. This sparse array will not contain any nonzero values. No storage will be allocated for nonzero values during construction. The type defaults to [`Float64`](../../base/numbers/#Core.Float64) if not specified.
**Examples**
```julia-repl
julia> spzeros(3, 3)
3×3 SparseMatrixCSC{Float64, Int64} with 0 stored entries:
  ⋅    ⋅    ⋅
  ⋅    ⋅    ⋅
  ⋅    ⋅    ⋅

julia> spzeros(Float32, 4)
4-element SparseVector{Float32, Int64} with 0 stored entries
```
```julia
spzeros([type], I::AbstractVector, J::AbstractVector, [m, n])
```
Create a sparse matrix `S` of dimensions `m x n` with structural zeros at `S[I[k], J[k]]`.
This method can be used to construct the sparsity pattern of the matrix, and is more efficient than using e.g. `sparse(I, J, zeros(length(I)))`.
For additional documentation and an expert driver, see `SparseArrays.spzeros!`.
This methods requires Julia version 1.10 or later.
```julia
spzeros!(::Type{Tv}, I::AbstractVector{Ti}, J::AbstractVector{Ti}, m::Integer, n::Integer,
         klasttouch::Vector{Ti}, csrrowptr::Vector{Ti}, csrcolval::Vector{Ti},
         [csccolptr::Vector{Ti}], [cscrowval::Vector{Ti}, cscnzval::Vector{Tv}]) where {Tv,Ti<:Integer}
```


# [SparseArrays API](#stdlib-sparse-arrays)
Parent of and expert driver for `spzeros(I, J)` allowing user to provide preallocated storage for intermediate objects. This method is to `spzeros` what `SparseArrays.sparse!` is to `sparse`. See documentation for `SparseArrays.sparse!` for details and required buffer lengths.
This methods requires Julia version 1.10 or later.
```julia
SparseArrays.spzeros!(::Type{Tv}, I, J, [m, n]) -> SparseMatrixCSC{Tv}
```
Variant of `spzeros!` that re-uses the input vectors `I` and `J` for the final matrix storage. After construction the input vectors will alias the matrix buffers; `S.colptr === I` and `S.rowval === J` holds, and they will be `resize!`d as necessary.
Note that some work buffers will still be allocated. Specifically, this method is a convenience wrapper around `spzeros!(Tv, I, J, m, n, klasttouch, csrrowptr, csrcolval, csccolptr, cscrowval)` where this method allocates `klasttouch`, `csrrowptr`, and `csrcolval` of appropriate size, but reuses `I` and `J` for `csccolptr` and `cscrowval`.
Arguments `m` and `n` defaults to `maximum(I)` and `maximum(J)`.
This method requires Julia version 1.10 or later.
```julia
spdiagm(kv::Pair{<:Integer,<:AbstractVector}...)
spdiagm(m::Integer, n::Integer, kv::Pair{<:Integer,<:AbstractVector}...)
```


# [SparseArrays API](#stdlib-sparse-arrays)
Construct a sparse diagonal matrix from `Pair`s of vectors and diagonals. Each vector `kv.second` will be placed on the `kv.first` diagonal. By default, the matrix is square and its size is inferred from `kv`, but a non-square size `m`×`n` (padded with zeros as needed) can be specified by passing `m,n` as the first arguments.
**Examples**
```julia-repl
julia> spdiagm(-1 => [1,2,3,4], 1 => [4,3,2,1])
5×5 SparseMatrixCSC{Int64, Int64} with 8 stored entries:
 ⋅  4  ⋅  ⋅  ⋅
 1  ⋅  3  ⋅  ⋅
 ⋅  2  ⋅  2  ⋅
 ⋅  ⋅  3  ⋅  1
 ⋅  ⋅  ⋅  4  ⋅
```
```julia
spdiagm(v::AbstractVector)
spdiagm(m::Integer, n::Integer, v::AbstractVector)
```
Construct a sparse matrix with elements of the vector as diagonal elements. By default (no given `m` and `n`), the matrix is square and its size is given by `length(v)`, but a non-square size `m`×`n` can be specified by passing `m` and `n` as the first arguments.
These functions require at least Julia 1.6.
**Examples**
```julia-repl
julia> spdiagm([1,2,3])
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 1  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  3

julia> spdiagm(sparse([1,0,3]))
3×3 SparseMatrixCSC{Int64, Int64} with 2 stored entries:
 1  ⋅  ⋅
 ⋅  ⋅  ⋅
 ⋅  ⋅  3
```
```julia
sparse_hcat(A...)
```
Concatenate along dimension 2. Return a SparseMatrixCSC object.
This method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized "sparse" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.


# [SparseArrays API](#stdlib-sparse-arrays)
```julia
sparse_vcat(A...)
```
Concatenate along dimension 1. Return a SparseMatrixCSC object.
This method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized "sparse" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.
```julia
sparse_hvcat(rows::Tuple{Vararg{Int}}, values...)
```
Sparse horizontal and vertical concatenation in one call. This function is called for block matrix syntax. The first argument specifies the number of arguments to concatenate in each block row.
This method was added in Julia 1.8. It mimics previous concatenation behavior, where the concatenation with specialized "sparse" matrix types from LinearAlgebra.jl automatically yielded sparse output even in the absence of any SparseArray argument.
```julia
blockdiag(A...)
```
Concatenate matrices block-diagonally. Currently only implemented for sparse matrices.
**Examples**
```julia-repl
julia> blockdiag(sparse(2I, 3, 3), sparse(4I, 2, 2))
5×5 SparseMatrixCSC{Int64, Int64} with 5 stored entries:
 2  ⋅  ⋅  ⋅  ⋅
 ⋅  2  ⋅  ⋅  ⋅
 ⋅  ⋅  2  ⋅  ⋅
 ⋅  ⋅  ⋅  4  ⋅
 ⋅  ⋅  ⋅  ⋅  4
```
```julia
sprand([rng],[T::Type],m,[n],p::AbstractFloat)
sprand([rng],m,[n],p::AbstractFloat,[rfn=rand])
```


# [SparseArrays API](#stdlib-sparse-arrays)
Create a random length `m` sparse vector or `m` by `n` sparse matrix, in which the probability of any element being nonzero is independently given by `p` (and hence the mean density of nonzeros is also exactly `p`). The optional `rng` argument specifies a random number generator, see [Random Numbers](../Random/#Random-Numbers). The optional `T` argument specifies the element type, which defaults to `Float64`.
By default, nonzero values are sampled from a uniform distribution using the [`rand`](../Random/#Base.rand) function, i.e. by `rand(T)`, or `rand(rng, T)` if `rng` is supplied; for the default `T=Float64`, this corresponds to nonzero values sampled uniformly in `[0,1)`.
You can sample nonzero values from a different distribution by passing a custom `rfn` function instead of `rand`. This should be a function `rfn(k)` that returns an array of `k` random numbers sampled from the desired distribution; alternatively, if `rng` is supplied, it should instead be a function `rfn(rng, k)`.
**Examples**
```julia-repl
julia> sprand(Bool, 2, 2, 0.5)
2×2 SparseMatrixCSC{Bool, Int64} with 2 stored entries:
 1  1
 ⋅  ⋅

julia> sprand(Float64, 3, 0.75)
3-element SparseVector{Float64, Int64} with 2 stored entries:
  [1]  =  0.795547
  [2]  =  0.49425
```
```julia
sprandn([rng][,Type],m[,n],p::AbstractFloat)
```


# [SparseArrays API](#stdlib-sparse-arrays)
Create a random sparse vector of length `m` or sparse matrix of size `m` by `n` with the specified (independent) probability `p` of any entry being nonzero, where nonzero values are sampled from the normal distribution. The optional `rng` argument specifies a random number generator, see [Random Numbers](../Random/#Random-Numbers).
Specifying the output element type `Type` requires at least Julia 1.1.
**Examples**
```julia-repl
julia> sprandn(2, 2, 0.75)
2×2 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 -1.20577     ⋅
  0.311817  -0.234641
```
```julia
nonzeros(A)
```
Return a vector of the structural nonzero values in sparse array `A`. This includes zeros that are explicitly stored in the sparse array. The returned vector points directly to the internal nonzero storage of `A`, and any modifications to the returned vector will mutate `A` as well. See [`rowvals`](#SparseArrays.rowvals) and [`nzrange`](#SparseArrays.nzrange).
**Examples**
```julia-repl
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 2  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  2

julia> nonzeros(A)
3-element Vector{Int64}:
 2
 2
 2
```
```julia
rowvals(A::AbstractSparseMatrixCSC)
```
Return a vector of the row indices of `A`. Any modifications to the returned vector will mutate `A` as well. Providing access to how the row indices are stored internally can be useful in conjunction with iterating over structural nonzero values. See also [`nonzeros`](#SparseArrays.nonzeros) and [`nzrange`](#SparseArrays.nzrange).
**Examples**


# [SparseArrays API](#stdlib-sparse-arrays)
```julia-repl
julia> A = sparse(2I, 3, 3)
3×3 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
 2  ⋅  ⋅
 ⋅  2  ⋅
 ⋅  ⋅  2

julia> rowvals(A)
3-element Vector{Int64}:
 1
 2
 3
```
```julia
nzrange(A::AbstractSparseMatrixCSC, col::Integer)
```
Return the range of indices to the structural nonzero values of a sparse matrix column. In conjunction with [`nonzeros`](#SparseArrays.nonzeros) and [`rowvals`](#SparseArrays.rowvals), this allows for convenient iterating over a sparse matrix :
```julia
A = sparse(I,J,V)
rows = rowvals(A)
vals = nonzeros(A)
m, n = size(A)
for j = 1:n
   for i in nzrange(A, j)
      row = rows[i]
      val = vals[i]
      # perform sparse wizardry...
   end
end
```
Adding or removing nonzero elements to the matrix may invalidate the `nzrange`, one should not mutate the matrix while iterating.
```julia
nzrange(x::SparseVectorUnion, col)
```
Give the range of indices to the structural nonzero values of a sparse vector. The column index `col` is ignored (assumed to be `1`).
```julia
droptol!(A::AbstractSparseMatrixCSC, tol)
```
Removes stored values from `A` whose absolute value is less than or equal to `tol`.
```julia
droptol!(x::AbstractCompressedVector, tol)
```
Removes stored values from `x` whose absolute value is less than or equal to `tol`.
```julia
dropzeros!(x::AbstractCompressedVector)
```
Removes stored numerical zeros from `x`.
For an out-of-place version, see [`dropzeros`](#SparseArrays.dropzeros). For algorithmic information, see `fkeep!`.
```julia
dropzeros(A::AbstractSparseMatrixCSC;)
```


# [SparseArrays API](#stdlib-sparse-arrays)
Generates a copy of `A` and removes stored numerical zeros from that copy.
For an in-place version and algorithmic information, see [`dropzeros!`](#SparseArrays.dropzeros!).
**Examples**
```julia-repl
julia> A = sparse([1, 2, 3], [1, 2, 3], [1.0, 0.0, 1.0])
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
 1.0   ⋅    ⋅
  ⋅   0.0   ⋅
  ⋅    ⋅   1.0

julia> dropzeros(A)
3×3 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
 1.0   ⋅    ⋅
  ⋅    ⋅    ⋅
  ⋅    ⋅   1.0
```
```julia
dropzeros(x::AbstractCompressedVector)
```
Generates a copy of `x` and removes numerical zeros from that copy.
For an in-place version and algorithmic information, see [`dropzeros!`](#SparseArrays.dropzeros!).
**Examples**
```julia-repl
julia> A = sparsevec([1, 2, 3], [1.0, 0.0, 1.0])
3-element SparseVector{Float64, Int64} with 3 stored entries:
  [1]  =  1.0
  [2]  =  0.0
  [3]  =  1.0

julia> dropzeros(A)
3-element SparseVector{Float64, Int64} with 2 stored entries:
  [1]  =  1.0
  [3]  =  1.0
```
```julia
permute(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
        q::AbstractVector{<:Integer}) where {Tv,Ti}
```
Bilaterally permute `A`, returning `PAQ` (`A[p,q]`). Column-permutation `q`'s length must match `A`'s column count (`length(q) == size(A, 2)`). Row-permutation `p`'s length must match `A`'s row count (`length(p) == size(A, 1)`).
For expert drivers and additional information, see [`permute!`](../../base/arrays/#Base.permute!-Tuple%7BAny,%20AbstractVector%7D).
**Examples**


# [SparseArrays API](#stdlib-sparse-arrays)
```julia-repl
julia> A = spdiagm(0 => [1, 2, 3, 4], 1 => [5, 6, 7])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
 1  5  ⋅  ⋅
 ⋅  2  6  ⋅
 ⋅  ⋅  3  7
 ⋅  ⋅  ⋅  4

julia> permute(A, [4, 3, 2, 1], [1, 2, 3, 4])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
 ⋅  ⋅  ⋅  4
 ⋅  ⋅  3  7
 ⋅  2  6  ⋅
 1  5  ⋅  ⋅

julia> permute(A, [1, 2, 3, 4], [4, 3, 2, 1])
4×4 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
 ⋅  ⋅  5  1
 ⋅  6  2  ⋅
 7  3  ⋅  ⋅
 4  ⋅  ⋅  ⋅
```
```julia
permute!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti},
         p::AbstractVector{<:Integer}, q::AbstractVector{<:Integer},
         [C::AbstractSparseMatrixCSC{Tv,Ti}]) where {Tv,Ti}
```
Bilaterally permute `A`, storing result `PAQ` (`A[p,q]`) in `X`. Stores intermediate result `(AQ)^T` (`transpose(A[:,q])`) in optional argument `C` if present. Requires that none of `X`, `A`, and, if present, `C` alias each other; to store result `PAQ` back into `A`, use the following method lacking `X`:
```julia
permute!(A::AbstractSparseMatrixCSC{Tv,Ti}, p::AbstractVector{<:Integer},
         q::AbstractVector{<:Integer}[, C::AbstractSparseMatrixCSC{Tv,Ti},
         [workcolptr::Vector{Ti}]]) where {Tv,Ti}
```


# [SparseArrays API](#stdlib-sparse-arrays)
`X`'s dimensions must match those of `A` (`size(X, 1) == size(A, 1)` and `size(X, 2) == size(A, 2)`), and `X` must have enough storage to accommodate all allocated entries in `A` (`length(rowvals(X)) >= nnz(A)` and `length(nonzeros(X)) >= nnz(A)`). Column-permutation `q`'s length must match `A`'s column count (`length(q) == size(A, 2)`). Row-permutation `p`'s length must match `A`'s row count (`length(p) == size(A, 1)`).
`C`'s dimensions must match those of `transpose(A)` (`size(C, 1) == size(A, 2)` and `size(C, 2) == size(A, 1)`), and `C` must have enough storage to accommodate all allocated entries in `A` (`length(rowvals(C)) >= nnz(A)` and `length(nonzeros(C)) >= nnz(A)`).
For additional (algorithmic) information, and for versions of these methods that forgo argument checking, see (unexported) parent methods `unchecked_noalias_permute!` and `unchecked_aliasing_permute!`.
See also [`permute`](#SparseArrays.permute).
```julia
halfperm!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{TvA,Ti},
          q::AbstractVector{<:Integer}, f::Function = identity) where {Tv,TvA,Ti}
```
Column-permute and transpose `A`, simultaneously applying `f` to each entry of `A`, storing the result `(f(A)Q)^T` (`map(f, transpose(A[:,q]))`) in `X`.


# [SparseArrays API](#stdlib-sparse-arrays)
Element type `Tv` of `X` must match `f(::TvA)`, where `TvA` is the element type of `A`. `X`'s dimensions must match those of `transpose(A)` (`size(X, 1) == size(A, 2)` and `size(X, 2) == size(A, 1)`), and `X` must have enough storage to accommodate all allocated entries in `A` (`length(rowvals(X)) >= nnz(A)` and `length(nonzeros(X)) >= nnz(A)`). Column-permutation `q`'s length must match `A`'s column count (`length(q) == size(A, 2)`).
This method is the parent of several methods performing transposition and permutation operations on [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC)s. As this method performs no argument checking, prefer the safer child methods (`[c]transpose[!]`, `permute[!]`) to direct use.
This method implements the `HALFPERM` algorithm described in F. Gustavson, "Two fast algorithms for sparse matrices: multiplication and permuted transposition," ACM TOMS 4(3), 250-269 (1978). The algorithm runs in `O(size(A, 1), size(A, 2), nnz(A))` time and requires no space beyond that passed in.
```julia
ftranspose!(X::AbstractSparseMatrixCSC{Tv,Ti}, A::AbstractSparseMatrixCSC{Tv,Ti}, f::Function) where {Tv,Ti}
```
Transpose `A` and store it in `X` while applying the function `f` to the non-zero elements. Does not remove the zeros created by `f`. `size(X)` must be equal to `size(transpose(A))`. No additional memory is allocated other than resizing the rowval and nzval of `X`, if needed.
See `halfperm!`


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia
cholesky(A, NoPivot(); check = true) -> Cholesky
```
Compute the Cholesky factorization of a dense symmetric positive definite matrix `A` and return a [`Cholesky`](../LinearAlgebra/#LinearAlgebra.Cholesky) factorization. The matrix `A` can either be a [`Symmetric`](../LinearAlgebra/#LinearAlgebra.Symmetric) or [`Hermitian`](../LinearAlgebra/#LinearAlgebra.Hermitian) [`AbstractMatrix`](../../base/arrays/#Base.AbstractMatrix) or a *perfectly* symmetric or Hermitian `AbstractMatrix`.
The triangular Cholesky factor can be obtained from the factorization `F` via `F.L` and `F.U`, where `A ≈ F.U' * F.U ≈ F.L * F.L'`.
The following functions are available for `Cholesky` objects: [`size`](../../base/arrays/#Base.size), [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D), [`inv`](../../base/math/#Base.inv-Tuple%7BNumber%7D), [`det`](../LinearAlgebra/#LinearAlgebra.det), [`logdet`](../LinearAlgebra/#LinearAlgebra.logdet) and [`isposdef`](../LinearAlgebra/#LinearAlgebra.isposdef).
If you have a matrix `A` that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in `Hermitian(A)` before passing it to `cholesky` in order to treat it as perfectly Hermitian.
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.
**Examples**


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia-repl
julia> A = [4. 12. -16.; 12. 37. -43.; -16. -43. 98.]
3×3 Matrix{Float64}:
   4.0   12.0  -16.0
  12.0   37.0  -43.0
 -16.0  -43.0   98.0

julia> C = cholesky(A)
Cholesky{Float64, Matrix{Float64}}
U factor:
3×3 UpperTriangular{Float64, Matrix{Float64}}:
 2.0  6.0  -8.0
  ⋅   1.0   5.0
  ⋅    ⋅    3.0

julia> C.U
3×3 UpperTriangular{Float64, Matrix{Float64}}:
 2.0  6.0  -8.0
  ⋅   1.0   5.0
  ⋅    ⋅    3.0

julia> C.L
3×3 LowerTriangular{Float64, Matrix{Float64}}:
  2.0   ⋅    ⋅
  6.0  1.0   ⋅
 -8.0  5.0  3.0

julia> C.L * C.U == A
true
```
```julia
cholesky(A, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted
```
Compute the pivoted Cholesky factorization of a dense symmetric positive semi-definite matrix `A` and return a [`CholeskyPivoted`](../LinearAlgebra/#LinearAlgebra.CholeskyPivoted) factorization. The matrix `A` can either be a [`Symmetric`](../LinearAlgebra/#LinearAlgebra.Symmetric) or [`Hermitian`](../LinearAlgebra/#LinearAlgebra.Hermitian) [`AbstractMatrix`](../../base/arrays/#Base.AbstractMatrix) or a *perfectly* symmetric or Hermitian `AbstractMatrix`.
The triangular Cholesky factor can be obtained from the factorization `F` via `F.L` and `F.U`, and the permutation via `F.p`, where `A[F.p, F.p] ≈ Ur' * Ur ≈ Lr * Lr'` with `Ur = F.U[1:F.rank, :]` and `Lr = F.L[:, 1:F.rank]`, or alternatively `A ≈ Up' * Up ≈ Lp * Lp'` with `Up = F.U[1:F.rank, invperm(F.p)]` and `Lp = F.L[invperm(F.p), 1:F.rank]`.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
The following functions are available for `CholeskyPivoted` objects: [`size`](../../base/arrays/#Base.size), [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D), [`inv`](../../base/math/#Base.inv-Tuple%7BNumber%7D), [`det`](../LinearAlgebra/#LinearAlgebra.det), and [`rank`](../LinearAlgebra/#LinearAlgebra.rank).
The argument `tol` determines the tolerance for determining the rank. For negative values, the tolerance is the machine precision.
If you have a matrix `A` that is slightly non-Hermitian due to roundoff errors in its construction, wrap it in `Hermitian(A)` before passing it to `cholesky` in order to treat it as perfectly Hermitian.
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.
**Examples**
```julia-repl
julia> X = [1.0, 2.0, 3.0, 4.0];

julia> A = X * X';

julia> C = cholesky(A, RowMaximum(), check = false)
CholeskyPivoted{Float64, Matrix{Float64}, Vector{Int64}}
U factor with rank 1:
4×4 UpperTriangular{Float64, Matrix{Float64}}:
 4.0  2.0  3.0  1.0
  ⋅   0.0  6.0  2.0
  ⋅    ⋅   9.0  3.0
  ⋅    ⋅    ⋅   1.0
permutation:
4-element Vector{Int64}:
 4
 2
 3
 1

julia> C.U[1:C.rank, :]' * C.U[1:C.rank, :] ≈ A[C.p, C.p]
true

julia> l, u = C; # destructuring via iteration

julia> l == C.L && u == C.U
true
```
```julia
cholesky(A::SparseMatrixCSC; shift = 0.0, check = true, perm = nothing) -> CHOLMOD.Factor
```


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
Compute the Cholesky factorization of a sparse positive definite matrix `A`. `A` must be a [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC) or a [`Symmetric`](../LinearAlgebra/#LinearAlgebra.Symmetric)/[`Hermitian`](../LinearAlgebra/#LinearAlgebra.Hermitian) view of a `SparseMatrixCSC`. Note that even if `A` doesn't have the type tag, it must still be symmetric or Hermitian. If `perm` is not given, a fill-reducing permutation is used. `F = cholesky(A)` is most frequently used to solve systems of equations with `F\b`, but also the methods [`diag`](../LinearAlgebra/#LinearAlgebra.diag), [`det`](../LinearAlgebra/#LinearAlgebra.det), and [`logdet`](../LinearAlgebra/#LinearAlgebra.logdet) are defined for `F`. You can also extract individual factors from `F`, using `F.L`. However, since pivoting is on by default, the factorization is internally represented as `A == P'*L*L'*P` with a permutation matrix `P`; using just `L` without accounting for `P` will give incorrect answers. To include the effects of permutation, it's typically preferable to extract "combined" factors like `PtL = F.PtL` (the equivalent of `P'*L`) and `LtP = F.UP` (the equivalent of `L'*P`).
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
Setting the optional `shift` keyword argument computes the factorization of `A+shift*I` instead of `A`. If the `perm` argument is provided, it should be a permutation of `1:size(A,1)` giving the ordering to use (instead of CHOLMOD's default AMD ordering).
**Examples**
In the following example, the fill-reducing permutation used is `[3, 2, 1]`. If `perm` is set to `1:3` to enforce no permutation, the number of nonzero elements in the factor is 6.
```julia-repl
julia> A = [2 1 1; 1 2 0; 1 0 2]
3×3 Matrix{Int64}:
 2  1  1
 1  2  0
 1  0  2

julia> C = cholesky(sparse(A))
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type:    LLt
method:  simplicial
maxnnz:  5
nnz:     5
success: true

julia> C.p
3-element Vector{Int64}:
 3
 2
 1

julia> L = sparse(C.L);

julia> Matrix(L)
3×3 Matrix{Float64}:
 1.41421   0.0       0.0
 0.0       1.41421   0.0
 0.707107  0.707107  1.0

julia> L * L' ≈ A[C.p, C.p]
true

julia> P = sparse(1:3, C.p, ones(3))
3×3 SparseMatrixCSC{Float64, Int64} with 3 stored entries:
  ⋅    ⋅   1.0
  ⋅   1.0   ⋅
 1.0   ⋅    ⋅

julia> P' * L * L' * P ≈ A
true

julia> C = cholesky(sparse(A), perm=1:3)
SparseArrays.CHOLMOD.Factor{Float64, Int64}
type:    LLt
method:  simplicial
maxnnz:  6
nnz:     6
success: true

julia> L = sparse(C.L);

julia> Matrix(L)
3×3 Matrix{Float64}:
 1.41421    0.0       0.0
 0.707107   1.22474   0.0
 0.707107  -0.408248  1.1547

julia> L * L' ≈ A
true
```


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
This method uses the CHOLMOD<sup>[[ACM887\]](#footnote-ACM887)[[DavisHager2009\]](#footnote-DavisHager2009)</sup> library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse). CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.
Many other functions from CHOLMOD are wrapped but not exported from the `Base.SparseArrays.CHOLMOD` module.
```julia
cholesky!(A::AbstractMatrix, NoPivot(); check = true) -> Cholesky
```
The same as [`cholesky`](../LinearAlgebra/#LinearAlgebra.cholesky), but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](../../base/base/#Core.InexactError) exception is thrown if the factorization produces a number not representable by the element type of `A`, e.g. for integer types.
**Examples**
```julia-repl
julia> A = [1 2; 2 50]
2×2 Matrix{Int64}:
 1   2
 2  50

julia> cholesky!(A)
ERROR: InexactError: Int64(6.782329983125268)
Stacktrace:
[...]
```
```julia
cholesky!(A::AbstractMatrix, RowMaximum(); tol = 0.0, check = true) -> CholeskyPivoted
```
The same as [`cholesky`](../LinearAlgebra/#LinearAlgebra.cholesky), but saves space by overwriting the input `A`, instead of creating a copy. An [`InexactError`](../../base/base/#Core.InexactError) exception is thrown if the factorization produces a number not representable by the element type of `A`, e.g. for integer types.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia
cholesky!(F::CHOLMOD.Factor, A::SparseMatrixCSC; shift = 0.0, check = true) -> CHOLMOD.Factor
```
Compute the Cholesky ($LL'$) factorization of `A`, reusing the symbolic factorization `F`. `A` must be a [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC) or a [`Symmetric`](../LinearAlgebra/#LinearAlgebra.Symmetric)/ [`Hermitian`](../LinearAlgebra/#LinearAlgebra.Hermitian) view of a `SparseMatrixCSC`. Note that even if `A` doesn't have the type tag, it must still be symmetric or Hermitian.
See also [`cholesky`](../LinearAlgebra/#LinearAlgebra.cholesky).
This method uses the CHOLMOD library from SuiteSparse, which only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.
```julia
lowrankupdate(C::Cholesky, v::AbstractVector) -> CC::Cholesky
```
Update a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then `CC = cholesky(C.U'C.U + v*v')` but the computation of `CC` only uses `O(n^2)` operations.
```julia
lowrankupdate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
```
Get an `LDLt` Factorization of `A + C*C'` given an `LDLt` or `LLt` factorization `F` of `A`.
The returned factor is always an `LDLt` factorization.
See also [`lowrankupdate!`](../LinearAlgebra/#LinearAlgebra.lowrankupdate!), [`lowrankdowndate`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate), [`lowrankdowndate!`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate!).


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia
lowrankupdate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky
```
Update a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then `CC = cholesky(C.U'C.U + v*v')` but the computation of `CC` only uses `O(n^2)` operations. The input factorization `C` is updated in place such that on exit `C == CC`. The vector `v` is destroyed during the computation.
```julia
lowrankupdate!(F::CHOLMOD.Factor, C::AbstractArray)
```
Update an `LDLt` or `LLt` Factorization `F` of `A` to a factorization of `A + C*C'`.
`LLt` factorizations are converted to `LDLt`.
See also [`lowrankupdate`](../LinearAlgebra/#LinearAlgebra.lowrankupdate), [`lowrankdowndate`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate), [`lowrankdowndate!`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate!).
```julia
lowrankdowndate(C::Cholesky, v::AbstractVector) -> CC::Cholesky
```
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then `CC = cholesky(C.U'C.U - v*v')` but the computation of `CC` only uses `O(n^2)` operations.
```julia
lowrankdowndate(F::CHOLMOD.Factor, C::AbstractArray) -> FF::CHOLMOD.Factor
```
Get an `LDLt` Factorization of `A + C*C'` given an `LDLt` or `LLt` factorization `F` of `A`.
The returned factor is always an `LDLt` factorization.
See also [`lowrankdowndate!`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate!), [`lowrankupdate`](../LinearAlgebra/#LinearAlgebra.lowrankupdate), [`lowrankupdate!`](../LinearAlgebra/#LinearAlgebra.lowrankupdate!).


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia
lowrankdowndate!(C::Cholesky, v::AbstractVector) -> CC::Cholesky
```
Downdate a Cholesky factorization `C` with the vector `v`. If `A = C.U'C.U` then `CC = cholesky(C.U'C.U - v*v')` but the computation of `CC` only uses `O(n^2)` operations. The input factorization `C` is updated in place such that on exit `C == CC`. The vector `v` is destroyed during the computation.
```julia
lowrankdowndate!(F::CHOLMOD.Factor, C::AbstractArray)
```
Update an `LDLt` or `LLt` Factorization `F` of `A` to a factorization of `A - C*C'`.
`LLt` factorizations are converted to `LDLt`.
See also [`lowrankdowndate`](../LinearAlgebra/#LinearAlgebra.lowrankdowndate), [`lowrankupdate`](../LinearAlgebra/#LinearAlgebra.lowrankupdate), [`lowrankupdate!`](../LinearAlgebra/#LinearAlgebra.lowrankupdate!).
```julia
lowrankupdowndate!(F::CHOLMOD.Factor, C::Sparse, update::Cint)
```
Update an `LDLt` or `LLt` Factorization `F` of `A` to a factorization of `A ± C*C'`.
If sparsity preserving factorization is used, i.e. `L*L' == P*A*P'` then the new factor will be `L*L' == P*A*P' + C'*C`
`update`: `Cint(1)` for `A + CC'`, `Cint(0)` for `A - CC'`
```julia
ldlt(S::SymTridiagonal) -> LDLt
```
Compute an `LDLt` (i.e., $LDL^T$) factorization of the real symmetric tridiagonal matrix `S` such that `S = L*Diagonal(d)*L'` where `L` is a unit lower triangular matrix and `d` is a vector. The main use of an `LDLt` factorization `F = ldlt(S)` is to solve the linear system of equations `Sx = b` with `F\b`.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
See also [`bunchkaufman`](../LinearAlgebra/#LinearAlgebra.bunchkaufman) for a similar, but pivoted, factorization of arbitrary symmetric or Hermitian matrices.
**Examples**
```julia-repl
julia> S = SymTridiagonal([3., 4., 5.], [1., 2.])
3×3 SymTridiagonal{Float64, Vector{Float64}}:
 3.0  1.0   ⋅
 1.0  4.0  2.0
  ⋅   2.0  5.0

julia> ldltS = ldlt(S);

julia> b = [6., 7., 8.];

julia> ldltS \ b
3-element Vector{Float64}:
 1.7906976744186047
 0.627906976744186
 1.3488372093023255

julia> S \ b
3-element Vector{Float64}:
 1.7906976744186047
 0.627906976744186
 1.3488372093023255
```
```julia
ldlt(A::SparseMatrixCSC; shift = 0.0, check = true, perm=nothing) -> CHOLMOD.Factor
```


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
Compute the $LDL'$ factorization of a sparse matrix `A`. `A` must be a [`SparseMatrixCSC`](#SparseArrays.SparseMatrixCSC) or a [`Symmetric`](../LinearAlgebra/#LinearAlgebra.Symmetric)/[`Hermitian`](../LinearAlgebra/#LinearAlgebra.Hermitian) view of a `SparseMatrixCSC`. Note that even if `A` doesn't have the type tag, it must still be symmetric or Hermitian. A fill-reducing permutation is used. `F = ldlt(A)` is most frequently used to solve systems of equations `A*x = b` with `F\b`. The returned factorization object `F` also supports the methods [`diag`](../LinearAlgebra/#LinearAlgebra.diag), [`det`](../LinearAlgebra/#LinearAlgebra.det), [`logdet`](../LinearAlgebra/#LinearAlgebra.logdet), and [`inv`](../../base/math/#Base.inv-Tuple%7BNumber%7D). You can extract individual factors from `F` using `F.L`. However, since pivoting is on by default, the factorization is internally represented as `A == P'*L*D*L'*P` with a permutation matrix `P`; using just `L` without accounting for `P` will give incorrect answers. To include the effects of permutation, it is typically preferable to extract "combined" factors like `PtL = F.PtL` (the equivalent of `P'*L`) and `LtP = F.UP` (the equivalent of `L'*P`). The complete list of supported factors is `:L, :PtL, :D, :UP, :U, :LD, :DU, :PtLD, :DUP`.
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
Setting the optional `shift` keyword argument computes the factorization of `A+shift*I` instead of `A`. If the `perm` argument is provided, it should be a permutation of `1:size(A,1)` giving the ordering to use (instead of CHOLMOD's default AMD ordering).
This method uses the CHOLMOD<sup>[[ACM887\]](#footnote-ACM887)[[DavisHager2009\]](#footnote-DavisHager2009)</sup> library from [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse). CHOLMOD only supports real or complex types in single or double precision. Input matrices not of those element types will be converted to these types as appropriate.
Many other functions from CHOLMOD are wrapped but not exported from the `Base.SparseArrays.CHOLMOD` module.
```julia
lu(A::AbstractSparseMatrixCSC; check = true, q = nothing, control = get_umfpack_control()) -> F::UmfpackLU
```
Compute the LU factorization of a sparse matrix `A`.
For sparse `A` with real or complex element type, the return type of `F` is `UmfpackLU{Tv, Ti}`, with `Tv` = [`Float64`](../../base/numbers/#Core.Float64) or `ComplexF64` respectively and `Ti` is an integer type ([`Int32`](../../base/numbers/#Core.Int32) or [`Int64`](../../base/numbers/#Core.Int64)).
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
The permutation `q` can either be a permutation vector or `nothing`. If no permutation vector is provided or `q` is `nothing`, UMFPACK's default is used. If the permutation is not zero-based, a zero-based copy is made.
The `control` vector defaults to the Julia SparseArrays package's default configuration for UMFPACK (NB: this is modified from the UMFPACK defaults to disable iterative refinement), but can be changed by passing a vector of length `UMFPACK_CONTROL`, see the UMFPACK manual for possible configurations. For example to reenable iterative refinement:
```julia
umfpack_control = SparseArrays.UMFPACK.get_umfpack_control(Float64, Int64) # read Julia default configuration for a Float64 sparse matrix
SparseArrays.UMFPACK.show_umf_ctrl(umfpack_control) # optional - display values
umfpack_control[SparseArrays.UMFPACK.JL_UMFPACK_IRSTEP] = 2.0 # reenable iterative refinement (2 is UMFPACK default max iterative refinement steps)

Alu = lu(A; control = umfpack_control)
x = Alu \ b   # solve Ax = b, including UMFPACK iterative refinement
```
The individual components of the factorization `F` can be accessed by indexing:


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
| Component | Description                         |
|:----------|:------------------------------------|
| `L`       | `L` (lower triangular) part of `LU` |
| `U`       | `U` (upper triangular) part of `LU` |
| `p`       | right permutation `Vector`          |
| `q`       | left permutation `Vector`           |
| `Rs`      | `Vector` of scaling factors         |
| `:`       | `(L,U,p,q,Rs)` components           |
The relation between `F` and `A` is
`F.L*F.U == (F.Rs .* A)[F.p, F.q]`
`F` further supports the following functions:
-   [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D)
-   [`det`](../LinearAlgebra/#LinearAlgebra.det)
See also [`lu!`](../LinearAlgebra/#LinearAlgebra.lu!)
`lu(A::AbstractSparseMatrixCSC)` uses the UMFPACK<sup>[[ACM832\]](#footnote-ACM832)</sup> library that is part of [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse). As this library only supports sparse matrices with [`Float64`](../../base/numbers/#Core.Float64) or `ComplexF64` elements, `lu` converts `A` into a copy that is of type `SparseMatrixCSC{Float64}` or `SparseMatrixCSC{ComplexF64}` as appropriate.
```julia
lu(A, pivot = RowMaximum(); check = true, allowsingular = false) -> F::LU
```
Compute the LU factorization of `A`.
When `check = true`, an error is thrown if the decomposition fails. When `check = false`, responsibility for checking the decomposition's validity (via [`issuccess`](../LinearAlgebra/#LinearAlgebra.issuccess)) lies with the user.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
By default, with `check = true`, an error is also thrown when the decomposition produces valid factors, but the upper-triangular factor `U` is rank-deficient. This may be changed by passing `allowsingular = true`.
In most cases, if `A` is a subtype `S` of `AbstractMatrix{T}` with an element type `T` supporting `+`, `-`, `*` and `/`, the return type is `LU{T,S{T}}`.
In general, LU factorization involves a permutation of the rows of the matrix (corresponding to the `F.p` output described below), known as "pivoting" (because it corresponds to choosing which row contains the "pivot", the diagonal entry of `F.U`). One of the following pivoting strategies can be selected via the optional `pivot` argument:
-   `RowMaximum()` (default): the standard pivoting strategy; the pivot corresponds to the element of maximum absolute value among the remaining, to be factorized rows. This pivoting strategy requires the element type to also support [`abs`](../../base/math/#Base.abs) and [`<`](../../base/math/#Base.:%3C). (This is generally the only numerically stable option for floating-point matrices.)
-   `RowNonZero()`: the pivot corresponds to the first non-zero element among the remaining, to be factorized rows. (This corresponds to the typical choice in hand calculations, and is also useful for more general algebraic number types that support [`iszero`](../../base/numbers/#Base.iszero) but not `abs` or `<`.)


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
-   `NoPivot()`: pivoting turned off (will fail if a zero entry is encountered in a pivot position, even when `allowsingular = true`).
The individual components of the factorization `F` can be accessed via [`getproperty`](../../base/base/#Base.getproperty):
| Component | Description                         |
|:----------|:------------------------------------|
| `F.L`     | `L` (lower triangular) part of `LU` |
| `F.U`     | `U` (upper triangular) part of `LU` |
| `F.p`     | (right) permutation `Vector`        |
| `F.P`     | (right) permutation `Matrix`        |
Iterating the factorization produces the components `F.L`, `F.U`, and `F.p`.
The relationship between `F` and `A` is
`F.L*F.U == A[F.p, :]`
`F` further supports the following functions:


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
| Supported function                                       | `LU` | `LU{T,Tridiagonal{T}}` |
|:---------------------------------------------------------|:-----|:-----------------------|
| [`/`](../../base/math/#Base.:/)                          | ✓    |                        |
| [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D)   | ✓    | ✓                      |
| [`inv`](../../base/math/#Base.inv-Tuple%7BNumber%7D)     | ✓    | ✓                      |
| [`det`](../LinearAlgebra/#LinearAlgebra.det)             | ✓    | ✓                      |
| [`logdet`](../LinearAlgebra/#LinearAlgebra.logdet)       | ✓    | ✓                      |
| [`logabsdet`](../LinearAlgebra/#LinearAlgebra.logabsdet) | ✓    | ✓                      |
| [`size`](../../base/arrays/#Base.size)                   | ✓    | ✓                      |
The `allowsingular` keyword argument was added in Julia 1.11.
**Examples**
```julia-repl
julia> A = [4 3; 6 3]
2×2 Matrix{Int64}:
 4  3
 6  3

julia> F = lu(A)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
2×2 Matrix{Float64}:
 1.0       0.0
 0.666667  1.0
U factor:
2×2 Matrix{Float64}:
 6.0  3.0
 0.0  1.0

julia> F.L * F.U == A[F.p, :]
true

julia> l, u, p = lu(A); # destructuring via iteration

julia> l == F.L && u == F.U && p == F.p
true

julia> lu([1 2; 1 2], allowsingular = true)
LU{Float64, Matrix{Float64}, Vector{Int64}}
L factor:
2×2 Matrix{Float64}:
 1.0  0.0
 1.0  1.0
U factor (rank-deficient):
2×2 Matrix{Float64}:
 1.0  2.0
 0.0  0.0
```


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia
qr(A::SparseMatrixCSC; tol=_default_tol(A), ordering=ORDERING_DEFAULT) -> QRSparse
```
Compute the `QR` factorization of a sparse matrix `A`. Fill-reducing row and column permutations are used such that `F.R = F.Q'*A[F.prow,F.pcol]`. The main application of this type is to solve least squares or underdetermined problems with [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D). The function calls the C library SPQR<sup>[[ACM933\]](#footnote-ACM933)</sup>.
`qr(A::SparseMatrixCSC)` uses the SPQR library that is part of [SuiteSparse](https://github.com/DrTimothyAldenDavis/SuiteSparse). As this library only supports sparse matrices with [`Float64`](../../base/numbers/#Core.Float64) or `ComplexF64` elements, as of Julia v1.4 `qr` converts `A` into a copy that is of type `SparseMatrixCSC{Float64}` or `SparseMatrixCSC{ComplexF64}` as appropriate.
**Examples**
```julia-repl
julia> A = sparse([1,2,3,4], [1,1,2,2], [1.0,1.0,1.0,1.0])
4×2 SparseMatrixCSC{Float64, Int64} with 4 stored entries:
 1.0   ⋅
 1.0   ⋅
  ⋅   1.0
  ⋅   1.0

julia> qr(A)
SparseArrays.SPQR.QRSparse{Float64, Int64}
Q factor:
4×4 SparseArrays.SPQR.QRSparseQ{Float64, Int64}
R factor:
2×2 SparseMatrixCSC{Float64, Int64} with 2 stored entries:
 -1.41421    ⋅
   ⋅       -1.41421
Row permutation:
4-element Vector{Int64}:
 1
 3
 4
 2
Column permutation:
2-element Vector{Int64}:
 1
 2
```
```julia
qr(A, pivot = NoPivot(); blocksize) -> F
```


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
Compute the QR factorization of the matrix `A`: an orthogonal (or unitary if `A` is complex-valued) matrix `Q`, and an upper triangular matrix `R` such that
\\\[A = Q R\\\]
The returned object `F` stores the factorization in a packed format:
-   if `pivot == ColumnNorm()` then `F` is a [`QRPivoted`](../LinearAlgebra/#LinearAlgebra.QRPivoted) object,
-   otherwise if the element type of `A` is a BLAS type ([`Float32`](../../base/numbers/#Core.Float32), [`Float64`](../../base/numbers/#Core.Float64), `ComplexF32` or `ComplexF64`), then `F` is a [`QRCompactWY`](../LinearAlgebra/#LinearAlgebra.QRCompactWY) object,
-   otherwise `F` is a [`QR`](../LinearAlgebra/#LinearAlgebra.QR) object.
The individual components of the decomposition `F` can be retrieved via property accessors:
-   `F.Q`: the orthogonal/unitary matrix `Q`
-   `F.R`: the upper triangular matrix `R`
-   `F.p`: the permutation vector of the pivot ([`QRPivoted`](../LinearAlgebra/#LinearAlgebra.QRPivoted) only)
-   `F.P`: the permutation matrix of the pivot ([`QRPivoted`](../LinearAlgebra/#LinearAlgebra.QRPivoted) only)
Each reference to the upper triangular factor via `F.R` allocates a new array. It is therefore advisable to cache that array, say, by `R = F.R` and continue working with `R`.
Iterating the decomposition produces the components `Q`, `R`, and if extant `p`.


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
The following functions are available for the `QR` objects: [`inv`](../../base/math/#Base.inv-Tuple%7BNumber%7D), [`size`](../../base/arrays/#Base.size), and [`\`](../../base/math/#Base.:\\-Tuple%7BAny,%20Any%7D). When `A` is rectangular, `\` will return a least squares solution and if the solution is not unique, the one with smallest norm is returned. When `A` is not full rank, factorization with (column) pivoting is required to obtain a minimum norm solution.
Multiplication with respect to either full/square or non-full/square `Q` is allowed, i.e. both `F.Q*F.R` and `F.Q*A` are supported. A `Q` matrix can be converted into a regular matrix with [`Matrix`](../../base/arrays/#Base.Matrix). This operation returns the "thin" Q factor, i.e., if `A` is `m`×`n` with `m>=n`, then `Matrix(F.Q)` yields an `m`×`n` matrix with orthonormal columns. To retrieve the "full" Q factor, an `m`×`m` orthogonal matrix, use `F.Q*I` or `collect(F.Q)`. If `m<=n`, then `Matrix(F.Q)` yields an `m`×`m` orthogonal matrix.
The block size for QR decomposition can be specified by keyword argument `blocksize :: Integer` when `pivot == NoPivot()` and `A isa StridedMatrix{<:BlasFloat}`. It is ignored when `blocksize > minimum(size(A))`. See [`QRCompactWY`](../LinearAlgebra/#LinearAlgebra.QRCompactWY).
The `blocksize` keyword argument requires Julia 1.4 or later.
**Examples**


# [Sparse Linear Algebra API](#stdlib-sparse-linalg-api)
```julia-repl
julia> A = [3.0 -6.0; 4.0 -8.0; 0.0 1.0]
3×2 Matrix{Float64}:
 3.0  -6.0
 4.0  -8.0
 0.0   1.0

julia> F = qr(A)
LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}, Matrix{Float64}}
Q factor: 3×3 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}, Matrix{Float64}}
R factor:
2×2 Matrix{Float64}:
 -5.0  10.0
  0.0  -1.0

julia> F.Q * F.R == A
true
```
`qr` returns multiple types because LAPACK uses several representations that minimize the memory storage requirements of products of Householder elementary reflectors, so that the `Q` and `R` matrices can be stored compactly rather as two separate dense matrices.


# [Noteworthy External Sparse Packages](#Noteworthy-External-Sparse-Packages)
Several other Julia packages provide sparse matrix implementations that should be mentioned:
1.  [SuiteSparseGraphBLAS.jl](https://github.com/JuliaSparse/SuiteSparseGraphBLAS.jl) is a wrapper over the fast, multithreaded SuiteSparse:GraphBLAS C library. On CPU this is typically the fastest option, often significantly outperforming MKLSparse.
2.  [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl) exposes the [CUSPARSE](https://docs.nvidia.com/cuda/cusparse/index.html) library for GPU sparse matrix operations.
3.  [SparseMatricesCSR.jl](https://github.com/gridap/SparseMatricesCSR.jl) provides a Julia native implementation of the Compressed Sparse Rows (CSR) format.
4.  [MKLSparse.jl](https://github.com/JuliaSparse/MKLSparse.jl) accelerates SparseArrays sparse-dense matrix operations using Intel's MKL library.
5.  [SparseArrayKit.jl](https://github.com/Jutho/SparseArrayKit.jl) available for multidimensional sparse arrays.
6.  [LuxurySparse.jl](https://github.com/QuantumBFS/LuxurySparse.jl) provides static sparse array formats, as well as a coordinate format.
7.  [ExtendableSparse.jl](https://github.com/j-fu/ExtendableSparse.jl) enables fast insertion into sparse matrices using a lazy approach to new stored indices.


# [Noteworthy External Sparse Packages](#Noteworthy-External-Sparse-Packages)
8.  [Finch.jl](https://github.com/willow-ahrens/Finch.jl) supports extensive multidimensional sparse array formats and operations through a mini tensor language and compiler, all in native Julia. Support for COO, CSF, CSR, CSC and more, as well as operations like broadcast, reduce, etc. and custom operations.
External packages providing sparse direct solvers:
1.  [KLU.jl](https://github.com/JuliaSparse/KLU.jl)
2.  [Pardiso.jl](https://github.com/JuliaSparse/Pardiso.jl/)
External packages providing solvers for iterative solution of eigensystems and singular value decompositions:
1.  [ArnoldiMethods.jl](https://github.com/JuliaLinearAlgebra/ArnoldiMethod.jl)
2.  [KrylovKit](https://github.com/Jutho/KrylovKit.jl)
3.  [Arpack.jl](https://github.com/JuliaLinearAlgebra/Arpack.jl)
External packages for working with graphs:
1.  [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl)
-   [ACM887](#citeref-ACM887)Chen, Y., Davis, T. A., Hager, W. W., & Rajamanickam, S. (2008). Algorithm 887: CHOLMOD, Supernodal Sparse Cholesky Factorization and Update/Downdate. ACM Trans. Math. Softw., 35(3). [doi:10.1145/1391989.1391995](https://doi.org/10.1145/1391989.1391995)
-   [DavisHager2009](#citeref-DavisHager2009)Davis, Timothy A., & Hager, W. W. (2009). Dynamic Supernodes in Sparse Cholesky Update/Downdate and Triangular Solves. ACM Trans. Math. Softw., 35(4). [doi:10.1145/1462173.1462176](https://doi.org/10.1145/1462173.1462176)


# [Noteworthy External Sparse Packages](#Noteworthy-External-Sparse-Packages)
-   [ACM832](#citeref-ACM832)Davis, Timothy A. (2004b). Algorithm 832: UMFPACK V4.3–-an Unsymmetric-Pattern Multifrontal Method. ACM Trans. Math. Softw., 30(2), 196–199. [doi:10.1145/992200.992206](https://doi.org/10.1145/992200.992206)
-   [ACM933](#citeref-ACM933)Foster, L. V., & Davis, T. A. (2013). Algorithm 933: Reliable Calculation of Numerical Rank, Null Space Bases, Pseudoinverse Solutions, and Basic Solutions Using SuitesparseQR. ACM Trans. Math. Softw., 40(1). [doi:10.1145/2513109.2513116](https://doi.org/10.1145/2513109.2513116)
------------------------------------------------------------------------


# Statistics · The Julia Language
Source: https://docs.julialang.org/en/v1/stdlib/Statistics/


# [Statistics](#Statistics)
The Statistics standard library module contains basic statistics functionality.
```julia
std(itr; corrected::Bool=true, mean=nothing[, dims])
```
Compute the sample standard deviation of collection `itr`.
The algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of `itr` is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating `sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1))`. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` with `n` the number of elements in `itr`.
If `itr` is an `AbstractArray`, `dims` can be provided to compute the standard deviation over dimensions.
A pre-computed `mean` may be provided. When `dims` is specified, `mean` must be an array with the same shape as `mean(itr, dims=dims)` (additional trailing singleton dimensions are allowed).
If array contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if array contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the standard deviation of non-missing values.
```julia
stdm(itr, mean; corrected::Bool=true[, dims])
```
Compute the sample standard deviation of collection `itr`, with known mean(s) `mean`.


# [Statistics](#Statistics)
The algorithm returns an estimator of the generative distribution's standard deviation under the assumption that each entry of `itr` is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating `sqrt(sum((itr .- mean(itr)).^2) / (length(itr) - 1))`. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` with `n` the number of elements in `itr`.
If `itr` is an `AbstractArray`, `dims` can be provided to compute the standard deviation over dimensions. In that case, `mean` must be an array with the same shape as `mean(itr, dims=dims)` (additional trailing singleton dimensions are allowed).
If array contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if array contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the standard deviation of non-missing values.
```julia
var(itr; corrected::Bool=true, mean=nothing[, dims])
```
Compute the sample variance of collection `itr`.


# [Statistics](#Statistics)
The algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of `itr` is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating `sum((itr .- mean(itr)).^2) / (length(itr) - 1)`. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` where `n` is the number of elements in `itr`.
If `itr` is an `AbstractArray`, `dims` can be provided to compute the variance over dimensions.
A pre-computed `mean` may be provided. When `dims` is specified, `mean` must be an array with the same shape as `mean(itr, dims=dims)` (additional trailing singleton dimensions are allowed).
If array contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if array contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the variance of non-missing values.
```julia
varm(itr, mean; dims, corrected::Bool=true)
```
Compute the sample variance of collection `itr`, with known mean(s) `mean`.


# [Statistics](#Statistics)
The algorithm returns an estimator of the generative distribution's variance under the assumption that each entry of `itr` is a sample drawn from the same unknown distribution, with the samples uncorrelated. For arrays, this computation is equivalent to calculating `sum((itr .- mean(itr)).^2) / (length(itr) - 1)`. If `corrected` is `true`, then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` with `n` the number of elements in `itr`.
If `itr` is an `AbstractArray`, `dims` can be provided to compute the variance over dimensions. In that case, `mean` must be an array with the same shape as `mean(itr, dims=dims)` (additional trailing singleton dimensions are allowed).
If array contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if array contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the variance of non-missing values.
```julia
cor(x::AbstractVector)
```
Return the number one.
```julia
cor(X::AbstractMatrix; dims::Int=1)
```
Compute the Pearson correlation matrix of the matrix `X` along the dimension `dims`.
```julia
cor(x::AbstractVector, y::AbstractVector)
```
Compute the Pearson correlation between the vectors `x` and `y`.
```julia
cor(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims=1)
```
Compute the Pearson correlation between the vectors or matrices `X` and `Y` along the dimension `dims`.
```julia
cov(x::AbstractVector; corrected::Bool=true)
```


# [Statistics](#Statistics)
Compute the variance of the vector `x`. If `corrected` is `true` (the default) then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` where `n = length(x)`.
```julia
cov(X::AbstractMatrix; dims::Int=1, corrected::Bool=true)
```
Compute the covariance matrix of the matrix `X` along the dimension `dims`. If `corrected` is `true` (the default) then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` where `n = size(X, dims)`.
```julia
cov(x::AbstractVector, y::AbstractVector; corrected::Bool=true)
```
Compute the covariance between the vectors `x` and `y`. If `corrected` is `true` (the default), computes $\\frac{1}{n-1}\\sum\_{i=1}^n (x_i-\\bar x) (y_i-\\bar y)^\*$ where $\*$ denotes the complex conjugate and `n = length(x) = length(y)`. If `corrected` is `false`, computes $\\frac{1}{n}\\sum\_{i=1}^n (x_i-\\bar x) (y_i-\\bar y)^\*$.
```julia
cov(X::AbstractVecOrMat, Y::AbstractVecOrMat; dims::Int=1, corrected::Bool=true)
```
Compute the covariance between the vectors or matrices `X` and `Y` along the dimension `dims`. If `corrected` is `true` (the default) then the sum is scaled with `n-1`, whereas the sum is scaled with `n` if `corrected` is `false` where `n = size(X, dims) = size(Y, dims)`.
```julia
mean!(r, v)
```
Compute the mean of `v` over the singleton dimensions of `r`, and write results to `r`.
**Examples**


# [Statistics](#Statistics)
```julia-repl
julia> using Statistics

julia> v = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> mean!([1., 1.], v)
2-element Vector{Float64}:
 1.5
 3.5

julia> mean!([1. 1.], v)
1×2 Matrix{Float64}:
 2.0  3.0
```
```julia
mean(itr)
```
Compute the mean of all elements in a collection.
If `itr` contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if array contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the mean of non-missing values.
**Examples**
```julia-repl
julia> using Statistics

julia> mean(1:20)
10.5

julia> mean([1, missing, 3])
missing

julia> mean(skipmissing([1, missing, 3]))
2.0
```
```julia
mean(f, itr)
```
Apply the function `f` to each element of collection `itr` and take the mean.
```julia-repl
julia> using Statistics

julia> mean(√, [1, 2, 3])
1.3820881233139908

julia> mean([√1, √2, √3])
1.3820881233139908
```
```julia
mean(f, A::AbstractArray; dims)
```
Apply the function `f` to each element of array `A` and take the mean over dimensions `dims`.
This method requires at least Julia 1.3.
```julia-repl
julia> using Statistics

julia> mean(√, [1, 2, 3])
1.3820881233139908

julia> mean([√1, √2, √3])
1.3820881233139908

julia> mean(√, [1 2 3; 4 5 6], dims=2)
2×1 Matrix{Float64}:
 1.3820881233139908
 2.2285192400943226
```
```julia
mean(A::AbstractArray; dims)
```
Compute the mean of an array over the given dimensions.
`mean` for empty arrays requires at least Julia 1.1.


# [Statistics](#Statistics)
**Examples**
```julia-repl
julia> using Statistics

julia> A = [1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4

julia> mean(A, dims=1)
1×2 Matrix{Float64}:
 2.0  3.0

julia> mean(A, dims=2)
2×1 Matrix{Float64}:
 1.5
 3.5
```
```julia
median!(v)
```
Like [`median`](#Statistics.median), but may overwrite the input vector.
```julia
median(itr)
```
Compute the median of all elements in a collection. For an even number of elements no exact median element exists, so the result is equivalent to calculating mean of two median elements.
If `itr` contains `NaN` or [`missing`](../../manual/missing/#missing) values, the result is also `NaN` or `missing` (`missing` takes precedence if `itr` contains both). Use the [`skipmissing`](../../base/base/#Base.skipmissing) function to omit `missing` entries and compute the median of non-missing values.
**Examples**
```julia-repl
julia> using Statistics

julia> median([1, 2, 3])
2.0

julia> median([1, 2, 3, 4])
2.5

julia> median([1, 2, missing, 4])
missing

julia> median(skipmissing([1, 2, missing, 4]))
2.0
```
```julia
median(A::AbstractArray; dims)
```
Compute the median of an array along the given dimensions.
**Examples**
```julia-repl
julia> using Statistics

julia> median([1 2; 3 4], dims=1)
1×2 Matrix{Float64}:
 2.0  3.0
```
```julia
middle(x)
```
Compute the middle of a scalar value, which is equivalent to `x` itself, but of the type of `middle(x, x)` for consistency.
```julia
middle(x, y)
```


# [Statistics](#Statistics)
Compute the middle of two numbers `x` and `y`, which is equivalent in both value and type to computing their mean (`(x + y) / 2`).
```julia
middle(a::AbstractArray)
```
Compute the middle of an array `a`, which consists of finding its extrema and then computing their mean.
```julia-repl
julia> using Statistics

julia> middle(1:10)
5.5

julia> a = [1,2,3.6,10.9]
4-element Vector{Float64}:
  1.0
  2.0
  3.6
 10.9

julia> middle(a)
5.95
```
```julia
quantile!([q::AbstractArray, ] v::AbstractVector, p; sorted=false, alpha::Real=1.0, beta::Real=alpha)
```
Compute the quantile(s) of a vector `v` at a specified probability or vector or tuple of probabilities `p` on the interval \[0,1\]. If `p` is a vector, an optional output array `q` may also be specified. (If not provided, a new output array is created.) The keyword argument `sorted` indicates whether `v` can be assumed to be sorted; if `false` (the default), then the elements of `v` will be partially sorted in-place.
Samples quantile are defined by `Q(p) = (1-γ)*x[j] + γ*x[j+1]`, where `x[j]` is the j-th order statistic of `v`, `j = floor(n*p + m)`, `m = alpha + p*(1 - alpha - beta)` and `γ = n*p + m - j`.
By default (`alpha = beta = 1`), quantiles are computed via linear interpolation between the points `((k-1)/(n-1), x[k])`, for `k = 1:n` where `n = length(v)`. This corresponds to Definition 7 of Hyndman and Fan (1996), and is the same as the R and NumPy default.