Changelog:
1.  Added LinmapQuant shortcut methods for "sum, maximum, minimum"
2.  More semantically correct eigenvalue decomposition
3.  `uconvert(u, q)` now works for quantities with unknown dimensions
4.  Added type macros
4.  Improved documentation


Current Tasks:
1.  Look at UnitfulLinearAlgebra, and UnitfulTensors for possible implementation improvements 
2.  Remove "eigen" for symmetric matrices
    -   This doesn't solve the eigenproblem
    -   If using PCA, on different units you generally want to use it on the correlation matrix anyway
3.  Support other functions for AbstractDimsMap and LinmapQuant like
    -   ureduce(f, A::AbstractArrayOrBroadcasted; dims=:, init=_InitialValue())
        -   Essentially checks if all values are the same, implement for same-units functions
            -   https://github.com/JuliaLang/julia/blob/5fe89b8ddc166260bfcd4a195b305aff0ccad686/base/reduce.jl#L444-L478
        -   These methods should call ureduce on a DimsMap
            -   maximum, minimum, sum, mean, std, var
        -   Prod should also have a shortcut implementation 
            -   dims=1, u_input = inv(prod(uoutput(d)) .* ufactor(d)^n) .* uinput(d).^n    
            -   mean(m, dims=n) #Should overload to "sum" for AbstractDimsMap
    -   cov(m), cor(m) #Should have special DimsMap operations

Backlog:

1.  Add plot recipes
    -   https://github.com/JuliaPlots/Plots.jl/blob/v2/PlotsBase/ext/UnitfulExt.jl
2.  Add interactive unit functionality
    -   unit_index() (produces dict that lists all units for every dimension)
    -   simplify(q::Quantity{T,AbstractDimLike}) (lists all standard SI units, performs a greedy search to make units as terse as possible)
        e.g. simplify(1.0u"(m^2*kg)/s^3") = 1 kW


#Example of #3 is shown below

julia> using FlexUnits, .UnitRegistry

julia> (x, y, z) = 1u"m/s", 1u"kg", 1u"kW"
(1.0 m/s, 1.0 kg, 1000.0 (m² kg)/s³)

julia> T = Union{typeof(x),typeof(y), typeof(z)}
Union{Quantity{Float64, StaticDims{m/s}}, Quantity{Float64, StaticDims{kg}}, Quantity{Float64, StaticDims{(m² kg)/s³}}}

julia> v = T[x,y,z]
3-element Vector{Union{Quantity{Float64, StaticDims{m/s}}, Quantity{Float64, StaticDims{kg}}, Quantity{Float64, StaticDims{(m² kg)/s³}}}}:
 1.0 m/s
 1.0 kg
 1000.0 (m² kg)/s³

julia> map(x->x*2, v)
3-element Vector{Quantity{Float64}}:
 2.0 m/s
 2.0 kg
 2000.0 (m² kg)/s³

julia> map(x->x*2, [x,y,z])
3-element Vector{Quantity{Float64, Dimensions{FixRat32}}}:
 2.0 m/s
 2.0 kg
 2000.0 (m² kg)/s³

julia> collect(map(x->x*2, (x,y,z)))
3-element Vector{Quantity{Float64}}:
 2.0 m/s
 2.0 kg
 2000.0 (m² kg)/s³

julia> vcat((map(x->x*2, (x,y,z)))...)
3-element Vector{Quantity{Float64, Dimensions{FixRat32}}}:
 2.0 m/s
 2.0 kg
 2000.0 (m² kg)/s³





#====================================================================================================
Some benchmarks
====================================================================================================#
import DynamicQuantities
import Unitful
using BenchmarkTools

v1flex = ubase.([1u"m/s", 1u"J/kg", 1u"A/V"])
v1uni  = [1*Unitful.u"m/s", 1*Unitful.u"J/kg", 1*Unitful.u"A/V"]
v1dyn  = [1*DynamicQuantities.u"m/s", 1*DynamicQuantities.u"J/kg", 1*DynamicQuantities.u"A/V"]

@btime sum(x->x^0.0, v1uni)
@btime sum(x->x^0.0, v1flex)
@btime sum(x->x^0.0, v1dyn)

t1flex = ubase.((1u"m/s", 1u"J/kg", 1u"A/V"))
t1uni  = (1*Unitful.u"m/s", 1*Unitful.u"J/kg", 1*Unitful.u"A/V")
t1dyn  = (1*DynamicQuantities.u"m/s", 1*DynamicQuantities.u"J/kg", 1*DynamicQuantities.u"A/V")

@btime sum(x->x^0, t1uni)
@btime sum(x->x^0, t1flex)
@btime sum(x->x^0, t1dyn)


