[
  {
    "path": ".github/dependabot.yml",
    "content": "# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\nversion: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/CompatHelper.yml",
    "content": "name: CompatHelper\non:\n  schedule:\n    - cron: 0 0 * * *\n  workflow_dispatch:\npermissions:\n  contents: write\n  pull-requests: write\njobs:\n  CompatHelper:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check if Julia is already available in the PATH\n        id: julia_in_path\n        run: which julia\n        continue-on-error: true\n      - name: Install Julia, but only if it is not already available in the PATH\n        uses: julia-actions/setup-julia@v3\n        with:\n          version: '1'\n          arch: ${{ runner.arch }}\n        if: steps.julia_in_path.outcome != 'success'\n      - name: \"Add the General registry via Git\"\n        run: |\n          import Pkg\n          ENV[\"JULIA_PKG_SERVER\"] = \"\"\n          Pkg.Registry.add(\"General\")\n        shell: julia --color=yes {0}\n      - name: \"Install CompatHelper\"\n        run: |\n          import Pkg\n          name = \"CompatHelper\"\n          uuid = \"aa819f21-2bde-4658-8897-bab36330d9b7\"\n          version = \"3\"\n          Pkg.add(; name, uuid, version)\n        shell: julia --color=yes {0}\n      - name: \"Run CompatHelper\"\n        run: |\n          import CompatHelper\n          CompatHelper.main()\n        shell: julia --color=yes {0}\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          # COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}\n          COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }}\n"
  },
  {
    "path": ".github/workflows/Invalidations.yml",
    "content": "name: Invalidations\n\non:\n  pull_request:\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n\nconcurrency:\n  # Skip intermediate builds: always.\n  # Cancel intermediate builds: always.\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  evaluate:\n    # Only run on PRs to the default branch.\n    # In the PR trigger above branches can be specified only explicitly whereas this check should work for master, main, or any other default branch\n    if: github.base_ref == github.event.repository.default_branch\n    runs-on: ubuntu-latest\n    steps:\n    - uses: julia-actions/setup-julia@v3\n      with:\n        version: '1.10'\n    - uses: actions/checkout@v6\n    - uses: julia-actions/julia-buildpkg@v1\n    - uses: julia-actions/julia-invalidations@v1\n      id: invs_pr\n\n    - uses: actions/checkout@v6\n      with:\n        ref: ${{ github.event.repository.default_branch }}\n    - uses: julia-actions/julia-buildpkg@v1\n    - uses: julia-actions/julia-invalidations@v1\n      id: invs_default\n\n    - name: Report invalidation counts\n      run: |\n        echo \"Invalidations on default branch: ${{ steps.invs_default.outputs.total }} (${{ steps.invs_default.outputs.deps }} via deps)\" >> $GITHUB_STEP_SUMMARY\n        echo \"This branch: ${{ steps.invs_pr.outputs.total }} (${{ steps.invs_pr.outputs.deps }} via deps)\" >> $GITHUB_STEP_SUMMARY\n    - name: Check if the PR does increase number of invalidations\n      if: steps.invs_pr.outputs.total > steps.invs_default.outputs.total\n      run: exit 1\n"
  },
  {
    "path": ".github/workflows/TagBot.yml",
    "content": "name: TagBot\non:\n  issue_comment:\n    types:\n      - created\n  workflow_dispatch:\n    inputs:\n      lookback:\n        default: 3\npermissions:\n  contents: write\njobs:\n  TagBot:\n    if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: JuliaRegistries/TagBot@v1\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          ssh: ${{ secrets.DOCUMENTER_KEY }}\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\non:\n  push:\n    branches:\n      - master\n    tags: [v*]\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n  pull_request:\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n\n\nconcurrency:\n  group: build-${{ github.event.pull_request.number || github.ref }}-${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  pre_job:\n    # continue-on-error: true # Uncomment once integration is finished\n    runs-on: ubuntu-latest\n    # Map a step output to a job output\n    outputs:\n      should_skip: ${{ steps.skip_check.outputs.should_skip }}\n    steps:\n      - id: skip_check\n        uses: fkirc/skip-duplicate-actions@v5\n  test:\n    needs: pre_job\n    if: needs.pre_job.outputs.should_skip != 'true'\n    name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        version:\n          - 'min'\n          - 'lts'\n          - '1'\n          - 'pre'\n        os:\n          - ubuntu-latest\n          - macOS-latest\n          - windows-latest\n    steps:\n      - uses: actions/checkout@v6\n      - uses: julia-actions/setup-julia@v3\n        with:\n          version: ${{ matrix.version }}\n      - uses: julia-actions/cache@v3\n      - uses: julia-actions/julia-buildpkg@v1\n      - uses: julia-actions/julia-runtest@v1\n      - uses: julia-actions/julia-processcoverage@v1\n      - uses: codecov/codecov-action@v6\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          files: lcov.info\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "content": "name: Documentation\n\non:\n  pull_request:\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n  push:\n    branches:\n      - 'master'\n      - 'release-'\n    tags: '*'\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n  release:\n    types: [published]\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        julia-version: [1]\n        os: [ubuntu-latest]\n    steps:\n      - uses: actions/checkout@v6\n      - uses: julia-actions/setup-julia@latest\n        with:\n          version: ${{ matrix.julia-version }}\n      - name: Cache artifacts\n        uses: actions/cache@v5\n        env:\n          cache-name: cache-artifacts\n        with:\n          path: ~/.julia/artifacts\n          key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}\n          restore-keys: |\n            ${{ runner.os }}-test-${{ env.cache-name }}-\n            ${{ runner.os }}-test-\n            ${{ runner.os }}-\n      - name: Install dependencies\n        run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'\n      - name: Build and deploy\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # If authenticating with SSH deploy key\n        run: julia --project=docs/ docs/make.jl\n"
  },
  {
    "path": ".github/workflows/downstream.yml",
    "content": "name: IntegrationTest\non:\n  push:\n    branches: [master]\n    tags: [v*]\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n  pull_request:\n    paths-ignore:\n      - 'LICENSE'\n      - 'README.md'\n      - '.github/workflows/TagBot.yml'\n\nconcurrency:\n  group: build-${{ github.event.pull_request.number || github.ref }}-${{ github.workflow }}\n  cancel-in-progress: true\n\njobs:\n  pre_job:\n    # continue-on-error: true # Uncomment once integration is finished\n    runs-on: ubuntu-latest\n    # Map a step output to a job output\n    outputs:\n      should_skip: ${{ steps.skip_check.outputs.should_skip }}\n    steps:\n      - id: skip_check\n        uses: fkirc/skip-duplicate-actions@v5\n  test:\n    needs: pre_job\n    if: needs.pre_job.outputs.should_skip != 'true'\n    name: ${{ matrix.package.group }}/${{ matrix.package.repo }}/${{ matrix.julia-version }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        julia-version: ['1']\n        os: [ubuntu-latest]\n        package:\n          - {repo: Distributions.jl, group: JuliaStats}\n          - {repo: BlockArrays.jl, group: JuliaArrays}\n          - {repo: LazyArrays.jl, group: JuliaArrays}\n          - {repo: InfiniteArrays.jl, group: JuliaArrays}\n          - {repo: ArrayLayouts.jl, group: JuliaLinearAlgebra}\n          - {repo: LazyBandedMatrices.jl, group: JuliaLinearAlgebra}\n          - {repo: BandedMatrices.jl, group: JuliaLinearAlgebra}\n          - {repo: BlockBandedMatrices.jl, group: JuliaLinearAlgebra}\n          - {repo: InfiniteLinearAlgebra.jl, group: JuliaLinearAlgebra}\n          - {repo: Optim.jl, group: JuliaNLSolvers}\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: julia-actions/setup-julia@v3\n        with:\n          version: ${{ matrix.julia-version }}\n          arch: x64\n      - uses: julia-actions/julia-buildpkg@latest\n      - name: Clone Downstream\n        uses: actions/checkout@v6\n        with:\n          repository: ${{ matrix.package.group }}/${{ matrix.package.repo }}\n          path: downstream\n      - name: Load this and run the downstream tests\n        shell: julia --color=yes --project=downstream {0}\n        run: |\n          using Pkg\n          try\n            # force it to use this PR's version of the package\n            Pkg.develop(PackageSpec(path=\".\"))  # resolver may fail with main deps\n            Pkg.update()\n            Pkg.test(; coverage = true, test_args=[\"--downstream_integration_test\"])  # resolver may fail with test time deps\n          catch err\n            err isa Pkg.Resolve.ResolverError || rethrow()\n            # If we can't resolve that means this is incompatible by SemVer and this is fine\n            # It means we marked this as a breaking change, so we don't need to worry about\n            # Mistakenly introducing a breaking change, as we have intentionally made one\n            @info \"Not compatible with this release. No problem.\" exception=err\n            exit(0)  # Exit immediately, as a success\n          end\n      - uses: julia-actions/julia-processcoverage@v1\n      - uses: codecov/codecov-action@v6\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          files: lcov.info\n"
  },
  {
    "path": ".gitignore",
    "content": "*.jl.cov\n*.jl.*.cov\n*.jl.mem\ndeps/deps.jl\n.DS_Store\nManifest.toml\nManifest-v*.*.toml\ndocs/build\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Sheehan Olver\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Project.toml",
    "content": "name = \"FillArrays\"\nuuid = \"1a297f60-69ca-5386-bcde-b61e274b549b\"\nversion = \"1.16.0\"\n\n[deps]\nLinearAlgebra = \"37e2e46d-f89d-539d-b4ee-838fcccc9c8e\"\n\n[weakdeps]\nPDMats = \"90014a1f-27ba-587c-ab20-58faa44d9150\"\nSparseArrays = \"2f01184e-e22b-5df5-ae63-d93ebab69eaf\"\nStatistics = \"10745b16-79ce-11e8-11f9-7d13ad32a3b2\"\nStaticArrays = \"90137ffa-7385-5640-81b9-e52037218182\"\n\n[extensions]\nFillArraysPDMatsExt = \"PDMats\"\nFillArraysSparseArraysExt = \"SparseArrays\"\nFillArraysStatisticsExt = \"Statistics\"\nFillArraysStaticArraysExt = \"StaticArrays\"\n\n[compat]\nAqua = \"0.8\"\nDocumenter = \"1\"\nInfinities = \"0.1\"\nLinearAlgebra = \"1\"\nPDMats = \"0.11.17\"\nQuaternions = \"0.7\"\nRandom = \"1\"\nReverseDiff = \"1\"\nSparseArrays = \"1\"\nStaticArrays = \"1\"\nStatistics = \"1\"\nTest = \"1\"\njulia = \"1.10\"\n\n[extras]\nAqua = \"4c88cf16-eb10-579e-8560-4a9242c79595\"\nDocumenter = \"e30172f5-a6a5-5a46-863b-614d45cd2de4\"\nInfinities = \"e1ba4f0e-776d-440f-acd9-e1d2e9742647\"\nPDMats = \"90014a1f-27ba-587c-ab20-58faa44d9150\"\nQuaternions = \"94ee1d12-ae83-5a48-8b1c-48b8ff168ae0\"\nRandom = \"9a3f8284-a2c9-5f02-9a11-845980a1fd5c\"\nReverseDiff = \"37e2e3b7-166d-5795-8a7a-e32c996b4267\"\nSparseArrays = \"2f01184e-e22b-5df5-ae63-d93ebab69eaf\"\nStaticArrays = \"90137ffa-7385-5640-81b9-e52037218182\"\nStatistics = \"10745b16-79ce-11e8-11f9-7d13ad32a3b2\"\nTest = \"8dfed614-e22c-5e08-85e1-65c5234f0b40\"\n\n[targets]\ntest = [\"Aqua\", \"Test\", \"Infinities\", \"PDMats\", \"ReverseDiff\", \"SparseArrays\", \"StaticArrays\", \"Statistics\", \"Quaternions\", \"Documenter\", \"Random\"]\n"
  },
  {
    "path": "README.md",
    "content": "# FillArrays.jl\n\n[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://JuliaArrays.github.io/FillArrays.jl/stable)\n[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://JuliaArrays.github.io/FillArrays.jl/dev)\n[![Build Status](https://github.com/JuliaArrays/FillArrays.jl/workflows/CI/badge.svg)](https://github.com/JuliaArrays/FillArrays.jl/actions)\n[![codecov](https://codecov.io/gh/JuliaArrays/FillArrays.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaArrays/FillArrays.jl)\n[![deps](https://juliahub.com/docs/FillArrays/deps.svg)](https://juliahub.com/ui/Packages/FillArrays/2Dg1l?t=2)\n[![version](https://juliahub.com/docs/FillArrays/version.svg)](https://juliahub.com/ui/Packages/FillArrays/2Dg1l)\n[![pkgeval](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/F/FillArrays.svg)](https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html)\n[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)\n\nJulia package to lazily represent matrices filled with a single entry,\nas well as identity matrices.  This package exports the following types:\n`Eye`, `Fill`, `Ones`, `Zeros`, `Trues`, `Falses`, and `OneElement`.\n\n\nThe primary purpose of this package is to present a unified way of constructing\nmatrices. \nFor example, to construct a 5-by-5 `BandedMatrix` of all zeros with bandwidths `(1,2)`, one would use  \n```julia\njulia> BandedMatrix(Zeros(5,5), (1, 2))\n```\n\n## Usage\n\nHere are the matrix types:\n```julia\njulia> Zeros(5, 6)\n5×6 Zeros{Float64}\n\njulia> Zeros{Int}(2, 3)\n2×3 Zeros{Int64}\n\njulia> Zeros(Int, 2, 3) # can also specify the type as an argument\n2×3 Zeros{Int64}\n\njulia> Ones{Int}(5)\n5-element Ones{Int64}\n\njulia> Eye{Int}(5)\n 5×5 Diagonal{Int64,Ones{Int64,1,Tuple{Base.OneTo{Int64}}}}:\n  1  ⋅  ⋅  ⋅  ⋅\n  ⋅  1  ⋅  ⋅  ⋅\n  ⋅  ⋅  1  ⋅  ⋅\n  ⋅  ⋅  ⋅  1  ⋅\n  ⋅  ⋅  ⋅  ⋅  1\n\njulia> Fill(7.0f0, 3, 2)\n3×2 Fill{Float32}: entries equal to 7.0\n\njulia> Trues(2, 3)\n2×3 Ones{Bool}\n\njulia> Falses(2)\n2-element Zeros{Bool}\n\njulia> OneElement(3.0, (2,1), (5,6))\n5×6 OneElement{Float64, 2, Tuple{Int64, Int64}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}:\n  ⋅    ⋅    ⋅    ⋅    ⋅    ⋅ \n 3.0   ⋅    ⋅    ⋅    ⋅    ⋅ \n  ⋅    ⋅    ⋅    ⋅    ⋅    ⋅ \n  ⋅    ⋅    ⋅    ⋅    ⋅    ⋅ \n  ⋅    ⋅    ⋅    ⋅    ⋅    ⋅ \n```\n\nThey support conversion to other matrix types like `Array`, `SparseVector`, `SparseMatrix`, and `Diagonal`:\n```julia\njulia> Matrix(Zeros(5, 5))\n5×5 Array{Float64,2}:\n 0.0  0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0  0.0\n 0.0  0.0  0.0  0.0  0.0\n\njulia> SparseMatrixCSC(Zeros(5, 5))\n5×5 SparseMatrixCSC{Float64,Int64} with 0 stored entries\n\njulia> Array(Fill(7, (2,3)))\n2×3 Array{Int64,2}:\n 7  7  7\n 7  7  7\n```\n\nThere is also support for offset index ranges,\nand the type includes the `axes`:\n```julia\njulia> Ones((-3:2, 1:2))\n6×2 Ones{Float64,2,Tuple{UnitRange{Int64},UnitRange{Int64}}} with indices -3:2×1:2\n\njulia> Fill(7, ((0:2), (-1:0)))\n3×2 Fill{Int64,2,Tuple{UnitRange{Int64},UnitRange{Int64}}} with indices 0:2×-1:0: entries equal to 7\n\njulia> typeof(Zeros(5,6))\nZeros{Float64,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}\n```\n\nThese types have methods that perform many operations efficiently,\nincluding elementary algebra operations like multiplication and addition,\nas well as linear algebra methods like\n`norm`, `adjoint`, `transpose` and `vec`.\n\n## Warning!\n\nBroadcasting operations and `map`, `mapreduce` are also done efficiently, by evaluating the function being applied only once:\n\n```julia\njulia> map(sqrt, Fill(4, 2,5))  # one evaluation, not 10, to save time\n2×5 Fill{Float64}: entries equal to 2.0\n\njulia> println.(Fill(pi, 10))\nπ\n10-element Fill{Nothing}: entries equal to nothing\n```\n\nNotice that this will only match the behaviour of a dense matrix from `fill` if the function is pure. And that this shortcut is taken *before* any other fused broadcast:\n\n```julia\njulia> map(_ -> rand(), Fill(\"pi\", 2,5))  # not a pure function!\n2×5 Fill{Float64}: entries equal to 0.7201617100284206\n\njulia> map(_ -> rand(), fill(\"4\", 2,5))  # 10 evaluations, different answer!\n2×5 Matrix{Float64}:\n 0.43675   0.270809  0.56536   0.0948089  0.24655\n 0.959363  0.79598   0.238662  0.401909   0.317716\n\njulia> ones(1,5) .+ (_ -> rand()).(Fill(\"vec\", 2))  # Fill broadcast is done first\n2×5 Matrix{Float64}:\n 1.51796  1.51796  1.51796  1.51796  1.51796\n 1.51796  1.51796  1.51796  1.51796  1.51796\n\njulia> ones(1,5) .+ (_ -> rand()).(fill(\"vec\", 2))  # fused, 10 evaluations\n2×5 Matrix{Float64}:\n 1.51337  1.17578  1.19815  1.43035  1.2987\n 1.30253  1.21909  1.61755  1.02645  1.77681\n```\n"
  },
  {
    "path": "appveyor.yml",
    "content": "environment:\n  matrix:\n  - julia_version: 1\n  - julia_version: 1.5\n  - julia_version: nightly\n\nplatform:\n  - x86 # 32-bit\n  - x64 # 64-bit\n\n# # Uncomment the following lines to allow failures on nightly julia\n# # (tests will run but not make your overall status red)\nmatrix:\n  allow_failures:\n  - julia_version: nightly\n\nbranches:\n  only:\n    - master\n    - /release-.*/\n\nnotifications:\n  - provider: Email\n    on_build_success: false\n    on_build_failure: false\n    on_build_status_changed: false\n\ninstall:\n  - ps: iex ((new-object net.webclient).DownloadString(\"https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1\"))\n\nbuild_script:\n  - echo \"%JL_BUILD_SCRIPT%\"\n  - C:\\julia\\bin\\julia -e \"%JL_BUILD_SCRIPT%\"\n\ntest_script:\n  - echo \"%JL_TEST_SCRIPT%\"\n  - C:\\julia\\bin\\julia -e \"%JL_TEST_SCRIPT%\"\n\n# # Uncomment to support code coverage upload. Should only be enabled for packages\n# # which would have coverage gaps without running on Windows\n# on_success:\n#   - echo \"%JL_CODECOV_SCRIPT%\"\n#   - C:\\julia\\bin\\julia -e \"%JL_CODECOV_SCRIPT%\"\n"
  },
  {
    "path": "benchmark/benchmarks.jl",
    "content": "using BenchmarkTools\nusing FillArrays\nusing LinearAlgebra: triu, tril\n\n# Subtract the overhead from benchmark times\nBenchmarkTools.DEFAULT_PARAMETERS.overhead = BenchmarkTools.estimate_overhead()\n\nconst SUITE = BenchmarkGroup()\n\n###\n### Eye\n###\n\ng = addgroup!(SUITE, \"Eye\", [])\n\neye1float = Eye{Float64}(1)\neye10float = Eye{Float64}(10)\neye1000float = Eye{Float64}(1000)\neye10int = Eye{Int}(10)\neye1000int = Eye{Int}(1000)\n\nr1 = addgroup!(g, \"reduction\", [])\nr2 = addgroup!(g, \"properties\", [\"properties\"])\nr3 = addgroup!(g, \"any/all\", [])\nr4 = addgroup!(g, \"iterate\", [])\nr5 = addgroup!(g, \"identities\", [])\n\ndimstring(a) = string(\"n=\", size(a, 1))\nfulldimstring(a) = string(\"size=\", size(a))\nfunop(fun, op) = string(fun,\"(\", op, \", a)\")\n\nfor a in (eye10float, eye1000float, eye10int, eye1000int)\n    for fun in (sum,)\n        r1[string(fun), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($a)\n    end\n    for fun in (isone, iszero)\n        r2[string(fun), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($a)\n    end\n    for (fun, op) in ((any, isone), (all, isone))\n        r3[funop(fun, op), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($op, $a)\n    end\n    for fun in (collect,)\n        r4[string(fun), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($a)\n    end\n    for fun in (permutedims, triu, tril, inv)\n        r5[string(fun), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($a)\n    end\nend\n\nfor a in (eye1float,)\n    for (fun, op) in ((any, isone), (all, isone))\n        r3[funop(fun, op), string(eltype(a)), dimstring(a)] = @benchmarkable $fun($op, $a)\n    end\nend\n\n###\n### Zeros\n###\n\ng1 = addgroup!(SUITE, \"Zeros\", [])\n\nzeros10 = Zeros(10)\nzeros10x10 = Zeros(10, 10)\n\nz1 = addgroup!(g1, \"properties\", [\"properties\"])\n\nfor a in (zeros10, zeros10x10)\n    for fun in (iszero, )\n        z1[string(fun), string(eltype(a)), fulldimstring(a)] = @benchmarkable $fun($a)\n    end\nend\n\n# If a cache of tuned parameters already exists, use it, otherwise, tune and cache\n# the benchmark parameters. Reusing cached parameters is faster and more reliable\n# than re-tuning `SUITE` every time the file is included.\nparamspath = joinpath(dirname(@__FILE__), \"params.json\")\n\nif isfile(paramspath)\n    loadparams!(SUITE, BenchmarkTools.load(paramspath)[1], :evals);\nelse\n    tune!(SUITE)\n    BenchmarkTools.save(paramspath, params(SUITE));\nend\n\nresult = run(SUITE, verbose = true)\n"
  },
  {
    "path": "docs/Project.toml",
    "content": "[deps]\nDocumenter = \"e30172f5-a6a5-5a46-863b-614d45cd2de4\"\nFillArrays = \"1a297f60-69ca-5386-bcde-b61e274b549b\"\nRandom = \"9a3f8284-a2c9-5f02-9a11-845980a1fd5c\"\nSparseArrays = \"2f01184e-e22b-5df5-ae63-d93ebab69eaf\"\nStaticArrays = \"90137ffa-7385-5640-81b9-e52037218182\"\n\n[compat]\nDocumenter = \"1\"\nRandom = \"1\"\nSparseArrays = \"1\"\nStaticArrays = \"1\"\n"
  },
  {
    "path": "docs/make.jl",
    "content": "using Documenter\nusing FillArrays\n\n# Setup for doctests in docstrings\nDocMeta.setdocmeta!(FillArrays, :DocTestSetup, :(using FillArrays))\n\nmakedocs(;\n    format = Documenter.HTML(\n        canonical = \"https://JuliaArrays.github.io/FillArrays.jl/stable/\",\n    ),\n    pages = [\n        \"Home\" => \"index.md\",\n        ],\n    sitename = \"FillArrays.jl\",\n)\n\ndeploydocs(; repo = \"github.com/JuliaArrays/FillArrays.jl\")\n"
  },
  {
    "path": "docs/src/index.md",
    "content": "```@meta\nDocTestSetup  = quote\n    using FillArrays\nend\n```\n\n# Introduction\n\n`FillArrays` allows one to lazily represent arrays filled with a single entry, as well as identity matrices. This package exports the following types: `Eye`, `Fill`, `Ones`, `Zeros`, `Trues` and `Falses`. Among these, the [`FillArrays.AbstractFill`](@ref) types represent lazy versions of dense arrays where all elements have the same value. `Eye`, on the other hand, represents a `Diagonal` matrix with ones along the principal diagonal. All these types accept sizes or axes as arguments, so one may create arrays of arbitrary sizes and dimensions. A rectangular `Eye` matrix may be constructed analogously, by passing the size of the matrix to `Eye`.\n\n## Quick Start\n\nCreate a 2x2 zero matrix\n\n```jldoctest\njulia> z = Zeros(2,2)\n2×2 Zeros{Float64}\n\njulia> Array(z)\n2×2 Matrix{Float64}:\n 0.0  0.0\n 0.0  0.0\n```\n\nWe may specify the element type as\n\n```jldoctest\njulia> z = Zeros{Int}(2,2)\n2×2 Zeros{Int64}\n\njulia> Array(z)\n2×2 Matrix{Int64}:\n 0  0\n 0  0\n```\n\nWe may create arrays with any number of dimensions. A `Vector` of ones may be created as\n\n```jldoctest\njulia> a = Ones(4)\n4-element Ones{Float64}\n\njulia> Array(a)\n4-element Vector{Float64}:\n 1.0\n 1.0\n 1.0\n 1.0\n```\n\nSimilarly, a `2x3x2` array, where every element is equal to `10`, may be created as\n\n```jldoctest\njulia> f = Fill(10, 2,3,2)\n2×3×2 Fill{Int64}, with entries equal to 10\n\njulia> Array(f)\n2×3×2 Array{Int64, 3}:\n[:, :, 1] =\n 10  10  10\n 10  10  10\n\n[:, :, 2] =\n 10  10  10\n 10  10  10\n```\n\nThe elements of a `Fill` array don't need to be restricted to numbers, and these may be any Julia object. For example, we may construct an array of strings using\n\n```jldoctest\njulia> f = Fill(\"hello\", 2,5)\n2×5 Fill{String}, with entries equal to \"hello\"\n\njulia> Array(f)\n2×5 Matrix{String}:\n \"hello\"  \"hello\"  \"hello\"  \"hello\"  \"hello\"\n \"hello\"  \"hello\"  \"hello\"  \"hello\"  \"hello\"\n```\n\n### Conversion to a sparse form\n\nThese `Fill` array types may be converted to sparse arrays as well, which might be useful in certain cases\n```jldoctest sparse\njulia> using SparseArrays\n\njulia> z = Zeros{Int}(2,2)\n2×2 Zeros{Int64}\n\njulia> sparse(z)\n2×2 SparseMatrixCSC{Int64, Int64} with 0 stored entries:\n ⋅  ⋅\n ⋅  ⋅\n```\nNote, however, that most `Fill` arrays are not sparse, despite being lazily evaluated.\n\nThese types have methods that perform many operations efficiently, including elementary algebra operations like multiplication and addition, as well as linear algebra methods like `norm`, `adjoint`, `transpose` and `vec`.\n\n### Custom axes\n\nThe various `Fill` equivalents all support offset or custom axes, where instead of the size, one may pass a `Tuple` of axes. So, for example, one may use a `SOneTo` axis from [`StaticArrays.jl`](https://github.com/JuliaArrays/StaticArrays.jl) to construct a statically sized `Fill`.\n\n```jldoctest\njulia> using StaticArrays\n\njulia> f = Fill(2, (SOneTo(4), SOneTo(5)))\n4×5 Fill{Int64, 2, Tuple{SOneTo{4}, SOneTo{5}}} with indices SOneTo(4)×SOneTo(5), with entries equal to 2\n```\n\nThe size of such an array would be known at compile time, permitting compiler optimizations.\n\nWe may construct infinite fill arrays by passing infinite-sized axes, see [`InfiniteArrays.jl`](https://github.com/JuliaArrays/InfiniteArrays.jl).\n\n### Other lazy types\n\nA lazy representation of an identity matrix may be constructured using `Eye`. For example, a `4x4` identity matrix with `Float32` elements may be constructed as\n\n```jldoctest sparse\njulia> id = Eye{Float32}(4)\n4×4 Eye{Float32}\n\njulia> Array(id)\n4×4 Matrix{Float32}:\n 1.0  0.0  0.0  0.0\n 0.0  1.0  0.0  0.0\n 0.0  0.0  1.0  0.0\n 0.0  0.0  0.0  1.0\n\njulia> sparse(id)\n4×4 SparseMatrixCSC{Float32, Int64} with 4 stored entries:\n 1.0   ⋅    ⋅    ⋅\n  ⋅   1.0   ⋅    ⋅\n  ⋅    ⋅   1.0   ⋅\n  ⋅    ⋅    ⋅   1.0\n\njulia> idrect = Eye(2,5) # rectangular matrix\n2×5 Eye{Float64}\n\njulia> sparse(idrect)\n2×5 SparseMatrixCSC{Float64, Int64} with 2 stored entries:\n 1.0   ⋅    ⋅    ⋅    ⋅\n  ⋅   1.0   ⋅    ⋅    ⋅\n```\n\nNote that an `Eye` actually returns a `Diagonal` matrix, where the diagonal is a `Ones` vector.\n\n## Warning about map and broadcasting\n\nBroadcasting operations, and `map` and `mapreduce`, are also done efficiently, by evaluating the function being applied only once:\n\n```jldoctest\njulia> map(sqrt, Fill(4, 2,5))  # one evaluation, not 10, to save time\n2×5 Fill{Float64}, with entries equal to 2.0\n\njulia> println.(Fill(pi, 10))\nπ\n10-element Fill{Nothing}, with entries equal to nothing\n```\n\nNotice that this will only match the behaviour of a dense matrix from `fill` if the function is pure. And that this shortcut is taken before any other fused broadcast:\n\n```jldoctest; setup=:(using Random; Random.seed!(1234))\njulia> map(_ -> rand(), Fill(\"pi\", 2,5))  # not a pure function!\n2×5 Fill{Float64}, with entries equal to 0.32597672886359486\n\njulia> map(_ -> rand(), fill(\"4\", 2,5))  # 10 evaluations, different answer!\n2×5 Matrix{Float64}:\n 0.549051  0.894245  0.394255  0.795547  0.748415\n 0.218587  0.353112  0.953125  0.49425   0.578232\n\njulia> ones(1,5) .+ (_ -> rand()).(Fill(\"vec\", 2))  # Fill broadcast is done first\n2×5 Matrix{Float64}:\n 1.72794  1.72794  1.72794  1.72794  1.72794\n 1.72794  1.72794  1.72794  1.72794  1.72794\n\njulia> ones(1,5) .+ (_ -> rand()).(fill(\"vec\", 2))  # fused, 10 evaluations\n2×5 Matrix{Float64}:\n 1.00745  1.43924  1.95674  1.99667  1.11008\n 1.19938  1.68253  1.64786  1.74919  1.49138\n```\n\n# API\n\n```@autodocs\nModules = [FillArrays]\n```\n"
  },
  {
    "path": "ext/FillArraysPDMatsExt.jl",
    "content": "module FillArraysPDMatsExt\n\nimport FillArrays\nimport FillArrays.LinearAlgebra\nimport PDMats\nusing FillArrays: mult_zeros, AbstractZeros\nusing PDMats: ScalMat\n\nfunction PDMats.AbstractPDMat(a::LinearAlgebra.Diagonal{T,<:FillArrays.AbstractFill{T,1}}) where {T<:Real}\n    dim = size(a, 1)\n    return ScalMat(dim, FillArrays.getindex_value(a.diag))\nend\n\nBase.:*(a::ScalMat, b::AbstractZeros{T, 1} where T) = mult_zeros(a, b)\nBase.:*(a::ScalMat, b::AbstractZeros{T, 2} where T) = mult_zeros(a, b)\nBase.:*(a::AbstractZeros{T, 2} where T, b::ScalMat) = mult_zeros(a, b) # This is implemented in case ScalMat implements right multiplication\n\nend # module\n"
  },
  {
    "path": "ext/FillArraysSparseArraysExt.jl",
    "content": "module FillArraysSparseArraysExt\n\nusing SparseArrays\nusing SparseArrays: SparseVectorUnion\nimport Base: convert, kron\nusing FillArrays\nusing FillArrays: RectDiagonalFill, RectOrDiagonalFill, ZerosVector, ZerosMatrix, getindex_value, AbstractFillVector, _fill_dot\n# Specifying the full namespace is necessary because of https://github.com/JuliaLang/julia/issues/48533\n# See https://github.com/JuliaStats/LogExpFunctions.jl/pull/63\nusing FillArrays.LinearAlgebra\nimport LinearAlgebra: dot, kron, I\n\n##################\n## Sparse arrays\n##################\nSparseVector{T}(Z::ZerosVector) where T = spzeros(T, length(Z))\nSparseVector{Tv,Ti}(Z::ZerosVector) where {Tv,Ti} = spzeros(Tv, Ti, length(Z))\n\nconvert(::Type{AbstractSparseVector}, Z::ZerosVector{T}) where T = spzeros(T, length(Z))\nconvert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, length(Z))\n\nSparseMatrixCSC{T}(Z::ZerosMatrix) where T = spzeros(T, size(Z)...)\nSparseMatrixCSC{Tv,Ti}(Z::Zeros{T,2,Axes}) where {Tv,Ti<:Integer,T,Axes} = spzeros(Tv, Ti, size(Z)...)\n\nconvert(::Type{AbstractSparseMatrix}, Z::ZerosMatrix{T}) where T = spzeros(T, size(Z)...)\nconvert(::Type{AbstractSparseMatrix{T}}, Z::ZerosMatrix) where T = spzeros(T, size(Z)...)\n\nconvert(::Type{AbstractSparseArray}, Z::Zeros{T}) where T = spzeros(T, size(Z)...)\nconvert(::Type{AbstractSparseArray{Tv}}, Z::Zeros{T}) where {T,Tv} = spzeros(Tv, size(Z)...)\nconvert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Zeros{T}) where {T,Tv,Ti} = spzeros(Tv, Ti, size(Z)...)\nconvert(::Type{AbstractSparseArray{Tv,Ti,N}}, Z::Zeros{T,N}) where {T,Tv,Ti,N} = spzeros(Tv, Ti, size(Z)...)\n\nSparseMatrixCSC{Tv}(Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)\n# works around missing `speye`:\nSparseMatrixCSC{Tv,Ti}(Z::Eye{T}) where {T,Tv,Ti<:Integer} =\n    convert(SparseMatrixCSC{Tv,Ti}, SparseMatrixCSC{Tv}(I, size(Z)...))\n\nconvert(::Type{AbstractSparseMatrix}, Z::Eye{T}) where {T} = SparseMatrixCSC{T}(I, size(Z)...)\nconvert(::Type{AbstractSparseMatrix{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)\n\nconvert(::Type{AbstractSparseArray}, Z::Eye{T}) where T = SparseMatrixCSC{T}(I, size(Z)...)\nconvert(::Type{AbstractSparseArray{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)\n\n\nconvert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Eye{T}) where {T,Tv,Ti} =\n    convert(SparseMatrixCSC{Tv,Ti}, Z)\nconvert(::Type{AbstractSparseArray{Tv,Ti,2}}, Z::Eye{T}) where {T,Tv,Ti} =\n    convert(SparseMatrixCSC{Tv,Ti}, Z)\n\nfunction SparseMatrixCSC{Tv}(R::RectOrDiagonalFill) where {Tv}\n    SparseMatrixCSC{Tv,eltype(axes(R,1))}(R)\nend\nfunction SparseMatrixCSC{Tv,Ti}(R::RectOrDiagonalFill) where {Tv,Ti}\n    Base.require_one_based_indexing(R)\n    v = parent(R)\n    J = getindex_value(v)*I\n    SparseMatrixCSC{Tv,Ti}(J, size(R))\nend\n\n# TODO: remove in v2.0\n@deprecate kron(E1::RectDiagonalFill, E2::RectDiagonalFill) kron(sparse(E1), sparse(E2))\n\n# Ambiguity. see #178\ndot(x::AbstractFillVector, y::SparseVectorUnion) = _fill_dot(x, y)\n\nend # module\n"
  },
  {
    "path": "ext/FillArraysStaticArraysExt.jl",
    "content": "module FillArraysStaticArraysExt\n\nusing FillArrays\nusing StaticArrays\n\nimport Base: promote_op\nimport FillArrays: elconvert\n\n# Disambiguity methods for StaticArrays\n\nfunction Base.:+(a::FillArrays.Zeros, b::StaticArray)\n    promote_shape(a,b)\n    return elconvert(promote_op(+,eltype(a),eltype(b)),b)\nend\nfunction Base.:+(a::StaticArray, b::FillArrays.Zeros)\n    promote_shape(a,b)\n    return elconvert(promote_op(+,eltype(a),eltype(b)),a)\nend\nfunction Base.:-(a::StaticArray, b::FillArrays.Zeros)\n    promote_shape(a,b)\n    return elconvert(promote_op(-,eltype(a),eltype(b)),a)\nend\nfunction Base.:-(a::FillArrays.Zeros, b::StaticArray)\n    promote_shape(a,b)\n    return elconvert(promote_op(-,eltype(a),eltype(b)),-b)\nend\n\nend # module"
  },
  {
    "path": "ext/FillArraysStatisticsExt.jl",
    "content": "module FillArraysStatisticsExt\n\nimport Statistics: mean, var, cov, cor\nusing LinearAlgebra: diagind\n\nusing FillArrays\nusing FillArrays: AbstractFill, AbstractFillVector, AbstractFillMatrix, getindex_value\n\nmean(A::AbstractFill; dims=(:)) = mean(identity, A; dims=dims)\nfunction mean(f::Union{Function, Type}, A::AbstractFill; dims=(:))\n    val = float(f(getindex_value(A)))\n    dims isa Colon ? val :\n        Fill(val, ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)\nend\n\n\nfunction var(A::AbstractFill{T}; corrected::Bool=true, mean=nothing, dims=(:)) where {T<:Number}\n    dims isa Colon ? zero(float(T)) :\n        Zeros{float(T)}(ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)\nend\n\ncov(::AbstractFillVector{T}; corrected::Bool=true) where {T<:Number} = zero(float(T))\ncov(A::AbstractFillMatrix{T}; corrected::Bool=true, dims::Integer=1) where {T<:Number} =\n    Zeros{float(T)}(size(A, 3-dims), size(A, 3-dims))\n\ncor(::AbstractFillVector{T}) where {T<:Number} = one(float(T))\nfunction cor(A::AbstractFillMatrix{T}; dims::Integer=1) where {T<:Number}\n    out = fill(float(T)(NaN), size(A, 3-dims), size(A, 3-dims))\n    out[diagind(out)] .= 1\n    out\nend\n\nend # module\n"
  },
  {
    "path": "src/FillArrays.jl",
    "content": "\"\"\" `FillArrays` module to lazily represent matrices with a single value \"\"\"\nmodule FillArrays\n\nusing LinearAlgebra\nimport Base: size, getindex, setindex!, IndexStyle, checkbounds, convert,\n    +, -, *, /, \\, diff, sum, cumsum, maximum, minimum, sort, sort!,\n    any, all, axes, isone, iszero, iterate, unique, allunique, permutedims, inv,\n    copy, vec, setindex!, count, ==, reshape, map, zero,\n    show, view, in, mapreduce, one, reverse, promote_op, promote_rule, repeat,\n    parent, similar, issorted, add_sum, accumulate, OneTo, permutedims\n\nimport LinearAlgebra: rank, svdvals!, tril, triu, tril!, triu!, diag, transpose, adjoint, fill!,\n    dot, norm2, norm1, normInf, normMinusInf, normp, lmul!, rmul!, diagzero, AdjointAbsVec, TransposeAbsVec,\n    issymmetric, ishermitian, AdjOrTransAbsVec, checksquare, mul!, kron, AbstractTriangular\n\n\nimport Base.Broadcast: broadcasted, DefaultArrayStyle, broadcast_shape, BroadcastStyle, Broadcasted\n\nexport Zeros, Ones, Fill, Eye, Trues, Falses, OneElement\n\nimport Base: oneto\n\n\"\"\"\n    AbstractFill{T, N, Axes} <: AbstractArray{T, N}\n\nSupertype for lazy array types whose entries are all equal.\nSubtypes of `AbstractFill` should implement [`FillArrays.getindex_value`](@ref) to return the value of the entries.\n\"\"\"\nabstract type AbstractFill{T, N, Axes} <: AbstractArray{T, N} end\nconst AbstractFillVector{T} = AbstractFill{T,1}\nconst AbstractFillMatrix{T} = AbstractFill{T,2}\nconst AbstractFillVecOrMat{T} = Union{AbstractFillVector{T},AbstractFillMatrix{T}}\n\n==(a::AbstractFill, b::AbstractFill) = axes(a) == axes(b) && getindex_value(a) == getindex_value(b)\n\n@inline function Base.isassigned(F::AbstractFill, i::Integer...)\n    @boundscheck checkbounds(Bool, F, to_indices(F, i)...) || return false\n    return true\nend\n\n@inline function _fill_getindex(F::AbstractFill, kj::Integer...)\n    @boundscheck checkbounds(F, kj...)\n    getindex_value(F)\nend\n\nBase.@propagate_inbounds getindex(F::AbstractFill, k::Integer) = _fill_getindex(F, k)\nBase.@propagate_inbounds getindex(F::AbstractFill{T, N}, kj::Vararg{Integer, N}) where {T, N} = _fill_getindex(F, kj...)\n\n@inline function setindex!(F::AbstractFill, v, k::Integer)\n    @boundscheck checkbounds(F, k)\n    v == getindex_value(F) || throw(ArgumentError(LazyString(\"Cannot setindex! to \", v, \" for an AbstractFill with value \", getindex_value(F), \".\")))\n    F\nend\n\n@inline function setindex!(F::AbstractFill{T, N}, v, kj::Vararg{Integer, N}) where {T, N}\n    @boundscheck checkbounds(F, kj...)\n    v == getindex_value(F) || throw(ArgumentError(LazyString(\"Cannot setindex! to \", v, \" for an AbstractFill with value \", getindex_value(F), \".\")))\n    F\nend\n\n@inline function fill!(F::AbstractFill, v)\n    v == getindex_value(F) || throw(ArgumentError(LazyString(\"Cannot fill! with \", v, \" an AbstractFill with value \", getindex_value(F), \".\")))\n    F\nend\n\nrank(F::AbstractFill) = iszero(getindex_value(F)) ? 0 : 1\nIndexStyle(::Type{<:AbstractFill{<:Any,N,<:NTuple{N,Base.OneTo{Int}}}}) where N = IndexLinear()\n\nissymmetric(F::AbstractFillMatrix) = axes(F,1) == axes(F,2) && (isempty(F) || issymmetric(getindex_value(F)))\nishermitian(F::AbstractFillMatrix) = axes(F,1) == axes(F,2) && (isempty(F) || ishermitian(getindex_value(F)))\n\nBase.IteratorSize(::Type{<:AbstractFill{T,N,Axes}}) where {T,N,Axes} = _IteratorSize(Axes)\n_IteratorSize(::Type{Tuple{}}) = Base.HasShape{0}()\n_IteratorSize(::Type{Tuple{T}}) where {T} = Base.IteratorSize(T)\nfunction _IteratorSize(::Type{T}) where {T<:Tuple}\n    N = fieldcount(T)\n    s = ntuple(i-> Base.IteratorSize(fieldtype(T, i)), N)\n    any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}()\nend\n\n\n\"\"\"\n    Fill{T, N, Axes} where {T,N,Axes<:Tuple{Vararg{AbstractUnitRange,N}}}\n\nA lazy representation of an array of dimension `N`\nwhose entries are all equal to a constant of type `T`,\nwith axes of type `Axes`.\nTypically created by `Fill` or `Zeros` or `Ones`\n\n# Examples\n\n```jldoctest\njulia> Fill(7, (2,3))\n2×3 Fill{Int64}, with entries equal to 7\n\njulia> Fill{Float64, 1, Tuple{UnitRange{Int64}}}(7.0, (1:2,))\n2-element Fill{Float64, 1, Tuple{UnitRange{Int64}}} with indices 1:2, with entries equal to 7.0\n```\n\"\"\"\nstruct Fill{T, N, Axes} <: AbstractFill{T, N, Axes}\n    value::T\n    axes::Axes\n\n    Fill{T,N,Axes}(x::T, sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =\n        new{T,N,Axes}(x,sz)\n    Fill{T,0,Tuple{}}(x::T, sz::Tuple{}) where T = new{T,0,Tuple{}}(x,sz)\nend\nconst FillVector{T} = Fill{T,1}\nconst FillMatrix{T} = Fill{T,2}\nconst FillVecOrMat{T} = Union{FillVector{T},FillMatrix{T}}\n\nFill{T,N,Axes}(x, sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =\n    Fill{T,N,Axes}(convert(T, x)::T, sz)\n\nFill{T,0}(x, ::Tuple{}) where T = Fill{T,0,Tuple{}}(convert(T, x)::T, ()) # ambiguity fix\n\n@inline Fill{T, N}(x, sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =\n    Fill{T,N,Axes}(convert(T, x)::T, sz)\n\n@inline Fill{T, N}(x, sz::SZ) where SZ<:Tuple{Vararg{Integer,N}} where {T, N} =\n    Fill{T,N}(x, oneto.(sz))\n@inline Fill{T, N}(x, sz::Vararg{Integer, N}) where {T, N} = Fill{T,N}(convert(T, x)::T, sz)\n\n\n@inline Fill{T}(x, sz::Vararg{Integer,N}) where {T, N} = Fill{T, N}(x, sz)\n@inline Fill{T}(x, sz::Tuple{Vararg{Any,N}}) where {T, N} = Fill{T, N}(x, sz)\n\"\"\" `Fill(x, dims...)` construct lazy version of `fill(x, dims...)` \"\"\"\n@inline Fill(x::T, sz::Vararg{Integer,N}) where {T, N}  = Fill{T, N}(x, sz)\n\"\"\" `Fill(x, dims)` construct lazy version of `fill(x, dims)` \"\"\"\n@inline Fill(x::T, sz::Tuple{Vararg{Any,N}}) where {T, N}  = Fill{T, N}(x, sz)\n\n# We restrict to  when T is specified to avoid ambiguity with a Fill of a Fill\n@inline Fill{T}(F::Fill{T}) where T = F\n@inline Fill{T,N}(F::Fill{T,N}) where {T,N} = F\n@inline Fill{T,N,Axes}(F::Fill{T,N,Axes}) where {T,N,Axes} = F\n\n@inline axes(F::Fill) = F.axes\n@inline size(F::Fill) = map(length, F.axes)\n\n\"\"\"\n    FillArrays.getindex_value(F::AbstractFill)\n\nReturn the value that `F` is filled with.\n\n# Examples\n\n```jldoctest\njulia> f = Ones(3);\n\njulia> FillArrays.getindex_value(f)\n1.0\n\njulia> g = Fill(2, 10);\n\njulia> FillArrays.getindex_value(g)\n2\n```\n\"\"\"\ngetindex_value\n\n@inline getindex_value(F::Fill) = F.value\n\nAbstractArray{T,N}(F::Fill{V,N}) where {T,V,N} = Fill{T}(convert(T, F.value)::T, F.axes)\nAbstractFill{T}(F::AbstractFill) where T = AbstractArray{T}(F)\nAbstractFill{T,N}(F::AbstractFill) where {T,N} = AbstractArray{T,N}(F)\nAbstractFill{T,N,Ax}(F::AbstractFill{<:Any,N,Ax}) where {T,N,Ax} = AbstractArray{T,N}(F)\n\nconvert(::Type{AbstractFill{T}}, F::AbstractFill) where T = convert(AbstractArray{T}, F)\nconvert(::Type{AbstractFill{T,N}}, F::AbstractFill) where {T,N} = convert(AbstractArray{T,N}, F)\nconvert(::Type{AbstractFill{T,N,Ax}}, F::AbstractFill{<:Any,N,Ax}) where {T,N,Ax} = convert(AbstractArray{T,N}, F)\n\ncopy(F::Fill) = Fill(F.value, F.axes)\n\n\"\"\"\n    unique_value(arr::AbstractArray)\n\nReturn `only(unique(arr))` without intermediate allocations.\nThrows an error if `arr` does not contain one and only one unique value.\n\"\"\"\nfunction unique_value(arr::AbstractArray)\n    if isempty(arr) error(\"Cannot convert empty array to Fill\") end\n    val = first(arr)\n    for x in arr\n        if x !== val\n            error(LazyString(\"Input array contains both \", x, \" and \", val, \". Cannot convert to Fill\"))\n        end\n    end\n    return val\nend\nunique_value(f::AbstractFill) = getindex_value(f)\nconvert(::Type{Fill}, arr::AbstractArray{T}) where T = Fill{T}(unique_value(arr), axes(arr))\nconvert(::Type{Fill{T}}, arr::AbstractArray) where T = Fill{T}(unique_value(arr), axes(arr))\nconvert(::Type{Fill{T,N}}, arr::AbstractArray{<:Any,N}) where {T,N} = Fill{T,N}(unique_value(arr), axes(arr))\nconvert(::Type{Fill{T,N,Axes}}, arr::AbstractArray{<:Any,N}) where {T,N,Axes} = Fill{T,N,Axes}(unique_value(arr), axes(arr))\n# ambiguity fix\nconvert(::Type{Fill}, arr::Fill{T}) where T = Fill{T}(unique_value(arr), axes(arr))\nconvert(::Type{T}, F::T) where T<:Fill = F\n\n\n\ngetindex(F::Fill{<:Any,0}) = getindex_value(F)\n\nBase.@propagate_inbounds @inline function _fill_getindex(A::AbstractFill, I::Vararg{Union{Real, AbstractArray}, N}) where N\n    @boundscheck checkbounds(A, I...)\n    shape = Base.index_shape(I...)\n    fillsimilar(A, shape)\nend\n\nBase.@propagate_inbounds @inline function _fill_getindex(A::AbstractFill, kr::AbstractArray{Bool})\n   @boundscheck checkbounds(A, kr)\n   fillsimilar(A, count(kr))\nend\n\nBase.@propagate_inbounds @inline Base._unsafe_getindex(::IndexStyle, F::AbstractFill, I::Vararg{Union{Real, AbstractArray}}) =\n    _fill_getindex(F, I...)\n\n\n\nBase.@propagate_inbounds getindex(A::AbstractFill, kr::AbstractVector{Bool}) = _fill_getindex(A, kr)\nBase.@propagate_inbounds getindex(A::AbstractFill, kr::AbstractArray{Bool}) = _fill_getindex(A, kr)\n\n@inline Base.iterate(F::AbstractFill) = length(F) == 0 ? nothing : (v = getindex_value(F); (v, (v, 1)))\n@inline function Base.iterate(F::AbstractFill, (v, n))\n    1 <= n < length(F) || return nothing\n    v, (v, n+1)\nend\n\n# Iterators\nIterators.rest(F::AbstractFill, (_,n)) = fillsimilar(F, n <= 0 ? 0 : max(length(F)-n, 0))\nfunction Iterators.drop(F::AbstractFill, n::Integer)\n    n >= 0 || throw(ArgumentError(\"drop length must be nonnegative\"))\n    fillsimilar(F, max(length(F)-n, 0))\nend\nfunction Iterators.take(F::AbstractFill, n::Integer)\n    n >= 0 || throw(ArgumentError(\"take length must be nonnegative\"))\n    fillsimilar(F, min(n, length(F)))\nend\nBase.rest(F::AbstractFill, s) = Iterators.rest(F, s)\n\n#################\n# Sorting\n#################\nfunction issorted(f::AbstractFill; kw...)\n    v = getindex_value(f)\n    issorted((v, v); kw...)\nend\nfunction sort(a::AbstractFill; kwds...)\n    issorted(a; kwds...) # ensure that the values may be compared\n    return a\nend\nfunction sort!(a::AbstractFill; kwds...)\n    issorted(a; kwds...) # ensure that the values may be compared\n    return a\nend\n\nsvdvals!(a::AbstractFillMatrix) = [getindex_value(a)*sqrt(prod(size(a))); Zeros(min(size(a)...)-1)]\n\nfunction fill_reshape(parent, dims::Integer...)\n    n = length(parent)\n    prod(dims) == n || throw(DimensionMismatch(LazyString(\"parent has \", n, \" elements, which is incompatible with size \", dims)))\n    fillsimilar(parent, dims...)\nend\n\nif VERSION < v\"1.12.0-DEV.1726\"\n    # resolve ambiguity with Base\n    reshape(parent::AbstractFillVector, ::Colon) = parent\n    reshape(parent::AbstractFill, dims::Integer...) = reshape(parent, dims)\n    reshape(parent::AbstractFill, dims::Union{Int,Colon}...) = reshape(parent, dims)\n    reshape(parent::AbstractFill, dims::Union{Integer,Colon}...) = reshape(parent, dims)\n    reshape(parent::AbstractFill, dims::Tuple{Vararg{Union{Integer,Colon}}}) =\n        fill_reshape(parent, Base._reshape_uncolon(parent, dims)...)\n    reshape(parent::AbstractFill, dims::Tuple{Vararg{Union{Int,Colon}}}) =\n        fill_reshape(parent, Base._reshape_uncolon(parent, dims)...)\n    reshape(parent::AbstractFill, shp::Tuple{Union{Integer,Base.OneTo}, Vararg{Union{Integer,Base.OneTo}}}) =\n        reshape(parent, Base.to_shape(shp))\n    # resolve ambiguity with Base\n    reshape(parent::AbstractFillVector, ::Tuple{Colon}) = parent\nend\nreshape(parent::AbstractFill, dims::Dims) = fill_reshape(parent, dims...)\nreshape(parent::AbstractFill, dims::Tuple{Integer, Vararg{Integer}}) = fill_reshape(parent, dims...)\n\n\nfor (AbsTyp, Typ, funcs, func) in ((:AbstractZeros, :Zeros, :zeros, :zero), (:AbstractOnes, :Ones, :ones, :one))\n    @eval begin\n        abstract type $AbsTyp{T, N, Axes} <: AbstractFill{T, N, Axes} end\n        $(Symbol(AbsTyp,\"Vector\")){T} = $AbsTyp{T,1}\n        $(Symbol(AbsTyp,\"Matrix\")){T} = $AbsTyp{T,2}\n        $(Symbol(AbsTyp,\"VecOrMat\")){T} = Union{$(Symbol(AbsTyp,\"Vector\")){T},$(Symbol(AbsTyp,\"Matrix\"))}\n\n        \"\"\" `$($Typ){T, N, Axes} <: AbstractFill{T, N, Axes}` (lazy `$($funcs)` with axes)\"\"\"\n        struct $Typ{T, N, Axes} <: $AbsTyp{T, N, Axes}\n            axes::Axes\n            @inline $Typ{T,N,Axes}(sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =\n                new{T,N,Axes}(sz)\n            @inline $Typ{T,N}(sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =\n                new{T,N,Axes}(sz)\n            @inline $Typ{T,0,Tuple{}}(sz::Tuple{}) where T = new{T,0,Tuple{}}(sz)\n        end\n        const $(Symbol(Typ,\"Vector\")){T} = $Typ{T,1}\n        const $(Symbol(Typ,\"Matrix\")){T} = $Typ{T,2}\n        const $(Symbol(Typ,\"VecOrMat\")){T} = Union{$Typ{T,1},$Typ{T,2}}\n\n\n        @inline $Typ{T, 0}(sz::Tuple{}) where {T} = $Typ{T,0,Tuple{}}(sz)\n        @inline $Typ{T, N}(sz::Tuple{Vararg{Integer, N}}) where {T, N} = $Typ{T,N}(oneto.(sz))\n        @inline $Typ{T, N}(sz::Vararg{Integer, N}) where {T, N} = $Typ{T,N}(sz)\n        \"\"\" `$($Typ){T}(dims...)` construct lazy version of `$($funcs)(dims...)`\"\"\"\n        @inline $Typ{T}(sz::Vararg{Integer,N}) where {T, N} = $Typ{T, N}(sz)\n        @inline $Typ{T}(sz::SZ) where SZ<:Tuple{Vararg{Any,N}} where {T, N} = $Typ{T, N}(sz)\n        @inline $Typ(sz::Vararg{Any,N}) where N = $Typ{Float64,N}(sz)\n        @inline $Typ(sz::SZ) where SZ<:Tuple{Vararg{Any,N}} where N = $Typ{Float64,N}(sz)\n        @inline $Typ{T}(n::Integer) where T = $Typ{T,1}(n)\n        @inline $Typ(n::Integer) = $Typ{Float64,1}(n)\n\n        @inline $Typ{T,N,Axes}(A::AbstractArray{V,N}) where{T,V,N,Axes} = $Typ{T,N,Axes}(axes(A))\n        @inline $Typ{T,N}(A::AbstractArray{V,N}) where{T,V,N} = $Typ{T,N}(size(A))\n        @inline $Typ{T}(A::AbstractArray) where{T} = $Typ{T}(size(A))\n        @inline $Typ(A::AbstractArray) = $Typ{eltype(A)}(A)\n        @inline $Typ(::Type{T}, m...) where T = $Typ{T}(m...)\n\n        @inline axes(Z::$Typ) = Z.axes\n        @inline size(Z::$AbsTyp) = length.(axes(Z))\n        @inline getindex_value(Z::$AbsTyp{T}) where T = $func(T)\n\n        AbstractArray{T}(F::$AbsTyp) where T = $Typ{T}(axes(F))\n        AbstractArray{T,N}(F::$AbsTyp{V,N}) where {T,V,N} = $Typ{T}(axes(F))\n\n        copy(F::$AbsTyp) = F\n\n        getindex(F::$AbsTyp{T,0}) where T = getindex_value(F)\n\n        promote_rule(::Type{$Typ{T, N, Axes}}, ::Type{$Typ{V, N, Axes}}) where {T,V,N,Axes} = $Typ{promote_type(T,V),N,Axes}\n        function convert(::Type{Typ}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes,Typ<:$AbsTyp{T,N,Axes}}\n            convert(T, getindex_value(A)) # checks that the types are convertible\n            Typ(axes(A))\n        end\n        convert(::Type{$Typ{T,N}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)\n        convert(::Type{$Typ{T}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)\n        function convert(::Type{Typ}, A::AbstractFill{V,N}) where {T,V,N,Axes,Typ<:$AbsTyp{T,N,Axes}}\n            axes(A) isa Axes || throw(ArgumentError(LazyString(\"cannot convert, as axes of array are not \", Axes)))\n            val = getindex_value(A)\n            y = convert(T, val)\n            y == $func(T) || throw(ArgumentError(LazyString(\"cannot convert an array containinig \", val, \" to \", Typ)))\n            Typ(axes(A))\n        end\n        function convert(::Type{$Typ{T,N}}, A::AbstractFill{<:Any,N}) where {T,N}\n            convert($Typ{T,N,typeof(axes(A))}, A)\n        end\n        function convert(::Type{$Typ{T}}, A::AbstractFill{<:Any,N}) where {T,N}\n            convert($Typ{T,N}, A)\n        end\n        function convert(::Type{$Typ}, A::AbstractFill{V,N}) where {V,N}\n            convert($Typ{V,N}, A)\n        end\n    end\nend\n\n# conversions\nfor TYPE in (:Fill, :AbstractFill, :Ones, :Zeros), STYPE in (:AbstractArray, :AbstractFill)\n    @eval begin\n        @inline $STYPE{T}(F::$TYPE{T}) where T = F\n        @inline $STYPE{T,N}(F::$TYPE{T,N}) where {T,N} = F\n    end\nend\n\npromote_rule(::Type{<:AbstractFill{T, N, Axes}}, ::Type{<:AbstractFill{V, N, Axes}}) where {T,V,N,Axes} = Fill{promote_type(T,V),N,Axes}\n\n\"\"\"\n    fillsimilar(a::AbstractFill, axes...)\n\ncreates a fill object that has the same fill value as `a` but\nwith the specified axes.\nFor example, if `a isa Zeros` then so is the returned object.\n\"\"\"\nfillsimilar(a::Ones{T}, axes...) where T = Ones{T}(axes...)\nfillsimilar(a::Zeros{T}, axes...) where T = Zeros{T}(axes...)\nfillsimilar(a::AbstractFill, axes...) = Fill(getindex_value(a), axes...)\n\n# functions\nfunction Base.sqrt(a::AbstractFillMatrix{<:Union{Real, Complex}})\n    Base.require_one_based_indexing(a)\n    size(a,1) == size(a,2) || throw(DimensionMismatch(LazyString(\"matrix is not square: dimensions are \", size(a))))\n    _sqrt(a)\nend\n_sqrt(a::AbstractZerosMatrix) = float(a)\nfunction _sqrt(a::AbstractFillMatrix)\n    n = size(a,1)\n    n == 0 && return float(a)\n    v = getindex_value(a)\n    Fill(√(v/n), axes(a))\nend\nfunction Base.cbrt(a::AbstractFillMatrix{<:Real})\n    Base.require_one_based_indexing(a)\n    size(a,1) == size(a,2) || throw(DimensionMismatch(LazyString(\"matrix is not square: dimensions are \", size(a))))\n    _cbrt(a)\nend\n_cbrt(a::AbstractZerosMatrix) = float(a)\nfunction _cbrt(a::AbstractFillMatrix)\n    n = size(a,1)\n    n == 0 && return float(a)\n    v = getindex_value(a)\n    Fill(cbrt(v)/cbrt(n)^2, axes(a))\nend\n\nstruct RectDiagonal{T,V<:AbstractVector{T},Axes<:Tuple{Vararg{AbstractUnitRange,2}}} <: AbstractMatrix{T}\n    diag::V\n    axes::Axes\n\n    @inline function RectDiagonal{T,V}(A::V, axes::Axes) where {T,V<:AbstractVector{T},Axes<:Tuple{Vararg{AbstractUnitRange,2}}}\n        Base.require_one_based_indexing(A)\n        @assert any(length(ax) == length(A) for ax in axes)\n        rd = new{T,V,Axes}(A, axes)\n        Base.require_one_based_indexing(rd)\n        return rd\n    end\nend\n\n@inline RectDiagonal{T,V}(A::V, sz::Tuple{Vararg{Integer, 2}}) where {T,V} = RectDiagonal{T,V}(A, oneto.(sz))\n@inline RectDiagonal{T,V}(A::V, axes::Vararg{Any, 2}) where {T,V} = RectDiagonal{T,V}(A, axes)\n@inline RectDiagonal{T,V}(A::V, sz::Vararg{Integer, 2}) where {T,V} = RectDiagonal{T,V}(A, sz)\n@inline RectDiagonal{T,V}(A::V) where {T,V} = RectDiagonal{T,V}(A, (axes(A, 1), axes(A, 1)))\n@inline RectDiagonal{T}(A::V, args...) where {T,V} = RectDiagonal{T,V}(A, args...)\n@inline RectDiagonal(A::V, args...) where {V} = RectDiagonal{eltype(V),V}(A, args...)\n\nconst UpperOrUnitUpperTriangular{T,S} = Union{UpperTriangular{T,S}, UnitUpperTriangular{T,S}}\nconst LowerOrUnitLowerTriangular{T,S} = Union{LowerTriangular{T,S}, UnitLowerTriangular{T,S}}\nconst UpperOrLowerTriangular{T,S} = Union{UpperOrUnitUpperTriangular{T,S}, LowerOrUnitLowerTriangular{T,S}}\n\n# patch missing overload from Base\naxes(rd::Diagonal{<:Any,<:AbstractFill}) = (axes(rd.diag,1),axes(rd.diag,1))\naxes(T::UpperOrLowerTriangular{<:Any,<:AbstractFill}) = axes(parent(T))\n\naxes(rd::RectDiagonal) = rd.axes\nsize(rd::RectDiagonal) = map(length, rd.axes)\n\nparent(rd::RectDiagonal) = rd.diag\n\n@inline function getindex(rd::RectDiagonal{T}, i::Integer, j::Integer) where T\n    @boundscheck checkbounds(rd, i, j)\n    if i == j\n        @inbounds r = rd.diag[i]\n    else\n        r = zero(T)\n    end\n    return r\nend\n\nfunction setindex!(rd::RectDiagonal, v, i::Integer, j::Integer)\n    @boundscheck checkbounds(rd, i, j)\n    if i == j\n        @inbounds rd.diag[i] = v\n    elseif !iszero(v)\n        throw(ArgumentError(LazyString(\"cannot set off-diagonal entry (\", i, \", \", j, \") to a nonzero value (\", v, \")\")))\n    end\n    return v\nend\n\ndiag(rd::RectDiagonal) = rd.diag\n\nfor f in (:triu, :triu!, :tril, :tril!)\n    @eval ($f)(M::RectDiagonal) = M\nend\n\n# Due to default definitions in LinearAlgebra only the following implementations are needed\n# (see above for more details)\nfunction +(a::RectDiagonal, b::UniformScaling)\n    LinearAlgebra.checksquare(a)\n    return Diagonal(a.diag .+ b.λ)\nend\nfunction -(a::UniformScaling, b::RectDiagonal)\n    LinearAlgebra.checksquare(b)\n    return Diagonal(a.λ .- b.diag)\nend\n\nBase.replace_in_print_matrix(A::RectDiagonal, i::Integer, j::Integer, s::AbstractString) =\n    i == j ? s : Base.replace_with_centered_mark(s)\n\n\nconst RectOrDiagonal{T,V,Axes} = Union{RectDiagonal{T,V,Axes}, Diagonal{T,V}}\nconst RectOrDiagonalFill{T,V<:AbstractFillVector{T},Axes} = RectOrDiagonal{T,V,Axes}\nconst RectDiagonalFill{T,V<:AbstractFillVector{T}} = RectDiagonal{T,V}\nconst SquareEye{T,Axes} = Diagonal{T,Ones{T,1,Tuple{Axes}}}\nconst Eye{T,Axes} = RectOrDiagonal{T,Ones{T,1,Tuple{Axes}}}\n\n@inline SquareEye{T}(n::Integer) where T = Diagonal(Ones{T}(n))\n@inline SquareEye(n::Integer) = Diagonal(Ones(n))\n@inline SquareEye{T}(ax::Tuple{AbstractUnitRange{Int}}) where T = Diagonal(Ones{T}(ax))\n@inline SquareEye(ax::Tuple{AbstractUnitRange{Int}}) = Diagonal(Ones(ax))\n\n@inline Eye{T}(n::Integer) where T = SquareEye{T}(n)\n@inline Eye(n::Integer) = SquareEye(n)\n@inline Eye{T}(ax::Tuple{AbstractUnitRange{Int}}) where T = SquareEye{T}(ax)\n@inline Eye(ax::Tuple{AbstractUnitRange{Int}}) = SquareEye(ax)\n\n# function iterate(iter::Eye, istate = (1, 1))\n#     (i::Int, j::Int) = istate\n#     m = size(iter, 1)\n#     return i > m ? nothing :\n#         ((@inbounds getindex(iter, i, j)),\n#          j == m ? (i + 1, 1) : (i, j + 1))\n# end\n\nisone(::SquareEye) = true\n\nfunction diag(E::Eye, k::Integer=0)\n    v = k == 0 ? oneunit(eltype(E)) : zero(eltype(E))\n    len = length(diagind(E, k))\n    Fill(v, len)\nend\n\n# These should actually be in StdLib, LinearAlgebra.jl, for all Diagonal\nfor f in (:permutedims, :triu, :triu!, :tril, :tril!, :copy)\n    @eval ($f)(IM::Diagonal{<:Any,<:AbstractFill}) = IM\nend\n\ninv(IM::SquareEye) = IM\ninv(IM::Diagonal{<:Any,<:AbstractFill}) = Diagonal(map(inv, IM.diag))\n\nEye(n::Integer, m::Integer) = RectDiagonal(Ones(min(n,m)), n, m)\nEye{T}(n::Integer, m::Integer) where T = RectDiagonal{T}(Ones{T}(min(n,m)), n, m)\nfunction Eye{T}((a,b)::NTuple{2,AbstractUnitRange{Int}}) where T\n    ab = length(a) ≤ length(b) ? a : b\n    RectDiagonal{T}(Ones{T}((ab,)), (a,b))\nend\nfunction Eye((a,b)::NTuple{2,AbstractUnitRange{Int}})\n    ab = length(a) ≤ length(b) ? a : b\n    RectDiagonal(Ones((ab,)), (a,b))\nend\n\n@inline Eye{T}(A::AbstractMatrix) where T = Eye{T}(size(A)...)\n@inline Eye(A::AbstractMatrix) = Eye{eltype(A)}(size(A)...)\n\n# This may break, as it uses undocumented internals of LinearAlgebra\n# Ideally this should be copied over to this package\n# Also, maybe this should reuse the broadcasting behavior of the parent,\n# once AbstractFill types implement their own BroadcastStyle\nBroadcastStyle(::Type{<:RectDiagonal}) = LinearAlgebra.StructuredMatrixStyle{RectDiagonal}()\nfunction LinearAlgebra.structured_broadcast_alloc(bc, ::Type{<:RectDiagonal}, ::Type{ElType}, n) where {ElType}\n    RectDiagonal(Array{ElType}(undef, minimum(n)), axes(bc))\nend\n@inline LinearAlgebra.fzero(S::RectDiagonal{T}) where {T} = zero(T)\n\n#########\n#  Special matrix types\n#########\n\n\n\n## Array\nBase.Array{T,N}(F::AbstractFill{V,N}) where {T,V,N} =\n    convert(Array{T,N}, fill(convert(T, getindex_value(F)), size(F)))\n\n# These are in case `zeros` or `ones` are ever faster than `fill`\nfor (Typ, funcs, func) in ((:AbstractZeros, :zeros, :zero), (:AbstractOnes, :ones, :one))\n    @eval begin\n        Base.Array{T,N}(F::$Typ{V,N}) where {T,V,N} = $funcs(T,size(F))\n    end\nend\n\nif VERSION < v\"1.11-\"\n    # temporary patch. should be a PR(#48895) to LinearAlgebra\n    Diagonal{T}(A::AbstractFillMatrix) where T = Diagonal{T}(diag(A))\n    function convert(::Type{T}, A::AbstractFillMatrix) where T<:Diagonal\n        checksquare(A)\n        isdiag(A) ? T(diag(A)) : throw(InexactError(:convert, T, A))\n    end\nend\n\nBase.StepRangeLen(F::AbstractFillVector{T}) where T = StepRangeLen(getindex_value(F), zero(T), length(F))\nconvert(::Type{SL}, F::AbstractFillVector) where SL<:AbstractRange = convert(SL, StepRangeLen(F))\n\n#################\n# Structured matrix types\n#################\n\nfor SMT in (:Diagonal, :Bidiagonal, :Tridiagonal, :SymTridiagonal)\n    @eval function diag(D::$SMT{T,<:AbstractFillVector{T}}, k::Integer=0) where {T<:Number}\n        inds = (1,1) .+ (k >= 0 ? (0,k) : (-k,0))\n        v = get(D, inds, zero(eltype(D)))\n        Fill(v, length(diagind(D, k)))\n    end\nend\n\n\n#########\n# maximum/minimum\n#########\n\nfor op in (:maximum, :minimum)\n    @eval $op(x::AbstractFill) = getindex_value(x)\nend\n\n\n#########\n# Cumsum\n#########\n\n# These methods are necessary to deal with infinite arrays\nsum(x::AbstractFill) = getindex_value(x)*length(x)\nsum(f, x::AbstractFill) = length(x) * f(getindex_value(x))\nsum(x::AbstractZeros) = getindex_value(x)\n\n# needed to support infinite case\nsteprangelen(st...) = StepRangeLen(st...)\nfunction cumsum(x::AbstractFill{T,1}) where T\n    V = promote_op(add_sum, T, T)\n    steprangelen(convert(V,getindex_value(x)), getindex_value(x), length(x))\nend\n\ncumsum(x::AbstractZerosVector{T}) where T = _range_convert(AbstractVector{promote_op(add_sum, T, T)}, x)\ncumsum(x::AbstractZerosVector{Bool}) = _range_convert(AbstractVector{Int}, x)\ncumsum(x::AbstractOnesVector{T}) where T<:Integer = _range_convert(AbstractVector{promote_op(add_sum, T, T)}, oneto(length(x)))\ncumsum(x::AbstractOnesVector{Bool}) = oneto(length(x))\n\n\nfor op in (:+, :-)\n    @eval begin\n        function accumulate(::typeof($op), x::AbstractFill{T,1}) where T\n            V = promote_op($op, T, T)\n            steprangelen(convert(V,getindex_value(x)), $op(getindex_value(x)), length(x))\n        end\n\n        accumulate(::typeof($op), x::AbstractZerosVector{T}) where T = _range_convert(AbstractVector{promote_op($op, T, T)}, x)\n        accumulate(::typeof($op), x::AbstractZerosVector{Bool}) = _range_convert(AbstractVector{Int}, x)\n    end\nend\n\naccumulate(::typeof(+), x::AbstractOnesVector{T}) where T<:Integer = _range_convert(AbstractVector{promote_op(+, T, T)}, oneto(length(x)))\naccumulate(::typeof(+), x::AbstractOnesVector{Bool}) = oneto(length(x))\n\n#########\n# Diff\n#########\n\ndiff(x::AbstractFillVector{T}) where T = Zeros{T}(length(x)-1)\n\n#########\n# unique\n#########\n\nunique(x::AbstractFill) = fillsimilar(x, Int(!isempty(x)))\nallunique(x::AbstractFill) = length(x) < 2\n\n#########\n# zero\n#########\n\nzero(r::AbstractZeros{T,N}) where {T,N} = r\n# TODO: Make this required?\nzero(r::AbstractOnes{T,N}) where {T,N} = Zeros{T,N}(axes(r))\nzero(r::Fill{T,N}) where {T,N} = Zeros{T,N}(r.axes)\n\n#########\n# oneunit\n#########\n\nfunction one(A::AbstractFillMatrix{T}) where {T}\n    Base.require_one_based_indexing(A)\n    m, n = size(A)\n    m == n || throw(ArgumentError(\"multiplicative identity defined only for square matrices\"))\n    SquareEye{T}(m)\nend\n\n#########\n# any/all/isone/iszero\n#########\n\nfunction isone(AF::AbstractFillMatrix)\n    (n,m) = size(AF)\n    n != m && return false\n    (n == 0 || m == 0) && return true\n    isone(getindex_value(AF)) || return false\n    n == 1 && return true\n    return false\nend\n\n# all(isempty, []) and any(isempty, []) have non-generic behavior.\n# We do not follow it here for Eye(0).\nfunction any(f::Function, IM::Eye{T}) where T\n    d1, d2 = size(IM)\n    (d1 < 1 || d2 < 1) && return false\n    (d1 > 1 || d2 > 1) && return f(zero(T)) || f(one(T))\n    return any(f(one(T)))\nend\n\nfunction all(f::Function, IM::Eye{T}) where T\n    d1, d2 = size(IM)\n    (d1 < 1 || d2 < 1) && return false\n    (d1 > 1 || d2 > 1) && return f(zero(T)) && f(one(T))\n    return all(f(one(T)))\nend\n\n# In particular, these make iszero(Eye(n))  efficient.\n# use any/all on scalar to get Boolean error message\nfunction any(f::Function, x::AbstractFill)\n    isempty(x) && return false\n    # If the condition is true for one value, then it's true for all\n    fval = f(getindex_value(x))\n    any((fval,))\nend\nfunction all(f::Function, x::AbstractFill)\n    isempty(x) && return true\n    # If the condition is true for one value, then it's true for all\n    fval = f(getindex_value(x))\n    return all((fval,))\nend\nany(x::AbstractFill) = any(identity, x)\nall(x::AbstractFill) = all(identity, x)\n\ncount(x::AbstractOnes{Bool}) = length(x)\ncount(x::AbstractZeros{Bool}) = 0\ncount(f, x::AbstractFill) = f(getindex_value(x)) ? length(x) : 0\n\n#########\n# in\n#########\nin(x, A::AbstractFill) = x == getindex_value(A)\nfunction in(x, A::RectDiagonal{<:Number})\n    any(iszero, size(A)) && return false # Empty matrix\n    all(isone, size(A)) && return x == A.diag[1] # A 1x1 matrix has only one element\n    x == zero(eltype(A)) || x in A.diag\nend\n\n#########\n# include\n#########\n\ninclude(\"fillalgebra.jl\")\ninclude(\"fillbroadcast.jl\")\ninclude(\"trues.jl\")\n\n##\n# print\n##\nBase.replace_in_print_matrix(::AbstractZeros, ::Integer, ::Integer, s::AbstractString) =\n    Base.replace_with_centered_mark(s)\n\n# following support blocked fill array printing via\n# BlockArrays.jl\naxes_print_matrix_row(lay, io, X, A, i, cols, sep, idxlast::Integer=last(axes(X, 2))) =\n    Base.invoke(Base.print_matrix_row, Tuple{IO,AbstractVecOrMat,Vector,Integer,AbstractVector,AbstractString,Integer},\n                    io, X, A, i, cols, sep, idxlast)\n\nBase.print_matrix_row(io::IO,\n        X::Union{AbstractFillVector,\n                 AbstractFillMatrix,\n                 Diagonal{<:Any,<:AbstractFillVector},\n                 RectDiagonal,\n                 UpperOrLowerTriangular{<:Any,<:AbstractFillMatrix}\n                 }, A::Vector,\n        i::Integer, cols::AbstractVector, sep::AbstractString, idxlast::Integer=last(axes(X, 2))) =\n        axes_print_matrix_row(axes(X), io, X, A, i, cols, sep)\n\n\n# Display concise description of a Fill.\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", x::Union{Eye, AbstractFill})\n    if get(IOContext(io), :compact, false)  # for example [Fill(i==j,2,2) for i in 1:3, j in 1:4]\n        return show(io, x)\n    end\n    summary(io, x)\n    if !(x isa Union{AbstractZeros, AbstractOnes, Eye})\n        print(io, \", with \", length(x) > 1 ? \"entries\" : \"entry\", \" equal to \")\n        show(io, getindex_value(x))\n    end\nend\n\nfunction Base.show(io::IO, x::AbstractFill)  # for example (Fill(π,3),)\n    print(io, nameof(typeof(x)))\n    sz = size(x)\n    args = if x isa Union{AbstractZeros, AbstractOnes}\n        T = eltype(x)\n        if T != Float64\n            print(io,\"{\", T, \"}\")\n        end\n        print(io, \"(\")\n    else\n        # show, not print, to handle (Fill(1f0,2),)\n        print(io, \"(\")\n        show(io, getindex_value(x))\n        ndims(x) == 0 || print(io, \", \")\n    end\n    join(io, size(x), \", \")\n    print(io, \")\")\nend\nfunction Base.show(io::IO, x::Eye)\n    print(io, \"Eye(\", size(x,1))\n    if size(x,1) != size(x,2)\n        print(io, \",\", size(x,2))\n    end\n    print(io, \")\")\nend\n\nBase.array_summary(io::IO, ::Zeros{T}, inds::Tuple{Vararg{Base.OneTo}}) where T =\n    print(io, Base.dims2string(length.(inds)), \" Zeros{$T}\")\nBase.array_summary(io::IO, ::Ones{T}, inds::Tuple{Vararg{Base.OneTo}}) where T =\n    print(io, Base.dims2string(length.(inds)), \" Ones{$T}\")\nBase.array_summary(io::IO, a::Fill{T}, inds::Tuple{Vararg{Base.OneTo}}) where T =\n    print(io, Base.dims2string(length.(inds)), \" Fill{$T}\")\nBase.array_summary(io::IO, a::Eye{T}, inds::Tuple{Vararg{Base.OneTo}}) where T =\n    print(io, Base.dims2string(length.(inds)), \" Eye{$T}\")\n\n\n##\n# interface\n##\n\ngetindex_value(a::LinearAlgebra.Adjoint) = adjoint(getindex_value(parent(a)))\ngetindex_value(a::LinearAlgebra.Transpose) = transpose(getindex_value(parent(a)))\ngetindex_value(a::SubArray) = getindex_value(parent(a))\n\ncopy(a::LinearAlgebra.Adjoint{<:Any,<:AbstractFill}) = copy(parent(a))'\ncopy(a::LinearAlgebra.Transpose{<:Any,<:AbstractFill}) = transpose(parent(a))\n\n##\n# view\n##\n\nBase.@propagate_inbounds view(A::AbstractFill{<:Any,N}, kr::AbstractArray{Bool,N}) where N = _fill_getindex(A, kr)\nBase.@propagate_inbounds view(A::AbstractFill{<:Any,1}, kr::AbstractVector{Bool}) = _fill_getindex(A, kr)\nBase.@propagate_inbounds view(A::AbstractFill, I...) =\n    _fill_getindex(A, Base.to_indices(A,I)...)\n\n# not getindex since we need array-like indexing\nBase.@propagate_inbounds function view(A::AbstractFill, I::Vararg{Real})\n    @boundscheck checkbounds(A, I...)\n    fillsimilar(A)\nend\n\n# repeat\n\n_first(t::Tuple) = t[1]\n_first(t::Tuple{}) = 1\n\n_maybetail(t::Tuple) = Base.tail(t)\n_maybetail(t::Tuple{}) = t\n\n_match_size(sz::Tuple{}, inner::Tuple{}, outer::Tuple{}) = ()\nfunction _match_size(sz::Tuple, inner::Tuple, outer::Tuple)\n    t1 = (_first(sz), _first(inner), _first(outer))\n    t2 = _match_size(_maybetail(sz), _maybetail(inner), _maybetail(outer))\n    (t1, t2...)\nend\n\nfunction _repeat_size(sz::Tuple, inner::Tuple, outer::Tuple)\n    t = _match_size(sz, inner, outer)\n    map(*, getindex.(t, 1), getindex.(t, 2), getindex.(t, 3))\nend\n\nfunction _repeat(A; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))\n    Base.require_one_based_indexing(A)\n    length(inner) >= ndims(A) ||\n        throw(ArgumentError(LazyString(\"number of inner repetitions \", length(inner), \" cannot be less than number of dimensions of input array \", ndims(A))))\n    length(outer) >= ndims(A) ||\n        throw(ArgumentError(LazyString(\"number of outer repetitions \", length(outer), \" cannot be less than number of dimensions of input array \", ndims(A))))\n    sz = _repeat_size(size(A), Tuple(inner), Tuple(outer))\n    fillsimilar(A, sz)\nend\n\nrepeat(A::AbstractFill, count::Integer...) = _repeat(A, outer=count)\nfunction repeat(A::AbstractFill; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))\n    _repeat(A, inner=inner, outer=outer)\nend\n\ninclude(\"oneelement.jl\")\n\nend # module\n"
  },
  {
    "path": "src/fillalgebra.jl",
    "content": "## vec\n\nvec(a::AbstractFill) = fillsimilar(a, length(a))\n\n## Transpose/Adjoint\n# cannot do this for vectors since that would destroy scalar dot product\n\n\nfor OP in (:transpose, :adjoint)\n    @eval begin\n        function $OP(a::AbstractZerosMatrix)\n            v = getindex_value(a)\n            T = typeof($OP(v))\n            Zeros{T}(reverse(axes(a)))\n        end\n        $OP(a::AbstractOnesMatrix) = fillsimilar(a, reverse(axes(a)))\n        $OP(a::FillMatrix) = Fill($OP(a.value), reverse(a.axes))\n    end\nend\n\npermutedims(a::AbstractFillVector) = fillsimilar(a, (1, length(a)))\npermutedims(a::AbstractFillMatrix) = fillsimilar(a, reverse(axes(a)))\n\nfunction permutedims(B::AbstractFill, perm)\n    dimsB = size(B)\n    ndimsB = length(dimsB)\n    (ndimsB == length(perm) && isperm(perm)) || throw(ArgumentError(\"no valid permutation of dimensions\"))\n    dimsP = ntuple(i->dimsB[perm[i]], ndimsB)::typeof(dimsB)\n    fillsimilar(B, dimsP)\nend\n\nBase.@propagate_inbounds function reverse(A::AbstractFill, start::Integer, stop::Integer=lastindex(A))\n    @boundscheck checkbounds(A, start)\n    @boundscheck checkbounds(A, stop)\n    A\nend\nreverse(A::AbstractFill; dims=:) = A\n\n## Algebraic identities\n\n# Default outputs, can overload to customize\nmult_fill(a, b, val, ax) = Fill(val, ax)\nmult_zeros(a, b, elt, ax) = Zeros{elt}(ax)\nmult_ones(a, b, elt, ax) = Ones{elt}(ax)\n\nfunction mult_fill(a::AbstractFill, b::AbstractFill, ax)\n    val = getindex_value(a)*getindex_value(b)*size(a,2)\n    return mult_fill(a, b, val, ax)\nend\n\nfunction mult_zeros(a, b, ax)\n    # This is currently only used in contexts where zero is defined\n    # might need a rethink\n    elt = typeof(zero(eltype(a)) * zero(eltype(b)))\n    return mult_zeros(a, b, elt, ax)\nend\n\nfunction mult_ones(a, b, ax)\n    # This is currently only used in contexts where zero is defined\n    # might need a rethink\n    elt = typeof(zero(eltype(a)) * zero(eltype(b)))\n    return mult_ones(a, b, elt, ax)\nend\n\nfunction mult_axes(a, b)\n    Base.require_one_based_indexing(a, b)\n    size(a, 2) ≠ size(b, 1) &&\n        throw(DimensionMismatch(LazyString(\"A has dimensions \", size(a), \" but B has dimensions \", size(b))))\n    return (axes(a, 1), axes(b)[2:end]...)\nend\n\nmult_fill(a, b) = mult_fill(a, b, mult_axes(a, b))\n# for arrays of numbers, we assume that zero is defined for the result\n# in this case, we may express the result as a Zeros\nmult_zeros(a::AbstractArray{<:Number}, b::AbstractArray{<:Number}) = mult_zeros(a, b, mult_axes(a, b))\n# In general, we create a Fill that doesn't assume anything about the\n# properties of the element type\nmult_zeros(a, b) = mult_fill(a, b, mult_axes(a, b))\nmult_ones(a, b) = mult_ones(a, b, mult_axes(a, b))\n\n*(a::AbstractFillMatrix, b::AbstractFillMatrix) = mult_fill(a,b)\n*(a::AbstractFillMatrix, b::AbstractFillVector) = mult_fill(a,b)\n\n# this treats a size (n,) vector as a nx1 matrix, so b needs to have 1 row\n# special cased, as OnesMatrix * OnesMatrix isn't a Ones\n*(a::AbstractOnesVector, b::AbstractOnesMatrix) = mult_ones(a, b)\n\n*(a::AbstractZerosMatrix, b::AbstractZerosMatrix) = mult_zeros(a, b)\n*(a::AbstractZerosMatrix, b::AbstractZerosVector) = mult_zeros(a, b)\n\n*(a::AbstractZerosMatrix, b::AbstractFillMatrix) = mult_zeros(a, b)\n*(a::AbstractZerosMatrix, b::AbstractFillVector) = mult_zeros(a, b)\n*(a::AbstractFillMatrix, b::AbstractZerosMatrix) = mult_zeros(a, b)\n*(a::AbstractFillMatrix, b::AbstractZerosVector) = mult_zeros(a, b)\n\nfor MT in (:AbstractMatrix, :AbstractTriangular)\n    @eval *(a::AbstractZerosMatrix, b::$MT) = mult_zeros(a, b)\n    @eval *(a::$MT, b::AbstractZerosMatrix) = mult_zeros(a, b)\nend\n# Odd way to deal with the type-parameters to avoid ambiguities\nfor MT in (:(AbstractMatrix{T}), :(Transpose{<:Any, <:AbstractMatrix{T}}), :(Adjoint{<:Any, <:AbstractMatrix{T}}),\n            :(AbstractTriangular{T}))\n    @eval *(a::$MT, b::AbstractZerosVector) where {T} = mult_zeros(a, b)\nend\nfor T in (:AbstractZerosMatrix, :AbstractFillMatrix)\n    @eval begin\n        *(a::Transpose{<:Any, <:AbstractVector}, b::$T) = transpose(transpose(b) * parent(a))\n        *(a::Adjoint{<:Any, <:AbstractVector}, b::$T) = adjoint(adjoint(b) * parent(a))\n    end\nend\n*(a::AbstractZerosMatrix, b::AbstractVector) = mult_zeros(a, b)\nfunction *(F::AbstractFillMatrix, v::AbstractVector)\n    check_matmul_sizes(F, v)\n    Fill(getindex_value(F) * sum(v), (axes(F,1),))\nend\n\nfunction lmul_diag(a::Diagonal, b)\n    size(a,2) == size(b,1) || throw(DimensionMismatch(LazyString(\"A has dimensions \", size(a), \" but B has dimensions \", size(b))))\n    parent(a) .* b # use special broadcast\nend\nfunction rmul_diag(a, b::Diagonal)\n    size(a,2) == size(b,1) || throw(DimensionMismatch(LazyString(\"A has dimensions \", size(a), \" but B has dimensions \", size(b))))\n    a .* permutedims(parent(b)) # use special broadcast\nend\n\n*(a::AbstractZerosMatrix, b::Diagonal) = rmul_diag(a, b)\n*(a::Diagonal, b::AbstractZerosVector) = lmul_diag(a, b)\n*(a::Diagonal, b::AbstractZerosMatrix) = lmul_diag(a, b)\n*(a::Diagonal, b::AbstractFillMatrix) = lmul_diag(a, b)\n*(a::AbstractFillMatrix, b::Diagonal) = rmul_diag(a, b)\n\n@noinline function check_matmul_sizes(A::AbstractMatrix, x::AbstractVector)\n    Base.require_one_based_indexing(A, x)\n    size(A,2) == size(x,1) ||\n        throw(DimensionMismatch(LazyString(\"second dimension of A, \", size(A,2), \", does not match length of x, \", length(x))))\nend\n@noinline function check_matmul_sizes(A::AbstractMatrix, B::AbstractMatrix)\n    Base.require_one_based_indexing(A, B)\n    size(A,2) == size(B,1) ||\n        throw(DimensionMismatch(LazyString(\"second dimension of A, \", size(A,2), \", does not match first dimension of B, \", size(B,1))))\nend\n@noinline function check_matmul_sizes(y::AbstractVector, A::AbstractMatrix, x::AbstractVector)\n    Base.require_one_based_indexing(A, x, y)\n    size(A,2) == size(x,1) ||\n        throw(DimensionMismatch(LazyString(\"second dimension of A, \", size(A,2), \", does not match length of x, \", length(x))))\n    size(y,1) == size(A,1) ||\n        throw(DimensionMismatch(LazyString(\"first dimension of A, \", size(A,1), \", does not match length of y, \", length(y))))\nend\n@noinline function check_matmul_sizes(C::AbstractMatrix, A::AbstractMatrix, B::AbstractMatrix)\n    Base.require_one_based_indexing(A, B, C)\n    size(A,2) == size(B,1) ||\n        throw(DimensionMismatch(LazyString(\"second dimension of A, \", size(A,2), \", does not match first dimension of B, \", size(B,1))))\n    size(C,1) == size(A,1) && size(C,2) == size(B,2) ||\n        throw(DimensionMismatch(LazyString(\"A has size \", size(A), \", B has size \", size(B), \", C has size \", size(C))))\nend\n\nfunction mul!(y::AbstractVector, A::AbstractFillMatrix, b::AbstractFillVector, alpha::Number, beta::Number)\n    check_matmul_sizes(y, A, b)\n\n    Abα = Ref(getindex_value(A) * getindex_value(b) * alpha * length(b))\n\n    if iszero(beta)\n        y .= Abα\n    else\n        y .= Abα .+ y .* beta\n    end\n    y\nend\n\nfunction mul!(y::StridedVector, A::StridedMatrix, b::AbstractFillVector, alpha::Number, beta::Number)\n    check_matmul_sizes(y, A, b)\n\n    bα = Ref(getindex_value(b) * alpha)\n\n    if iszero(beta)\n        y .= Ref(zero(eltype(y)))\n    else\n        rmul!(y, beta)\n    end\n    for Acol in eachcol(A)\n        @. y += Acol * bα\n    end\n    y\nend\n\nfunction mul!(y::StridedVector, A::AbstractFillMatrix, b::StridedVector, alpha::Number, beta::Number)\n    check_matmul_sizes(y, A, b)\n\n    Abα = Ref(getindex_value(A) * sum(b) * alpha)\n\n    if iszero(beta)\n        y .= Abα\n    else\n        y .= Abα .+ y .* beta\n    end\n    y\nend\n\nfunction _mul_adjtrans!(y::AbstractVector, A::AbstractMatrix, b::AbstractFillVector, alpha, beta, f)\n    bα = getindex_value(b) * alpha\n    At = f(A)\n\n    if iszero(beta)\n        for (ind, Atcol) in zip(eachindex(y), eachcol(At))\n            y[ind] = f(sum(Atcol)) * bα\n        end\n    else\n        for (ind, Atcol) in zip(eachindex(y), eachcol(At))\n            y[ind] = f(sum(Atcol)) * bα .+ y[ind] .* beta\n        end\n    end\n    y\nend\n\nfor (T, f) in ((:Adjoint, :adjoint), (:Transpose, :transpose))\n    @eval function mul!(y::StridedVector, A::$T{<:Any, <:StridedMatrix}, b::AbstractFillVector, alpha::Number, beta::Number)\n        check_matmul_sizes(y, A, b)\n        _mul_adjtrans!(y, A, b, alpha, beta, $f)\n    end\nend\n\n# unnecessary indirection, added for ambiguity resolution\nfunction _mulfill!(C::AbstractMatrix, A::AbstractFillMatrix, B::AbstractFillMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    ABα = getindex_value(A) * getindex_value(B) * alpha * size(B,1)\n    if iszero(beta)\n        C .= ABα\n    else\n        C .= ABα .+ C .* beta\n    end\n    return C\nend\n\nfunction mul!(C::AbstractMatrix, A::AbstractFillMatrix, B::AbstractFillMatrix, alpha::Number, beta::Number)\n    _mulfill!(C, A, B, alpha, beta)\n    return C\nend\n\nfunction copyfirstcol!(C)\n    @views for i in axes(C,2)[2:end]\n        C[:, i] .= C[:, 1]\n    end\n    return C\nend\n\n_firstcol(C::AbstractMatrix) = first(eachcol(C))\n\nfunction copyfirstrow!(C)\n    # C[begin+1:end, ind] .= permutedims(_firstrow(C))\n    # we loop here as the aliasing check isn't smart enough to\n    # detect that the two sides don't alias, and ends up materializing the RHS\n    for (ind, v) in pairs(_firstrow(C))\n        C[begin+1:end, ind] .= Ref(v)\n    end\n    return C\nend\n_firstrow(C::AbstractMatrix) = first(eachrow(C))\n\nfunction _mulfill!(C::AbstractMatrix, A::AbstractMatrix, B::AbstractFillMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    iszero(size(B,2)) && return C # no columns in B and C, empty matrix\n    if iszero(beta)\n        # the mat-vec product sums along the rows of A\n        mul!(_firstcol(C), A, _firstcol(B), alpha, beta)\n        copyfirstcol!(C)\n    else\n        # the mat-vec product sums along the rows of A, which produces the first column of ABα\n        # allocate a temporary column vector to store the result\n        v = A * (_firstcol(B) * alpha)\n        C .= v .+ C .* beta\n    end\n    return C\nend\nfunction _mulfill!(C::AbstractMatrix, A::AbstractFillMatrix, B::AbstractMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    iszero(size(A,1)) && return C # no rows in A and C, empty matrix\n    Aval = getindex_value(A)\n    if iszero(beta)\n        Crow = _firstrow(C)\n        # sum along the columns of B\n        Crow .= Ref(Aval) .* sum.(eachcol(B)) .* alpha\n        copyfirstrow!(C)\n    else\n        # sum along the columns of B, and allocate the result.\n        # This is the first row of ABα\n        ABα_row = Ref(Aval) .* sum.(eachcol(B)) .* alpha\n        C .= permutedims(ABα_row) .+ C .* beta\n    end\n    return C\nend\n\nfunction mul!(C::StridedMatrix, A::StridedMatrix, B::AbstractFillMatrix, alpha::Number, beta::Number)\n    _mulfill!(C, A, B, alpha, beta)\n    return C\nend\nfunction mul!(C::StridedMatrix, A::AbstractFillMatrix, B::StridedMatrix, alpha::Number, beta::Number)\n    _mulfill!(C, A, B, alpha, beta)\n    return C\nend\n\nfor T in (:Adjoint, :Transpose)\n    @eval begin\n        function mul!(C::StridedMatrix, A::$T{<:Any, <:StridedMatrix}, B::AbstractFillMatrix, alpha::Number, beta::Number)\n            _mulfill!(C, A, B, alpha, beta)\n            return C\n        end\n        function mul!(C::StridedMatrix, A::AbstractFillMatrix, B::$T{<:Any, <:StridedMatrix}, alpha::Number, beta::Number)\n            _mulfill!(C, A, B, alpha, beta)\n            return C\n        end\n    end\nend\n\nfunction _adjvec_mul_zeros(a, b)\n    la, lb = length(a), length(b)\n    if la ≠ lb\n        throw(DimensionMismatch(LazyString(\"dot product arguments have lengths \", la, \" and \", lb)))\n    end\n    # ensure that all the elements of `a` are of the same size,\n    # so that ∑ᵢaᵢbᵢ = b₁∑ᵢaᵢ makes sense\n    if la == 0\n        # this errors if a is a nested array, and zero isn't well-defined\n        return zero(eltype(a)) * zero(eltype(b))\n    end\n    a1 = a[1]\n    sza1 = size(a1)\n    all(x -> size(x) == sza1, a) || throw(DimensionMismatch(LazyString(\"not all elements of A are of size \", sza1)))\n    # we replace b₁∑ᵢaᵢ by b₁a₁, as we know that b₁ is zero.\n    # Each term in the summation is zero, so the sum is equal to the first term\n    return a1 * b[1]\nend\n\nfor MT in (:AbstractMatrix, :AbstractTriangular, :(Adjoint{<:Any,<:TransposeAbsVec}), :AbstractFillMatrix)\n    @eval *(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::$MT) = (b' * a')'\nend\n# ambiguity\nfunction *(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::TransposeAbsVec{<:Any,<:AdjointAbsVec})\n    # change from Transpose ∘ Adjoint to Adjoint ∘ Transpose\n    b2 = adjoint(transpose(adjoint(transpose(b))))\n    a * b2\nend\n*(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractZerosMatrix) = (b' * a')'\nfor MT in (:AbstractMatrix, :AbstractTriangular, :(Transpose{<:Any,<:AdjointAbsVec}), :AbstractFillMatrix)\n    @eval *(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, b::$MT) = transpose(transpose(b) * transpose(a))\nend\n*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractZerosMatrix) = transpose(transpose(b) * transpose(a))\n\n*(a::AbstractVector, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))\nfor MT in (:AbstractMatrix, :AbstractTriangular)\n    @eval *(a::$MT, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))\nend\n*(a::AbstractZerosVector, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))\n*(a::AbstractZerosMatrix, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))\n\n*(a::AdjointAbsVec, b::AbstractZerosVector) = _adjvec_mul_zeros(a, b)\n*(a::AdjointAbsVec{<:Number}, b::AbstractZerosVector{<:Number}) = _adjvec_mul_zeros(a, b)\n*(a::TransposeAbsVec, b::AbstractZerosVector) = _adjvec_mul_zeros(a, b)\n*(a::TransposeAbsVec{<:Number}, b::AbstractZerosVector{<:Number}) = _adjvec_mul_zeros(a, b)\n\n*(a::Adjoint{T, <:AbstractMatrix{T}} where T, b::AbstractZeros{<:Any, 1}) = mult_zeros(a, b)\n\n*(D::Diagonal, a::Adjoint{<:Any,<:AbstractZerosVector}) = (a' * D')'\n*(D::Diagonal, a::Transpose{<:Any,<:AbstractZerosVector}) = transpose(transpose(a) * transpose(D))\n*(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal) = (D' * a')'\n*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal) = transpose(D*transpose(a))\nfunction _triple_zeromul(x, D::Diagonal, y)\n    if !(length(x) == length(D.diag) == length(y))\n        throw(DimensionMismatch(LazyString(\"x has length \", length(x), \", D has size \", size(D), \", and y has \", length(y))))\n    end\n    zero(promote_type(eltype(x), eltype(D), eltype(y)))\nend\n\n*(x::AdjointAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal, y::AbstractVector) = _triple_zeromul(x, D, y)\n*(x::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal, y::AbstractVector) = _triple_zeromul(x, D, y)\n*(x::AdjointAbsVec, D::Diagonal, y::AbstractZerosVector) = _triple_zeromul(x, D, y)\n*(x::TransposeAbsVec, D::Diagonal, y::AbstractZerosVector) = _triple_zeromul(x, D, y)\n*(x::AdjointAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal, y::AbstractZerosVector) = _triple_zeromul(x, D, y)\n*(x::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal, y::AbstractZerosVector) = _triple_zeromul(x, D, y)\n\n\nfunction *(a::Transpose{T, <:AbstractVector}, b::AbstractZerosVector{T}) where T<:Real\n    la, lb = length(a), length(b)\n    if la ≠ lb\n        throw(DimensionMismatch(LazyString(\"dot product arguments have lengths \", la, \" and \", lb)))\n    end\n    return zero(T)\nend\n*(a::Transpose{T, <:AbstractMatrix{T}}, b::AbstractZerosVector{T}) where T<:Real = mult_zeros(a, b)\n\n# support types with fast sum\n# infinite cases should be supported in InfiniteArrays.jl\n# type issues of Bool dot are ignored at present.\nfunction _fill_dot(a::AbstractFillVector{T}, b::AbstractVector{V}) where {T,V}\n    axes(a) == axes(b) || throw(DimensionMismatch(LazyString(\"dot product arguments have lengths \", length(a), \" and \", length(b))))\n    dot(getindex_value(a), sum(b))\nend\n\nfunction _fill_dot_rev(a::AbstractVector{T}, b::AbstractFillVector{V}) where {T,V}\n    axes(a) == axes(b) || throw(DimensionMismatch(LazyString(\"dot product arguments have lengths \", length(a), \" and \", length(b))))\n    dot(sum(a), getindex_value(b))\nend\n\ndot(a::AbstractFillVector, b::AbstractFillVector) = _fill_dot(a, b)\ndot(a::AbstractFillVector, b::AbstractVector) = _fill_dot(a, b)\ndot(a::AbstractVector, b::AbstractFillVector) = _fill_dot_rev(a, b)\n\nfunction dot(u::AbstractVector, E::Eye, v::AbstractVector)\n    length(u) == size(E,1) && length(v) == size(E,2) ||\n        throw(DimensionMismatch(LazyString(\"dot product arguments have dimensions \", length(u), \"×\", size(E), \"×\", length(v))))\n    d = dot(u,v)\n    T = typeof(one(eltype(E)) * d)\n    convert(T, d)\nend\n\nfunction dot(u::AbstractVector, D::Diagonal{<:Any,<:Fill}, v::AbstractVector)\n    length(u) == size(D,1) && length(v) == size(D,2) ||\n        throw(DimensionMismatch(LazyString(\"dot product arguments have dimensions \", length(u), \"×\", size(D), \"×\", length(v))))\n    D.diag.value*dot(u, v)\nend\n\nfunction dot(u::AbstractVector{T}, D::Diagonal{U,<:Zeros}, v::AbstractVector{V}) where {T,U,V}\n    length(u) == size(D,1) && length(v) == size(D,2) ||\n        throw(DimensionMismatch(LazyString(\"dot product arguments have dimensions \", length(u), \"×\", size(D), \"×\", length(v))))\n    zero(promote_type(T,U,V))\nend\n\n# Addition and Subtraction\n+(a::AbstractFill) = a\n-(a::AbstractZeros) = a\n-(a::AbstractFill) = Fill(-getindex_value(a), size(a))\n\n# special-cased for type-stability, as Ones + Ones is not a Ones\nBase.reduce_first(::typeof(+), x::AbstractOnes) = Fill(Base.reduce_first(+, getindex_value(x)), axes(x))\n\nfunction +(a::AbstractZeros{T}, b::AbstractZeros{V}) where {T, V} # for disambiguity\n    promote_shape(a,b)\n    return elconvert(promote_op(+,T,V),a)\nend\n\nfunction -(a::AbstractZeros{T}, b::AbstractZeros{V}) where {T, V} # for disambiguity\n    promote_shape(a,b)\n    return elconvert(promote_op(-,T,V),-b)\nend\n\n# AbstractFill and Array for disambiguity\nfor TYPE in (:Array, :AbstractFill, :AbstractRange, :AbstractArray)\n    @eval function +(a::$TYPE{T}, b::AbstractZeros{V}) where {T, V}\n        promote_shape(a,b)\n        return elconvert(promote_op(+,T,V),a)\n    end\n     @eval function -(a::$TYPE{T}, b::AbstractZeros{V}) where {T, V}\n        promote_shape(a,b)\n        return elconvert(promote_op(-,T,V),a)\n    end\n    @eval function -(a::AbstractZeros{T}, b::$TYPE{V}) where {T, V}\n        promote_shape(a,b)\n        return elconvert(promote_op(-,T,V),-b)\n    end\n    @eval +(a::AbstractZeros, b::$TYPE) = b + a\nend\n\n# for VERSION other than 1.6, could use ZerosMatrix only\nfunction +(a::AbstractFillMatrix{T}, b::UniformScaling) where {T}\n    n = checksquare(a)\n    return a + Diagonal(Fill(zero(T) + b.λ, n))\nend\n\n# LinearAlgebra defines `-(a::AbstractMatrix, b::UniformScaling) = a + (-b)`,\n# so the implementation of `-(a::UniformScaling, b::AbstractFill{<:Any,2})` is sufficient\n-(a::UniformScaling, b::AbstractFill) = -b + a # @test I-Zeros(3,3) === Diagonal(Ones(3))\n\n# TODO: How to do this conversion generically?\n-(a::AbstractOnes, b::AbstractOnes) = broadcasted_zeros(+, a, eltype(a), axes(a)) + broadcasted_zeros(-, b, eltype(a), axes(a))\n\n# no AbstractArray. Otherwise incompatible with StaticArrays.jl\nfor TYPE in (:Array, :AbstractRange)\n    @eval begin\n        +(a::$TYPE, b::AbstractFill) = fill_add(a, b)\n        -(a::$TYPE, b::AbstractFill) = a + (-b)\n        +(a::AbstractFill, b::$TYPE) = fill_add(b, a)\n        -(a::AbstractFill, b::$TYPE) = a + (-b)\n    end\nend\n+(a::AbstractFill, b::AbstractFill) = Fill(getindex_value(a) + getindex_value(b), promote_shape(a,b))\n-(a::AbstractFill, b::AbstractFill) = a + (-b)\n\n@inline function fill_add(a::AbstractArray, b::AbstractFill)\n    promote_shape(a, b)\n    a .+ (getindex_value(b),)\nend\n@inline function fill_add(a::AbstractArray{<:Number}, b::AbstractFill)\n    promote_shape(a, b)\n    a .+ getindex_value(b)\nend\n\n# following needed since as of Julia v1.8 convert(AbstractArray{T}, ::AbstractRange) might return a Vector\n@inline elconvert(::Type{T}, A::AbstractRange) where T = T(first(A)):T(step(A)):T(last(A))\n@inline elconvert(::Type{T}, A::AbstractUnitRange) where T<:Integer = AbstractUnitRange{T}(A)\n@inline elconvert(::Type{T}, A::AbstractArray) where T = AbstractArray{T}(A)\n\n####\n# norm\n####\n\nfor op in (:norm1, :norm2, :normInf, :normMinusInf)\n    @eval $op(a::AbstractZeros) = norm(getindex_value(a))\nend\n\nnormp(a::AbstractZeros, p) = norm(getindex_value(a))\n\nnorm1(a::AbstractFill) = length(a)*norm(getindex_value(a))\nfunction norm2(a::AbstractFill)\n    nrm1 = norm(getindex_value(a))\n    sqrt(oftype(nrm1, length(a)))*nrm1\nend\nfunction normp(a::AbstractFill, p)\n    nrm1 = norm(getindex_value(a))\n    (length(a))^(1/oftype(nrm1, p))*nrm1\nend\nnormInf(a::AbstractFill) = norm(getindex_value(a))\nnormMinusInf(a::AbstractFill) = norm(getindex_value(a))\n\n\n###\n# lmul!/rmul!\n###\n\nfunction lmul!(x::Number, z::AbstractFill)\n    λ = getindex_value(z)\n    # Following check ensures consistency w/ lmul!(x, Array(z))\n    # for, e.g., lmul!(NaN, z)\n    x*λ == λ || throw(ArgumentError(LazyString(\"Cannot scale by \", x)))\n    z\nend\n\nfunction rmul!(z::AbstractFill, x::Number)\n    λ = getindex_value(z)\n    # Following check ensures consistency w/ lmul!(x, Array(z))\n    # for, e.g., lmul!(NaN, z)\n    λ*x == λ || throw(ArgumentError(LazyString(\"Cannot scale by \", x)))\n    z\nend\n\nfillzero(::Type{Fill{T,N,AXIS}}, n, m) where {T,N,AXIS} = Fill{T,N,AXIS}(zero(T), (n, m))\nfillzero(::Type{<:AbstractZeros{T,N,AXIS}}, n, m) where {T,N,AXIS} = Zeros{T,N,AXIS}((n, m))\nfillzero(::Type{F}, n, m) where F = throw(ArgumentError(LazyString(\"Cannot create a zero array of type \", F)))\n\ndiagzero(D::Diagonal{F}, i, j) where F<:AbstractFill = fillzero(F, axes(D.diag[i], 1), axes(D.diag[j], 2))\n\n# kron\n\n# Default outputs, can overload to customize\nkron_fill(a, b, val, ax) = Fill(val, ax)\nkron_zeros(a, b, elt, ax) = Zeros{elt}(ax)\nkron_ones(a, b, elt, ax) = Ones{elt}(ax)\n\n_kronsize(f::AbstractFillVector, g::AbstractFillVector) = (size(f,1)*size(g,1),)\n_kronsize(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat) = (size(f,1)*size(g,1), size(f,2)*size(g,2))\nfunction _kron(f::AbstractFill, g::AbstractFill, sz)\n    v = getindex_value(f)*getindex_value(g)\n    return kron_fill(f, g, v, sz)\nend\nfunction _kron(f::AbstractZeros, g::AbstractZeros, sz)\n    elt = promote_type(eltype(f), eltype(g))\n    return kron_zeros(f, g, elt, sz)\nend\nfunction _kron(f::AbstractOnes, g::AbstractOnes, sz)\n    elt = promote_type(eltype(f), eltype(g))\n    return kron_ones(f, g, elt, sz)\nend\nfunction kron(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat)\n    sz = _kronsize(f, g)\n    return _kron(f, g, sz)\nend\n\n# bandedness\nfunction LinearAlgebra.istriu(A::AbstractFillMatrix, k::Integer = 0)\n    iszero(A) || k <= -(size(A,1)-1)\nend\nfunction LinearAlgebra.istril(A::AbstractFillMatrix, k::Integer = 0)\n    iszero(A) || k >= size(A,2)-1\nend\n\ntriu(A::AbstractZerosMatrix, k::Integer=0) = A\ntril(A::AbstractZerosMatrix, k::Integer=0) = A\n"
  },
  {
    "path": "src/fillbroadcast.jl",
    "content": "### map\n\nmap(f::Function, r::AbstractFill) = Fill(f(getindex_value(r)), axes(r))\n\nfunction map(f::Function, v::AbstractFillVector, ws::AbstractFillVector...)\n    stop = mapreduce(length, min, (v, ws...))\n    val = f(map(getindex_value, (v, ws...))...)\n    Fill(val, stop)\nend\n\nfunction map(f::Function, q::AbstractFill, rs::AbstractFill...)\n    if _maplinear(q, rs...)\n        map(f, map(vec, (q, rs...))...)\n    else\n        val = f(map(getindex_value, (q, rs...))...)\n        Fill(val, axes(q))\n    end\nend\n\nfunction _maplinear(rs...) # tries to match Base's behaviour, could perhaps hook in more deeply\n    if any(ndims(r)==1 for r in rs)\n        return true\n    else\n        r1 = axes(first(rs))\n        for r in rs\n            axes(r) == r1 || throw(DimensionMismatch(\n            LazyString(\"dimensions must match: a has dims \", r1, \", b has dims \", axes(r))))\n        end\n        return false\n    end\nend\n\n### mapreduce\n\nfunction Base._mapreduce_dim(f, op, ::Base._InitialValue, A::AbstractFill, ::Colon)\n    fval = f(getindex_value(A))\n    out = fval\n    for _ in 2:length(A)\n        out = op(out, fval)\n    end\n    out\nend\n\nfunction Base._mapreduce_dim(f, op, ::Base._InitialValue, A::AbstractFill, dims)\n    fval = f(getindex_value(A))\n    red = *(ntuple(d -> d in dims ? size(A,d) : 1, ndims(A))...)\n    out = fval\n    for _ in 2:red\n        out = op(out, fval)\n    end\n    Fill(out, ntuple(d -> d in dims ? Base.OneTo(1) : axes(A,d), ndims(A)))\nend\n\nfunction mapreduce(f, op, A::AbstractFill, B::AbstractFill; kw...)\n    val(_...) = f(getindex_value(A), getindex_value(B))\n    reduce(op, map(val, A, B); kw...)\nend\n\n# These are particularly useful because mapreduce(*, +, A, B; dims) is slow in Base,\n# but can be re-written as some mapreduce(g, +, C; dims) which is fast.\n\nfunction mapreduce(f, op, A::AbstractFill, B::AbstractArray, Cs::AbstractArray...; kw...)\n    g(b, cs...) = f(getindex_value(A), b, cs...)\n    mapreduce(g, op, B, Cs...; kw...)\nend\nfunction mapreduce(f, op, A::AbstractArray, B::AbstractFill, Cs::AbstractArray...; kw...)\n    h(a, cs...) = f(a, getindex_value(B), cs...)\n    mapreduce(h, op, A, Cs...; kw...)\nend\nfunction mapreduce(f, op, A::AbstractFill, B::AbstractFill, Cs::AbstractArray...; kw...)\n    gh(cs...) = f(getindex_value(A), getindex_value(B), cs...)\n    mapreduce(gh, op, Cs...; kw...)\nend\n\n\n### Unary broadcasting\n\nfunction broadcasted(::DefaultArrayStyle{N}, op, r::AbstractFill{T,N}) where {T,N}\n    return Fill(op(getindex_value(r)), axes(r))\nend\n\nbroadcasted(::DefaultArrayStyle, ::typeof(+), r::AbstractZeros) = r\nbroadcasted(::DefaultArrayStyle, ::typeof(-), r::AbstractZeros) = r\nbroadcasted(::DefaultArrayStyle, ::typeof(+), r::AbstractOnes) = r\n\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(conj), r::AbstractZeros{T,N}) where {T,N} = r\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(conj), r::AbstractOnes{T,N}) where {T,N} = r\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(real), r::AbstractZeros{T,N}) where {T,N} = Zeros{real(T)}(axes(r))\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(real), r::AbstractOnes{T,N}) where {T,N} = Ones{real(T)}(axes(r))\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(imag), r::AbstractZeros{T,N}) where {T,N} = Zeros{real(T)}(axes(r))\nbroadcasted(::DefaultArrayStyle{N}, ::typeof(imag), r::AbstractOnes{T,N}) where {T,N} = Zeros{real(T)}(axes(r))\n\n### Binary broadcasting\n\n# Default outputs, can overload to customize\nbroadcasted_fill(f, a, val, ax) = Fill(val, ax)\nbroadcasted_fill(f, a, b, val, ax) = Fill(val, ax)\nbroadcasted_zeros(f, a, elt, ax) = Zeros{elt}(ax)\nbroadcasted_zeros(f, a, b, elt, ax) = Zeros{elt}(ax)\nbroadcasted_ones(f, a, elt, ax) = Ones{elt}(ax)\nbroadcasted_ones(f, a, b, elt, ax) = Ones{elt}(ax)\n\nfunction broadcasted(::DefaultArrayStyle, op, a::AbstractFill, b::AbstractFill)\n    val = op(getindex_value(a), getindex_value(b))\n    ax = broadcast_shape(axes(a), axes(b))\n    return broadcasted_fill(op, a, b, val, ax)\nend\n\nfunction _broadcasted_zeros(f, a, b)\n  elt = Base.Broadcast.combine_eltypes(f, (a, b))\n  ax = broadcast_shape(axes(a), axes(b))\n  return broadcasted_zeros(f, a, b, elt, ax)\nend\nfunction _broadcasted_ones(f, a, b)\n  elt = Base.Broadcast.combine_eltypes(f, (a, b))\n  ax = broadcast_shape(axes(a), axes(b))\n  return broadcasted_ones(f, a, b, elt, ax)\nend\nfunction _broadcasted_nan(f, a, b)\n  val = convert(Base.Broadcast.combine_eltypes(f, (a, b)), NaN)\n  ax = broadcast_shape(axes(a), axes(b))\n  return broadcasted_fill(f, a, b, val, ax)\nend\n\nbroadcasted(::DefaultArrayStyle, ::typeof(+), a::AbstractZeros, b::AbstractZeros) = _broadcasted_zeros(+, a, b)\nbroadcasted(::DefaultArrayStyle, ::typeof(+), a::AbstractOnes, b::AbstractZeros) = _broadcasted_ones(+, a, b)\nbroadcasted(::DefaultArrayStyle, ::typeof(+), a::AbstractZeros, b::AbstractOnes) = _broadcasted_ones(+, a, b)\n\nbroadcasted(::DefaultArrayStyle, ::typeof(-), a::AbstractZeros, b::AbstractZeros) = _broadcasted_zeros(-, a, b)\nbroadcasted(::DefaultArrayStyle, ::typeof(-), a::AbstractOnes, b::AbstractZeros) = _broadcasted_ones(-, a, b)\nbroadcasted(::DefaultArrayStyle, ::typeof(-), a::AbstractOnes, b::AbstractOnes) = _broadcasted_zeros(-, a, b)\n\nbroadcasted(::DefaultArrayStyle{1}, ::typeof(+), a::AbstractZerosVector, b::AbstractZerosVector) = _broadcasted_zeros(+, a, b)\nbroadcasted(::DefaultArrayStyle{1}, ::typeof(+), a::AbstractOnesVector, b::AbstractZerosVector) = _broadcasted_ones(+, a, b)\nbroadcasted(::DefaultArrayStyle{1}, ::typeof(+), a::AbstractZerosVector, b::AbstractOnesVector) = _broadcasted_ones(+, a, b)\n\nbroadcasted(::DefaultArrayStyle{1}, ::typeof(-), a::AbstractZerosVector, b::AbstractZerosVector) = _broadcasted_zeros(-, a, b)\nbroadcasted(::DefaultArrayStyle{1}, ::typeof(-), a::AbstractOnesVector, b::AbstractZerosVector) = _broadcasted_ones(-, a, b)\n\n\nbroadcasted(::DefaultArrayStyle, ::typeof(*), a::AbstractZeros, b::AbstractZeros) = _broadcasted_zeros(*, a, b)\n\n# In following, need to restrict to <: Number as otherwise we cannot infer zero from type\n# TODO: generalise to things like SVector\nfor op in (:*, :/)\n    @eval begin\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::AbstractOnes) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::AbstractFill{<:Number}) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::Number) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::AbstractRange) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::AbstractArray{<:Number}) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros, b::Base.Broadcast.Broadcasted) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractZeros, b::AbstractRange) = _broadcasted_zeros($op, a, b)\n    end\nend\n\nfor op in (:*, :\\)\n    @eval begin\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractOnes, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractFill{<:Number}, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::Number, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractRange, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractArray{<:Number}, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle, ::typeof($op), a::Base.Broadcast.Broadcasted, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n        broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractRange, b::AbstractZeros) = _broadcasted_zeros($op, a, b)\n    end\nend\n\nfor op in (:*, :/, :\\)\n    @eval broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractOnes, b::AbstractOnes) = _broadcasted_ones($op, a, b)\nend\n\nfor op in (:/, :\\)\n    @eval broadcasted(::DefaultArrayStyle, ::typeof($op), a::AbstractZeros{<:Number}, b::AbstractZeros{<:Number}) = _broadcasted_nan($op, a, b)\nend\n\n# special case due to missing converts for ranges\n_range_convert(::Type{AbstractVector{T}}, a::AbstractRange{T}) where T = a\n_range_convert(::Type{AbstractVector{T}}, a::AbstractUnitRange) where T = convert(T,first(a)):convert(T,last(a))\n_range_convert(::Type{AbstractVector{T}}, a::OneTo) where T = OneTo(convert(T, a.stop))\n_range_convert(::Type{AbstractVector{T}}, a::AbstractRange) where T = convert(T,first(a)):step(a):convert(T,last(a))\n_range_convert(::Type{AbstractVector{T}}, a::ZerosVector) where T = ZerosVector{T}(length(a))\n\n\n# TODO: replacing with the following will support more general broadcasting.\n# function broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractFill, b::AbstractRange)\n#     broadcast_shape(axes(a), axes(b)) # check axes\n#     r1 = b[1] * getindex_value(a)\n#     T = typeof(r1)\n#     if length(b) == 1 # Need a fill, but for type stability use StepRangeLen\n#         StepRangeLen{T}(r1, zero(T), length(a))\n#     else\n#         StepRangeLen{T}(r1, convert(T, getindex_value(a) * step(b)), length(b))\n#     end\n# end\n\n# function broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractRange, b::AbstractFill)\n#     broadcast_shape(axes(a), axes(b)) # check axes\n#     r1 = a[1] * getindex_value(b)\n#     T = typeof(r1)\n#     if length(a) == 1 # Need a fill, but for type stability use StepRangeLen\n#         StepRangeLen{T}(r1, zero(T), length(b))\n#     else\n#         StepRangeLen{T}(r1, convert(T, step(a) * getindex_value(b)), length(a))\n#     end\n# end\n\nfunction broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractOnesVector, b::AbstractRange)\n    broadcast_shape(axes(a), axes(b)) == axes(b) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", b, \" to a Vector first.\")))\n    TT = typeof(zero(eltype(a)) * zero(eltype(b)))\n    return _range_convert(AbstractVector{TT}, b)\nend\n\nfunction broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractRange, b::AbstractOnesVector)\n    broadcast_shape(axes(a), axes(b)) == axes(a) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", b, \" to a Vector first.\")))\n    TT = typeof(zero(eltype(a)) * zero(eltype(b)))\n    return _range_convert(AbstractVector{TT}, a)\nend\n\nfor op in (:+, :-)\n    @eval begin\n        function broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractVector, b::AbstractZerosVector)\n            broadcast_shape(axes(a), axes(b)) == axes(a) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", b, \" to a Vector first.\")))\n            TT = typeof($op(zero(eltype(a)), zero(eltype(b))))\n            # Use `TT ∘ (+)` to fix AD issues with `broadcasted(TT, x)`\n            eltype(a) === TT ? a : broadcasted(TT ∘ (+), a)\n        end\n        function broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractZerosVector, b::AbstractVector)\n            broadcast_shape(axes(a), axes(b)) == axes(b) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", a, \" to a Vector first.\")))\n            TT = typeof($op(zero(eltype(a)), zero(eltype(b))))\n            $op === (+) && eltype(b) === TT ? b : broadcasted(TT ∘ ($op), b)\n        end\n\n        broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractFillVector, b::AbstractZerosVector) =\n            Base.invoke(broadcasted, Tuple{DefaultArrayStyle, typeof($op), AbstractFill, AbstractFill}, DefaultArrayStyle{1}(), $op, a, b)\n\n        broadcasted(::DefaultArrayStyle{1}, ::typeof($op), a::AbstractZerosVector, b::AbstractFillVector) =\n            Base.invoke(broadcasted, Tuple{DefaultArrayStyle, typeof($op), AbstractFill, AbstractFill}, DefaultArrayStyle{1}(), $op, a, b)\n    end\nend\n\n# Need to prevent array-valued fills from broadcasting over entry\n_broadcast_getindex_value(a::AbstractFill{<:Number}) = getindex_value(a)\n_broadcast_getindex_value(a::AbstractFill) = Ref(getindex_value(a))\n\n\nfunction broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractFill, b::AbstractRange)\n    broadcast_shape(axes(a), axes(b)) == axes(b) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", b, \" to a Vector first.\")))\n    return broadcasted(*, _broadcast_getindex_value(a), b)\nend\n\nfunction broadcasted(::DefaultArrayStyle{1}, ::typeof(*), a::AbstractRange, b::AbstractFill)\n    broadcast_shape(axes(a), axes(b)) == axes(a) || throw(ArgumentError(LazyString(\"Cannot broadcast \", a, \" and \", b, \". Convert \", b, \" to a Vector first.\")))\n    return broadcasted(*, a, _broadcast_getindex_value(b))\nend\n\nbroadcasted(::DefaultArrayStyle{N}, op, r::AbstractFill{T,N}, x::Number) where {T,N} = broadcasted_fill(op, r, op(getindex_value(r),x), axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op, x::Number, r::AbstractFill{T,N}) where {T,N} = broadcasted_fill(op, r, op(x, getindex_value(r)), axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op, r::AbstractFill{T,N}, x::Ref) where {T,N} = broadcasted_fill(op, r, op(getindex_value(r),x[]), axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op, x::Ref, r::AbstractFill{T,N}) where {T,N} = broadcasted_fill(op, r, op(x[], getindex_value(r)), axes(r))\n\n# support AbstractFill .^ k\nbroadcasted(::DefaultArrayStyle{N}, op::typeof(Base.literal_pow), ::Base.RefValue{typeof(^)}, r::AbstractFill{T,N}, ::Base.RefValue{Val{k}}) where {T,N,k} = broadcasted_fill(op, r, getindex_value(r)^k, axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op::typeof(Base.literal_pow), ::Base.RefValue{typeof(^)}, r::AbstractOnes{T,N}, ::Base.RefValue{Val{k}}) where {T,N,k} = broadcasted_ones(op, r, T, axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op::typeof(Base.literal_pow), ::Base.RefValue{typeof(^)}, r::AbstractZeros{T,N}, ::Base.RefValue{Val{0}}) where {T,N} = broadcasted_ones(op, r, T, axes(r))\nbroadcasted(::DefaultArrayStyle{N}, op::typeof(Base.literal_pow), ::Base.RefValue{typeof(^)}, r::AbstractZeros{T,N}, ::Base.RefValue{Val{k}}) where {T,N,k} = broadcasted_zeros(op, r, T, axes(r))\n\n# supports structured broadcast\nif isdefined(LinearAlgebra, :fzero)\n    LinearAlgebra.fzero(x::AbstractZeros) = zero(eltype(x))\nend\n"
  },
  {
    "path": "src/oneelement.jl",
    "content": "\"\"\"\n    OneElement(val, ind, axesorsize) <: AbstractArray\n\nRepresents an array with the specified axes (if its a tuple of `AbstractUnitRange`s)\nor size (if its a tuple of `Integer`s), with a single entry set to `val` and all others equal to zero,\nspecified by `ind``.\n\"\"\"\nstruct OneElement{T,N,I,A} <: AbstractArray{T,N}\n  val::T\n  ind::I\n  axes::A\n  OneElement(val::T, ind::I, axes::A) where {T, I<:NTuple{N,Int}, A<:NTuple{N,AbstractUnitRange}} where {N} = new{T,N,I,A}(val, ind, axes)\n  OneElement(val::T, ind::Tuple{}, axes::Tuple{}) where {T} = new{T,0,Tuple{},Tuple{}}(val, ind, axes)\nend\n\nconst OneElementVector{T,I,A} = OneElement{T,1,I,A}\nconst OneElementMatrix{T,I,A} = OneElement{T,2,I,A}\nconst OneElementVecOrMat{T,I,A} = Union{OneElementVector{T,I,A}, OneElementMatrix{T,I,A}}\n\nOneElement(val, inds::NTuple{N,Int}, sz::NTuple{N,Integer}) where N = OneElement(val, inds, oneto.(sz))\n\"\"\"\n    OneElement(val, ind::Int, n::Integer)\n\nCreates a length `n` vector where the `ind` entry is equal to `val`, and all other entries are zero.\n\"\"\"\nOneElement(val, ind::Int, len::Integer) = OneElement(val, (ind,), (len,))\n\"\"\"\n    OneElement(ind::Int, n::Integer)\n\nCreates a length `n` vector where the `ind` entry is equal to `1`, and all other entries are zero.\n\"\"\"\nOneElement(inds::Int, sz::Integer) = OneElement(1, inds, sz)\nOneElement{T}(val, inds::NTuple{N,Int}, sz::NTuple{N,Integer}) where {T,N} = OneElement(convert(T,val), inds, oneto.(sz))\nOneElement{T}(val, inds::Int, sz::Integer) where T = OneElement{T}(val, (inds,), (sz,))\n\n\"\"\"\n    OneElement{T}(ind::Int, n::Int)\n\nCreates a length `n` vector where the `ind` entry is equal to `one(T)`, and all other entries are zero.\n\"\"\"\nOneElement{T}(inds::Int, sz::Integer) where T = OneElement(one(T), inds, sz)\n\nBase.size(A::OneElement) = map(length, A.axes)\nBase.axes(A::OneElement) = A.axes\nBase.getindex(A::OneElement{T,0}) where {T} = getindex_value(A)\nBase.@propagate_inbounds function Base.getindex(A::OneElement{T,N}, kj::Vararg{Int,N}) where {T,N}\n    @boundscheck checkbounds(A, kj...)\n    ifelse(kj == A.ind, A.val, zero(T))\nend\nconst VectorInds = Union{AbstractUnitRange{<:Integer}, Integer} # no index is repeated for these indices\nconst VectorIndsWithColon = Union{VectorInds, Colon}\n# retain the values from Ainds corresponding to the vector indices in inds\n_index_shape(Ainds, inds::Tuple{Integer, Vararg{Any}}) = _index_shape(Base.tail(Ainds), Base.tail(inds))\n_index_shape(Ainds, inds::Tuple{AbstractVector, Vararg{Any}}) = (Ainds[1], _index_shape(Base.tail(Ainds), Base.tail(inds))...)\n_index_shape(::Tuple{}, ::Tuple{}) = ()\nBase.@propagate_inbounds function Base.getindex(A::OneElement{T,N}, inds::Vararg{VectorIndsWithColon,N}) where {T,N}\n    I = to_indices(A, inds) # handle Bool, and convert to compatible index types\n    @boundscheck checkbounds(A, I...)\n    shape = _index_shape(I, I)\n    nzind = _index_shape(A.ind, I) .- first.(shape) .+ firstindex.(shape)\n    containsval = all(in.(A.ind, I))\n    OneElement(getindex_value(A), containsval ? Int.(nzind) : Int.(lastindex.(shape,1)).+1, axes.(shape,1))\nend\n\n\"\"\"\n    nzind(A::OneElement{T,N}) -> CartesianIndex{N}\n\nReturn the index where `A` contains a non-zero value.\n\n!!! note\n    The indices are not guaranteed to lie within the valid index bounds for `A`,\n    and if `FillArrays.nzind(A) ∉ CartesianIndices(A)` then `all(iszero, A)`.\n    On the other hand, if `FillArrays.nzind(A) in CartesianIndices(A)` then\n    `A[FillArrays.nzind(A)] == FillArrays.getindex_value(A)`\n\n# Examples\n```jldoctest\njulia> A = OneElement(2, (1,2), (2,2))\n2×2 OneElement{Int64, 2, Tuple{Int64, Int64}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}:\n ⋅  2\n ⋅  ⋅\n\njulia> FillArrays.nzind(A)\nCartesianIndex(1, 2)\n\njulia> A[FillArrays.nzind(A)]\n2\n```\n\"\"\"\nnzind(f::OneElement) = CartesianIndex(f.ind)\n\n\"\"\"\n    getindex_value(A::OneElement)\n\nReturn the only non-zero value stored in `A`.\n\n!!! note\n    If the index at which the value is stored doesn't lie within the valid indices of `A`, then\n    this returns `zero(eltype(A))`.\n\n# Examples\n```jldoctest\njulia> A = OneElement(2, 3)\n3-element OneElement{Int64, 1, Tuple{Int64}, Tuple{Base.OneTo{Int64}}}:\n ⋅\n 1\n ⋅\n\njulia> FillArrays.getindex_value(A)\n1\n```\n\"\"\"\ngetindex_value(A::OneElement) = all(in.(A.ind, axes(A))) ? A.val : zero(eltype(A))\n\n@inline function Base.isassigned(F::OneElement, i::Integer...)\n    @boundscheck checkbounds(Bool, F, to_indices(F, i)...) || return false\n    return true\nend\n\nBase.AbstractArray{T,N}(A::OneElement{<:Any,N}) where {T,N} = OneElement(T(A.val), A.ind, A.axes)\n\nBase.replace_in_print_matrix(o::OneElementVector, k::Integer, j::Integer, s::AbstractString) =\n    o.ind == (k,) ? s : Base.replace_with_centered_mark(s)\n\nBase.replace_in_print_matrix(o::OneElementMatrix, k::Integer, j::Integer, s::AbstractString) =\n    o.ind == (k,j) ? s : Base.replace_with_centered_mark(s)\n\nBase.@propagate_inbounds function Base.setindex(A::AbstractZeros{T,N}, v, kj::Vararg{Int,N}) where {T,N}\n    @boundscheck checkbounds(A, kj...)\n    OneElement(convert(T, v), kj, axes(A))\nend\n\nzero(A::OneElement) = OneElement(zero(A.val), A.ind, A.axes)\n\niszero(A::OneElement) = iszero(getindex_value(A))\n\nfunction isone(A::OneElementMatrix)\n    lenA = length(A)\n    lenA == 0 && return true\n    lenA > 1 && return false\n    isone(getindex_value(A))\nend\n\n-(O::OneElement) = OneElement(-O.val, O.ind, O.axes)\n\n*(x::OneElement, b::Number) = OneElement(x.val * b, x.ind, x.axes)\n*(b::Number, x::OneElement) = OneElement(b * x.val, x.ind, x.axes)\n/(x::OneElement, b::Number) = OneElement(x.val / b, x.ind, x.axes)\n\\(b::Number, x::OneElement) = OneElement(b \\ x.val, x.ind, x.axes)\n\n# matrix-vector and matrix-matrix multiplication\n\n# Fill and OneElement\nfunction *(A::OneElementMatrix, B::OneElementVecOrMat)\n    check_matmul_sizes(A, B)\n    valA = getindex_value(A)\n    valB = getindex_value(B)\n    val = valA * valB * (A.ind[2] == B.ind[1])\n    OneElement(val, (A.ind[1], B.ind[2:end]...), (axes(A,1), axes(B)[2:end]...))\nend\n\n*(A::OneElementMatrix, x::AbstractZerosVector) = mult_zeros(A, x)\n\nfunction *(A::OneElementMatrix, B::AbstractFillVector)\n    check_matmul_sizes(A, B)\n    val = getindex_value(A) * getindex_value(B)\n    OneElement(val, A.ind[1], size(A,1))\nend\n\n# Special matrix types\n\nfunction *(A::OneElementMatrix, D::Diagonal)\n    check_matmul_sizes(A, D)\n    nzcol = A.ind[2]\n    val = if nzcol in axes(D,1)\n        A.val * D[nzcol, nzcol]\n    else\n        A.val * zero(eltype(D))\n    end\n    OneElement(val, A.ind, size(A))\nend\nfunction *(D::Diagonal, A::OneElementMatrix)\n    check_matmul_sizes(D, A)\n    nzrow = A.ind[1]\n    val = if nzrow in axes(D,2)\n        D[nzrow, nzrow] * A.val\n    else\n        zero(eltype(D)) * A.val\n    end\n    OneElement(val, A.ind, size(A))\nend\n\n# Inplace multiplication\n\n# We use this for out overloads for _mul! for OneElement because its more efficient\n# due to how efficient 2 arg mul is when one or more of the args are OneElement\nfunction __mulonel!(C, A, B, alpha, beta)\n    ABα = A * B * alpha\n    if iszero(beta)\n        C .= ABα\n    else\n        C .= ABα .+ C .* beta\n    end\n    return C\nend\n# These methods remove the ambituity in _mul!. This isn't strictly necessary, but this makes Aqua happy.\nfunction _mul!(C::AbstractVector, A::OneElementMatrix, B::OneElementVector, alpha, beta)\n    __mulonel!(C, A, B, alpha, beta)\nend\nfunction _mul!(C::AbstractMatrix, A::OneElementMatrix, B::OneElementMatrix, alpha, beta)\n    __mulonel!(C, A, B, alpha, beta)\nend\n\nfunction mul!(C::AbstractMatrix, A::OneElementMatrix, B::OneElementMatrix, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\nfunction mul!(C::AbstractVector, A::OneElementMatrix, B::OneElementVector, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\n\n@inline function __mul!(y, A::AbstractMatrix, x::OneElement, alpha, beta)\n    xα = Ref(x.val * alpha)\n    ind1 = x.ind[1]\n    if iszero(beta)\n        y .= view(A, :, ind1) .* xα\n    else\n        y .= view(A, :, ind1) .* xα .+ y .* beta\n    end\n    return y\nend\n\nfunction _mul!(y::AbstractVector, A::AbstractMatrix, x::OneElementVector, alpha, beta)\n    check_matmul_sizes(y, A, x)\n    if iszero(getindex_value(x))\n        mul!(y, A, Zeros{eltype(x)}(axes(x)), alpha, beta)\n        return y\n    end\n    __mul!(y, A, x, alpha, beta)\n    y\nend\n\nfunction _mul!(C::AbstractMatrix, A::AbstractMatrix, B::OneElementMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    if iszero(getindex_value(B))\n        mul!(C, A, Zeros{eltype(B)}(axes(B)), alpha, beta)\n        return C\n    end\n    nzrow, nzcol = B.ind\n    if iszero(beta)\n        C .= Ref(zero(eltype(C)))\n    else\n        view(C, :, 1:nzcol-1) .*= beta\n        view(C, :, nzcol+1:size(C,2)) .*= beta\n    end\n    y = view(C, :, nzcol)\n    __mul!(y, A, B, alpha, beta)\n    C\nend\nfunction _mul!(C::AbstractMatrix, A::Diagonal, B::OneElementMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    if iszero(getindex_value(B))\n        mul!(C, A, Zeros{eltype(B)}(axes(B)), alpha, beta)\n        return C\n    end\n    nzrow, nzcol = B.ind\n    ABα = A * B * alpha\n    if iszero(beta)\n        C .= Ref(zero(eltype(C)))\n        C[nzrow, nzcol] = ABα[nzrow, nzcol]\n    else\n        view(C, :, 1:nzcol-1) .*= beta\n        view(C, :, nzcol+1:size(C,2)) .*= beta\n        y = view(C, :, nzcol)\n        y .= view(ABα, :, nzcol) .+ y .* beta\n    end\n    C\nend\n\nfunction _mul!(C::AbstractMatrix, A::OneElementMatrix, B::AbstractMatrix, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    if iszero(getindex_value(A))\n        mul!(C, Zeros{eltype(A)}(axes(A)), B, alpha, beta)\n        return C\n    end\n    nzrow, nzcol = A.ind\n    y = view(C, nzrow, :)\n    Aval = A.val\n    if iszero(beta)\n        C .= Ref(zero(eltype(C)))\n        y .= Ref(Aval) .* view(B, nzcol, :) .* alpha\n    else\n        view(C, 1:nzrow-1, :) .*= beta\n        view(C, nzrow+1:size(C,1), :) .*= beta\n        y .= Ref(Aval) .* view(B, nzcol, :) .* alpha .+ y .* beta\n    end\n    C\nend\nfunction _mul!(C::AbstractMatrix, A::OneElementMatrix, B::Diagonal, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    if iszero(getindex_value(A))\n        mul!(C, Zeros{eltype(A)}(axes(A)), B, alpha, beta)\n        return C\n    end\n    nzrow, nzcol = A.ind\n    ABα = A * B * alpha\n    if iszero(beta)\n        C .= Ref(zero(eltype(C)))\n        C[nzrow, nzcol] = ABα[nzrow, nzcol]\n    else\n        view(C, 1:nzrow-1, :) .*= beta\n        view(C, nzrow+1:size(C,1), :) .*= beta\n        y = view(C, nzrow, :)\n        y .= view(ABα, nzrow, :) .+ y .* beta\n    end\n    C\nend\n\nfunction _mul!(C::AbstractVector, A::OneElementMatrix, B::AbstractVector, alpha, beta)\n    check_matmul_sizes(C, A, B)\n    if iszero(getindex_value(A))\n        mul!(C, Zeros{eltype(A)}(axes(A)), B, alpha, beta)\n        return C\n    end\n    nzrow, nzcol = A.ind\n    Aval = A.val\n    if iszero(beta)\n        C .= Ref(zero(eltype(C)))\n        C[nzrow] = Aval * B[nzcol] * alpha\n    else\n        view(C, 1:nzrow-1) .*= beta\n        view(C, nzrow+1:size(C,1)) .*= beta\n        C[nzrow] = Aval * B[nzcol] * alpha + C[nzrow] * beta\n    end\n    C\nend\n\nfor MT in (:StridedMatrix, :(Transpose{<:Any, <:StridedMatrix}), :(Adjoint{<:Any, <:StridedMatrix}))\n    @eval function mul!(y::StridedVector, A::$MT, x::OneElementVector, alpha::Number, beta::Number)\n        _mul!(y, A, x, alpha, beta)\n    end\nend\nfor MT in (:StridedMatrix, :(Transpose{<:Any, <:StridedMatrix}), :(Adjoint{<:Any, <:StridedMatrix}),\n            :Diagonal)\n    @eval function mul!(C::StridedMatrix, A::$MT, B::OneElementMatrix, alpha::Number, beta::Number)\n        _mul!(C, A, B, alpha, beta)\n    end\n    @eval function mul!(C::StridedMatrix, A::OneElementMatrix, B::$MT, alpha::Number, beta::Number)\n        _mul!(C, A, B, alpha, beta)\n    end\nend\nfunction mul!(C::StridedVector, A::OneElementMatrix, B::StridedVector, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\n\nfunction mul!(y::AbstractVector, A::AbstractFillMatrix, x::OneElementVector, alpha::Number, beta::Number)\n    _mul!(y, A, x, alpha, beta)\nend\nfunction mul!(C::AbstractMatrix, A::AbstractFillMatrix, B::OneElementMatrix, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\nfunction mul!(C::AbstractVector, A::OneElementMatrix, B::AbstractFillVector, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\nfunction mul!(C::AbstractMatrix, A::OneElementMatrix, B::AbstractFillMatrix, alpha::Number, beta::Number)\n    _mul!(C, A, B, alpha, beta)\nend\n\n# adjoint/transpose\n\nadjoint(A::OneElementMatrix) = OneElement(adjoint(A.val), reverse(A.ind), reverse(A.axes))\ntranspose(A::OneElementMatrix) = OneElement(transpose(A.val), reverse(A.ind), reverse(A.axes))\n\n# isbanded\nfunction LinearAlgebra.isbanded(A::OneElementMatrix, kl::Integer, ku::Integer)\n    iszero(getindex_value(A)) || kl <= A.ind[2] - A.ind[1] <= ku\nend\n\n# tril/triu\n\nfunction tril(A::OneElementMatrix, k::Integer=0)\n    nzband = A.ind[2] - A.ind[1]\n    OneElement(nzband > k ? zero(A.val) : A.val, A.ind, axes(A))\nend\n\nfunction triu(A::OneElementMatrix, k::Integer=0)\n    nzband = A.ind[2] - A.ind[1]\n    OneElement(nzband < k ? zero(A.val) : A.val, A.ind, axes(A))\nend\n\n\n# issymmetric\nissymmetric(O::OneElement) = axes(O,1) == axes(O,2) && isdiag(O) && issymmetric(getindex_value(O))\nishermitian(O::OneElement) = axes(O,1) == axes(O,2) && isdiag(O) && ishermitian(getindex_value(O))\n\n# diag\nfunction diag(O::OneElementMatrix, k::Integer=0)\n    Base.require_one_based_indexing(O)\n    len = length(diagind(O, k))\n    ind = O.ind[2] - O.ind[1] == k ? (k >= 0 ? O.ind[2] - k : O.ind[1] + k) : len + 1\n    OneElement(getindex_value(O), ind, len)\nend\n\n# broadcast\n\nfor f in (:abs, :abs2, :conj, :real, :imag)\n    @eval function broadcasted(::DefaultArrayStyle{N}, ::typeof($f), r::OneElement{<:Any,N}) where {N}\n        OneElement($f(r.val), r.ind, axes(r))\n    end\nend\nfunction broadcasted(::DefaultArrayStyle{N}, ::typeof(^), r::OneElement{<:Any,N}, x::Number) where {N}\n    OneElement(r.val^x, r.ind, axes(r))\nend\nfunction broadcasted(::DefaultArrayStyle{N}, ::typeof(*), r::OneElement{<:Any,N}, x::Number) where {N}\n    OneElement(r.val*x, r.ind, axes(r))\nend\nfunction broadcasted(::DefaultArrayStyle{N}, ::typeof(/), r::OneElement{<:Any,N}, x::Number) where {N}\n    OneElement(r.val/x, r.ind, axes(r))\nend\nfunction broadcasted(::DefaultArrayStyle{N}, ::typeof(\\), x::Number, r::OneElement{<:Any,N}) where {N}\n    OneElement(x \\ r.val, r.ind, axes(r))\nend\n\n# reshape\n\nfunction Base.reshape(A::OneElement, shape::Tuple{Vararg{Int}})\n    prod(shape) == length(A) || throw(DimensionMismatch(LazyString(\"new dimension \", shape, \" must be consistent with array size \", length(A))))\n    if all(in.(A.ind, axes(A)))\n        # we use the fact that the linear index of the non-zero value is preserved\n        oldlinind = LinearIndices(A)[A.ind...]\n        newcartind = CartesianIndices(shape)[oldlinind]\n    else\n        # arbitrarily set to some value outside the domain\n        newcartind = shape .+ 1\n    end\n    OneElement(A.val, Tuple(newcartind), shape)\nend\n\n#permute\n_permute(x, p) = ntuple(i -> x[p[i]], length(x))\npermutedims(o::OneElementMatrix) = OneElement(o.val, reverse(o.ind), reverse(o.axes))\npermutedims(o::OneElementVector) = reshape(o, (1, length(o)))\npermutedims(o::OneElement, dims) = OneElement(o.val, _permute(o.ind, dims), _permute(o.axes, dims))\n\n# unique\nfunction unique(O::OneElement)\n    v = getindex_value(O)\n    len = iszero(v) ? 1 : min(2, length(O))\n    OneElement(getindex_value(O), len, len)\nend\nallunique(O::OneElement) = length(O) <= 1 || (length(O) < 3 && !iszero(getindex_value(O)))\n\n# show\n_maybesize(t::Tuple{Base.OneTo{Int}, Vararg{Base.OneTo{Int}}}) = size.(t,1)\n_maybesize(t) = t\nBase.show(io::IO, A::OneElement) = print(io, OneElement, \"(\", A.val, \", \", A.ind, \", \", _maybesize(axes(A)), \")\")\nBase.show(io::IO, A::OneElement{<:Any,1,Tuple{Int},Tuple{Base.OneTo{Int}}}) =\n    print(io, OneElement, \"(\", A.val, \", \", A.ind[1], \", \", size(A,1), \")\")\n\n# mapreduce\nBase.sum(O::OneElement; dims=:, kw...) = _sum(O, dims; kw...)\n_sum(O::OneElement, ::Colon; kw...) = sum((getindex_value(O),); kw...)\nfunction _sum(O::OneElement, dims; kw...)\n    v = _sum(O, :; kw...)\n    ax = Base.reduced_indices(axes(O), dims)\n    ind = ntuple(x -> x in dims ? first(ax[x]) + (O.ind[x] in axes(O)[x]) - 1 : O.ind[x], ndims(O))\n    OneElement(v, ind, ax)\nend\n"
  },
  {
    "path": "src/trues.jl",
    "content": "\n\"\"\"\n    Trues = Ones{Bool, N, Axes} where {N, Axes}\n\nLazy version of `trues` with axes.\nTypically created using `Trues(dims)` or `Trues(dims...)`\n\n# Example\n```jldoctest\njulia> T = Trues(1,3)\n1×3 Ones{Bool}\n\njulia> Array(T)\n1×3 Matrix{Bool}:\n 1  1  1\n```\n\"\"\"\nconst Trues = Ones{Bool, N, Axes} where {N, Axes}\n\n\n\"\"\"\n    Falses = Zeros{Bool, N, Axes}\n\nLazy version of `falses` with axes.\n\nSee also: [`Trues`](@ref)\n\"\"\"\nconst Falses = Zeros{Bool, N, Axes} where {N, Axes}\n\n\n# y[mask] = x when mask isa Trues (cf y[:] = x)\n\nfunction Base.to_indices(A::AbstractArray{T,N}, inds, I::Tuple{Trues{N}}) where {T,N}\n    @boundscheck axes(A) == axes(I[1]) || Base.throw_boundserror(A, I[1])\n    (vec(LinearIndices(A)),)\nend\n"
  },
  {
    "path": "test/aqua.jl",
    "content": "using Aqua\nusing FillArrays\nusing Test\ndownstream_test = \"--downstream_integration_test\" in ARGS\n@testset \"Project quality\" begin\n    Aqua.test_all(FillArrays;\n        # https://github.com/JuliaArrays/FillArrays.jl/issues/105#issuecomment-1582516319\n        ambiguities=(; broken=true),\n        stale_deps = !downstream_test,\n    )\nend\n"
  },
  {
    "path": "test/infinitearrays.jl",
    "content": "# Infinite Arrays implementation from\n# https://github.com/JuliaLang/julia/blob/master/test/testhelpers/InfiniteArrays.jl\nmodule InfiniteArrays\n    using Infinities\n    export OneToInf\n\n    abstract type AbstractInfUnitRange{T<:Real} <: AbstractUnitRange{T} end\n    Base.length(r::AbstractInfUnitRange) = ℵ₀\n    Base.size(r::AbstractInfUnitRange) = (ℵ₀,)\n    Base.last(r::AbstractInfUnitRange) = ℵ₀\n    Base.axes(r::AbstractInfUnitRange) = (OneToInf(),)\n\n    Base.IteratorSize(::Type{<:AbstractInfUnitRange}) = Base.IsInfinite()\n\n    \"\"\"\n        OneToInf(n)\n    Define an `AbstractInfUnitRange` that behaves like `1:∞`, with the added\n    distinction that the limits are guaranteed (by the type system) to\n    be 1 and ∞.\n    \"\"\"\n    struct OneToInf{T<:Integer} <: AbstractInfUnitRange{T} end\n\n    OneToInf() = OneToInf{Int}()\n\n    Base.axes(r::OneToInf) = (r,)\n    Base.first(r::OneToInf{T}) where {T} = oneunit(T)\n    Base.oneto(::InfiniteCardinal{0}) = OneToInf()\n\n    struct InfUnitRange{T<:Real} <: AbstractInfUnitRange{T}\n        start::T\n    end\n    Base.first(r::InfUnitRange) = r.start\n    InfUnitRange(a::InfUnitRange) = a\n    InfUnitRange{T}(a::AbstractInfUnitRange) where T<:Real = InfUnitRange{T}(first(a))\n    InfUnitRange(a::AbstractInfUnitRange{T}) where T<:Real = InfUnitRange{T}(first(a))\n    Base.:(:)(start::T, stop::InfiniteCardinal{0}) where {T<:Integer} = InfUnitRange{T}(start)\n    function getindex(v::InfUnitRange{T}, i::Integer) where T\n        @boundscheck i > 0 || Base.throw_boundserror(v, i)\n        convert(T, first(v) + i - 1)\n    end\nend\n"
  },
  {
    "path": "test/runtests.jl",
    "content": "using FillArrays, LinearAlgebra, PDMats, SparseArrays, StaticArrays, ReverseDiff, Random, Test, Statistics, Quaternions\n\nimport FillArrays: AbstractFill, RectDiagonal, SquareEye\n\nusing Documenter\nDocMeta.setdocmeta!(FillArrays, :DocTestSetup, :(using FillArrays))\ndoctest(FillArrays; manual = false)\n\ninclude(\"aqua.jl\")\n\ninclude(\"infinitearrays.jl\")\nimport .InfiniteArrays\n\n# we may use this instead of rand(n) to generate deterministic arrays\noneton(T::Type, sz...) = reshape(T.(1:prod(sz)), sz)\noneton(sz...) = oneton(Float64, sz...)\n\nstringmime(args...) = sprint(show, args...)\n\n@testset \"fill array constructors and convert\" begin\n    for (Typ, funcs) in ((Zeros, zeros), (Ones, ones))\n        @test Typ((-1,5)) == Typ((0,5))\n        @test Typ(5) isa AbstractVector{Float64}\n        @test Typ(5,5) isa AbstractMatrix{Float64}\n        @test Typ(5) == Typ((5,))\n        @test Typ(5,5) == Typ((5,5))\n        @test eltype(Typ(5,5)) == Float64\n\n        for T in (Int, Float64)\n            Z = Typ{T}(5)\n            @test Typ(T, 5) ≡ Z\n            @test eltype(Z) == T\n            @test Array(Z) == funcs(T,5)\n            @test Array{T}(Z) == funcs(T,5)\n            @test Array{T,1}(Z) == funcs(T,5)\n\n            @test convert(AbstractArray,Z) ≡ Z\n            @test convert(AbstractArray{T},Z) ≡ AbstractArray{T}(Z) ≡ Z\n            @test convert(AbstractVector{T},Z) ≡ AbstractVector{T}(Z) ≡ Z\n            @test convert(AbstractFill{T},Z) ≡ AbstractFill{T}(Z) ≡ Z\n\n            @test Typ{T,1}(2ones(T,5)) == Z\n            @test Typ{T}(2ones(T,5)) == Z\n            @test Typ(2ones(T,5)) == Z\n\n            Z = Typ{T}(5, 5)\n            @test Typ(T, 5, 5) ≡ Z\n            @test eltype(Z) == T\n            @test Array(Z) == funcs(T,5,5)\n            @test Array{T}(Z) == funcs(T,5,5)\n            @test Array{T,2}(Z) == funcs(T,5,5)\n\n            @test convert(AbstractArray,Z) ≡ convert(AbstractFill,Z) ≡ Z\n            @test convert(AbstractArray{T},Z) ≡ convert(AbstractFill{T},Z) ≡ AbstractArray{T}(Z) ≡ Z\n            @test convert(AbstractMatrix{T},Z) ≡ convert(AbstractFill{T,2},Z) ≡ AbstractMatrix{T}(Z) ≡ Z\n\n            @test_throws Exception convert(Fill{Float64}, [1,1,2])\n            @test_throws Exception convert(Fill, [])\n            @test convert(Fill{Float64}, [1,1,1]) ≡ Fill(1.0, 3)\n            @test convert(Fill, Float64[1,1,1]) ≡ Fill(1.0, 3)\n            @test convert(Fill{Float64}, Fill(1.0,2)) ≡ Fill(1.0, 2) # was ambiguous\n            @test convert(Fill{Int}, Ones(20)) ≡ Fill(1, 20)\n            @test convert(Fill{Int,1}, Ones(20)) ≡ Fill(1, 20)\n            @test convert(Fill{Int,1,Tuple{Base.OneTo{Int}}}, Ones(20)) ≡ Fill(1, 20)\n            @test convert(AbstractFill{Int}, Ones(20)) ≡ AbstractFill{Int}(Ones(20)) ≡ Ones{Int}(20)\n            @test convert(AbstractFill{Int,1}, Ones(20)) ≡ AbstractFill{Int,1}(Ones(20)) ≡ Ones{Int}(20)\n            @test convert(AbstractFill{Int,1,Tuple{Base.OneTo{Int}}}, Ones(20)) ≡ AbstractFill{Int,1,Tuple{Base.OneTo{Int}}}(Ones(20)) ≡ Ones{Int}(20)\n\n            @test Typ{T,2}(2ones(T,5,5)) ≡ Typ{T}(5,5)\n            @test Typ{T}(2ones(T,5,5)) ≡ Typ{T}(5,5)\n            @test Typ(2ones(T,5,5)) ≡ Typ{T}(5,5)\n\n            z = Typ{T}()[]\n            @test convert(Typ, Fill(z,2)) === Typ{T}(2)\n            z = Typ{Int8}()[]\n            @test convert(Typ{T}, Fill(z,2)) === Typ{T}(2)\n            @test convert(Typ{T,1}, Fill(z,2)) === Typ{T}(2)\n            @test convert(Typ{T,1,Tuple{Base.OneTo{Int}}}, Fill(z,2)) === Typ{T}(2)\n            @test_throws ArgumentError convert(Typ, Fill(2,2))\n\n            @test Typ(Z) ≡ Typ{T}(Z) ≡ Typ{T,2}(Z) ≡ typeof(Z)(Z) ≡ Z\n\n            @test AbstractArray{Float32}(Z) ≡ Typ{Float32}(5,5)\n            @test AbstractArray{Float32,2}(Z) ≡ Typ{Float32}(5,5)\n        end\n    end\n\n    @test Fill(1) ≡ Fill{Int}(1) ≡ Fill{Int,0}(1) ≡ Fill{Int,0,Tuple{}}(1,())\n    @test Fill(1,(-1,5)) ≡ Fill(1,(0,5))\n    @test Fill(1.0,5) isa AbstractVector{Float64}\n    @test Fill(1.0,5,5) isa AbstractMatrix{Float64}\n    @test Fill(1,5) ≡ Fill(1,(5,))\n    @test Fill(1,5,5) ≡ Fill(1,(5,5))\n    @test eltype(Fill(1.0,5,5)) == Float64\n\n    @test Matrix{Float64}(Zeros{ComplexF64}(10,10)) == zeros(10,10)\n    @test_throws InexactError Matrix{Float64}(Fill(1.0+1.0im,10,10))\n\n\n    for T in (Int, Float64)\n        F = Fill{T, 0}(2)\n        @test size(F) == ()\n        @test F[] === T(2)\n\n        F = Fill{T}(1, 5)\n\n        @test eltype(F) == T\n        @test Array(F) == fill(one(T),5)\n        @test Array{T}(F) == fill(one(T),5)\n        @test Array{T,1}(F) == fill(one(T),5)\n\n        F = Fill{T}(1, 5, 5)\n        @test eltype(F) == T\n        @test Array(F) == fill(one(T),5,5)\n        @test Array{T}(F) == fill(one(T),5,5)\n        @test Array{T,2}(F) == fill(one(T),5,5)\n\n        @test convert(AbstractArray,F) ≡ F\n        @test convert(AbstractArray{T},F) ≡ AbstractArray{T}(F) ≡ F\n        @test convert(AbstractMatrix{T},F) ≡ AbstractMatrix{T}(F) ≡ F\n\n        @test convert(AbstractArray{Float32},F) ≡ AbstractArray{Float32}(F) ≡\n                Fill{Float32}(one(Float32),5,5)\n        @test convert(AbstractMatrix{Float32},F) ≡ AbstractMatrix{Float32}(F) ≡\n                Fill{Float32}(one(Float32),5,5)\n\n        @test Fill{T}(F) ≡ Fill{T,2}(F) ≡ typeof(F)(F) ≡ F\n\n        show(devnull, MIME(\"text/plain\"), F) # for codecov\n    end\n\n    @test Eye(5) isa Diagonal{Float64}\n    @test SquareEye(5) isa Diagonal{Float64}\n    @test Eye(5) == Eye{Float64}(5) == SquareEye(5) == SquareEye{Float64}(5)\n    @test Eye(5,6) == Eye{Float64}(5,6)\n    @test Eye(Ones(5,6)) == Eye{Float64}(5,6)\n    @test eltype(Eye(5)) == Float64\n    @test eltype(Eye(5,6)) == Float64\n\n    @test Eye((Base.OneTo(5),)) ≡ SquareEye((Base.OneTo(5),)) ≡ Eye(5)\n    @test Eye((Base.OneTo(5),Base.OneTo(6))) ≡ Eye(5,6)\n\n    for T in (Int, Float64)\n        E = Eye{T}(5)\n        M = Matrix{T}(I, 5, 5)\n\n        @test eltype(E) == T\n        @test Array(E) == M\n        @test Array{T}(E) == M\n        @test Array{T,2}(E) == M\n\n        @test convert(AbstractArray,E) === E\n        @test convert(AbstractArray{T},E) === E\n        @test convert(AbstractMatrix{T},E) === E\n\n\n        @test AbstractArray{Float32}(E) == Eye{Float32}(5)\n        @test AbstractArray{Float32}(E) == Eye{Float32}(5, 5)\n\n        @test Eye{T}(randn(4,5)) ≡ Eye{T}(4,5) ≡ Eye{T}((Base.OneTo(4),Base.OneTo(5)))\n        @test Eye{T}((Base.OneTo(5),)) ≡ SquareEye{T}((Base.OneTo(5),)) ≡ Eye{T}(5)\n    end\n\n    @testset \"Bool should change type\" begin\n        x = Fill(true,5)\n        y = x + x\n        @test y isa Fill{Int,1}\n        @test y[1] == 2\n\n        x = Ones{Bool}(5)\n        y = x + x\n        @test y isa Fill{Int,1}\n        @test y[1] == 2\n        @test x + Zeros{Bool}(5) ≡ Ones{Int}(5)\n        @test x - Zeros{Bool}(5) ≡ Ones{Int}(5)\n        @test Zeros{Bool}(5) + x ≡ Ones{Int}(5)\n        @test -x ≡ Fill(-1,5)\n    end\n\n    @testset \"copy should return Fill\" begin\n        x = Fill(1.0,10)\n        @test copy(x) ≡ x\n        x = Zeros(10)\n        @test copy(x) ≡ x\n        x = Fill([1.,2.],10)\n        @test copy(x) == x\n        @test copy(x) === x   # because isbits(x)\n        @test copy(x) isa Fill\n        @test copy(Fill(:a, 4)) == fill(:a, 4)    # FillArrays#63\n    end\n\n    @testset \"vec\" begin\n        @test vec(Ones{Int}(5,10)) ≡ Ones{Int}(50)\n        @test vec(Zeros{Int}(5,10)) ≡ Zeros{Int}(50)\n        @test vec(Zeros{Int}(5,10,20)) ≡ Zeros{Int}(1000)\n        @test vec(Fill(1,5,10)) ≡ Fill(1,50)\n    end\n\n    @testset \"in\" begin\n        for T in [Zeros, Ones, Fill, Trues, Falses]\n            A = T(4, 4)\n            @test FillArrays.getindex_value(A) in A\n            @test !(FillArrays.getindex_value(A) + 1 in A)\n        end\n        A = FillArrays.RectDiagonal([1, 2, 3])\n        @test 3 in A\n        @test 0 in A\n        @test !(4 in A)\n        A = FillArrays.RectDiagonal([1])\n        @test 1 in A\n        @test !(0 in A)\n        A = FillArrays.RectDiagonal([2], (1:1, 1:4))\n        @test 2 in A\n        @test 0 in A\n        @test !(1 in A)\n        @test !(Zeros(1,1) in A)\n        A = FillArrays.RectDiagonal(Int[])\n        @test !(0 in A)\n        A = FillArrays.RectDiagonal(Int[], (1:0, 1:4))\n        @test !(0 in A)\n    end\n\n    @testset \"promotion\" begin\n        Z = Zeros{Int}(5)\n        Zf = Zeros(5)\n        @test promote_type(typeof(Z), typeof(Zf)) == typeof(Zf)\n        O = Ones{Int}(5)\n        Of = Ones{Float64}(5)\n        @test promote_type(typeof(O), typeof(Of)) == typeof(Of)\n        @test [Z,O] isa Vector{Fill{Int,1,Tuple{Base.OneTo{Int}}}}\n        @test [Z,Of] isa Vector{Fill{Float64,1,Tuple{Base.OneTo{Int}}}}\n        @test [O,O] isa Vector{Ones{Int,1,Tuple{Base.OneTo{Int}}}}\n        @test [O,Of] isa Vector{Ones{Float64,1,Tuple{Base.OneTo{Int}}}}\n        @test [Z,Zf] isa Vector{Zeros{Float64,1,Tuple{Base.OneTo{Int}}}}\n\n        @test convert(Ones{Int}, Of) ≡ convert(Ones{Int,1}, Of) ≡ convert(typeof(O), Of) ≡ O\n        @test convert(Zeros{Int}, Zf) ≡ convert(Zeros{Int,1}, Zf) ≡ convert(typeof(Z), Zf) ≡ Z\n\n        F = Fill(1, 2)\n        Ff = Fill(1.0, 2)\n        @test promote_type(typeof(F), typeof(Ff)) == typeof(Ff)\n\n        @test_throws MethodError convert(Zeros{SVector{2,Int}}, Zf)\n    end\nend\n\n@testset \"interface\" begin\n    struct Twos{T,N} <: FillArrays.AbstractFill{T,N,NTuple{N,Base.OneTo{Int}}}\n        sz :: NTuple{N,Int}\n    end\n    Twos{T}(sz::NTuple{N,Int}) where {T,N} = Twos{T,N}(sz)\n    Twos{T}(sz::Vararg{Int,N}) where {T,N} = Twos{T,N}(sz)\n    Base.size(A::Twos) = A.sz\n    FillArrays.getindex_value(A::Twos{T}) where {T} = oneunit(T) + oneunit(T)\n\n    @testset \"broadcasting ambiguities\" begin\n        A = Twos{Int}(3)\n        B = Zeros{Int}(size(A))\n        @test A .* B === B\n        @test B .* A === B\n        @test B ./ A === Zeros{Float64}(size(A))\n        @test A .\\ B === Zeros{Float64}(size(A))\n        @test A ./ B === Fill(Inf, size(A))\n    end\nend\n\n@testset \"isassigned\" begin\n    for f in (Fill(\"\", 3, 4), Zeros(3,4), Ones(3,4))\n        @test !isassigned(f, 0, 0)\n        @test isassigned(f, 2, 2)\n        @test !isassigned(f, 10, 10)\n        @test_throws ArgumentError isassigned(f, true)\n    end\nend\n\n@testset \"indexing\" begin\n    A = Fill(3.0,5)\n    @test A[1:3] ≡ Fill(3.0,3)\n    @test A[1:3,1:1] ≡ Fill(3.0,3,1)\n    @test_throws BoundsError A[1:3,2]\n    @test_throws BoundsError A[1:26]\n    @test A[[true, false, true, false, false]] ≡ Fill(3.0, 2)\n    A = Fill(3.0, 2, 2)\n    @test A[[true true; true false]] ≡ Fill(3.0, 3)\n    @test_throws BoundsError A[[true, false]]\n\n    A = Ones{Int}(5,5)\n    @test A[1:3] ≡ Ones{Int}(3)\n    @test A[1:3,1:2] ≡ Ones{Int}(3,2)\n    @test A[1:3,2] ≡ Ones{Int}(3)\n    @test_throws BoundsError A[1:26]\n    A = Ones{Int}(2,2)\n    @test A[[true false; true false]] ≡ Ones{Int}(2)\n    @test A[[true, false, true, false]] ≡ Ones{Int}(2)\n    @test_throws BoundsError A[[true false false; true false false]]\n\n    A = Zeros{Int}(5,5)\n    @test A[1:3] ≡ Zeros{Int}(3)\n    @test A[1:3,1:2] ≡ Zeros{Int}(3,2)\n    @test A[1:3,2] ≡ Zeros{Int}(3)\n    @test_throws BoundsError A[1:26]\n    A = Zeros{Int}(2,2)\n    @test A[[true false; true false]] ≡ Zeros{Int}(2)\n    @test A[[true, false, true, false]] ≡ Zeros{Int}(2)\n    @test_throws BoundsError A[[true false false; true false false]]\n\n    @testset \"colon\" begin\n        @test Ones(2)[:] ≡ Ones(2)[Base.Slice(Base.OneTo(2))] ≡ Ones(2)\n        @test Zeros(2)[:] ≡ Zeros(2)[Base.Slice(Base.OneTo(2))] ≡ Zeros(2)\n        @test Fill(3.0,2)[:] ≡ Fill(3.0,2)[Base.Slice(Base.OneTo(2))] ≡ Fill(3.0,2)\n\n        @test Ones(2,2)[:,:] ≡ Ones(2,2)[Base.Slice(Base.OneTo(2)),Base.Slice(Base.OneTo(2))] ≡ Ones(2,2)\n        @test Zeros(2,2)[:,:] ≡ Zeros(2)[Base.Slice(Base.OneTo(2)),Base.Slice(Base.OneTo(2))] ≡ Zeros(2,2)\n        @test Fill(3.0,2,2)[:,:] ≡ Fill(3.0,2,2)[Base.Slice(Base.OneTo(2)),Base.Slice(Base.OneTo(2))] ≡ Fill(3.0,2,2)\n    end\n\n    @testset \"mixed integer / vector /colon\" begin\n        a = Fill(2.0,5)\n        z = Zeros(5)\n        @test a[1:5] ≡ a[:] ≡ a\n        @test z[1:5] ≡ z[:] ≡ z\n\n        A = Fill(2.0,5,6)\n        Z = Zeros(5,6)\n        @test A[:,1] ≡ A[1:5,1] ≡ Fill(2.0,5)\n        @test A[1,:] ≡ A[1,1:6] ≡ Fill(2.0,6)\n        @test A[:,:] ≡ A[1:5,1:6] ≡ A[1:5,:] ≡ A[:,1:6] ≡ A\n        @test Z[:,1] ≡ Z[1:5,1] ≡ Zeros(5)\n        @test Z[1,:] ≡ Z[1,1:6] ≡ Zeros(6)\n        @test Z[:,:] ≡ Z[1:5,1:6] ≡ Z[1:5,:] ≡ Z[:,1:6] ≡ Z\n\n        A = Fill(2.0,5,6,7)\n        Z = Zeros(5,6,7)\n        @test A[:,1,1] ≡ A[1:5,1,1] ≡ Fill(2.0,5)\n        @test A[1,:,1] ≡ A[1,1:6,1] ≡ Fill(2.0,6)\n        @test A[:,:,:] ≡ A[1:5,1:6,1:7] ≡ A[1:5,:,1:7] ≡ A[:,1:6,1:7] ≡ A\n    end\n\n    @testset \"StepRangeLen convert\" begin\n        for (z,s) in  ((Zeros{Int}(5), StepRangeLen(0, 0, 5)), (Ones{Int}(5), StepRangeLen(1, 0, 5)), (Fill(2,5), StepRangeLen(2, 0, 5)))\n            @test s == z\n            @test StepRangeLen(z) ≡ convert(StepRangeLen, z) ≡ convert(StepRangeLen{Int}, z) ≡ convert(typeof(s), z) ≡ convert(AbstractRange, z) ≡ s\n        end\n    end\nend\n\n@testset \"RectDiagonal\" begin\n    data = 1:3\n    expected_size = (5, 3)\n    expected_axes = Base.OneTo.(expected_size)\n    expected_matrix = [1 0 0; 0 2 0; 0 0 3; 0 0 0; 0 0 0]\n    expected = RectDiagonal{Int, UnitRange{Int}}(data, expected_axes)\n\n    @test axes(expected) == expected_axes\n    @test size(expected) == expected_size\n    @test (axes(expected, 1), axes(expected, 2)) == expected_axes\n    @test (size(expected, 1), size(expected, 2)) == expected_size\n\n    @test expected == expected_matrix\n    @test Matrix(expected) == expected_matrix\n    @test expected[:, 2] == expected_matrix[:, 2]\n    @test expected[2, :] == expected_matrix[2, :]\n    @test expected[5, :] == expected_matrix[5, :]\n\n\n    for Typ in (RectDiagonal, RectDiagonal{Int}, RectDiagonal{Int, UnitRange{Int}})\n        @test Typ(data) == expected[1:3, 1:3]\n        @test Typ(data, expected_axes) == expected\n        @test Typ(data, expected_axes...) == expected\n        @test Typ(data, expected_size) == expected\n        @test Typ(data, expected_size...) == expected\n    end\n\n    @test diag(expected) === expected.diag\n\n    mut = RectDiagonal(collect(data), expected_axes)\n    @test mut == expected\n    @test mut == expected_matrix\n    mut[1, 1] = 5\n    @test mut[1] == 5\n    @test diag(mut) == [5, 2, 3]\n    mut[2, 1] = 0\n    @test_throws ArgumentError mut[2, 1] = 9\n\n    D = RectDiagonal([1.,2.], (Base.OneTo(3),Base.OneTo(2)))\n    @test stringmime(\"text/plain\", D) == \"3×2 RectDiagonal{Float64, Vector{Float64}, Tuple{Base.OneTo{$Int}, Base.OneTo{$Int}}}:\\n 1.0   ⋅ \\n  ⋅   2.0\\n  ⋅    ⋅ \"\nend\n\n# Check that all pair-wise combinations of + / - elements of As and Bs yield the correct\n# type, and produce numerically correct results.\nas_array(x::AbstractArray) = Array(x)\nas_array(x::UniformScaling) = x\nisapprox_or_undef(a::Number, b::Number) = (a ≈ b) || isequal(a, b)\nisapprox_or_undef(a, b) = all(((x,y),) -> isapprox_or_undef(x,y), zip(a, b))\nfunction test_addition_subtraction_dot(As, Bs, Tout::Type)\n    for A in As, B in Bs\n        @testset \"$(typeof(A)) and $(typeof(B))\" begin\n            @test @inferred(A + B) isa Tout{promote_type(eltype(A), eltype(B))}\n            @test isapprox_or_undef(as_array(A + B), as_array(A) + as_array(B))\n\n            @test @inferred(A - B) isa Tout{promote_type(eltype(A), eltype(B))}\n            @test isapprox_or_undef(as_array(A - B), as_array(A) - as_array(B))\n\n            @test @inferred(B + A) isa Tout{promote_type(eltype(B), eltype(A))}\n            @test isapprox_or_undef(as_array(B + A), as_array(B) + as_array(A))\n\n            @test @inferred(B - A) isa Tout{promote_type(eltype(B), eltype(A))}\n            @test isapprox_or_undef(as_array(B - A), as_array(B) - as_array(A))\n\n            d1 = dot(A, B)\n            d2 = dot(as_array(A), as_array(B))\n            d3 = dot(B, A)\n            d4 = dot(as_array(B), as_array(A))\n            @test d1 ≈ d2 || d1 ≡ d2\n            @test d3 ≈ d4 || d3 ≡ d4\n        end\n    end\nend\n\n# Check that all permutations of + / - throw a `DimensionMismatch` exception.\nfunction test_addition_and_subtraction_dim_mismatch(a, b)\n    @testset \"$(typeof(a)) ± $(typeof(b))\" begin\n        @test_throws DimensionMismatch a + b\n        @test_throws DimensionMismatch a - b\n        @test_throws DimensionMismatch b + a\n        @test_throws DimensionMismatch b - a\n    end\nend\n\n@testset \"FillArray addition and subtraction\" begin\n    test_addition_and_subtraction_dim_mismatch(Zeros(5), Zeros(6))\n    test_addition_and_subtraction_dim_mismatch(Zeros(5), Zeros{Int}(6))\n    test_addition_and_subtraction_dim_mismatch(Zeros(5), Zeros(6,6))\n    test_addition_and_subtraction_dim_mismatch(Zeros(5), Zeros{Int}(6,5))\n\n    # Construct FillArray for repeated use.\n    rng = MersenneTwister(123456)\n    A_fill, B_fill = Fill(randn(rng, Float64), 5), Fill(4, 5)\n\n    # Unary +/- constructs a new FillArray.\n    @test +A_fill === A_fill\n    @test -A_fill === Fill(-A_fill.value, 5)\n\n    # FillArray +/- FillArray should construct a new FillArray.\n    test_addition_subtraction_dot((A_fill, B_fill), (A_fill, B_fill), Fill)\n    test_addition_and_subtraction_dim_mismatch(A_fill, Fill(randn(rng), 5, 2))\n\n    # FillArray + Array (etc) should construct a new Array using `getindex`.\n    B_dense = (randn(rng, 5), [5, 4, 3, 2, 1], fill(Inf, 5), fill(NaN, 5))\n    test_addition_subtraction_dot((A_fill, B_fill), B_dense, Array)\n    test_addition_and_subtraction_dim_mismatch(A_fill, randn(rng, 5, 2))\n\n    # FillArray + StepLenRange / UnitRange (etc) should yield an AbstractRange.\n    A_ur, B_ur = 1.0:5.0, 6:10\n    test_addition_subtraction_dot((A_fill, B_fill), (A_ur, B_ur), AbstractRange)\n    test_addition_and_subtraction_dim_mismatch(A_fill, 1.0:6.0)\n    test_addition_and_subtraction_dim_mismatch(A_fill, 5:10)\n\n    # FillArray + UniformScaling should yield a Matrix in general\n    As_fill_square = (Fill(randn(rng, Float64), 3, 3), Fill(5, 4, 4))\n    Bs_us = (UniformScaling(2.3), UniformScaling(3))\n    test_addition_subtraction_dot(As_fill_square, Bs_us, Matrix)\n    As_fill_nonsquare = (Fill(randn(rng, Float64), 3, 2), Fill(5, 3, 4))\n    for A in As_fill_nonsquare, B in Bs_us\n        test_addition_and_subtraction_dim_mismatch(A, B)\n    end\n\n    # FillArray + StaticArray should not have ambiguities\n    A_svec, B_svec = SVector{5}(rand(5)), SVector(1, 2, 3, 4, 5)\n    test_addition_subtraction_dot((A_fill, B_fill, Zeros(5)), (A_svec, B_svec), SVector{5})\n\n    # Issue #224\n    A_matmat, B_matmat = Fill(rand(3,3),5), [rand(3,3) for n=1:5]\n    test_addition_subtraction_dot((A_matmat,), (A_matmat,), Fill)\n    test_addition_subtraction_dot((B_matmat,), (A_matmat,), Vector)\n\n    # Optimizations for Zeros and RectOrDiagonal{<:Any, <:AbstractFill}\n    As_special_square = (\n        Zeros(3, 3), Zeros{Int}(4, 4),\n        Eye(3), Eye{Int}(4), Eye(3, 3), Eye{Int}(4, 4),\n        Diagonal(Fill(randn(rng, Float64), 3)), Diagonal(Fill(3, 4)),\n        RectDiagonal(Fill(randn(rng, Float64), 3), 3, 3), RectDiagonal(Fill(3, 4), 4, 4)\n    )\n    DiagonalAbstractFill{T} = Diagonal{T, <:AbstractFill{T, 1}}\n    test_addition_subtraction_dot(As_special_square, Bs_us, DiagonalAbstractFill)\n    As_special_nonsquare = (\n        Zeros(3, 2), Zeros{Int}(3, 4),\n        Eye(3, 2), Eye{Int}(3, 4),\n        RectDiagonal(Fill(randn(rng, Float64), 2), 3, 2), RectDiagonal(Fill(3, 3), 3, 4)\n    )\n    for A in As_special_nonsquare, B in Bs_us\n        test_addition_and_subtraction_dim_mismatch(A, B)\n    end\n\n    @testset \"Zeros\" begin\n        As = ([1,2], Float64[1,2], Int8[1,2], ComplexF16[2,4])\n        Zs = (TZ -> Zeros{TZ}(2)).((Int, Float64, Int8, ComplexF64))\n        test_addition_subtraction_dot(As, Zs, Vector)\n        for A in As, Z in (TZ -> Zeros{TZ}(3)).((Int, Float64, Int8, ComplexF64))\n            test_addition_and_subtraction_dim_mismatch(A, Z)\n        end\n\n        As = (@SArray([1,2]), @SArray(Float64[1,2]), @SArray(Int8[1,2]), @SArray(ComplexF16[2,4]))\n        test_addition_subtraction_dot(As, Zs, SVector{2})\n        for A in As, Z in (TZ -> Zeros{TZ}(3)).((Int, Float64, Int8, ComplexF64))\n            test_addition_and_subtraction_dim_mismatch(A, Z)\n        end\n\n        # Zeros should act as an additive identity\n        # Arbitrary AbstractMatrix\n        D = Diagonal([1, 1])\n        Z = Zeros(2, 2)\n        @test D + Z isa Diagonal\n        @test D + Z == D\n        @test D - Z == D\n        @test Z - D == -D\n\n        @test Z + Z isa Zeros\n        @test Z + Z == Z\n        @test Z - Z == Z\n    end\nend\n\n@testset \"Other matrix types\" begin\n    @test Diagonal(Zeros(5)) == Diagonal(zeros(5))\n\n    @test Diagonal(Zeros(8,5)) == Diagonal(zeros(5))\n    @test convert(Diagonal, Zeros(5,5)) == Diagonal(zeros(5))\n    @test_throws DimensionMismatch convert(Diagonal, Zeros(8,5))\n\n    @test convert(Diagonal{Int}, Zeros(5,5)) == Diagonal(zeros(Int,5))\n    @test_throws DimensionMismatch convert(Diagonal{Int}, Zeros(8,5))\n\n\n    @test Diagonal(Eye(8,5)) == Diagonal(ones(5))\n    @test convert(Diagonal, Eye(5)) == Diagonal(ones(5))\n    @test convert(Diagonal{Int}, Eye(5)) == Diagonal(ones(Int,5))\n\n    for E in (Eye(2,4), Eye(3))\n        M = collect(E)\n        for i in -5:5\n            @test diag(E, i) == diag(M, i)\n        end\n    end\nend\n\n@testset \"one\" begin\n    @testset for A in Any[Eye(4), Zeros(4,4), Ones(4,4), Fill(3,4,4)]\n        B = one(A)\n        @test B * A == A * B == A\n    end\n    @test_throws ArgumentError one(Ones(3,4))\n    @test_throws ArgumentError one(Ones((3:5,4:5)))\nend\n\n@testset \"Sparse vectors and matrices\" begin\n    @test SparseVector(Zeros(5)) ==\n            SparseVector{Int}(Zeros(5)) ==\n            SparseVector{Float64}(Zeros(5)) ==\n            SparseVector{Float64,Int}(Zeros(5)) ==\n            convert(AbstractSparseArray,Zeros(5)) ==\n            convert(AbstractSparseVector,Zeros(5)) ==\n            convert(AbstractSparseArray{Float64},Zeros(5)) ==\n            convert(AbstractSparseVector{Float64},Zeros(5)) ==\n            convert(AbstractSparseVector{Float64,Int},Zeros(5)) ==\n            spzeros(5)\n\n    for (Mat, SMat) in ((Zeros(5,5), spzeros(5,5)), (Zeros(6,5), spzeros(6,5)),\n                        (Eye(5), sparse(I,5,5)), (Eye(6,5), sparse(I,6,5)))\n        @test SparseMatrixCSC(Mat) ==\n                SparseMatrixCSC{Int}(Mat) ==\n                SparseMatrixCSC{Float64}(Mat) ==\n                SparseMatrixCSC{Float64,Int}(Mat) ==\n                convert(AbstractSparseArray,Mat) ==\n                convert(AbstractSparseMatrix,Mat) ==\n                convert(AbstractSparseArray{Float64},Mat) ==\n                convert(AbstractSparseArray{Float64,Int},Mat) ==\n                convert(AbstractSparseMatrix{Float64},Mat) ==\n                convert(AbstractSparseMatrix{Float64,Int},Mat) ==\n                SMat\n    end\n\n    function testsparsediag(E)\n        S = @inferred SparseMatrixCSC(E)\n        @test S == E\n        S = @inferred SparseMatrixCSC{Float64}(E)\n        @test S == E\n        @test S isa SparseMatrixCSC{Float64}\n        @test convert(SparseMatrixCSC{Float64}, E) == S\n        S = @inferred SparseMatrixCSC{Float64,Int32}(E)\n        @test S == E\n        @test S isa SparseMatrixCSC{Float64,Int32}\n        @test convert(SparseMatrixCSC{Float64,Int32}, E) == S\n    end\n\n    for f in (Fill(Int8(4),3), Ones{Int8}(3), Zeros{Int8}(3))\n        E = Diagonal(f)\n        testsparsediag(E)\n        for sz in ((3,6), (6,3), (3,3))\n            E = RectDiagonal(f, sz)\n            testsparsediag(E)\n        end\n    end\nend\n\n@testset \"==\" begin\n    @test Zeros(5,4) == Fill(0,5,4)\n    @test Zeros(5,4) ≠ Zeros(3)\n    @test Ones(5,4) == Fill(1,5,4)\nend\n\n@testset \"Rank\" begin\n    @test rank(Zeros(5,4)) == 0\n    @test rank(Ones(5,4)) == 1\n    @test rank(Fill(2,5,4)) == 1\n    @test rank(Fill(0,5,4)) == 0\n    @test rank(Eye(2)) == 2\nend\n\n@testset \"ishermitian\" begin\n    @testset for el in (2, 3+0im, 4+5im, [1 2; 3 4], fill(2, 2, 2)), size in [(3,3), (3,4), (0,0), (0,1)]\n        @test issymmetric(Fill(el, size...)) == issymmetric(fill(el, size...))\n        @test ishermitian(Fill(el, size...)) == ishermitian(fill(el, size...))\n    end\nend\n\n@testset \"BigInt indices\" begin\n    for A in (Zeros(BigInt(100)), Ones(BigInt(100)), Fill(2, BigInt(100)))\n        @test length(A) isa BigInt\n        @test axes(A) == tuple(Base.OneTo{BigInt}(BigInt(100)))\n        @test size(A) isa Tuple{BigInt}\n    end\n    for A in (Eye(BigInt(100)), Eye(BigInt(100), BigInt(100)))\n        @test length(A) isa BigInt\n        @test axes(A) == tuple(Base.OneTo{BigInt}(BigInt(100)),Base.OneTo{BigInt}(BigInt(100)))\n        @test size(A) isa Tuple{BigInt,BigInt}\n    end\n    for A in (Zeros(BigInt(10), 10), Ones(BigInt(10), 10), Fill(2.0, (BigInt(10), 10)), Eye(BigInt(10), 8))\n        @test size(A) isa Tuple{BigInt,Int}\n    end\n\nend\n\n@testset \"IndexStyle\" begin\n    @test IndexStyle(Zeros(5,5)) == IndexStyle(typeof(Zeros(5,5))) == IndexLinear()\nend\n\n@testset \"Identities\" begin\n    @test Zeros(3,4) * randn(4,5) === randn(3,4) * Zeros(4,5) === Zeros(3, 5)\n    @test_throws DimensionMismatch randn(3,4) * Zeros(3, 3)\n    @test eltype(Zeros{Int}(3,4) * fill(1, 4, 5)) == Int\n    @test eltype(Zeros{Int}(3,4) * fill(3.4, 4, 5)) == Float64\n    @test Zeros(3, 4) * randn(4) == Zeros(3, 4) * Zeros(4) == Zeros(3)\n    @test Zeros(3, 4) * Zeros(4, 5) === Zeros(3, 5)\n\n    @test_throws MethodError [1,2,3]*Zeros(1) # Not defined for [1,2,3]*[0] either\n    @test [1,2,3]*Zeros(1,3) ≡ Zeros(3,3)\n    @test_throws MethodError [1,2,3]*Zeros(3) # Not defined for [1,2,3]*[0,0,0] either\n\n    @testset \"Matrix multiplication with array elements\" begin\n        x = [1 2; 3 4]\n        z = zero(SVector{2,Int})\n        ZV = Zeros{typeof(z)}(2)\n        A = Fill(x, 3, 2) * ZV\n        @test A isa Fill\n        @test size(A) == (3,)\n        @test A[1] == x * z\n        @test_throws DimensionMismatch Fill(x, 1, 1) * ZV\n        @test_throws DimensionMismatch Fill(oneton(1,1), 1, length(ZV)) * ZV\n\n        @test_throws DimensionMismatch Ones(SMatrix{3,3,Int,9},2) * Ones(SMatrix{2,2,Int,4},1,2)\n    end\n\n    @testset \"Check multiplication by Adjoint vectors works as expected.\" begin\n        @test @inferred(oneton(4, 3)' * Zeros(4)) ≡ Zeros(3)\n        @test @inferred(oneton(4)' * Zeros(4)) ≡ @inferred(transpose(oneton(4)) * Zeros(4)) == 0.0\n        @test [1, 2, 3]' * Zeros{Int}(3) ≡ zero(Int)\n        @test [SVector(1,2)', SVector(2,3)', SVector(3,4)']' * Zeros{Int}(3) === SVector(0,0)\n        @test_throws DimensionMismatch oneton(4)' * Zeros(3)\n        @test Zeros(5)' * oneton(5,3) ≡ Zeros(5)'*Zeros(5,3) ≡ Zeros(5)'*Ones(5,3) ≡ Zeros(3)'\n        @test abs(Zeros(5)' * oneton(5)) == abs(Zeros(5)' * Zeros(5)) ≡ abs(Zeros(5)' * Ones(5)) == 0.0\n        @test Zeros(5) * Zeros(6)' ≡ Zeros(5,1) * Zeros(6)' ≡ Zeros(5,6)\n        @test oneton(5) * Zeros(6)' ≡ oneton(5,1) * Zeros(6)' ≡ Zeros(5,6)\n        @test Zeros(5) * oneton(6)' ≡ Zeros(5,6)\n\n        @test @inferred(Zeros{Int}(0)' * Zeros{Int}(0)) === zero(Int)\n\n        @test Any[1,2.0]' * Zeros{Int}(2) == 0\n        @test Real[1,2.0]' * Zeros{Int}(2) == 0\n\n        @test @inferred(([[1,2]])' * Zeros{SVector{2,Int}}(1)) ≡ 0\n        @test ([[1,2], [1,2]])' * Zeros{SVector{2,Int}}(2) ≡ 0\n        @test_throws DimensionMismatch ([[1,2,3]])' * Zeros{SVector{2,Int}}(1)\n        @test_throws DimensionMismatch ([[1,2,3], [1,2]])' * Zeros{SVector{2,Int}}(2)\n\n        A = SMatrix{2,1,Int,2}[]'\n        B = Zeros(SVector{2,Int},0)\n        C = collect(B)\n        @test @inferred(A * B) == @inferred(A * C)\n    end\n\n    @testset \"Check multiplication by Transpose-d vectors works as expected.\" begin\n        @test transpose(oneton(4, 3)) * Zeros(4) === Zeros(3)\n        @test transpose(oneton(4)) * Zeros(4) == 0.0\n        @test transpose([1, 2, 3]) * Zeros{Int}(3) === zero(Int)\n        @test_throws DimensionMismatch transpose(oneton(4)) * Zeros(3)\n        @test transpose(Zeros(5)) * oneton(5,3) ≡ transpose(Zeros(5))*Zeros(5,3) ≡ transpose(Zeros(5))*Ones(5,3) ≡ transpose(Zeros(3))\n        @test abs(transpose(Zeros(5)) * oneton(5)) ≡ abs(transpose(Zeros(5)) * Zeros(5)) ≡ abs(transpose(Zeros(5)) * Ones(5)) ≡ 0.0\n        @test oneton(5) * transpose(Zeros(6)) ≡ oneton(5,1) * transpose(Zeros(6)) ≡ Zeros(5,6)\n        @test Zeros(5) * transpose(oneton(6)) ≡ Zeros(5,6)\n        @test transpose(oneton(5)) * Zeros(5) == 0.0\n        @test transpose(oneton(5) .+ im) * Zeros(5) == 0.0 + 0im\n\n        @test @inferred(transpose(Zeros{Int}(0)) * Zeros{Int}(0)) === zero(Int)\n\n        @test transpose(Any[1,2.0]) * Zeros{Int}(2) == 0\n        @test transpose(Real[1,2.0]) * Zeros{Int}(2) == 0\n\n        @test @inferred(transpose([[1,2]]) * Zeros{SVector{2,Int}}(1)) ≡ 0\n        @test transpose([[1,2], [1,2]]) * Zeros{SVector{2,Int}}(2) ≡ 0\n        @test_throws DimensionMismatch transpose([[1,2,3]]) * Zeros{SVector{2,Int}}(1)\n        @test_throws DimensionMismatch transpose([[1,2,3], [1,2]]) * Zeros{SVector{2,Int}}(2)\n\n        A = transpose(SMatrix{2,1,Int,2}[])\n        B = Zeros(SVector{2,Int},0)\n        C = collect(B)\n        @test @inferred(A * B) == @inferred(A * C)\n\n        @testset \"Diagonal mul introduced in v1.9\" begin\n            @test Zeros(5)'*Diagonal(1:5) ≡ Zeros(5)'\n            @test transpose(Zeros(5))*Diagonal(1:5) ≡ transpose(Zeros(5))\n            @test Zeros(5)'*Diagonal(1:5)*(1:5) ==\n                (1:5)'*Diagonal(1:5)*Zeros(5) ==\n                transpose(1:5)*Diagonal(1:5)*Zeros(5) ==\n                Zeros(5)'*Diagonal(1:5)*Zeros(5) ==\n                transpose(Zeros(5))*Diagonal(1:5)*Zeros(5) ==\n                transpose(Zeros(5))*Diagonal(1:5)*(1:5)\n\n            @test_throws DimensionMismatch Zeros(6)'*Diagonal(1:5)*Zeros(5)\n            @test_throws DimensionMismatch Zeros(5)'*Diagonal(1:6)*Zeros(5)\n            @test_throws DimensionMismatch Zeros(5)'*Diagonal(1:5)*Zeros(6)\n        end\n    end\n\n    z1, z2 = Zeros{Float64}(4), Zeros{Int}(4)\n\n    @testset \"`Zeros` are closed under addition and subtraction (both unary and binary).\" begin\n        @test +(Zeros{Float64}(3, 5)) === Zeros{Float64}(3, 5)\n        @test -(Zeros{Float32}(5, 2)) === Zeros{Float32}(5, 2)\n\n        @test +(z1) === z1\n        @test -(z1) === z1\n\n        test_addition_subtraction_dot((z1, z2), (z1, z2), Zeros)\n        test_addition_and_subtraction_dim_mismatch(z1, Zeros{Float64}(4, 2))\n    end\n\n    # `Zeros` +/- `Fill`s should yield `Fills`.\n    fill1, fill2 = Fill(5.0, 4), Fill(5, 4)\n    test_addition_subtraction_dot((z1, z2), (fill1, fill2), Fill)\n    test_addition_and_subtraction_dim_mismatch(z1, Fill(5, 5))\n\n    X = randn(3, 5)\n    for op in [+, -]\n\n        # Addition / subtraction with same eltypes.\n        @test op(Zeros(6, 4), Zeros(6, 4)) === Zeros(6, 4)\n        @test_throws DimensionMismatch op(X, Zeros(4, 6))\n        @test eltype(op(Zeros(3, 5), X)) == Float64\n\n        # Different eltypes, the other way around.\n        @test op(X, Zeros{Float32}(3, 5)) isa Matrix{Float64}\n        @test !(op(X, Zeros{Float32}(3, 5)) === X)\n        @test op(X, Zeros{Float32}(3, 5)) == X\n        @test !(op(X, Zeros{ComplexF64}(3, 5)) === X)\n        @test op(X, Zeros{ComplexF64}(3, 5)) == X\n\n        # Addition / subtraction of Zeros.\n        @test eltype(op(Zeros{Float64}(4, 5), Zeros{Int}(4, 5))) == Float64\n        @test eltype(op(Zeros{Int}(5, 4), Zeros{Float32}(5, 4))) == Float32\n        @test op(Zeros{Float64}(4, 5), Zeros{Int}(4, 5)) isa Zeros{Float64}\n        @test op(Zeros{Float64}(4, 5), Zeros{Int}(4, 5)) === Zeros{Float64}(4, 5)\n    end\n\n    @testset \"Zeros +/- dense where + / - have different results.\" begin\n        @test +(Zeros(3, 5), X) == X && +(X, Zeros(3, 5)) == X\n        @test !(Zeros(3, 5) + X === X) && !(X + Zeros(3, 5) === X)\n        @test -(Zeros(3, 5), X) == -X\n    end\n\n    @testset \"Addition with different eltypes.\" begin\n        @test +(Zeros{Float32}(3, 5), X) isa Matrix{Float64}\n        @test !(+(Zeros{Float32}(3, 5), X) === X)\n        @test +(Zeros{Float32}(3, 5), X) == X\n        @test !(+(Zeros{ComplexF64}(3, 5), X) === X)\n        @test +(Zeros{ComplexF64}(3, 5), X) == X\n    end\n\n    @testset \"Subtraction with different eltypes.\" begin\n        @test -(Zeros{Float32}(3, 5), X) isa Matrix{Float64}\n        @test -(Zeros{Float32}(3, 5), X) == -X\n        @test -(Zeros{ComplexF64}(3, 5), X) == -X\n    end\n\n    @testset \"Tests for ranges.\" begin\n        X = randn(5)\n        @test !(Zeros(5) + X ≡ X)\n        @test Zeros{Int}(5) + (1:5) ≡ (1:5) + Zeros{Int}(5) ≡ (1:5)\n        @test Zeros(5) + (1:5) ≡ (1:5) + Zeros(5) ≡ (1.0:1.0:5.0)\n        @test (1:5) - Zeros{Int}(5) ≡ (1:5)\n        @test Zeros{Int}(5) - (1:5) ≡ -1:-1:-5\n        @test Zeros(5) - (1:5) ≡ -1.0:-1.0:-5.0\n        @test Zeros{Int}(5) + (1.0:5) ≡ (1.0:5) + Zeros{Int}(5) ≡ 1.0:5\n    end\n\n    @testset \"test Base.zero\" begin\n        @test zero(Zeros(10)) == Zeros(10)\n        @test zero(Ones(10,10)) == Zeros(10,10)\n        @test zero(Fill(0.5, 10, 10)) == Zeros(10,10)\n    end\n\n    @testset \"Matrix ±\" begin\n        x = Fill([1,2], 5)\n        z = Zeros{SVector{2,Int}}(5)\n        @test +(z) ≡ -(z) ≡ z\n        @test +(x) == x\n        @test -(x) == Fill(-[1,2], 5)\n    end\nend\n\n@testset \"maximum/minimum/svd/sort\" begin\n    @test maximum(Fill(1, 1_000_000_000)) == minimum(Fill(1, 1_000_000_000)) == 1\n    @test svdvals(fill(2,5,6)) ≈ svdvals(Fill(2,5,6))\n    @test svdvals(Eye(5)) === Fill(1.0,5)\n    @test sort(Ones(5)) == sort!(Ones(5))\n\n    @test_throws MethodError issorted(Fill(im, 2))\n    @test_throws MethodError sort(Fill(im, 2))\n    @test_throws MethodError sort!(Fill(im, 2))\nend\n\n@testset \"Cumsum, accumulate and diff\" begin\n    @test @inferred(sum(Fill(3,10))) ≡ 30\n    @test @inferred(reduce(+, Fill(3,10))) ≡ 30\n    @test @inferred(sum(x -> x + 1, Fill(3,10))) ≡ 40\n    @test @inferred(cumsum(Fill(3,10))) ≡ @inferred(accumulate(+, Fill(3,10))) ≡ StepRangeLen(3,3,10)\n    @test @inferred(accumulate(-, Fill(3,10))) ≡ StepRangeLen(3,-3,10)\n\n    @test @inferred(sum(Ones(10))) ≡ 10.0\n    @test @inferred(sum(x -> x + 1, Ones(10))) ≡ 20.0\n    @test @inferred(cumsum(Ones(10))) ≡ @inferred(accumulate(+, Ones(10))) ≡ StepRangeLen(1.0, 1.0, 10)\n    @test @inferred(accumulate(-, Ones(10))) ≡ StepRangeLen(1.0,-1.0,10)\n\n    @test sum(Ones{Int}(10)) ≡ 10\n    @test sum(x -> x + 1, Ones{Int}(10)) ≡ 20\n    @test cumsum(Ones{Int}(10)) ≡ accumulate(+,Ones{Int}(10)) ≡ Base.OneTo(10)\n    @test accumulate(-, Ones{Int}(10)) ≡ StepRangeLen(1,-1,10)\n\n    @test sum(Zeros(10)) ≡ 0.0\n    @test sum(x -> x + 1, Zeros(10)) ≡ 10.0\n    @test cumsum(Zeros(10)) ≡ accumulate(+,Zeros(10)) ≡ accumulate(-,Zeros(10)) ≡ Zeros(10)\n\n    @test sum(Zeros{Int}(10)) ≡ 0\n    @test sum(x -> x + 1, Zeros{Int}(10)) ≡ 10\n    @test cumsum(Zeros{Int}(10)) ≡ accumulate(+,Zeros{Int}(10)) ≡ accumulate(-,Zeros{Int}(10)) ≡ Zeros{Int}(10)\n\n    # we want cumsum of fills to match the types of the standard cusum\n    @test all(cumsum(Zeros{Bool}(10)) .≡ cumsum(zeros(Bool,10)))\n    @test all(accumulate(+, Zeros{Bool}(10)) .≡ accumulate(+, zeros(Bool,10)) .≡ accumulate(-, zeros(Bool,10)))\n    @test cumsum(Zeros{Bool}(10)) ≡ accumulate(+, Zeros{Bool}(10)) ≡ accumulate(-, Zeros{Bool}(10)) ≡ Zeros{Int}(10)\n    @test cumsum(Ones{Bool}(10)) ≡ accumulate(+, Ones{Bool}(10)) ≡ Base.OneTo{Int}(10)\n    @test all(cumsum(Fill(true,10)) .≡ cumsum(fill(true,10)))\n    @test cumsum(Fill(true,10)) ≡ StepRangeLen(1, true, 10)\n\n    @test all(cumsum(Zeros{UInt8}(10)) .≡ cumsum(zeros(UInt8,10)))\n    @test all(accumulate(+, Zeros{UInt8}(10)) .≡ accumulate(+, zeros(UInt8,10)))\n    @test cumsum(Zeros{UInt8}(10)) ≡ Zeros{UInt64}(10)\n    @test accumulate(+, Zeros{UInt8}(10)) ≡ accumulate(-, Zeros{UInt8}(10)) ≡ Zeros{UInt8}(10)\n    \n    @test all(cumsum(Ones{UInt8}(10)) .≡ cumsum(ones(UInt8,10)))\n    @test all(accumulate(+, Ones{UInt8}(10)) .≡ accumulate(+, ones(UInt8,10)))\n    @test cumsum(Ones{UInt8}(10)) ≡ Base.OneTo(UInt64(10))\n    @test accumulate(+, Ones{UInt8}(10)) ≡ Base.OneTo(UInt8(10))\n    \n    @test all(cumsum(Fill(UInt8(2),10)) .≡ cumsum(fill(UInt8(2),10)))\n    @test all(accumulate(+,  Fill(UInt8(2))) .≡ accumulate(+, fill(UInt8(2))))\n    @test cumsum(Fill(UInt8(2),10)) ≡ StepRangeLen(UInt64(2), UInt8(2), 10)\n    @test accumulate(+, Fill(UInt8(2),10)) ≡ StepRangeLen(UInt8(2), UInt8(2), 10)\n\n    @test diff(Fill(1,10)) ≡ Zeros{Int}(9)\n    @test diff(Ones{Float64}(10)) ≡ Zeros{Float64}(9)\n    @test_throws UndefKeywordError cumsum(Fill(1,1,5))\n\n    @test @inferred(sum([Ones(4)])) ≡ Fill(1.0, 4)\n    @test @inferred(sum([Trues(4)])) ≡ Fill(1, 4)\n\n    @testset \"infinite arrays\" begin\n        r = InfiniteArrays.OneToInf()\n        A = Ones{Int}((r,))\n        @test isinf(sum(A))\n        @test sum(A) == length(A)\n        @test sum(x->x^2, A) == sum(A.^2)\n        @testset \"IteratorSize\" begin\n            @test (@inferred Base.IteratorSize(Ones())) == Base.IteratorSize(ones())\n            @test (@inferred Base.IteratorSize(Ones(2))) == Base.IteratorSize(ones(2))\n            @test (@inferred Base.IteratorSize(Ones(r))) == Base.IsInfinite()\n            @test (@inferred Base.IteratorSize(Fill(2, (1:2, 1:2)))) == Base.HasShape{2}()\n            @test (@inferred Base.IteratorSize(Fill(2, (1:2, r)))) == Base.IsInfinite()\n            @test (@inferred Base.IteratorSize(Fill(2, (r, 1:2)))) == Base.IsInfinite()\n            @test (@inferred Base.IteratorSize(Fill(2, (r, r)))) == Base.IsInfinite()\n        end\n\n        @test issorted(Fill(2, (InfiniteArrays.OneToInf(),)))\n    end\nend\n\n@testset \"iterators\" begin\n    @testset \"invalid state\" begin\n        @test isnothing(iterate(Ones(4), (1,-3)))\n        @test isempty(Iterators.rest(Ones(4), (1,-3)))\n    end\n    @testset \"Iterators.rest\" begin\n        @test Iterators.rest(Fill(4, 10), (4, 3)) === Fill(4, 7)\n        # Base.rest\n        a, b... = Fill(3, 4)\n        @test a === 3\n        @test b === Fill(3, 3)\n        a, b... = Ones(3, 4)\n        @test a === 1.0\n        @test b === Ones(11)\n    end\n    @testset \"Iterators.drop/take\" begin\n        @test Iterators.drop(Fill(4, 10), 3) === Fill(4, 7)\n        @test Iterators.take(Fill(4, 10), 3) === Fill(4, 3)\n        @test Iterators.drop(Fill(4, 10), 0) === Fill(4, 10)\n        @test Iterators.take(Fill(4, 10), 0) === Fill(4, 0)\n        @test Iterators.drop(Fill(4, 10), 11) === Fill(4, 0)\n        @test Iterators.take(Fill(4, 10), 11) === Fill(4, 10)\n        @test_throws ArgumentError Iterators.drop(Fill(4, 10), -11)\n        @test_throws ArgumentError Iterators.take(Fill(4, 10), -11)\n        @test Iterators.drop(Ones(4, 10), 3) === Ones(37)\n        @test Iterators.take(Ones(4, 10), 3) === Ones(3)\n    end\nend\n\n@testset \"Broadcast\" begin\n    x = Fill(5,5)\n    @test (.+)(x) ≡ x\n    @test (.-)(x) ≡ -x\n    @test exp.(x) ≡ Fill(exp(5),5)\n    @test x .+ 1 ≡ Fill(6,5)\n    @test 1 .+ x ≡ Fill(6,5)\n    @test x .+ x ≡ Fill(10,5)\n    @test x .+ Ones(5) ≡ Fill(6.0,5)\n    f = (x,y) -> cos(x*y)\n    @test f.(x, Ones(5)) ≡ Fill(f(5,1.0),5)\n    @test x .^ 1 ≡ Fill(5,5)\n\n    y = Ones(5,5)\n    @test (.+)(y) ≡ Ones(5,5)\n    @test (.-)(y) ≡ Fill(-1.0,5,5)\n    @test exp.(y) ≡ Fill(exp(1),5,5)\n    @test y .+ 1 ≡ Fill(2.0,5,5)\n    @test y .+ y ≡ Fill(2.0,5,5)\n    @test y .* y ≡ y ./ y ≡ y .\\ y ≡ y\n    @test y .^ 1 ≡ y .^ 0 ≡ Ones(5,5)\n\n    rng = MersenneTwister(123456)\n    sizes = [(5, 4), (5, 1), (1, 4), (1, 1), (5,)]\n    for sx in sizes, sy in sizes\n        x, y = Fill(randn(rng), sx), Fill(randn(rng), sy)\n        x_one, y_one = Ones(sx), Ones(sy)\n        x_zero, y_zero = Zeros(sx), Zeros(sy)\n        x_dense, y_dense = randn(rng, sx), randn(rng, sy)\n\n        for x in [x, x_one, x_zero, x_dense], y in [y, y_one, y_zero, y_dense]\n            @test x .+ y == collect(x) .+ collect(y)\n        end\n        @test x_zero .+ y_zero isa Zeros\n        @test x_zero .+ y_one isa Ones\n        @test x_one .+ y_zero isa Ones\n\n        for x in [x, x_one, x_zero, x_dense], y in [y, y_one, y_zero, y_dense]\n            @test x .* y == collect(x) .* collect(y)\n        end\n        for x in [x, x_one, x_zero, x_dense]\n            @test x .* y_zero isa Zeros\n        end\n        for y in [y, y_one, y_zero, y_dense]\n            @test x_zero .* y isa Zeros\n        end\n    end\n\n    @test Zeros{Int}(5) .^ 0 ≡ Ones{Int}(5)\n    @test Zeros{Int}(5) .^ 1 ≡ Zeros{Int}(5)\n    @test Zeros{Int}(5) .+ Zeros(5) isa Zeros{Float64}\n\n    # Test for conj, real and imag with complex element types\n    @test conj(Zeros{ComplexF64}(10)) isa Zeros{ComplexF64}\n    @test conj(Zeros{ComplexF64}(10,10)) isa Zeros{ComplexF64}\n    @test conj(Ones{ComplexF64}(10)) isa Ones{ComplexF64}\n    @test conj(Ones{ComplexF64}(10,10)) isa Ones{ComplexF64}\n    @test real(Zeros{Float64}(10)) isa Zeros{Float64}\n    @test real(Zeros{Float64}(10,10)) isa Zeros{Float64}\n    @test real(Zeros{ComplexF64}(10)) isa Zeros{Float64}\n    @test real(Zeros{ComplexF64}(10,10)) isa Zeros{Float64}\n    @test real(Ones{Float64}(10)) isa Ones{Float64}\n    @test real(Ones{Float64}(10,10)) isa Ones{Float64}\n    @test real(Ones{ComplexF64}(10)) isa Ones{Float64}\n    @test real(Ones{ComplexF64}(10,10)) isa Ones{Float64}\n    @test imag(Zeros{Float64}(10)) isa Zeros{Float64}\n    @test imag(Zeros{Float64}(10,10)) isa Zeros{Float64}\n    @test imag(Zeros{ComplexF64}(10)) isa Zeros{Float64}\n    @test imag(Zeros{ComplexF64}(10,10)) isa Zeros{Float64}\n    @test imag(Ones{Float64}(10)) isa Zeros{Float64}\n    @test imag(Ones{Float64}(10,10)) isa Zeros{Float64}\n    @test imag(Ones{ComplexF64}(10)) isa Zeros{Float64}\n    @test imag(Ones{ComplexF64}(10,10)) isa Zeros{Float64}\n\n    @testset \"range broadcast\" begin\n        rnge = range(-5.0, step=1.0, length=10)\n        @test broadcast(*, Fill(5.0, 10), rnge) == broadcast(*, 5.0, rnge)\n        @test broadcast(*, Zeros(10, 10), rnge) ≡ Zeros{Float64}(10, 10)\n        @test broadcast(*, rnge, Zeros(10, 10)) ≡ Zeros{Float64}(10, 10)\n        @test broadcast(*, Ones{Int}(10), rnge) ≡ rnge\n        @test broadcast(*, rnge, Ones{Int}(10)) ≡ rnge\n        @test broadcast(*, Ones(10), -5:4) ≡ broadcast(*, -5:4, Ones(10)) ≡ rnge\n        @test broadcast(*, Ones(10), -5:1:4) ≡ broadcast(*, -5:1:4, Ones(10)) ≡ rnge\n        @test_throws DimensionMismatch broadcast(*, Fill(5.0, 11), rnge)\n        @test broadcast(*, rnge, Fill(5.0, 10)) == broadcast(*, rnge, 5.0)\n        @test_throws DimensionMismatch broadcast(*, rnge, Fill(5.0, 11))\n\n        # following should pass using alternative implementation in code\n        deg = 5:5\n        @test_throws ArgumentError @inferred(broadcast(*, Fill(5.0, 10), deg)) == broadcast(*, fill(5.0,10), deg)\n        @test_throws ArgumentError @inferred(broadcast(*, deg, Fill(5.0, 10))) == broadcast(*, deg, fill(5.0,10))\n\n        @test rnge .+ Zeros(10) ≡ rnge .- Zeros(10) ≡ Zeros(10) .+ rnge ≡ rnge\n\n        @test_throws DimensionMismatch rnge .+ Zeros(5)\n        @test_throws DimensionMismatch rnge .- Zeros(5)\n        @test_throws DimensionMismatch Zeros(5) .+ rnge\n\n        @test Fill(2,10) + (1:10) isa UnitRange\n        @test (1:10) + Fill(2,10) isa UnitRange\n\n        f = Fill(1+im,10)\n        @test f + rnge isa AbstractRange\n        @test f + rnge == rnge + f\n        @test f + (1:10) isa AbstractRange\n    end\n\n    @testset \"Special Zeros/Ones\" begin\n        @test broadcast(+,Zeros(5)) ≡ broadcast(-,Zeros(5)) ≡ Zeros(5)\n        @test broadcast(+,Ones(5)) ≡ Ones(5)\n\n        @test Zeros(5) .* Ones(5) ≡ Zeros(5) .* 1 ≡ Zeros(5)\n        @test Zeros(5) .* Fill(5.0, 5) ≡ Zeros(5) .* 5.0 ≡ Zeros(5)\n        @test Ones(5) .* Zeros(5) ≡ 1 .* Zeros(5) ≡ Zeros(5)\n        @test Fill(5.0, 5) .* Zeros(5) ≡ 5.0 .* Zeros(5) ≡ Zeros(5)\n\n        @test Zeros(5) ./ Ones(5) ≡ Zeros(5) ./ 1 ≡ Zeros(5)\n        @test Zeros(5) ./ Fill(5.0, 5) ≡ Zeros(5) ./ 5.0 ≡ Zeros(5)\n        @test Ones(5) .\\ Zeros(5) ≡ 1 .\\ Zeros(5) ≡ Zeros(5)\n        @test Fill(5.0, 5) .\\ Zeros(5) ≡ 5.0 .\\ Zeros(5) ≡ Zeros(5)\n\n        @test conj.(Zeros(5)) ≡ Zeros(5)\n        @test conj.(Zeros{ComplexF64}(5)) ≡ Zeros{ComplexF64}(5)\n\n        @test_throws DimensionMismatch broadcast(*, Ones(3), 1:6)\n        @test_throws DimensionMismatch broadcast(*, 1:6, Ones(3))\n        @test_throws DimensionMismatch broadcast(*, Fill(1,3), 1:6)\n        @test_throws DimensionMismatch broadcast(*, 1:6, Fill(1,3))\n\n        @testset \"Number\" begin\n            @test broadcast(*, Zeros(5), 2) ≡ broadcast(*, 2, Zeros(5)) ≡ Zeros(5)\n        end\n\n        @testset \"Nested\" begin\n            @test randn(5) .\\ rand(5) .* Zeros(5) ≡ Zeros(5)\n            @test broadcast(*, Zeros(5), Base.Broadcast.broadcasted(\\, randn(5), rand(5))) ≡ Zeros(5)\n        end\n\n        @testset \"array-valued\" begin\n            @test broadcast(*, Fill([1,2],3), 1:3) == broadcast(*, 1:3, Fill([1,2],3)) == broadcast(*, 1:3, fill([1,2],3))\n            @test broadcast(*, Fill([1,2],3), Zeros(3)) == broadcast(*, Zeros(3), Fill([1,2],3)) == broadcast(*, zeros(3), fill([1,2],3))\n            @test broadcast(*, Fill([1,2],3), Zeros(3)) isa Fill{Vector{Float64}}\n            @test broadcast(*, [[1,2], [3,4,5]], Zeros(2)) == broadcast(*, Zeros(2), [[1,2], [3,4,5]]) == broadcast(*, zeros(2), [[1,2], [3,4,5]])\n        end\n\n        @testset \"NaN\" begin\n            @test Zeros(5) ./ Zeros(5) ≡ Zeros(5) .\\ Zeros(5) ≡ Fill(NaN,5)\n            @test Zeros{Int}(5,6) ./ Zeros{Int}(5) ≡ Zeros{Int}(5) .\\ Zeros{Int}(5,6) ≡ Fill(NaN,5,6)\n        end\n\n        @testset \"Addition/Subtraction\" begin\n            @test Zeros{Int}(5) .+ (1:5) ≡ (1:5) .+ Zeros{Int}(5) ≡ (1:5) .- Zeros{Int}(5) ≡ 1:5\n            @test Zeros{Int}(1) .+ (1:5) ≡ (1:5) .+ Zeros{Int}(1) ≡ (1:5) .- Zeros{Int}(1) ≡ 1:5\n            @test Zeros(5) .+ (1:5) == (1:5) .+ Zeros(5) == (1:5) .- Zeros(5) == 1:5\n            @test Zeros{Int}(5) .+ Fill(1,5) ≡ Fill(1,5) .+ Zeros{Int}(5) ≡ Fill(1,5) .- Zeros{Int}(5) ≡ Fill(1,5)\n            @test_throws DimensionMismatch Zeros{Int}(2) .+ (1:5)\n            @test_throws DimensionMismatch (1:5) .+ Zeros{Int}(2)\n\n            for v in (rand(Bool, 5), [1:5;], SVector{5}(1:5), SVector{5,ComplexF16}(1:5)), T in (Bool, Int, Float64)\n                TT = eltype(v + zeros(T, 5))\n                S = v isa SVector ? SVector{5,TT} : Vector{TT}\n\n                a = @inferred(Zeros{T}(5) .+ v)\n                b = @inferred(v .+ Zeros{T}(5))\n                c = @inferred(v .- Zeros{T}(5))\n                @test a == b == c == v\n                d = @inferred(Zeros{T}(5) .- v)\n                @test d == -v\n                @test all(Base.Fix2(isa, S), (a,b,c,d))\n            end\n        end\n    end\n\n    @testset \"support Ref\" begin\n        @test Fill(1,10) .- 1 ≡ Fill(1,10) .- Ref(1) ≡ Fill(1,10) .- Ref(1I)\n        @test Fill([1 2; 3 4],10) .- Ref(1I) == Fill([0 2; 3 3],10)\n        @test Ref(1I) .+ Fill([1 2; 3 4],10) == Fill([2 2; 3 5],10)\n    end\n\n    @testset \"Special Ones\" begin\n        @test Ones{Int}(5) .* (1:5) ≡ (1:5) .* Ones{Int}(5) ≡ 1:5\n        @test Ones(5) .* (1:5) ≡ (1:5) .* Ones(5) ≡ 1.0:5\n        @test Ones{Int}(5) .* Ones{Int}(5) ≡ Ones{Int}(5)\n        @test Ones{Int}(5,2) .* (1:5) == Array(Ones{Int}(5,2)) .* Array(1:5)\n        @test (1:5) .* Ones{Int}(5,2)  == Array(1:5) .* Array(Ones{Int}(5,2))\n        @test (1:0.5:5) .* Ones{Int}(9,2)  == Array(1:0.5:5) .* Array(Ones{Int}(9,2))\n        @test Ones{Int}(9,2) .* (1:0.5:5)  == Array(Ones{Int}(9,2)) .* Array(1:0.5:5)\n        @test_throws DimensionMismatch Ones{Int}(6) .* (1:5)\n        @test_throws DimensionMismatch (1:5) .* Ones{Int}(6)\n        @test_throws DimensionMismatch Ones{Int}(5) .* Ones{Int}(6)\n    end\n\n    @testset \"Zeros -\" begin\n        @test Zeros(10) - Zeros(10) ≡ Zeros(10)\n        @test Ones(10) - Zeros(10) ≡ Ones(10)\n        @test Ones(10) - Ones(10) ≡ Zeros(10)\n        @test Fill(1,10) - Zeros(10) ≡ Fill(1.0,10)\n\n        @test Zeros(10) .- Zeros(10) ≡ Zeros(10)\n        @test Ones(10) .- Zeros(10) ≡ Ones(10)\n        @test Ones(10) .- Ones(10) ≡ Zeros(10)\n        @test Fill(1,10) .- Zeros(10) ≡ Fill(1.0,10)\n\n        @test Zeros(10) .- Zeros(1,9) ≡ Zeros(10,9)\n        @test Ones(10) .- Zeros(1,9) ≡ Ones(10,9)\n        @test Ones(10) .- Ones(1,9) ≡ Zeros(10,9)\n\n    end\n\n    @testset \"issue #208\" begin\n        TS = (Bool, Int, Float32, Float64)\n        for S in TS, T in TS\n            u = rand(S, 2)\n            v = Zeros(T, 2)\n            if zero(S) + zero(T) isa S\n                @test @inferred(Broadcast.broadcasted(-, u, v)) === u\n                @test @inferred(Broadcast.broadcasted(+, u, v)) === u\n                @test @inferred(Broadcast.broadcasted(+, v, u)) === u\n            else\n                @test @inferred(Broadcast.broadcasted(-, u, v)) isa Broadcast.Broadcasted\n                @test @inferred(Broadcast.broadcasted(+, u, v)) isa Broadcast. Broadcasted\n                @test @inferred(Broadcast.broadcasted(+, v, u)) isa Broadcast.Broadcasted\n            end\n            @test @inferred(Broadcast.broadcasted(-, v, u)) isa Broadcast.Broadcasted\n        end\n    end\n\n    @testset \"Zero .*\" begin\n        TS = (Bool, Int, Float32, Float64)\n        for S in TS, T in TS\n            U = typeof(zero(S) * zero(T))\n            @test Zeros{S}(10) .* Zeros{T}(10) ≡ Zeros{U}(10)\n            @test rand(S, 10) .* Zeros(T, 10) ≡ Zeros(U, 10)\n            @test Zeros(S, 10) .* rand(T, 10) ≡ Zeros(U, 10)\n            if S !== Bool\n                @test (S(1):S(10)) .* Zeros(T, 10) ≡ Zeros(U, 10)\n                @test_throws DimensionMismatch (S(1):S(11)) .* Zeros(T, 10)\n            end\n            if T !== Bool\n                @test Zeros(S, 10) .* (T(1):T(10)) ≡ Zeros(U, 10)\n                @test_throws DimensionMismatch Zeros(S, 10) .* (T(1):T(11))\n            end\n        end\n    end\nend\n\n@testset \"map\" begin\n    x1 = Ones(5)\n    @test map(exp,x1) === Fill(exp(1.0),5)\n    @test map(isone,x1) === Fill(true,5)\n\n    x0 = Zeros(5)\n    @test map(exp,x0) === exp.(x0)\n\n    x2 = Fill(2,5,3)\n    @test map(exp,x2) === Fill(exp(2),5,3)\n\n    @test map(+, x1, x2) === Fill(3.0, 5)\n    @test map(+, x2, x2) === x2 .+ x2\n    @test_throws DimensionMismatch map(+, x2', x2)\n\n    # Issue https://github.com/JuliaArrays/FillArrays.jl/issues/179\n    if VERSION < v\"1.11.0-\"  # In 1.11, 1-arg map & mapreduce was removed\n        @test map(() -> \"ok\") == \"ok\"  # was MethodError: reducing over an empty collection is not allowed\n        @test mapreduce(() -> \"ok\", *) == \"ok\"\n    else\n        @test_throws \"no method matching map\" map(() -> \"ok\")\n        @test_throws \"no method matching map\" mapreduce(() -> \"ok\", *)\n    end\nend\n\n@testset \"mapreduce\" begin\n    x = rand(3, 4)\n    y = fill(1.0, 3, 4)\n    Y = Fill(1.0, 3, 4)\n    O = Ones(3, 4)\n\n    @test mapreduce(exp, +, Y) == mapreduce(exp, +, y)\n    @test mapreduce(exp, +, Y; dims=2) == mapreduce(exp, +, y; dims=2)\n    @test mapreduce(identity, +, Y) == sum(y) == sum(Y)\n    @test mapreduce(identity, +, Y, dims=1) == sum(y, dims=1) == sum(Y, dims=1)\n\n    @test mapreduce(exp, +, Y; dims=(1,), init=5.0) == mapreduce(exp, +, y; dims=(1,), init=5.0)\n\n    # Two arrays\n    @test mapreduce(*, +, x, Y) == mapreduce(*, +, x, y)\n    @test mapreduce(*, +, Y, x) == mapreduce(*, +, y, x)\n    @test mapreduce(*, +, x, O) == mapreduce(*, +, x, y)\n    @test mapreduce(*, +, Y, O) == mapreduce(*, +, y, y)\n\n    f2(x,y) = 1 + x/y\n    op2(x,y) = x^2 + 3y\n    @test mapreduce(f2, op2, x, Y) == mapreduce(f2, op2, x, y)\n\n    @test mapreduce(f2, op2, x, Y, dims=1, init=5.0) == mapreduce(f2, op2, x, y, dims=1, init=5.0)\n    @test mapreduce(f2, op2, Y, x, dims=1, init=5.0) == mapreduce(f2, op2, y, x, dims=1, init=5.0)\n    @test mapreduce(f2, op2, x, O, dims=1, init=5.0) == mapreduce(f2, op2, x, y, dims=1, init=5.0)\n    @test mapreduce(f2, op2, Y, O, dims=1, init=5.0) == mapreduce(f2, op2, y, y, dims=1, init=5.0)\n\n    # More than two\n    @test mapreduce(+, +, x, Y, x) == mapreduce(+, +, x, y, x)\n    @test mapreduce(+, +, Y, x, x) == mapreduce(+, +, y, x, x)\n    @test mapreduce(+, +, x, O, Y) == mapreduce(+, +, x, y, y)\n    @test mapreduce(+, +, Y, O, Y) == mapreduce(+, +, y, y, y)\n    @test mapreduce(+, +, Y, O, Y, x) == mapreduce(+, +, y, y, y, x)\nend\n\n@testset \"Offset indexing\" begin\n    A = Fill(3, (Base.Slice(-1:1),))\n    @test axes(A)  == (Base.Slice(-1:1),)\n    @test A[0] == 3\n    @test_throws BoundsError A[2]\n    @test_throws BoundsError A[-2]\n\n    A = Zeros((Base.Slice(-1:1),))\n    @test axes(A)  == (Base.Slice(-1:1),)\n    @test A[0] == 0\n    @test_throws BoundsError A[2]\n    @test_throws BoundsError A[-2]\nend\n\n@testset \"0-dimensional\" begin\n    A = Fill{Int,0,Tuple{}}(3, ())\n\n    @test A[] ≡ A[1] ≡ 3\n    @test A ≡ Fill{Int,0}(3, ()) ≡ Fill(3, ()) ≡ Fill(3)\n    @test size(A) == ()\n    @test axes(A) == ()\n\n    A = Ones{Int,0,Tuple{}}(())\n    @test A[] ≡ A[1] ≡ 1\n    @test A ≡ Ones{Int,0}(()) ≡ Ones{Int}(()) ≡ Ones{Int}()\n\n    A = Zeros{Int,0,Tuple{}}(())\n    @test A[] ≡ A[1] ≡ 0\n    @test A ≡ Zeros{Int,0}(()) ≡ Zeros{Int}(()) ≡ Zeros{Int}()\nend\n\n@testset \"unique\" begin\n    @test unique(Fill(12, 20)) == unique(fill(12, 20))\n    @test unique(Fill(1, 0)) == []\n    @test unique(Zeros(0)) == Zeros(0)\n    @test !allunique(Fill(\"a\", 2))\n    @test allunique(Ones(0))\nend\n\n@testset \"iterate\" begin\n    for d in (0, 1, 2, 100)\n        for T in (Float64, Int)\n            m = Eye(d)\n            mcp = [x for x in m]\n            @test mcp == m\n            @test eltype(mcp) == eltype(m)\n        end\n    end\nend\n\n@testset \"properties\" begin\n    for d in (0, 1, 2, 100)\n        @test isone(Eye(d))\n    end\nend\n\n@testset \"any all iszero isone\" begin\n    for T in (Int, Float64, ComplexF64)\n        for m in (Eye{T}(0), Eye{T}(0, 0), Eye{T}(0, 1), Eye{T}(1, 0))\n            @test ! any(isone, m)\n            @test ! any(iszero, m)\n            @test ! all(iszero, m)\n            @test ! all(isone, m)\n        end\n        @testset for d in (0, 1)\n            for m in (Eye{T}(d), Eye{T}(d, d))\n                M = Array(m)\n                @test ! any(iszero, m)\n                @test ! all(iszero, m)\n                @test any(isone, m) == !isempty(m)\n                @test all(isone, m) == !isempty(m)\n                if !isempty(m)\n                    @test ! any(iszero, m) == ! any(iszero, M)\n                    @test ! all(iszero, m) == ! all(iszero, M)\n                    @test any(isone, m) == any(isone, M)\n                    @test all(isone, m) == all(isone, M)\n                end\n            end\n\n            for m in (Eye{T}(d, d + 1), Eye{T}(d + 1, d))\n                M = Array(m)\n                @test any(iszero, m) == !isempty(m)\n                @test ! all(iszero, m)\n                @test any(isone, m) == !isempty(m)\n                @test ! all(isone, m)\n                if !isempty(M)\n                    @test any(iszero, m) == any(iszero, M)\n                    @test ! all(iszero, m) == ! all(iszero, M)\n                    @test any(isone, m) == any(isone, M)\n                    @test ! all(isone, m) == ! all(isone, M)\n                end\n            end\n\n            onem = Ones{T}(d, d)\n            @test isone(onem) == isone(Array(onem))\n            @test iszero(onem) == isempty(onem) == iszero(Array(onem))\n\n            if d > 0\n                @test !isone(Ones{T}(d, 2d))\n            end\n\n            zerom = Zeros{T}(d, d)\n            @test  isone(zerom) == isempty(zerom) == isone(Array(zerom))\n            @test  iszero(zerom) == iszero(Array(zerom))\n\n            if d > 0\n                @test iszero(Zeros{T}(d, 2d))\n            end\n\n            fillm0 = Fill(T(0), d, d)\n            @test   isone(fillm0) == isempty(fillm0) == isone(Array(fillm0))\n            @test   iszero(fillm0) == iszero(Array(fillm0))\n\n            fillm1 = Fill(T(1), d, d)\n            @test isone(fillm1) == isone(Array(fillm1))\n            @test iszero(fillm1) == isempty(fillm1) == iszero(Array(fillm1))\n\n            fillm2 = Fill(T(2), d, d)\n            @test isone(fillm2) == isempty(fillm2) == isone(Array(fillm2))\n            @test iszero(fillm2) == isempty(fillm2) == iszero(Array(fillm2))\n        end\n        for d in (2, 3)\n            for m in (Eye{T}(d), Eye{T}(d, d), Eye{T}(d, d + 2), Eye{T}(d + 2, d))\n                @test any(iszero, m)\n                @test ! all(iszero, m)\n                @test any(isone, m)\n                @test ! all(isone, m)\n            end\n\n            m1 = Ones{T}(d, d)\n            @test ! isone(m1)\n            @test ! iszero(m1)\n            @test all(isone, m1)\n            @test ! all(iszero, m1)\n\n            m2 = Zeros{T}(d, d)\n            @test ! isone(m2)\n            @test iszero(m2)\n            @test ! all(isone, m2)\n            @test  all(iszero, m2)\n\n            m3 = Fill(T(2), d, d)\n            @test ! isone(m3)\n            @test ! iszero(m3)\n            @test ! all(isone, m3)\n            @test ! all(iszero, m3)\n            @test ! any(iszero, m3)\n\n            m4 = Fill(T(1), d, d)\n            @test ! isone(m4)\n            @test ! iszero(m4)\n        end\n    end\n\n    @test iszero(Zeros{SMatrix{2,2,Int,4}}(2))\n    @test iszero(Fill(SMatrix{2,2}(0,0,0,0), 2))\n    @test iszero(Fill(SMatrix{2,2}(0,0,0,1), 0))\n\n    # compile-time evaluation\n    @test @inferred((Z -> Val(iszero(Z)))(Zeros(3,3))) == Val(true)\n\n    @testset \"all/any\" begin\n        @test any(Ones{Bool}(10)) === all(Ones{Bool}(10)) === any(Fill(true,10)) === all(Fill(true,10)) === true\n        @test any(Zeros{Bool}(10)) === all(Zeros{Bool}(10)) === any(Fill(false,10)) === all(Fill(false,10)) === false\n        @test all(b -> ndims(b) ==  1, Fill([1,2],10))\n        @test any(b -> ndims(b) ==  1, Fill([1,2],10))\n\n        @test all(Fill(2,0))\n        @test !any(Fill(2,0))\n        @test any(Trues(2,0)) == any(trues(2,0))\n        @test_throws TypeError all(Fill(2,2))\n        @test all(iszero, Fill(missing,0)) === all(iszero, fill(missing,0)) === true\n        @test all(iszero, Fill(missing,2)) === all(iszero, fill(missing,2)) === missing\n        @test any(iszero, Fill(missing,0)) === any(iszero, fill(missing,0)) === false\n        @test any(iszero, Fill(missing,2)) === any(iszero, fill(missing,2)) === missing\n    end\n\n    @testset \"Error\" begin\n        @test_throws TypeError any(exp, Fill(1,5))\n        @test_throws TypeError all(exp, Fill(1,5))\n        @test_throws TypeError any(exp, Eye(5))\n        @test_throws TypeError all(exp, Eye(5))\n        @test_throws TypeError any(Fill(1,5))\n        @test_throws TypeError all(Fill(1,5))\n        @test_throws TypeError any(Zeros(5))\n        @test_throws TypeError all(Zeros(5))\n        @test_throws TypeError any(Ones(5))\n        @test_throws TypeError all(Ones(5))\n        @test_throws TypeError any(Eye(5))\n        @test_throws TypeError all(Eye(5))\n    end\nend\n\n@testset \"Eye identity ops\" begin\n    m = Eye(10)\n    D = Diagonal(Fill(2,10))\n\n    for op in (permutedims, inv)\n        @test op(m) === m\n    end\n    @test permutedims(D) ≡ D\n    @test inv(D) ≡ Diagonal(Fill(1/2,10))\n\n    for m in (Eye(10), Eye(10, 10), Eye(10, 8), Eye(8, 10), D)\n        for op in (tril, triu, tril!, triu!)\n            @test op(m) === m\n        end\n    end\n\n    @test copy(m) ≡ m\n    @test copy(D) ≡ D\nend\n\n@testset \"Eye broadcast\" begin\n    E = Eye(2,3)\n    M = Matrix(E)\n    F = E .+ E\n    @test F isa FillArrays.RectDiagonal\n    @test F == M + M\n\n    F = E .+ 1\n    @test F == M .+ 1\n\n    E = Eye((SOneTo(2), SOneTo(2)))\n    @test axes(E .+ E) === axes(E)\nend\n\n@testset \"Issues\" begin\n    @testset \"#31\" begin\n        @test convert(SparseMatrixCSC{Float64,Int64}, Zeros{Float64}(3, 3)) == spzeros(3, 3)\n        @test sparse(Zeros(4, 2)) == spzeros(4, 2)\n    end\n    @testset \"#178\" begin\n        @test Zeros(10)'*spzeros(10) == 0\n    end\nend\n\n@testset \"Adjoint/Transpose/permutedims\" begin\n    @test Ones{ComplexF64}(5,6)' ≡ transpose(Ones{ComplexF64}(5,6)) ≡ Ones{ComplexF64}(6,5)\n    @test Zeros{ComplexF64}(5,6)' ≡ transpose(Zeros{ComplexF64}(5,6)) ≡ Zeros{ComplexF64}(6,5)\n    @test Fill(1+im, 5, 6)' ≡ Fill(1-im, 6,5)\n    @test transpose(Fill(1+im, 5, 6)) ≡ Fill(1+im, 6,5)\n    @test Ones(5)' isa Adjoint # Vectors still need special dot product\n    @test copy(Ones(5)') ≡ Ones(5)'\n    @test copy(transpose(Ones(5))) ≡ transpose(Ones(5))\n    @test Fill([1+im 2; 3 4; 5 6], 2,3)' == Fill([1+im 2; 3 4; 5 6]', 3,2)\n    @test transpose(Fill([1+im 2; 3 4; 5 6], 2,3)) == Fill(transpose([1+im 2; 3 4; 5 6]), 3,2)\n\n    @test permutedims(Ones(10)) ≡ Ones(1,10)\n    @test permutedims(Zeros(10)) ≡ Zeros(1,10)\n    @test permutedims(Fill(2.0,10)) ≡ Fill(2.0,1,10)\n    @test permutedims(Ones(10,3)) ≡ Ones(3,10)\n    @test permutedims(Zeros(10,3)) ≡ Zeros(3,10)\n    @test permutedims(Fill(2.0,10,3)) ≡ Fill(2.0,3,10)\n\n    @test permutedims(Ones(2,4,5), [3,2,1]) == permutedims(Array(Ones(2,4,5)), [3,2,1])\n    @test permutedims(Ones(2,4,5), [3,2,1]) ≡ Ones(5,4,2)\n    @test permutedims(Zeros(2,4,5), [3,2,1]) ≡ Zeros(5,4,2)\n    @test permutedims(Fill(2.0,2,4,5), [3,2,1]) ≡ Fill(2.0,5,4,2)\n\n    @testset \"recursive\" begin\n        S = SMatrix{2,3}(1:6)\n        Z = Zeros(typeof(S), 2, 3)\n        Y = zeros(typeof(S), 2, 3)\n        @test Z' == Y'\n        @test transpose(Z) == transpose(Y)\n\n        F = Fill(S, 2, 3)\n        G = fill(S, 2, 3)\n        @test F' == G'\n        @test transpose(F) == transpose(G)\n    end\nend\n\n@testset \"reverse\" begin\n    for A in (Zeros{Int}(6), Ones(2,3), Fill(\"abc\", 2, 3, 4))\n        @test reverse(A) == reverse(Array(A))\n        @test reverse(A, dims=1) == reverse(Array(A), dims=1)\n    end\n    A = Ones{Int}(6)\n    @test reverse(A, 2, 4) == reverse(Array(A), 2, 4)\n    @test_throws BoundsError reverse(A, 1, 10)\nend\n\n@testset \"setindex!/fill!\" begin\n    F = Fill(1,10)\n    @test (F[1] = 1) == 1\n    @test_throws BoundsError (F[11] = 1)\n    @test_throws ArgumentError (F[10] = 2)\n\n\n    F = Fill(1,10,5)\n    @test (F[1] = 1) == 1\n    @test (F[3,3] = 1) == 1\n    @test_throws BoundsError (F[51] = 1)\n    @test_throws BoundsError (F[1,6] = 1)\n    @test_throws ArgumentError (F[10] = 2)\n    @test_throws ArgumentError (F[10,1] = 2)\n\n    @test (F[:,1] .= 1) == fill(1,10)\n    @test_throws ArgumentError (F[:,1] .= 2)\n\n    @test fill!(F,1) == F\n    @test_throws ArgumentError fill!(F,2)\nend\n\n@testset \"mult\" begin\n    @test Fill(2,10)*Fill(3,1,12) == Vector(Fill(2,10))*Matrix(Fill(3,1,12))\n    @test Fill(2,10)*Fill(3,1,12) ≡ Fill(6,10,12)\n    @test Fill(2,3,10)*Fill(3,10,12) ≡ Fill(60,3,12)\n    @test Fill(2,3,10)*Fill(3,10) ≡ Fill(60,3)\n    @test_throws DimensionMismatch Fill(2,10)*Fill(3,2,12)\n    @test_throws DimensionMismatch Fill(2,3,10)*Fill(3,2,12)\n\n    f = Fill(1, (Base.IdentityUnitRange(1:3), Base.IdentityUnitRange(1:3)))\n    @test f * f === Fill(size(f,2), axes(f))\n\n    f = Fill(2, (Base.IdentityUnitRange(2:3), Base.IdentityUnitRange(2:3)))\n    @test_throws ArgumentError f * f\n\n    @test Ones(10)*Fill(3,1,12) ≡ Fill(3.0,10,12)\n    @test Ones(10,3)*Fill(3,3,12) ≡ Fill(9.0,10,12)\n    @test Ones(10,3)*Fill(3,3) ≡ Fill(9.0,10)\n\n    @test Fill(2,10)*Ones(1,12) ≡ Fill(2.0,10,12)\n    @test Fill(2,3,10)*Ones(10,12) ≡ Fill(20.0,3,12)\n    @test Fill(2,3,10)*Ones(10) ≡ Fill(20.0,3)\n\n    @test Ones(10)*Ones(1,12) ≡ Ones(10,12)\n    @test Ones(3,10)*Ones(10,12) ≡ Fill(10.0,3,12)\n    @test Ones(3,10)*Ones(10) ≡ Fill(10.0,3)\n\n    @test Zeros(10)*Fill(3,1,12) ≡   Zeros(10,12)\n    @test Zeros(10,3)*Fill(3,3,12) ≡ Zeros(10,12)\n    @test Zeros(10,3)*Fill(3,3) ≡    Zeros(10)\n\n    @test Fill(2,10)*  Zeros(1,12) ≡  Zeros(10,12)\n    @test Fill(2,3,10)*Zeros(10,12) ≡ Zeros(3,12)\n    @test Fill(2,3,10)*Zeros(10) ≡    Zeros(3)\n\n    @test Zeros(10)*Zeros(1,12) ≡ Zeros(10,12)\n    @test Zeros(3,10)*Zeros(10,12) ≡ Zeros(3,12)\n    @test Zeros(3,10)*Zeros(10) ≡ Zeros(3)\n\n    f = Zeros((Base.IdentityUnitRange(1:4), Base.IdentityUnitRange(1:4)))\n    @test f * f === f\n\n    f = Zeros((Base.IdentityUnitRange(3:4), Base.IdentityUnitRange(3:4)))\n    @test_throws ArgumentError f * f\n\n    @testset \"Arrays as elements\" begin\n        SMT = SMatrix{2,2,Int,4}\n        SVT = SVector{2,Int}\n        @test @inferred(Zeros{SMT}(0,0) * Fill([1 2; 3 4], 0, 0)) == Zeros{SMT}(0,0)\n        @test @inferred(Zeros{SMT}(4,2) * Fill([1 2; 3 4], 2, 3)) == Zeros{SMT}(4,3)\n        @test @inferred(Fill([1 2; 3 4], 2, 3) * Zeros{SMT}(3, 4)) == Zeros{SMT}(2,4)\n        @test @inferred(Zeros{SMT}(4,2) * Fill([1, 2], 2, 3)) == Zeros{SVT}(4,3)\n        @test @inferred(Fill([1 2], 2, 3) * Zeros{SMT}(3,4)) == Zeros{SMatrix{1,2,Int,2}}(2,4)\n\n        TSM = SMatrix{2,2,Int,4}\n        s = TSM(1:4)\n        for n in 0:3\n            v = fill(s, 1)\n            z = zeros(TSM, n)\n            A = @inferred Zeros{TSM}(n) * Diagonal(v)\n            B = z * Diagonal(v)\n            @test A == B\n\n            w = fill(s, n)\n            A = @inferred Diagonal(w) * Zeros{TSM}(n)\n            B = Diagonal(w) * z\n            @test A == B\n\n            A = @inferred Zeros{TSM}(2n, n) * Diagonal(w)\n            B = zeros(TSM, 2n, n) * Diagonal(w)\n            @test A == B\n\n            A = @inferred Diagonal(w) * Zeros{TSM}(n, 2n)\n            B = Diagonal(w) * zeros(TSM, n, 2n)\n            @test A == B\n        end\n\n        D = Diagonal([[1 2; 3 4], [1 2 3; 4 5 6]])\n        @test @inferred(Zeros(TSM, 2,2) * D) == zeros(TSM, 2,2) * D\n\n        D = Diagonal(fill(SMatrix{2,3}(fill(im,6)),1))\n        Z = Zeros(SMatrix{2,3,ComplexF64,6},1)\n        @test D * Z' == fill(zero(SMatrix{2,2,ComplexF64,4}),1,1)\n\n        D = Diagonal(fill(zeros(2,3), 2))\n        Z = Zeros(SMatrix{2,3,Float64,6}, 2)\n        @test Z' * D == Array(Z)' * D\n\n        S = SMatrix{2,3}(1:6)\n        A = reshape([S,2S,3S,4S],2,2)\n        F = Fill(S',2,2)\n        @test A * F == A * fill(S',size(F))\n        @test mul!(A * F, A, F, 2, 1) == 3 * A * fill(S',size(F))\n        @test F * A == fill(S',size(F)) * A\n        @test mul!(F * A, F, A, 2, 1) == 3 * fill(S',size(F)) * A\n\n        # doubly nested\n        A = [[[1,2]]]'\n        Z = Zeros(SMatrix{1,1,SMatrix{2,2,Int,4},1},1)\n        Z2 = zeros(SMatrix{1,1,SMatrix{2,2,Int,4},1},1)\n        @test A * Z == A * Z2\n\n        x = [1 2 3; 4 5 6]\n        A = reshape([x,2x,3x,4x],2,2)\n        F = Fill(x,2,2)\n        @test A' * F == A' * fill(x,size(F))\n        @test mul!(A' * F, A', F, 2, 1) == 3 * A' * fill(x,size(F))\n    end\n\n    for W in (zeros(3,4), @MMatrix zeros(3,4))\n        mW, nW = size(W)\n        @test mul!(W, Fill(2,mW,5), Fill(3,5,nW)) ≈ Fill(30,mW,nW) ≈ fill(2,mW,5) * fill(3,5,nW)\n        W .= 2\n        @test mul!(W, Fill(2,mW,5), Fill(3,5,nW), 1.0, 2.0) ≈ Fill(30,mW,nW) .+ 4 ≈ fill(2,mW,5) * fill(3,5,nW) .+ 4\n    end\n\n    for w in (zeros(5), @MVector zeros(5))\n        mw = size(w,1)\n        @test mul!(w, Fill(2,mw,5), Fill(3,5)) ≈ Fill(30,mw) ≈ fill(2,mw,5) * fill(3,5)\n        w .= 2\n        @test mul!(w, Fill(2,mw,5), Fill(3,5), 1.0, 2.0) ≈ Fill(30,mw) .+ 4 ≈ fill(2,mw,5) * fill(3,5) .+ 4\n    end\n\n    @testset \"strided\" begin\n        @testset for (la, (mA, nA)) in [(3, (1,4)), (0, (1,4)), (3, (1, 0))]\n\n            a = randn(la)\n            na = 1\n            A = randn(mA,nA)\n\n            @test Fill(2,3)*A ≈ Vector(Fill(2,3))*A\n            @test Fill(2,0)*A ≈ Vector(Fill(2,0))*A\n            @test Fill(2,3,mA)*A ≈ mul!(similar(A, 3,nA), Fill(2,3,mA), A) ≈ Matrix(Fill(2,3,mA))*A\n            @test Fill(2,3,la)*a ≈ mul!(similar(a, 3), Fill(2,3,la), a) ≈ Matrix(Fill(2,3,la))*a\n            @test Fill(2,3,la)*a isa Fill\n            @test Ones(3)*A ≈ Vector(Ones(3))*A\n            @test Ones(3,mA)*A ≈ mul!(similar(A, 3, nA), Ones(3,mA), A) ≈ Matrix(Ones(3,mA))*A\n            @test Ones(3,la)*a ≈ mul!(similar(a, 3), Ones(3,la), a) ≈ Matrix(Ones(3,la))*a\n            @test Ones(3,la)*a isa Fill\n            @test Zeros(3)*A  ≡ Zeros(3,nA)\n            @test Zeros(3,mA)*A == mul!(similar(A, 3, nA), Zeros(3,mA), A) == Zeros(3,nA)\n            @test Zeros(3,la)*a == mul!(similar(A, 3), Zeros(3,la), a) == Zeros(3)\n\n            @test A*Fill(2,nA) ≈ A*Vector(Fill(2,nA))\n            @test A*Fill(2,nA,1) ≈ A*Matrix(Fill(2,nA,1))\n            @test a*Fill(2,na,3) ≈ a*Matrix(Fill(2,na,3))\n            @test A*Fill(2,nA,0) ≈ A*Matrix(Fill(2,nA,0))\n            @test a*Fill(2,na,0) ≈ a*Matrix(Fill(2,na,0))\n            @test A*Ones(nA) ≈ A*Vector(Ones(nA))\n            @test A*Ones(nA,1) ≈ A*Matrix(Ones(nA,1))\n            @test a*Ones(na,3) ≈ a*Matrix(Ones(na,3))\n            @test A*Zeros(nA)  ≡ Zeros(mA)\n            @test A*Zeros(nA,1) ≡ Zeros(mA,1)\n            @test a*Zeros(na,3) ≡ Zeros(la,3)\n\n            @test transpose(A) * Zeros(mA) ≡ Zeros(nA)\n            @test A' * Zeros(mA) ≡ Zeros(nA)\n\n            @test transpose(a) * Zeros(la, 3) ≡ transpose(Zeros(3))\n            @test a' * Zeros(la,3) ≡ adjoint(Zeros(3))\n\n            @test Zeros(la)' * Transpose(Adjoint(a)) == 0.0\n\n            F = Fill(2, mA, 3)\n            @test transpose(A) * F ≈ transpose(Fill(2, 3, mA) * A)\n            F = Fill(2, la, 3)\n            FS = Fill(2, (Base.OneTo(la), SOneTo(3)))\n            @testset for (adjf, adjT) in ((transpose, Transpose), (adjoint, Adjoint))\n                @test adjf(a) * F ≈ adjf(Fill(2, 3, la) * a)\n                @test adjf(a) * F isa adjT{<:Any, <:Fill{<:Any,1}}\n                @test adjf(a) * FS ≈ adjf(Fill(2, 3, la) * a)\n                @test axes(adjf(a) * FS, 2) == SOneTo(3)\n            end\n\n            w = zeros(mA)\n            @test mul!(w, A, Fill(2,nA), true, false) ≈ A * fill(2,nA)\n            w .= 2\n            @test mul!(w, A, Fill(2,nA), 1.0, 1.0) ≈ A * fill(2,nA) .+ 2\n\n            nW = 3\n            W = zeros(mA, nW)\n            @test mul!(W, A, Fill(2,nA,nW), true, false) ≈ A * fill(2,nA,nW)\n            W .= 2\n            @test mul!(W, A, Fill(2,nA,nW), 1.0, 1.0) ≈ A * fill(2,nA,nW) .+ 2\n\n            mW = 5\n            W = zeros(mW, nA)\n            @test mul!(W, Fill(2,mW,mA), A, true, false) ≈ fill(2,mW,mA) * A\n            W .= 2\n            @test mul!(W, Fill(2,mW,mA), A, 1.0, 1.0) ≈ fill(2,mW,mA) * A .+ 2\n\n            mw = 5\n            w = zeros(mw)\n            @test mul!(w, Fill(2,mw,la), a, true, false) ≈ fill(2,mw,la) * a\n            w .= 2\n            @test mul!(w, Fill(2,mw,la), a, 1.0, 1.0) ≈ fill(2,mw,la) * a .+ 2\n\n            @testset for f in [adjoint, transpose]\n                w = zeros(nA)\n                @test mul!(w, f(A), Fill(2,mA), true, false) ≈ f(A) * fill(2,mA)\n                w .= 2\n                @test mul!(w, f(A), Fill(2,mA), 1.0, 1.0) ≈ f(A) * fill(2,mA) .+ 2\n\n                W = zeros(nA, nW)\n                @test mul!(W, f(A), Fill(2,mA,nW), true, false) ≈ f(A) * fill(2,mA,nW)\n                W .= 2\n                @test mul!(W, f(A), Fill(2,mA,nW), 1.0, 1.0) ≈ f(A) * fill(2,mA,nW) .+ 2\n\n                W = zeros(mW, mA)\n                @test mul!(W, Fill(2,mW,nA), f(A), true, false) ≈ fill(2,mW,nA) * f(A)\n                W .= 2\n                @test mul!(W, Fill(2,mW,nA), f(A), 1.0, 1.0) ≈ fill(2,mW,nA) * f(A) .+ 2\n            end\n        end\n    end\n\n    D = Diagonal(randn(1))\n    @test Zeros(1,1)*D ≡ Zeros(1,1)\n    @test Zeros(1)*D ≡ Zeros(1,1)\n    @test D*Zeros(1,1) ≡ Zeros(1,1)\n    @test D*Zeros(1) ≡ Zeros(1)\n\n    D = Diagonal(Fill(2,10))\n    @test D * Ones(10) ≡ Fill(2.0,10)\n    @test D * Ones(10,5) ≡ Fill(2.0,10,5)\n    @test Ones(5,10) * D ≡ Fill(2.0,5,10)\n\n    # following test is broken in Base as of Julia v1.5\n    @test_throws DimensionMismatch Diagonal(Fill(1,1)) * Ones(10)\n    @test_throws DimensionMismatch Diagonal(Fill(1,1)) * Ones(10,5)\n    @test_throws DimensionMismatch Ones(5,10) * Diagonal(Fill(1,1))\n\n    E = Eye(5)\n    @test E*(1:5) ≡ 1.0:5.0\n    @test (1:5)'E == (1.0:5)'\n    @test E*E ≡ E\n\n    n  = 10\n    k  = 12\n    m  = 15\n    for T in (Float64, ComplexF64)\n        Ank  = rand(T, n, k)\n        Akn = rand(T, k, n)\n        Ak = rand(T, k)\n        onesm = ones(m)\n        zerosm = zeros(m)\n\n        fv = T == Float64 ? T(1.6) : T(1.6, 1.3)\n\n        for (fillvec, fillmat) in ((Fill(fv, k), Fill(fv, k, m)),\n                                    (Ones(T, k), Ones(T, k, m)),\n                                    (Zeros(T, k), Zeros(T, k, m)))\n\n            Afillvec = Array(fillvec)\n            Afillmat = Array(fillmat)\n            @test Ank * fillvec ≈ Ank * Afillvec\n            @test Ank * fillmat ≈ Ank * Afillmat\n\n            for A  in (Akn, Ak)\n                @test transpose(A)*fillvec ≈ transpose(A)*Afillvec\n                AtF = transpose(A)*fillmat\n                AtM = transpose(A)*Afillmat\n                @test AtF ≈ AtM\n                @test AtF * Ones(m) ≈ AtM * onesm\n                @test AtF * Zeros(m) ≈ AtM * zerosm\n                @test adjoint(A)*fillvec ≈ adjoint(A)*Afillvec\n                AadjF = adjoint(A)*fillmat\n                AadjM = adjoint(A)*Afillmat\n                @test AadjF ≈ AadjM\n                @test AadjF * Ones(m) ≈ AadjM * onesm\n                @test AadjF * Zeros(m) ≈ AadjM * zerosm\n            end\n        end\n\n        # inplace C = F * A' * alpha + C * beta\n        F = Fill(fv, m, k)\n        M = Array(F)\n        C = rand(T, m, n)\n        @testset for f in (adjoint, transpose)\n            @test mul!(copy(C), F, f(Ank)) ≈ mul!(copy(C), M, f(Ank))\n            @test mul!(copy(C), F, f(Ank), 1.0, 2.0) ≈ mul!(copy(C), M, f(Ank), 1.0, 2.0)\n        end\n    end\n\n    @testset \"non-commutative\" begin\n        A = Fill(quat(rand(4)...), 2, 2)\n        M = Array(A)\n        α, β = quat(0,1,1,0), quat(1,0,0,1)\n        @testset \"matvec\" begin\n            f = Fill(quat(rand(4)...), size(A,2))\n            v = Array(f)\n            D = copy(v)\n            exp_res = M * v * α + D * β\n            @test mul!(copy(D), A, f, α, β) ≈ mul!(copy(D), M, v, α, β) ≈ exp_res\n            @test mul!(copy(D), M, f, α, β) ≈ mul!(copy(D), M, v, α, β) ≈ exp_res\n            @test mul!(copy(D), A, v, α, β) ≈ mul!(copy(D), M, v, α, β) ≈ exp_res\n\n            @test mul!(copy(D), M', f, α, β) ≈ mul!(copy(D), M', v, α, β) ≈ M' * v * α + D * β\n            @test mul!(copy(D), transpose(M), f, α, β) ≈ mul!(copy(D), transpose(M), v, α, β) ≈ transpose(M) * v * α + D * β\n        end\n\n        @testset \"matmat\" begin\n            B = Fill(quat(rand(4)...), 2, 2)\n            N = Array(B)\n            D = copy(N)\n            exp_res = M * N * α + D * β\n            @test mul!(copy(D), A, B, α, β) ≈ mul!(copy(D), M, N, α, β) ≈ exp_res\n            @test mul!(copy(D), M, B, α, β) ≈ mul!(copy(D), M, N, α, β) ≈ exp_res\n            @test mul!(copy(D), A, N, α, β) ≈ mul!(copy(D), M, N, α, β) ≈ exp_res\n\n            @test mul!(copy(D), M', B, α, β) ≈ mul!(copy(D), M', N, α, β) ≈ M' * N * α + D * β\n            @test mul!(copy(D), transpose(M), B, α, β) ≈ mul!(copy(D), transpose(M), N, α, β) ≈ transpose(M) * N * α + D * β\n\n            @test mul!(copy(D), A, N', α, β) ≈ mul!(copy(D), M, N', α, β) ≈ M * N' * α + D * β\n            @test mul!(copy(D), A, transpose(N), α, β) ≈ mul!(copy(D), M, transpose(N), α, β) ≈ M * transpose(N) * α + D * β\n        end\n    end\n\n    @testset \"ambiguities\" begin\n        UT33 = UpperTriangular(ones(3,3))\n        UT11 = UpperTriangular(ones(1,1))\n        @test transpose(Zeros(3)) * Transpose(Adjoint([1,2,3])) == 0\n        @test Zeros(3)' * Adjoint(Transpose([1,2,3])) == 0\n        @test Zeros(3)' * UT33 == Zeros(3)'\n        @test transpose(Zeros(3)) * UT33 == transpose(Zeros(3))\n        @test UT11 * Zeros(3)' == Zeros(1,3)\n        @test UT11 * transpose(Zeros(3)) == Zeros(1,3)\n        @test Zeros(2,3) * UT33 == Zeros(2,3)\n        @test UT33 * Zeros(3,2) == Zeros(3,2)\n        @test UT33 * Zeros(3) == Zeros(3)\n        @test Diagonal([1]) * transpose(Zeros(3)) == Zeros(1,3)\n        @test Diagonal([1]) * Zeros(3)' == Zeros(1,3)\n    end\nend\n\n@testset \"count\" begin\n    @test count(Ones{Bool}(10)) == count(Fill(true,10)) == 10\n    @test count(Zeros{Bool}(10)) == count(Fill(false,10)) == 0\n    @test count(x -> 1 ≤ x < 2, Fill(1.3,10)) == 10\n    @test count(x -> 1 ≤ x < 2, Fill(2.0,10)) == 0\nend\n\n@testset \"norm\" begin\n    for a in (Zeros{Int}(5), Zeros(5,3), Zeros(2,3,3), Zeros{ComplexF32}(5),\n                Ones{Int}(5), Ones(5,3), Ones(2,3,3), Ones{ComplexF32}(5),\n                Fill(2.3,5), Fill([2.3,4.2],5), Fill(4), Fill(2f0+3f0im,5)),\n        p in (-Inf, 0, 0.1, 1, 2, 3, Inf)\n        @test @inferred(norm(a,p)) ≈ norm(Array(a),p)\n        @test typeof(norm(a,p)) == typeof(norm(Array(a),p))\n    end\nend\n\n@testset \"kron\" begin\n    for T in (Fill, Zeros, Ones), sz in ((2,), (2,2))\n        f = T{Int}((T == Fill ? (3,sz...) : sz)...)\n        g = Ones{Int}(2)\n        z = Zeros{Int}(2)\n        fc = collect(f)\n        gc = collect(g)\n        zc = collect(z)\n        @test kron(f, f) == kron(fc, fc)\n        @test kron(f, f) isa T{Int,length(sz)}\n        @test kron(f, g) == kron(fc, gc)\n        @test kron(f, g) isa AbstractFill{Int,length(sz)}\n        @test kron(g, f) == kron(gc, fc)\n        @test kron(g, f) isa AbstractFill{Int,length(sz)}\n        @test kron(f, z) == kron(fc, zc)\n        @test kron(f, z) isa AbstractFill{Int,length(sz)}\n        @test kron(z, f) == kron(zc, fc)\n        @test kron(z, f) isa AbstractFill{Int,length(sz)}\n        @test kron(f, f .+ 0.5) == kron(fc, fc .+ 0.5)\n        @test kron(f, f .+ 0.5) isa AbstractFill{Float64,length(sz)}\n        @test kron(f, g .+ 0.5) isa AbstractFill{Float64,length(sz)}\n    end\n\n    for m in (Fill(2,2,2), \"a\"), sz in ((2,2), (2,))\n        f = Fill(m, sz)\n        g = fill(m, sz)\n        @test kron(f, f) == kron(g, g)\n    end\n\n    @test_throws MethodError kron(Fill(\"a\",2), Zeros(1)) # can't multiply String and Float64\n\n    E = Eye(2)\n    K = kron(E, E)\n    @test K isa Diagonal\n    @test K isa typeof(E)\n    C = collect(E)\n    @test K == kron(C, C)\n\n    E = Eye(2,3)\n    K = kron(E, E)\n    C = collect(E)\n    @test K == kron(C, C)\n    @test issparse(kron(E,E))\n\n    E = RectDiagonal(Fill(4,3), (6,3))\n    C = collect(E)\n    K = kron(E, E)\n    @test K == kron(C, C)\n    @test issparse(K)\nend\n\n@testset \"dot products\" begin\n    n = 15\n    o = Ones(1:n)\n    z = Zeros(1:n)\n    D = Diagonal(o)\n    Z = Diagonal(z)\n\n    Random.seed!(5)\n    u = rand(n)\n    v = rand(n)\n    c = rand(ComplexF16, n)\n\n    @test dot(u, D, v) == dot(u, v)\n    @test dot(u, 2D, v) == 2dot(u, v)\n    @test dot(u, Z, v) == 0\n\n    @test @inferred(dot(Zeros(5), Zeros{ComplexF16}(5))) ≡ zero(ComplexF64)\n    @test @inferred(dot(Zeros(5), Ones{ComplexF16}(5))) ≡ zero(ComplexF64)\n    @test abs(@inferred(dot(Ones{ComplexF16}(5), Zeros(5)))) ≡ abs(@inferred(dot(randn(5), Zeros{ComplexF16}(5)))) ≡ abs(@inferred(dot(Zeros{ComplexF16}(5), randn(5)))) ≡ zero(Float64) # 0.0 !≡ -0.0\n    @test @inferred(dot(c, Fill(1 + im, 15))) ≡ (@inferred(dot(Fill(1 + im, 15), c)))' ≈ @inferred(dot(c, fill(1 + im, 15)))\n\n    @test @inferred(dot(Fill(1,5), Fill(2.0,5))) ≡ 10.0\n    @test_skip dot(Fill(true,5), Fill(Int8(1),5)) isa Int8 # not working at present\n\n    let N = 2^big(1000) # fast dot for fast sum\n        @test dot(Fill(2,N),1:N) == dot(Fill(2,N),1:N) == dot(1:N,Fill(2,N)) == 2*sum(1:N)\n    end\n\n    @test dot(1:4, Eye(4), 1:4) === dot(1:4, oneunit(eltype(Eye(4))) * I(4), 1:4)\n\n    @test_throws DimensionMismatch dot(u[1:end-1], D, v)\n    @test_throws DimensionMismatch dot(u[1:end-1], D, v[1:end-1])\n\n    @test_throws DimensionMismatch dot(u, 2D, v[1:end-1])\n    @test_throws DimensionMismatch dot(u, 2D, v[1:end-1])\n\n    @test_throws DimensionMismatch dot(u, Z, v[1:end-1])\n    @test_throws DimensionMismatch dot(u, Z, v[1:end-1])\n\n    @test_throws DimensionMismatch dot(Zeros(5), Zeros(6))\n    @test_throws DimensionMismatch dot(Zeros(5), randn(6))\nend\n\n@testset \"print\" begin\n    # 3-arg show, full printing\n    @test stringmime(\"text/plain\", Zeros(3)) == \"3-element Zeros{Float64}\"\n    @test stringmime(\"text/plain\", Ones(3)) == \"3-element Ones{Float64}\"\n    @test stringmime(\"text/plain\", Fill(7,2)) == \"2-element Fill{$Int}, with entries equal to 7\"\n    @test stringmime(\"text/plain\", Zeros(3,2)) == \"3×2 Zeros{Float64}\"\n    @test stringmime(\"text/plain\", Ones(3,2)) == \"3×2 Ones{Float64}\"\n    @test stringmime(\"text/plain\", Fill(7,2,3)) == \"2×3 Fill{$Int}, with entries equal to 7\"\n    @test stringmime(\"text/plain\", Fill(8.0,1)) == \"1-element Fill{Float64}, with entry equal to 8.0\"\n    @test stringmime(\"text/plain\", Eye(5)) == \"5×5 Eye{Float64}\"\n    # used downstream in LazyArrays.jl to deduce sparsity\n    @test Base.replace_in_print_matrix(Zeros(5,3), 1, 2, \"0.0\") == \" ⋅ \"\n\n    # 2-arg show, compact printing\n    @test repr(Zeros{Int}()) == \"Zeros{$Int}()\"\n    @test repr(Zeros{Int}(3)) == \"Zeros{$Int}(3)\"\n    @test repr(Zeros(3)) == \"Zeros(3)\"\n    @test repr(Ones{Int}(3)) == \"Ones{$Int}(3)\"\n    @test repr(Ones{Int}(3,2)) == \"Ones{$Int}(3, 2)\"\n    @test repr(Ones(3,2)) == \"Ones(3, 2)\"\n    @test repr(Fill(7,3,2)) == \"Fill(7, 3, 2)\"\n    @test repr(Fill(1f0,10)) == \"Fill(1.0f0, 10)\"  # Float32!\n    @test repr(Fill(0)) == \"Fill(0)\"\n    @test repr(Eye(9)) == \"Eye(9)\"\n    @test repr(Eye(9,4)) == \"Eye(9,4)\"\n    # also used for arrays of arrays:\n    @test occursin(\"Eye(2) \", stringmime(\"text/plain\", [Eye(2) for i in 1:2, j in 1:2]))\nend\n\n@testset \"reshape\" begin\n    @test reshape(Fill(2,6),2,3) ≡ reshape(Fill(2,6),(2,3)) ≡ reshape(Fill(2,6),:,3) ≡ reshape(Fill(2,6),2,:) ≡ Fill(2,2,3)\n    @test reshape(Fill(2,6),big(2),3) == reshape(Fill(2,6), (big(2),3)) == reshape(Fill(2,6), big(2),:) == Fill(2,big(2),3)\n    @test_throws DimensionMismatch reshape(Fill(2,6),2,4)\n    @test reshape(Ones(6),2,3) ≡ reshape(Ones(6),(2,3)) ≡ reshape(Ones(6),:,3) ≡ reshape(Ones(6),2,:) ≡ Ones(2,3)\n    @test reshape(Zeros(6),2,3) ≡ Zeros(2,3)\n    @test reshape(Zeros(6),big(2),3) == Zeros(big(2),3)\n    @test reshape(Fill(2,2,3),Val(1)) ≡ Fill(2,6)\n    @test reshape(Fill(2, 2), (2, )) ≡ Fill(2, 2)\n\n    @test reshape(Fill(2,3), :) === reshape(Fill(2,3), (:,)) === Fill(2,3)\nend\n\n@testset \"lmul!/rmul!\" begin\n    z = Zeros(1_000_000_000_000)\n    @test lmul!(2.0,z) === z\n    @test rmul!(z,2.0) === z\n    @test_throws ArgumentError lmul!(Inf,z)\n    @test_throws ArgumentError rmul!(z,Inf)\n\n    x = Fill([1,2],1_000_000_000_000)\n    @test lmul!(1.0,x) === x\n    @test rmul!(x,1.0) === x\n    @test_throws ArgumentError lmul!(2.0,x)\n    @test_throws ArgumentError rmul!(x,2.0)\nend\n\n@testset \"Modified\" begin\n    @testset \"Diagonal{<:Fill}\" begin\n        D = Diagonal(Fill(Fill(0.5,2,2),10))\n        @test @inferred(D[1,1]) === Fill(0.5,2,2)\n        @test @inferred(D[1,2]) === Fill(0.0,2,2)\n        @test axes(D) == (Base.OneTo(10),Base.OneTo(10))\n        D = Diagonal(Fill(Zeros(2,2),10))\n        @test @inferred(D[1,1]) === Zeros(2,2)\n        @test @inferred(D[1,2]) === Zeros(2,2)\n        D = Diagonal([Zeros(1,1), Zeros(2,2)])\n        @test @inferred(D[1,1]) === Zeros(1,1)\n        @test @inferred(D[1,2]) === Zeros(1,2)\n\n        @test_throws ArgumentError Diagonal(Fill(Ones(2,2),10))[1,2]\n    end\n    @testset \"Triangular\" begin\n        U = UpperTriangular(Ones(3,3))\n        @test U == UpperTriangular(ones(3,3))\n        @test axes(U) == (Base.OneTo(3),Base.OneTo(3))\n    end\nend\n\n@testset \"Trues\" begin\n    @test Trues(2,3) == Trues((2,3)) == trues(2,3)\n    @test Falses(2,3) == Falses((2,3)) == falses(2,3)\n    dim = (4,5)\n    mask = Trues(dim)\n    x = randn(dim)\n    @test x[mask] == vec(x) # getindex\n    y = similar(x)\n    y[mask] = x # setindex!\n    @test y == x\n    @test_throws BoundsError ones(3)[Trues(2)]\n    @test_throws BoundsError setindex!(ones(3), zeros(3), Trues(2))\n    @test_throws DimensionMismatch setindex!(ones(2), zeros(3), Trues(2))\n    @test Ones(3)[Trues(3)] == Ones(3)\n    @test_throws BoundsError Ones(3)[Trues(2)]\n    @test Ones(2,3)[Trues(2,3)] == Ones(6)\n    @test Ones(2,3)[Trues(6)] == Ones(6)\n    @test_throws BoundsError Ones(2,3)[Trues(3,2)]\nend\n\n@testset \"FillArray interface\" begin\n    @testset \"SubArray\" begin\n        a = Fill(2.0,5)\n        v = SubArray(a,(1:2,))\n        @test FillArrays.getindex_value(v) == FillArrays.unique_value(v) == 2.0\n        @test convert(Fill, v) ≡ Fill(2.0,2)\n    end\n\n    @testset \"views\" begin\n        a = Fill(2.0,5)\n        v = view(a,1:2)\n        @test v isa Fill\n        @test FillArrays.getindex_value(v) == FillArrays.unique_value(v) == 2.0\n        @test convert(Fill, v) ≡ Fill(2.0,2)\n        @test view(a,1) ≡ Fill(2.0)\n        @test view(a,1,1) ≡ Fill(2.0)\n        @test view(a, :) === a\n        @test view(a, CartesianIndices(a)) === a\n        vv = view(a, CartesianIndices(a), :, 1)\n        @test ndims(vv) == 2\n        @test vv isa Fill && FillArrays.getindex_value(vv) == 2.0\n        vv = view(a, CartesianIndices(a), :, 1:1)\n        @test ndims(vv) == 3\n        @test vv isa Fill && FillArrays.getindex_value(vv) == 2.0\n    end\n\n    @testset \"view with bool\" begin\n        a = Fill(2.0,5)\n        @test a[[true,false,false,true,false]] ≡ view(a,[true,false,false,true,false])\n        a = Fill(2.0,2,2)\n        @test a[[true false; false true]] ≡ view(a, [true false; false true])\n    end\n\n    @testset \"adjtrans\" begin\n        a = Fill(2.0+im, 5)\n        @test FillArrays.getindex_value(a') == FillArrays.unique_value(a') == 2.0 - im\n        @test convert(Fill, a') ≡ Fill(2.0-im,1,5)\n        @test FillArrays.getindex_value(transpose(a)) == FillArrays.unique_value(transpose(a)) == 2.0 + im\n        @test convert(Fill, transpose(a)) ≡ Fill(2.0+im,1,5)\n    end\n\n    @testset \"custom AbstractFill types\" begin\n        # implicit axes\n        struct StaticZerosVec{L,T} <: FillArrays.AbstractZeros{T,1,Tuple{SOneTo{L}}} end\n        Base.size(::StaticZerosVec{L}) where {L} = (L,)\n        Base.axes(::StaticZerosVec{L}) where {L} = (SOneTo(L),)\n        S = StaticZerosVec{3,Int}()\n        @test real.(S) == S\n        @test imag.(S) == S\n\n        struct StaticOnesVec{L,T} <: FillArrays.AbstractOnes{T,1,Tuple{SOneTo{L}}} end\n        Base.size(::StaticOnesVec{L}) where {L} = (L,)\n        Base.axes(::StaticOnesVec{L}) where {L} = (SOneTo(L),)\n        S = StaticOnesVec{3,Int}()\n        @test real.(S) == S\n        @test imag.(S) == zero(S)\n\n        struct StaticFill{S1,S2,T} <: FillArrays.AbstractFill{T,2,Tuple{SOneTo{S1},SOneTo{S2}}}\n            x :: T\n        end\n        StaticFill{S1,S2}(x::T) where {S1,S2,T} = StaticFill{S1,S2,T}(x)\n        Base.size(::StaticFill{S1,S2}) where {S1,S2} = (S1,S2)\n        Base.axes(::StaticFill{S1,S2}) where {S1,S2} = (SOneTo(S1), SOneTo(S2))\n        FillArrays.getindex_value(S::StaticFill) = S.x\n        S = StaticFill{2,3}(2)\n        @test permutedims(S) == Fill(2, reverse(size(S)))\n    end\nend\n\n@testset \"Statistics\" begin\n    @test mean(Fill(3,4,5)) === mean(fill(3,4,5))\n    @test std(Fill(3,4,5)) === std(fill(3,4,5))\n    @test var(Trues(5)) === var(trues(5))\n    @test mean(Trues(5)) === mean(trues(5))\n\n    @test mean(sqrt, Fill(3,4,5)) ≈ mean(sqrt, fill(3,4,5))\n\n    @test mean(Fill(3,4,5), dims=2) == mean(fill(3,4,5), dims=2)\n    @test std(Fill(3,4,5), corrected=true, mean=3) == std(fill(3,4,5), corrected=true, mean=3)\n\n    @test cov(Fill(3,4)) === cov(fill(3,4))\n    @test cov(Fill(3,4,5)) == cov(fill(3,4,5))\n    @test cov(Fill(3,4,5), dims=2) == cov(fill(3,4,5), dims=2)\n\n    @test cor(Fill(3,4)) == cor(fill(3,4))\n    @test cor(Fill(3, 4, 5)) ≈ cor(fill(3, 4, 5)) nans=true\n    @test cor(Fill(3, 4, 5), dims=2) ≈ cor(fill(3, 4, 5), dims=2) nans=true\nend\n\n@testset \"Structured broadcast\" begin\n    D = Diagonal(1:5)\n    @test D + Zeros(5,5) isa Diagonal\n    @test D - Zeros(5,5) isa Diagonal\n    @test D .+ Zeros(5,5) isa Diagonal\n    @test D .- Zeros(5,5) isa Diagonal\n    @test D .* Zeros(5,5) isa Diagonal\n    @test Zeros(5,5) .* D isa Diagonal\n    @test Zeros(5,5) - D isa Diagonal\n    @test Zeros(5,5) + D isa Diagonal\n    @test Zeros(5,5) .- D isa Diagonal\n    @test Zeros(5,5) .+ D isa Diagonal\n    f = (x,y) -> x+1\n    @test f.(D, Zeros(5,5)) isa Matrix\nend\n\n@testset \"OneElement\" begin\n    A = OneElement(2, (), ())\n    @test FillArrays.nzind(A) == CartesianIndex()\n    @test A == Fill(2, ())\n    @test A[] === 2\n    @test A[1] === A[1,1] === 2\n\n    e₁ = OneElement(2, 5)\n    @test e₁ == [0,1,0,0,0]\n    @test FillArrays.nzind(e₁) == CartesianIndex(2)\n    @test e₁[2] === e₁[2,1] === e₁[2,1,1] === 1\n    @test_throws BoundsError e₁[6]\n    @test -e₁ === OneElement(-1, 2, 5)\n\n    f₁ = AbstractArray{Float64}(e₁)\n    @test f₁ isa OneElement{Float64,1}\n    @test f₁ == e₁\n    fv₁ = AbstractVector{Float64}(e₁)\n    @test fv₁ isa OneElement{Float64,1}\n    @test fv₁ == e₁\n\n    @test stringmime(\"text/plain\", e₁) == \"5-element OneElement{$Int, 1, Tuple{$Int}, Tuple{Base.OneTo{$Int}}}:\\n ⋅\\n 1\\n ⋅\\n ⋅\\n ⋅\"\n\n    e₁ = OneElement{Float64}(2, 5)\n    @test e₁ == [0,1,0,0,0]\n\n    v = OneElement{Float64}(2, 3, 4)\n    @test v == [0,0,2,0]\n\n    V = OneElement(2, (2,3), (3,4))\n    @test V == [0 0 0 0; 0 0 2 0; 0 0 0 0]\n    @test FillArrays.nzind(V) == CartesianIndex(2,3)\n    @test -V == OneElement(-2, (2,3), (3,4))\n\n    Vf = AbstractArray{Float64}(V)\n    @test Vf isa OneElement{Float64,2}\n    @test Vf == V\n    VMf = AbstractMatrix{Float64}(V)\n    @test VMf isa OneElement{Float64,2}\n    @test VMf == V\n\n    @test stringmime(\"text/plain\", V) == \"3×4 OneElement{$Int, 2, Tuple{$Int, $Int}, Tuple{Base.OneTo{$Int}, Base.OneTo{$Int}}}:\\n ⋅  ⋅  ⋅  ⋅\\n ⋅  ⋅  2  ⋅\\n ⋅  ⋅  ⋅  ⋅\"\n\n    @test Base.setindex(Zeros(5), 2, 2) ≡ OneElement(2.0, 2, 5)\n    @test Base.setindex(Zeros(5,3), 2, 2, 3) ≡ OneElement(2.0, (2,3), (5,3))\n    @test_throws BoundsError Base.setindex(Zeros(5), 2, 6)\n\n    @testset \"non-numeric\" begin\n        S = SMatrix{2,2}(1:4)\n        A = OneElement(S, (2,2), (2,2))\n        @test A[2,2] === S\n        @test A[1,1] === A[1,2] === A[2,1] === zero(S)\n    end\n\n    @testset \"Vector indexing\" begin\n        @testset \"1D\" begin\n            A = OneElement(2, 2, 4)\n            @test @inferred(A[:]) === @inferred(A[axes(A)...]) === A\n            @test @inferred(A[3:4]) isa OneElement{Int,1}\n            @test @inferred(A[3:4]) == Zeros(2)\n            @test @inferred(A[1:2]) === OneElement(2, 2, 2)\n            @test @inferred(A[2:3]) === OneElement(2, 1, 2)\n            @test @inferred(A[Base.IdentityUnitRange(2:3)]) isa OneElement{Int,1}\n            @test @inferred(A[Base.IdentityUnitRange(2:3)]) == OneElement(2,(2,),(Base.IdentityUnitRange(2:3),))\n            @test A[:,:] == reshape(A, size(A)..., 1)\n\n            @test A[reverse(axes(A,1))] == A[collect(reverse(axes(A,1)))]\n\n            @testset \"repeated indices\" begin\n                @test A[StepRangeLen(2, 0, 3)] == A[fill(2, 3)]\n            end\n\n            B = OneElement(2, (2,), (Base.IdentityUnitRange(-1:4),))\n            @test @inferred(A[:]) === @inferred(A[axes(A)...]) === A\n            @test @inferred(A[3:4]) isa OneElement{Int,1}\n            @test @inferred(A[3:4]) == Zeros(2)\n            @test @inferred(A[2:3]) === OneElement(2, 1, 2)\n\n            C = OneElement(2, (2,), (Base.OneTo(big(4)),))\n            @test @inferred(C[1:4]) === OneElement(2, 2, 4)\n\n            D = OneElement(2, (2,), (InfiniteArrays.OneToInf(),))\n            D2 = D[:]\n            @test axes(D2) == axes(D)\n            @test D2[2] == D[2]\n            D3 = D[axes(D)...]\n            @test axes(D3) == axes(D)\n            @test D3[2] == D[2]\n        end\n        @testset \"2D\" begin\n            A = OneElement(2, (2,3), (4,5))\n            @test @inferred(A[:,:]) === @inferred(A[axes(A)...]) === A\n            @test @inferred(A[:,1]) isa OneElement{Int,1}\n            @test @inferred(A[:,1]) == Zeros(4)\n            @test A[:, Int64(1)] === A[:, Int32(1)]\n            @test @inferred(A[1,:]) isa OneElement{Int,1}\n            @test @inferred(A[1,:]) == Zeros(5)\n            @test @inferred(A[:,3]) === OneElement(2, 2, 4)\n            @test @inferred(A[2,:]) === OneElement(2, 3, 5)\n            @test @inferred(A[1:1,:]) isa OneElement{Int,2}\n            @test @inferred(A[1:1,:]) == Zeros(1,5)\n            @test @inferred(A[4:4,:]) isa OneElement{Int,2}\n            @test @inferred(A[4:4,:]) == Zeros(1,5)\n            @test @inferred(A[2:2,:]) === OneElement(2, (1,3), (1,5))\n            @test @inferred(A[1:4,:]) === OneElement(2, (2,3), (4,5))\n            @test @inferred(A[:,3:3]) === OneElement(2, (2,1), (4,1))\n            @test @inferred(A[:,1:5]) === OneElement(2, (2,3), (4,5))\n            @test @inferred(A[1:4,1:4]) === OneElement(2, (2,3), (4,4))\n            @test @inferred(A[2:4,2:4]) === OneElement(2, (1,2), (3,3))\n            @test @inferred(A[2:4,3:4]) === OneElement(2, (1,1), (3,2))\n            @test @inferred(A[4:4,5:5]) isa OneElement{Int,2}\n            @test @inferred(A[4:4,5:5]) == Zeros(1,1)\n            @test @inferred(A[Base.IdentityUnitRange(2:4), :]) isa OneElement{Int,2}\n            @test axes(A[Base.IdentityUnitRange(2:4), :]) == (Base.IdentityUnitRange(2:4), axes(A,2))\n            @test @inferred(A[:,:,:]) == reshape(A, size(A)...,1)\n\n            B = OneElement(2, (2,3), (Base.IdentityUnitRange(2:4),Base.IdentityUnitRange(2:5)))\n            @test @inferred(B[:,:]) === @inferred(B[axes(B)...])  === B\n            @test @inferred(B[:,3]) === OneElement(2, (2,), (Base.IdentityUnitRange(2:4),))\n            @test @inferred(B[3:4, 4:5]) isa OneElement{Int,2}\n            @test @inferred(B[3:4, 4:5]) == Zeros(2,2)\n            b = @inferred(B[Base.IdentityUnitRange(3:4), Base.IdentityUnitRange(4:5)])\n            @test b == Zeros(axes(b))\n\n            C = OneElement(2, (2,3), (Base.OneTo(big(4)), Base.OneTo(big(5))))\n            @test @inferred(C[1:4, 1:5]) === OneElement(2, (2,3), Int.(size(C)))\n\n            D = OneElement(2, (2,3), (InfiniteArrays.OneToInf(), InfiniteArrays.OneToInf()))\n            D2 = @inferred D[:,:]\n            @test axes(D2) == axes(D)\n            @test D2[2,3] == D[2,3]\n            D3 = @inferred D[axes(D)...]\n            @test axes(D3) == axes(D)\n            @test D3[2,3] == D[2,3]\n        end\n    end\n\n    @testset \"adjoint/transpose\" begin\n        A = OneElement(3im, (2,4), (4,6))\n        @test A' === OneElement(-3im, (4,2), (6,4))\n        @test transpose(A) === OneElement(3im, (4,2), (6,4))\n\n        A = OneElement(3im, 2, 3)\n        @test A' isa Adjoint\n        @test transpose(A) isa Transpose\n        @test A' == OneElement(-3im, (1,2), (1,3))\n        @test transpose(A) == OneElement(3im, (1,2), (1,3))\n\n        A = OneElement(3, (2,2), (4,4))\n        @test adjoint(A) === A\n        @test transpose(A) === A\n\n        A = OneElement(3, 2, 4)\n        @test transpose(A) isa Transpose\n        @test adjoint(A) isa Adjoint\n        @test transpose(A) == OneElement(3, (1,2), (1,4))\n        @test adjoint(A) == OneElement(3, (1,2), (1,4))\n    end\n\n    @testset \"reshape\" begin\n        for O in (OneElement(2, (2,3), (4,5)), OneElement(2, (2,), (20,)),\n                    OneElement(2, (1,2,2), (2,2,5)))\n            A = Array(O)\n            for shp in ((2,5,2), (5,1,4), (20,), (2,2,5,1,1))\n                @test reshape(O, shp) == reshape(A, shp)\n            end\n        end\n        O = OneElement(2, (), ())\n        @test reshape(O, ()) === O\n\n        O = OneElement(5, 3)\n        @test reshape(O, 1, 3) == reshape(Array(O), 1, 3)\n        @test reshape(reshape(O, 1, 3), 3) == O\n    end\n\n    @testset \"isassigned\" begin\n        f = OneElement(2, (3,3), (4,4))\n        @test !isassigned(f, 0, 0)\n        @test isassigned(f, 2, 2)\n        @test !isassigned(f, 10, 10)\n        @test_throws ArgumentError isassigned(f, true)\n    end\n\n    @testset \"matmul\" begin\n        A = reshape(Float64[1:9;], 3, 3)\n        v = reshape(Float64[1:3;], 3)\n        testinds(w::AbstractArray) = testinds(size(w))\n        testinds(szw::Tuple{Int}) = (szw .- 1, szw .+ 1)\n        function testinds(szA::Tuple{Int,Int})\n            (szA .- 1, szA .+ (-1,0), szA .+ (0,-1), szA .+ 1, szA .+ (1,-1), szA .+ (-1,1))\n        end\n        # test matvec if w is a vector, or matmat if w is a matrix\n        function test_mat_mul_OneElement(A, (w, w2), sz)\n            @testset for ind in testinds(sz)\n                x = OneElement(3, ind, sz)\n                xarr = Array(x)\n                Axarr = A * xarr\n                Aadjxarr = A' * xarr\n\n                @test A * x ≈ Axarr\n                @test A' * x ≈ Aadjxarr\n                @test transpose(A) * x ≈ transpose(A) * xarr\n\n                @test mul!(w, A, x) ≈ Axarr\n                # check columnwise to ensure zero columns\n                @test all(((c1, c2),) -> c1 ≈ c2, zip(eachcol(w), eachcol(Axarr)))\n                @test mul!(w, A', x) ≈ Aadjxarr\n                w .= 1\n                @test mul!(w, A, x, 1.0, 2.0) ≈ Axarr .+ 2\n                w .= 1\n                @test mul!(w, A', x, 1.0, 2.0) ≈ Aadjxarr .+ 2\n\n                F = Fill(3, size(A))\n                w2 .= 1\n                @test mul!(w2, F, x, 1.0, 1.0) ≈ Array(F) * xarr .+ 1\n            end\n        end\n        function test_OneElementMatrix_mul_mat(A, (w, w2), sz)\n            @testset for ind in testinds(sz)\n                O = OneElement(3, ind, sz)\n                Oarr = Array(O)\n                OarrA = Oarr * A\n                OarrAadj = Oarr * A'\n\n                @test O * A ≈ OarrA\n                @test O * A' ≈ OarrAadj\n                @test O * transpose(A) ≈ Oarr * transpose(A)\n\n                @test mul!(w, O, A) ≈ OarrA\n                # check columnwise to ensure zero columns\n                @test all(((c1, c2),) -> c1 ≈ c2, zip(eachcol(w), eachcol(OarrA)))\n                @test mul!(w, O, A') ≈ OarrAadj\n                w .= 1\n                @test mul!(w, O, A, 1.0, 2.0) ≈ OarrA .+ 2\n                w .= 1\n                @test mul!(w, O, A', 1.0, 2.0) ≈ OarrAadj .+ 2\n\n                F = Fill(3, size(A))\n                w2 .= 1\n                @test mul!(w2, O, F, 1.0, 1.0) ≈ Oarr * Array(F) .+ 1\n            end\n        end\n        function test_OneElementMatrix_mul_vec(v, (w, w2), sz)\n            @testset for ind in testinds(sz)\n                O = OneElement(3, ind, sz)\n                Oarr = Array(O)\n                Oarrv = Oarr * v\n\n                @test O * v == Oarrv\n\n                @test mul!(w, O, v) == Oarrv\n                # check rowwise to ensure zero rows\n                @test all(((r1, r2),) -> r1 == r2, zip(eachrow(w), eachrow(Oarrv)))\n                w .= 1\n                @test mul!(w, O, v, 1.0, 2.0) == Oarrv .+ 2\n\n                F = Fill(3, size(v))\n                w2 .= 1\n                @test mul!(w2, O, F, 1.0, 1.0) == Oarr * Array(F) .+ 1\n            end\n        end\n        @testset \"Matrix * OneElementVector\" begin\n            w = zeros(size(A,1))\n            w2 = MVector{length(w)}(w)\n            test_mat_mul_OneElement(A, (w, w2), size(w))\n        end\n        @testset \"Matrix * OneElementMatrix\" begin\n            C = zeros(size(A))\n            C2 = MMatrix{size(C)...}(C)\n            test_mat_mul_OneElement(A, (C, C2), size(C))\n        end\n        @testset \"OneElementMatrix * Vector\" begin\n            w = zeros(size(v))\n            w2 = MVector{size(v)...}(v)\n            test_OneElementMatrix_mul_vec(v, (w, w2), size(A))\n        end\n        @testset \"OneElementMatrix * Matrix\" begin\n            C = zeros(size(A))\n            C2 = MMatrix{size(C)...}(C)\n            test_OneElementMatrix_mul_mat(A, (C, C2), size(A))\n        end\n        @testset \"OneElementMatrix * OneElement\" begin\n            @testset for ind in testinds(A)\n                O = OneElement(3, ind, size(A))\n                v = OneElement(4, ind[2], size(A,1))\n                @test O * v isa OneElement\n                @test O * v == Array(O) * Array(v)\n                @test mul!(ones(size(O,1)), O, v) == O * v\n                @test mul!(ones(size(O,1)), O, v, 2, 1) == 2 * O * v .+ 1\n\n                B = OneElement(4, ind, size(A))\n                @test O * B isa OneElement\n                @test O * B == Array(O) * Array(B)\n                @test mul!(ones(size(O,1), size(B,2)), O, B) == O * B\n                @test mul!(ones(size(O,1), size(B,2)), O, B, 2, 1) == 2 * O * B .+ 1\n            end\n\n            @test OneElement(3, (2,3), (5,4)) * OneElement(2, 2, 4) == Zeros(5)\n            @test OneElement(3, (2,3), (5,4)) * OneElement(2, (2,1), (4,2)) == Zeros(5,2)\n        end\n        @testset \"AbstractFillMatrix * OneElementVector\" begin\n            F = Fill(3, size(A))\n            sw = (size(A,1),)\n            @testset for ind in testinds(sw)\n                x = OneElement(3, ind, sw)\n                @test F * x isa Fill\n                @test F * x == Array(F) * Array(x)\n            end\n\n            @test Zeros{Int8}(2,2) * OneElement{Int16}(2,2) === Zeros{Int16}(2)\n        end\n        @testset \"OneElementMatrix * AbstractFillVector\" begin\n            @testset for ind in testinds(A)\n                O = OneElement(3, ind, size(A))\n                v = Fill(2, size(O,1))\n                @test O * v isa OneElement\n                @test O * v == Array(O) * Array(v)\n            end\n\n            A = OneElement(2,(2,2),(5,4))\n            B = Zeros(4)\n            @test A * B === Zeros(5)\n        end\n        @testset \"Diagonal and OneElementMatrix\" begin\n            for ind in ((2,3), (2,2), (10,10))\n                O = OneElement(3, ind, (4,3))\n                Oarr = Array(O)\n                C = zeros(size(O))\n                D = Diagonal(axes(O,1))\n                @test D * O == D * Oarr\n                @test mul!(C, D, O) == D * O\n                C .= 1\n                @test mul!(C, D, O, 2, 2) == 2 * D * O .+ 2\n                D = Diagonal(axes(O,2))\n                @test O * D == Oarr * D\n                @test mul!(C, O, D) == O * D\n                C .= 1\n                @test mul!(C, O, D, 2, 2) == 2 * O * D .+ 2\n            end\n        end\n        @testset \"array elements\" begin\n            A = [SMatrix{2,3}(1:6)*(i+j) for i in 1:3, j in 1:2]\n            @testset \"StridedMatrix * OneElementMatrix\" begin\n                B = OneElement(SMatrix{3,2}(1:6), (size(A,2),2), (size(A,2),4))\n                C = [SMatrix{2,2}(1:4) for i in axes(A,1), j in axes(B,2)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n            @testset \"StridedMatrix * OneElementVector\" begin\n                B = OneElement(SMatrix{3,2}(1:6), (size(A,2),), (size(A,2),))\n                C = [SMatrix{2,2}(1:4) for i in axes(A,1)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n\n            A = OneElement(SMatrix{3,2}(1:6), (3,2), (5,4))\n            @testset \"OneElementMatrix * StridedMatrix\" begin\n                B = [SMatrix{2,3}(1:6)*(i+j) for i in axes(A,2), j in 1:2]\n                C = [SMatrix{3,3}(1:9) for i in axes(A,1), j in axes(B,2)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n            @testset \"OneElementMatrix * StridedVector\" begin\n                B = [SMatrix{2,3}(1:6)*i for i in axes(A,2)]\n                C = [SMatrix{3,3}(1:9) for i in axes(A,1)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n            @testset \"OneElementMatrix * OneElementMatrix\" begin\n                B = OneElement(SMatrix{2,3}(1:6), (2,4), (size(A,2), 3))\n                C = [SMatrix{3,3}(1:9) for i in axes(A,1), j in axes(B,2)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n            @testset \"OneElementMatrix * OneElementVector\" begin\n                B = OneElement(SMatrix{2,3}(1:6), 2, size(A,2))\n                C = [SMatrix{3,3}(1:9) for i in axes(A,1)]\n                @test mul!(copy(C), A, B) == A * B\n                @test mul!(copy(C), A, B, 2, 2) == 2 * A * B + 2 * C\n            end\n        end\n        @testset \"non-commutative\" begin\n            A = OneElement(quat(rand(4)...), (2,3), (3,4))\n            for (B,C) in (\n                        # OneElementMatrix * OneElementVector\n                        (OneElement(quat(rand(4)...), 3, size(A,2)),\n                            [quat(rand(4)...) for i in axes(A,1)]),\n\n                        # OneElementMatrix * OneElementMatrix\n                        (OneElement(quat(rand(4)...), (3,2), (size(A,2), 4)),\n                            [quat(rand(4)...) for i in axes(A,1), j in 1:4]),\n                        )\n                @test mul!(copy(C), A, B) ≈ A * B\n                α, β = quat(0,0,1,0), quat(1,0,1,0)\n                @test mul!(copy(C), A, B, α, β) ≈ mul!(copy(C), A, Array(B), α, β) ≈ A * B * α + C * β\n            end\n\n            A = [quat(rand(4)...)*(i+j) for i in 1:2, j in 1:3]\n            for (B,C) in (\n                        # StridedMatrix * OneElementVector\n                        (OneElement(quat(rand(4)...), 1, size(A,2)),\n                            [quat(rand(4)...) for i in axes(A,1)]),\n\n                        # StridedMatrix * OneElementMatrix\n                        (OneElement(quat(rand(4)...), (2,2), (size(A,2), 4)),\n                            [quat(rand(4)...) for i in axes(A,1), j in 1:4]),\n                        )\n                @test mul!(copy(C), A, B) ≈ A * B\n                α, β = quat(0,0,1,0), quat(1,0,1,0)\n                @test mul!(copy(C), A, B, α, β) ≈ mul!(copy(C), A, Array(B), α, β) ≈ A * B * α + C * β\n            end\n\n            A = OneElement(quat(rand(4)...), (2,2), (3, 4))\n            for (B,C) in (\n                        # OneElementMatrix * StridedMatrix\n                        ([quat(rand(4)...) for i in axes(A,2), j in 1:3],\n                            [quat(rand(4)...) for i in axes(A,1), j in 1:3]),\n\n                        # OneElementMatrix * StridedVector\n                        ([quat(rand(4)...) for i in axes(A,2)],\n                            [quat(rand(4)...) for i in axes(A,1)]),\n                        )\n                @test mul!(copy(C), A, B) ≈ A * B\n                α, β = quat(0,0,1,0), quat(1,0,1,0)\n                @test mul!(copy(C), A, B, α, β) ≈ mul!(copy(C), A, Array(B), α, β) ≈ A * B * α + C * β\n            end\n        end\n    end\n\n    @testset \"multiplication/division by a number\" begin\n        val = 2\n        x = OneElement(val,1,5)\n        y = sparse(x)\n        @test 3x === OneElement(3val,1,5) == 3y\n        @test 3.0 * x === OneElement(3.0*val,1,5) == 3.0 * y\n        @test 3.0 \\ x === OneElement(3.0 \\ val,1,5) == 3.0 \\ y\n        @test x * 3.0 === OneElement(val * 3.0,1,5) == y * 3.0\n        @test x / 3.0 === OneElement(val / 3.0,1,5) == y / 3.0\n\n        val = 3im\n        A = OneElement(val, (2,2), (3,4))\n        B = sparse(A)\n        @test 3A === OneElement(3val, (2,2), (3,4)) == 3B\n        @test 3.0im * A === OneElement(3.0im * val, (2,2), (3,4)) == 3.0im * B\n        @test 3.0im \\ A === OneElement(3.0im \\ val, (2,2), (3,4)) == 3.0im \\ B\n        @test A * (2 + 3.0im) === OneElement(val * (2 + 3.0im), (2,2), (3,4)) == B * (2 + 3.0im)\n        @test A / (2 + 3.0im) === OneElement(val / (2 + 3.0im), (2,2), (3,4)) == B / (2 + 3.0im)\n    end\n\n\n    @testset \"isbanded\" begin\n        A = OneElement(3, (2,3), (4,5))\n        @test !isdiag(A)\n        @test istriu(A)\n        @test !istril(A)\n        @test LinearAlgebra.isbanded(A, 1, 2)\n        @test LinearAlgebra.isbanded(A, -1, 2)\n        @test !LinearAlgebra.isbanded(A, 2, 2)\n\n        A = OneElement(3, (4,2), (4,5))\n        @test !isdiag(A)\n        @test !istriu(A)\n        @test istril(A)\n        @test LinearAlgebra.isbanded(A, -2, -2)\n        @test LinearAlgebra.isbanded(A, -2, 2)\n        @test !LinearAlgebra.isbanded(A, 2, 2)\n\n        for A in (OneElement(3, (2,2), (4,5)), OneElement(3, (1,1), (1,2)), OneElement(3, (8,7), (2,1)))\n            @test isdiag(A)\n            @test istriu(A)\n            @test istril(A)\n        end\n\n        for A in (OneElement(0, (2,3), (4,5)), OneElement(0, (3,2), (4,5)))\n            @test isdiag(A)\n            @test istriu(A)\n            @test istril(A)\n        end\n    end\n\n    @testset \"zero/iszero\" begin\n        v = OneElement(10, 3, 4)\n        @test v + zero(v) == v\n        @test typeof(zero(v)) == typeof(v)\n\n        @test !iszero(v)\n        @test iszero(OneElement(0, 3, 4))\n        @test iszero(OneElement(0, 5, 4))\n        @test iszero(OneElement(3, (2,2), (0,0)))\n        @test iszero(OneElement(3, (2,2), (1,2)))\n\n        v = OneElement(SMatrix{2,2}(1:4), 3, 4)\n        @test v + zero(v) == v\n        @test typeof(zero(v)) == typeof(v)\n    end\n\n    @testset \"isone\" begin\n        @test isone(OneElement(3, (0,0), (0,0)))\n        @test isone(OneElement(1, (1,1), (1,1)))\n        @test !isone(OneElement(2, (1,1), (1,1)))\n        @test !isone(OneElement(1, (2,2), (2,2)))\n    end\n\n    @testset \"tril/triu\" begin\n        for A in (OneElement(3, (4,2), (4,5)), OneElement(3, (2,3), (4,5)), OneElement(3, (3,3), (4,5)))\n            B = Array(A)\n            for k in -5:5\n                @test tril(A, k) == tril(B, k)\n                @test triu(A, k) == triu(B, k)\n            end\n        end\n    end\n\n    @testset \"broadcasting\" begin\n        for v in (OneElement(-2, 3, 4), OneElement(2im, (1,2), (3,4)))\n            w = Array(v)\n            n = 2\n            @test abs.(v) == abs.(w)\n            @test abs2.(v) == abs2.(w)\n            @test real.(v) == real.(w)\n            @test imag.(v) == imag.(w)\n            @test conj.(v) == conj.(w)\n            @test v .^ n == w .^ n\n            @test v .* n == w .* n\n            @test v ./ n == w ./ n\n            @test n .\\ v == n .\\ w\n        end\n    end\n\n    @testset \"permutedims\" begin\n        v = OneElement(1, (2, 3), (2, 5))\n        @test permutedims(v) === OneElement(1, (3, 2), (5, 2))\n        w = OneElement(1, 3, 5)\n        @test permutedims(w) === OneElement(1, (1, 3), (1, 5))\n        x = OneElement(1, (1, 2, 3), (4, 5, 6))\n        @test permutedims(x, (1, 2, 3)) === x\n        @test permutedims(x, (3, 2, 1)) === OneElement(1, (3, 2, 1), (6, 5, 4))\n        @test permutedims(x, [2, 3, 1]) === OneElement(1, (2, 3, 1), (5, 6, 4))\n        @test_throws BoundsError permutedims(x, (2, 1))\n    end\n    @testset \"show\" begin\n        B = OneElement(2, (1, 2), (3, 4))\n        @test repr(B) == \"OneElement(2, (1, 2), (3, 4))\"\n        B = OneElement(2, 1, 3)\n        @test repr(B) == \"OneElement(2, 1, 3)\"\n        B = OneElement(2, (1, 2), (Base.IdentityUnitRange(1:1), Base.IdentityUnitRange(2:2)))\n        @test repr(B) == \"OneElement(2, (1, 2), (Base.IdentityUnitRange(1:1), Base.IdentityUnitRange(2:2)))\"\n    end\n\n    @testset \"issymmetric/ishermitian\" begin\n        for el in (2, 3+0im, 4+5im, SMatrix{2,2}(1:4), SMatrix{2,3}(1:6)), size in [(3,3), (3,4)]\n            O = OneElement(el, (2,2), size)\n            A = Array(O)\n            @test issymmetric(O) == issymmetric(A)\n            @test ishermitian(O) == ishermitian(A)\n            O = OneElement(el, (1,2), size)\n            A = Array(O)\n            @test issymmetric(O) == issymmetric(A)\n            @test ishermitian(O) == ishermitian(A)\n            O = OneElement(el, (5,5), size)\n            A = Array(O)\n            @test issymmetric(O) == issymmetric(A)\n            @test ishermitian(O) == ishermitian(A)\n        end\n    end\n\n    @testset \"unique\" begin\n        @testset for n in 1:3\n            O = OneElement(5, 2, n)\n            @test unique(O) == unique(Array(O))\n            @test allunique(O) == allunique(Array(O))\n            O = OneElement(0, 2, n)\n            @test unique(O) == unique(Array(O))\n            @test allunique(O) == allunique(Array(O))\n            @testset for m in 1:4\n                O2 = OneElement(2, (2,1), (m,n))\n                @test unique(O2) == unique(Array(O2))\n                @test allunique(O2) == allunique(Array(O2))\n                O2 = OneElement(0, (2,1), (m,n))\n                @test unique(O2) == unique(Array(O2))\n                @test allunique(O2) == allunique(Array(O2))\n            end\n        end\n    end\n\n    @testset \"sum\" begin\n        @testset \"OneElement($v, $ind, $sz)\" for (v, ind, sz) in (\n                                    (Int8(2), 3, 4),\n                                    (3.0, 5, 4),\n                                    (3.0, 0, 0),\n                                    (SMatrix{2,2}(1:4), (4, 2), (12,6)),\n                                )\n            O = OneElement(v,ind,sz)\n            A = Array(O)\n            @test @inferred(sum(O)) === sum(A)\n            @test @inferred(sum(O, init=zero(eltype(O)))) === sum(A, init=zero(eltype(O)))\n            @test @inferred(sum(x->1, O, init=0)) === sum(Fill(1, axes(O)), init=0)\n        end\n\n        @testset for O in (OneElement(Int8(2), (1,2), (2,4)),\n                    OneElement(3, (1,2,3), (2,4,4)),\n                    OneElement(2.0, (3,2,5), (2,3,2)),\n                    OneElement(SMatrix{2,2}(1:4), (1,2), (2,4)),\n                )\n            A = Array(O)\n            init = sum((zero(FillArrays.getindex_value(O)),))\n            for i in 1:3\n                @test @inferred(sum(O, dims=i)) == sum(A, dims=i)\n                @test @inferred(sum(O, dims=i, init=init)) == sum(A, dims=i, init=init)\n                @test @inferred(sum(x->1, O, dims=i, init=0)) == sum(Fill(1, axes(O)), dims=i, init=0)\n            end\n            @test @inferred(sum(O, dims=1:1)) == sum(A, dims=1:1)\n            @test @inferred(sum(O, dims=1:2)) == sum(A, dims=1:2)\n            @test @inferred(sum(O, dims=1:3)) == sum(A, dims=1:3)\n            @test @inferred(sum(O, dims=(1,))) == sum(A, dims=(1,))\n            @test @inferred(sum(O, dims=(1,2))) == sum(A, dims=(1,2))\n            @test @inferred(sum(O, dims=(1,3))) == sum(A, dims=(1,3))\n            @test @inferred(sum(O, dims=(2,3))) == sum(A, dims=(2,3))\n            @test @inferred(sum(O, dims=(1,2,3))) == sum(A, dims=(1,2,3))\n            @test @inferred(sum(O, dims=1:1, init=init)) == sum(A, dims=1:1, init=init)\n            @test @inferred(sum(O, dims=1:2, init=init)) == sum(A, dims=1:2, init=init)\n            @test @inferred(sum(O, dims=1:3, init=init)) == sum(A, dims=1:3, init=init)\n            @test @inferred(sum(O, dims=(1,), init=init)) == sum(A, dims=(1,), init=init)\n            @test @inferred(sum(O, dims=(1,2), init=init)) == sum(A, dims=(1,2), init=init)\n            @test @inferred(sum(O, dims=(1,3), init=init)) == sum(A, dims=(1,3), init=init)\n            @test @inferred(sum(O, dims=(2,3), init=init)) == sum(A, dims=(2,3), init=init)\n            @test @inferred(sum(O, dims=(1,2,3), init=init)) == sum(A, dims=(1,2,3), init=init)\n            @test @inferred(sum(x->1, O, dims=(1,2,3), init=0)) == sum(Fill(1, axes(O)), dims=(1,2,3), init=0)\n        end\n    end\n\n    @testset \"diag\" begin\n        @testset for sz in [(0,0), (0,1), (1,0), (1,1), (4,4), (4,6), (6,3)], ind in CartesianIndices(sz)\n            O = OneElement(4, Tuple(ind), sz)\n            @testset for k in -maximum(sz):maximum(sz)\n                @test diag(O, k) == diag(Array(O), k)\n                @test diag(O, k) isa OneElement{Int,1}\n            end\n        end\n    end\nend\n\n@testset \"repeat\" begin\n    @testset \"0D\" begin\n        @test repeat(Zeros()) isa Zeros\n        @test repeat(Zeros()) == repeat(zeros())\n        @test repeat(Ones()) isa Ones\n        @test repeat(Ones()) == repeat(ones())\n        @test repeat(Fill(3)) isa Fill\n        @test repeat(Fill(3)) == repeat(fill(3))\n\n        @test repeat(Zeros(), inner=(), outer=()) isa Zeros\n        @test repeat(Zeros(), inner=(), outer=()) == repeat(zeros(), inner=(), outer=())\n        @test repeat(Ones(), inner=(), outer=()) isa Ones\n        @test repeat(Ones(), inner=(), outer=()) == repeat(ones(), inner=(), outer=())\n        @test repeat(Fill(4), inner=(), outer=()) isa Fill\n        @test repeat(Fill(4), inner=(), outer=()) == repeat(fill(4), inner=(), outer=())\n\n        @test repeat(Zeros{Bool}(), 2, 3) isa Zeros{Bool}\n        @test repeat(Zeros{Bool}(), 2, 3) == repeat(zeros(Bool), 2, 3)\n        @test repeat(Ones{Bool}(), 2, 3) isa Ones{Bool}\n        @test repeat(Ones{Bool}(), 2, 3) == repeat(ones(Bool), 2, 3)\n        @test repeat(Fill(false), 2, 3) isa Fill\n        @test repeat(Fill(false), 2, 3) == repeat(fill(false), 2, 3)\n\n        @test repeat(Zeros(), inner=(2,2), outer=5) isa Zeros\n        @test repeat(Zeros(), inner=(2,2), outer=5) == repeat(zeros(), inner=(2,2), outer=5)\n        @test repeat(Ones(), inner=(2,2), outer=5) isa Ones\n        @test repeat(Ones(), inner=(2,2), outer=5) == repeat(ones(), inner=(2,2), outer=5)\n        @test repeat(Fill(2), inner=(2,2), outer=5) isa Fill\n        @test repeat(Fill(2), inner=(2,2), outer=5) == repeat(fill(2), inner=(2,2), outer=5)\n\n        @test repeat(Zeros(), inner=(2,2), outer=(2,3)) isa Zeros\n        @test repeat(Zeros(), inner=(2,2), outer=(2,3)) == repeat(zeros(), inner=(2,2), outer=(2,3))\n        @test repeat(Ones(), inner=(2,2), outer=(2,3)) isa Ones\n        @test repeat(Ones(), inner=(2,2), outer=(2,3)) == repeat(ones(), inner=(2,2), outer=(2,3))\n        @test repeat(Fill(\"a\"), inner=(2,2), outer=(2,3)) isa Fill\n        @test repeat(Fill(\"a\"), inner=(2,2), outer=(2,3)) == repeat(fill(\"a\"), inner=(2,2), outer=(2,3))\n    end\n    @testset \"1D\" begin\n        @test repeat(Zeros(2), 2, 3) isa Zeros\n        @test repeat(Zeros(2), 2, 3) == repeat(zeros(2), 2, 3)\n        @test repeat(Ones(2), 2, 3) isa Ones\n        @test repeat(Ones(2), 2, 3) == repeat(ones(2), 2, 3)\n        @test repeat(Fill(2,3), 2, 3) isa Fill\n        @test repeat(Fill(2,3), 2, 3) == repeat(fill(2,3), 2, 3)\n\n        @test repeat(Zeros(2), inner=2, outer=4) isa Zeros\n        @test repeat(Zeros(2), inner=2, outer=4) == repeat(zeros(2), inner=2, outer=4)\n        @test repeat(Ones(2), inner=2, outer=4) isa Ones\n        @test repeat(Ones(2), inner=2, outer=4) == repeat(ones(2), inner=2, outer=4)\n        @test repeat(Fill(2,3), inner=2, outer=4) isa Fill\n        @test repeat(Fill(2,3), inner=2, outer=4) == repeat(fill(2,3), inner=2, outer=4)\n\n        @test repeat(Zeros(2), inner=2, outer=(2,3)) isa Zeros\n        @test repeat(Zeros(2), inner=2, outer=(2,3)) == repeat(zeros(2), inner=2, outer=(2,3))\n        @test repeat(Ones(2), inner=2, outer=(2,3)) isa Ones\n        @test repeat(Ones(2), inner=2, outer=(2,3)) == repeat(ones(2), inner=2, outer=(2,3))\n        @test repeat(Fill(\"b\",3), inner=2, outer=(2,3)) isa Fill\n        @test repeat(Fill(\"b\",3), inner=2, outer=(2,3)) == repeat(fill(\"b\",3), inner=2, outer=(2,3))\n\n        @test repeat(Zeros(Int, 2), inner=(2,), outer=(2,3)) isa Zeros\n        @test repeat(Zeros(Int, 2), inner=(2,), outer=(2,3)) == repeat(zeros(Int, 2), inner=(2,), outer=(2,3))\n        @test repeat(Ones(Int, 2), inner=(2,), outer=(2,3)) isa Ones\n        @test repeat(Ones(Int, 2), inner=(2,), outer=(2,3)) == repeat(ones(Int, 2), inner=(2,), outer=(2,3))\n        @test repeat(Fill(2,3), inner=(2,), outer=(2,3)) isa Fill\n        @test repeat(Fill(2,3), inner=(2,), outer=(2,3)) == repeat(fill(2,3), inner=(2,), outer=(2,3))\n\n        @test repeat(Zeros(2), inner=(2,2,1,4), outer=(2,3)) isa Zeros\n        @test repeat(Zeros(2), inner=(2,2,1,4), outer=(2,3)) == repeat(zeros(2), inner=(2,2,1,4), outer=(2,3))\n        @test repeat(Ones(2), inner=(2,2,1,4), outer=(2,3)) isa Ones\n        @test repeat(Ones(2), inner=(2,2,1,4), outer=(2,3)) == repeat(ones(2), inner=(2,2,1,4), outer=(2,3))\n        @test repeat(Fill(2,3), inner=(2,2,1,4), outer=(2,3)) isa Fill\n        @test repeat(Fill(2,3), inner=(2,2,1,4), outer=(2,3)) == repeat(fill(2,3), inner=(2,2,1,4), outer=(2,3))\n\n        @test_throws ArgumentError repeat(Fill(2,3), inner=())\n        @test_throws ArgumentError repeat(Fill(2,3), outer=())\n    end\n\n    @testset \"2D\" begin\n        @test repeat(Zeros(2,3), 2, 3) isa Zeros\n        @test repeat(Zeros(2,3), 2, 3) == repeat(zeros(2,3), 2, 3)\n        @test repeat(Ones(2,3), 2, 3) isa Ones\n        @test repeat(Ones(2,3), 2, 3) == repeat(ones(2,3), 2, 3)\n        @test repeat(Fill(2,3,4), 2, 3) isa Fill\n        @test repeat(Fill(2,3,4), 2, 3) == repeat(fill(2,3,4), 2, 3)\n\n        @test repeat(Zeros(2,3), inner=(1,2), outer=(4,2)) isa Zeros\n        @test repeat(Zeros(2,3), inner=(1,2), outer=(4,2)) == repeat(zeros(2,3), inner=(1,2), outer=(4,2))\n        @test repeat(Ones(2,3), inner=(1,2), outer=(4,2)) isa Ones\n        @test repeat(Ones(2,3), inner=(1,2), outer=(4,2)) == repeat(ones(2,3), inner=(1,2), outer=(4,2))\n        @test repeat(Fill(2,3,4), inner=(1,2), outer=(4,2)) isa Fill\n        @test repeat(Fill(2,3,4), inner=(1,2), outer=(4,2)) == repeat(fill(2,3,4), inner=(1,2), outer=(4,2))\n\n        @test repeat(Zeros(2,3), inner=(2,2,1,4), outer=(2,1,3)) isa Zeros\n        @test repeat(Zeros(2,3), inner=(2,2,1,4), outer=(2,1,3)) == repeat(zeros(2,3), inner=(2,2,1,4), outer=(2,1,3))\n        @test repeat(Ones(2,3), inner=(2,2,1,4), outer=(2,1,3)) isa Ones\n        @test repeat(Ones(2,3), inner=(2,2,1,4), outer=(2,1,3)) == repeat(ones(2,3), inner=(2,2,1,4), outer=(2,1,3))\n        @test repeat(Fill(2,3,4), inner=(2,2,1,4), outer=(2,1,3)) isa Fill\n        @test repeat(Fill(2,3,4), inner=(2,2,1,4), outer=(2,1,3)) == repeat(fill(2,3,4), inner=(2,2,1,4), outer=(2,1,3))\n\n        @test_throws ArgumentError repeat(Fill(2,3,4), inner=())\n        @test_throws ArgumentError repeat(Fill(2,3,4), outer=())\n        @test_throws ArgumentError repeat(Fill(2,3,4), inner=(1,))\n        @test_throws ArgumentError repeat(Fill(2,3,4), outer=(1,))\n    end\nend\n\n@testset \"structured matrix\" begin\n    bands = ((Fill(2,3), Fill(6,2)), (Zeros(3), Zeros(2)))\n    @testset for (dv, ev) in bands\n        for D in (Diagonal(dv), Bidiagonal(dv, ev, :U),\n                    Tridiagonal(ev, dv, ev), SymTridiagonal(dv, ev))\n\n            M = Matrix(D)\n            for k in -5:5\n                @test diag(D, k) isa FillArrays.AbstractFill{eltype(D),1}\n                @test diag(D, k) == diag(M, k)\n            end\n        end\n    end\nend\n\n@testset \"ReverseDiff with Zeros\" begin\n    # MWE in https://github.com/JuliaArrays/FillArrays.jl/issues/252\n    @test ReverseDiff.gradient(x -> sum(abs2.((Zeros(5) .- zeros(5)) ./ x)), rand(5)) == zeros(5)\n    @test ReverseDiff.gradient(x -> sum(abs2.((zeros(5) .- Zeros(5)) ./ x)), rand(5)) == zeros(5)\n    # MWE in https://github.com/JuliaArrays/FillArrays.jl/pull/278\n    @test ReverseDiff.gradient(x -> sum(abs2.((Zeros{eltype(x)}(5) .- zeros(5)) ./ x)), rand(5)) == zeros(5)\n    @test ReverseDiff.gradient(x -> sum(abs2.((zeros(5) .- Zeros{eltype(x)}(5)) ./ x)), rand(5)) == zeros(5)\n\n    # Corresponding tests with +\n    @test ReverseDiff.gradient(x -> sum(abs2.((Zeros(5) .+ zeros(5)) ./ x)), rand(5)) == zeros(5)\n    @test ReverseDiff.gradient(x -> sum(abs2.((zeros(5) .+ Zeros(5)) ./ x)), rand(5)) == zeros(5)\n    @test ReverseDiff.gradient(x -> sum(abs2.((Zeros{eltype(x)}(5) .+ zeros(5)) ./ x)), rand(5)) == zeros(5)\n    @test ReverseDiff.gradient(x -> sum(abs2.((zeros(5) .+ Zeros{eltype(x)}(5)) ./ x)), rand(5)) == zeros(5)\nend\n\n@testset \"FillArraysPDMatsExt\" begin\n    for diag in (Ones(5), Fill(4.1, 8))\n        a = @inferred(AbstractPDMat(Diagonal(diag)))\n        @test a isa ScalMat\n        @test a.dim == length(diag)\n        @test a.value == first(diag)\n    end\n    a = ScalMat(4, 1.)\n    for zero in (Zeros(4), Zeros(4,4))\n        @test a * zero === zero\n    end\n    @test Zeros(4,4) * a === Zeros(4,4)\nend\n\n@testset \"isbanded/isdiag\" begin\n    @testset for A in Any[Zeros(2,3), Zeros(0,1), Zeros(1,1), Zeros(1,2),\n            Ones(0,1), Ones(1,1), Ones(3,4), Ones(0,4), Ones(7,0), Ones(7,2), Ones(2,7),\n            Fill(3, 0,1), Fill(3, 1,1), Fill(3, 2,4), Fill(0, 3, 4), Fill(2, 0, 4), Fill(2, 6, 0), Fill(0, 8, 8)]\n        B = Array(A)\n        @test isdiag(A) == isdiag(B)\n        for k in -5:5\n            @test istriu(A, k) == istriu(B, k)\n            @test istril(A, k) == istril(B, k)\n        end\n    end\nend\n\n@testset \"triu/tril for Zeros\" begin\n    Z = Zeros(3, 4)\n    @test triu(Z) === Z\n    @test tril(Z) === Z\n    @test triu(Z, 2) === Z\n    @test tril(Z, 2) === Z\nend\n\n@testset \"Diagonal conversion (#389)\" begin\n    @test convert(Diagonal{Int, Vector{Int}}, Zeros(5,5)) isa Diagonal{Int,Vector{Int}}\n    @test convert(Diagonal{Int, Vector{Int}}, Zeros(5,5)) == zeros(5,5)\n    @test Diagonal{Int}(Zeros(5,5)) ≡ Diagonal(Zeros{Int}(5))\n    @test Diagonal{Int}(Ones(5,5)) ≡ Diagonal(Ones{Int}(5))\nend\n\n@testset \"sqrt/cbrt\" begin\n    F = Fill(4, 4, 4)\n    A = Array(F)\n    @test sqrt(F) ≈ sqrt(A) rtol=3e-8\n    @test sqrt(F)^2 ≈ F\n    F = Fill(4+4im, 4, 4)\n    A = Array(F)\n    @test sqrt(F) ≈ sqrt(A) rtol=1e-8\n    @test sqrt(F)^2 ≈ F\n    F = Fill(-4, 4, 4)\n    A = Array(F)\n    if VERSION >= v\"1.11.0-rc3\"\n        @test cbrt(F) ≈ cbrt(A) rtol=1e-5\n    end\n    @test cbrt(F)^3 ≈ F\n\n    # avoid overflow\n    F = Fill(4, typemax(Int), typemax(Int))\n    @test sqrt(F)^2 ≈ F\n    @test cbrt(F)^3 ≈ F\n\n    # zeros\n    F = Zeros(4, 4)\n    A = Array(F)\n    @test sqrt(F) ≈ sqrt(A) atol=1e-14\n    @test sqrt(F)^2 == F\n    @test cbrt(F)^3 == F\nend\n"
  }
]