Git Product home page Git Product logo

wavelets.jl's Introduction

Wavelets

Build Status Coverage Status

A Julia package for fast wavelet transforms (1-D, 2-D, 3-D, by filtering or lifting). The package includes discrete wavelet transforms, column-wise discrete wavelet transforms, and wavelet packet transforms.

  • 1st generation wavelets using filter banks (periodic and orthogonal). Filters are included for the following types: Haar, Daubechies, Coiflet, Symmlet, Battle-Lemarie, Beylkin, Vaidyanathan.

  • 2nd generation wavelets by lifting (periodic and general type including orthogonal and biorthogonal). Included lifting schemes are currently only for Haar and Daubechies (under development). A new lifting scheme can be easily constructed by users. The current implementation of the lifting transforms is 2x faster than the filter transforms.

  • Thresholding, best basis and denoising functions, e.g. TI denoising by cycle spinning, best basis for WPT, noise estimation, matching pursuit. See example code and image below.

  • Wavelet utilities e.g. indexing and size calculation, scaling and wavelet functions computation, test functions, up and down sampling, filter mirrors, coefficient counting, inplace circshifts, and more.

  • Plotting/visualization utilities for 1-D and 2-D signals.

See license (MIT) in LICENSE.md.

Other related packages include WaveletsExt.jl and ContinuousWavelets.jl.

Usage

Install via the package manager and load with using

julia> Pkg.add("Wavelets")
julia> using Wavelets

API

Wavelet Transforms

The functions dwt and wpt (and their inverses) are linear operators. See wavelet below for construction of the type wt.

Discrete Wavelet Transform

# DWT
dwt(x, wt, L=maxtransformlevels(x))
idwt(x, wt, L=maxtransformlevels(x))
dwt!(y, x, filter, L=maxtransformlevels(x))
idwt!(y, scheme, L=maxtransformlevels(x))

Wavelet Packet Transform

# WPT (tree can also be an integer, equivalent to maketree(length(x), L, :full))
wpt(x, wt, tree::BitVector=maketree(x, :full))
iwpt(x, wt, tree::BitVector=maketree(x, :full))
wpt!(y, x, filter, tree::BitVector=maketree(x, :full))
iwpt!(y, scheme, tree::BitVector=maketree(y, :full))

Wavelet Types

The function wavelet is a type contructor for the transform functions. The transform type t can be either WT.Filter or WT.Lifting.

wavelet(c, t=WT.Filter, boundary=WT.Periodic)

Wavelet Classes

The module WT contains the types for wavelet classes. The module defines constants of the form e.g. WT.coif4 as shortcuts for WT.Coiflet{4}(). The numbers for orthogonal wavelets indicate the number vanishing moments of the wavelet function.

Class Type Namebase Supertype Numbers
Haar haar OrthoWaveletClass
Coiflet coif OrthoWaveletClass 2:2:8
Daubechies db OrthoWaveletClass 1:Inf
Symlet sym OrthoWaveletClass 4:10
Battle batt OrthoWaveletClass 2:2:6
Beylkin beyl OrthoWaveletClass
Vaidyanathan vaid OrthoWaveletClass
CDF cdf BiOrthoWaveletClass (9,7)

Class information

WT.class(::WaveletClass) ::String              # class full name
WT.name(::WaveletClass) ::String               # type short name
WT.vanishingmoments(::WaveletClass)            # vanishing moments of wavelet function

Transform type information

WT.name(wt)                                     # type short name
WT.length(f::OrthoFilter)                       # length of filter
WT.qmf(f::OrthoFilter)                          # quadrature mirror filter
WT.makeqmfpair(f::OrthoFilter, fw=true)
WT.makereverseqmfpair(f::OrthoFilter, fw=true)

Examples

The simplest way to transform a signal x is

xt = dwt(x, wavelet(WT.db2))

The transform type can be more explicitly specified (filter, Periodic, Orthogonal, 4 vanishing moments)

wt = wavelet(WT.Coiflet{4}(), WT.Filter, WT.Periodic)

For a periodic biorthogonal CDF 9/7 lifting scheme:

wt = wavelet(WT.cdf97, WT.Lifting)

Perform a transform of vector x

# 5 level transform
xt = dwt(x, wt, 5)
# inverse tranform
xti = idwt(xt, wt, 5)
# a full transform
xt = dwt(x, wt)

Other examples:

# scaling filters is easy
wt = wavelet(WT.haar)
wt = WT.scale(wt, 1/sqrt(2))
# signals can be transformed inplace with a low-level command
# requiring very little memory allocation (especially for L=1 for filters)
dwt!(x, wt, L)      # inplace (lifting)
dwt!(xt, x, wt, L)  # write to xt (filter)

# denoising with default parameters (VisuShrink hard thresholding)
x0 = testfunction(128, "HeaviSine")
x = x0 + 0.3*randn(128)
y = denoise(x)

# plotting utilities 1-d (see images and code in /example)
x = testfunction(128, "Bumps")
y = dwt(x, wavelet(WT.cdf97, WT.Lifting))
d,l = wplotdots(y, 0.1, 128)
A = wplotim(y)
# plotting utilities 2-d
img = imread("lena.png")
x = permutedims(img.data, [ndims(img.data):-1:1])
L = 2
xts = wplotim(x, L, wavelet(WT.db3))

See Bumps and Lena for plot images.

Thresholding

The Wavelets.Threshold module includes the following utilities

  • denoising (VisuShrink, translation invariant (TI))
  • best basis for WPT
  • noise estimator
  • matching pursuit
  • threshold functions (see table for types)

API

# threshold types with parameter
threshold!(x::AbstractArray, TH::THType, t::Real)
threshold(x::AbstractArray, TH::THType, t::Real)
# without parameter (PosTH, NegTH)
threshold!(x::AbstractArray, TH::THType)
threshold(x::AbstractArray, TH::THType)
# denoising
denoise(x::AbstractArray,
        wt=DEFAULT_WAVELET;
        L::Int=min(maxtransformlevels(x),6),
        dnt=VisuShrink(size(x,1)),
        estnoise::Function=noisest,
        TI=false,
        nspin=tuple([8 for i=1:ndims(x)]...) )
# entropy
coefentropy(x, et::Entropy, nrm)
# best basis for WPT limited to active inital tree nodes
bestbasistree(y::AbstractVector, wt::DiscreteWavelet,
        L::Integer=nscales(y), et::Entropy=ShannonEntropy() )
bestbasistree(y::AbstractVector, wt::DiscreteWavelet,
        tree::BitVector, et::Entropy=ShannonEntropy() )
Type Details
Thresholding <: THType
HardTH hard thresholding
SoftTH soft threshold
SemiSoftTH semisoft thresholding
SteinTH stein thresholding
PosTH positive thresholding
NegTH negative thresholding
BiggestTH biggest m-term (best m-term) approx.
Denoising <: DNFT
VisuShrink VisuShrink denoising
Entropy <: Entropy
ShannonEntropy -v^2*log(v^2) (Coifman-Wickerhauser)
LogEnergyEntropy -log(v^2)

Examples

Find best basis tree for wpt, and compare to dwt using biggest m-term approximations.

wt = wavelet(WT.db4)
x = sin.(4*range(0, stop=2*pi-eps(), length=1024))
tree = bestbasistree(x, wt)
xtb = wpt(x, wt, tree)
xt = dwt(x, wt)
# get biggest m-term approximations
m = 50
threshold!(xtb, BiggestTH(), m)
threshold!(xt, BiggestTH(), m)
# compare sparse approximations in ell_2 norm
norm(x - iwpt(xtb, wt, tree), 2) # best basis wpt
norm(x - idwt(xt, wt), 2)        # regular dwt
julia> norm(x - iwpt(xtb, wt, tree), 2)
0.008941070750964843
julia> norm(x - idwt(xt, wt), 2)
0.05964431178940861

Denoising:

n = 2^11;
x0 = testfunction(n,"Doppler")
x = x0 + 0.05*randn(n)
y = denoise(x,TI=true)

Doppler

Benchmarks

Timing of dwt (using db2 filter of length 4) and fft. The lifting wavelet transforms are faster and use less memory than fft in 1-D and 2-D. dwt by lifting is currently 2x faster than by filtering.

# 10 iterations
dwt by filtering (N=1048576), 20 levels
elapsed time: 0.247907616 seconds (125861504 bytes allocated, 8.81% gc time)
dwt by lifting (N=1048576), 20 levels
elapsed time: 0.131240966 seconds (104898544 bytes allocated, 17.48% gc time)
fft (N=1048576), (FFTW)
elapsed time: 0.487693289 seconds (167805296 bytes allocated, 8.67% gc time)

For 2-D transforms (using a db4 filter and CDF 9/7 lifting scheme):

# 10 iterations
dwt by filtering (N=1024x1024), 10 levels
elapsed time: 0.773281141 seconds (85813504 bytes allocated, 2.87% gc time)
dwt by lifting (N=1024x1024), 10 levels
elapsed time: 0.317705928 seconds (88765424 bytes allocated, 3.44% gc time)
fft (N=1024x1024), (FFTW)
elapsed time: 0.577537263 seconds (167805888 bytes allocated, 5.53% gc time)

By using the low-level function dwt! and pre-allocating temporary arrays, significant gains can be made in terms of memory usage (and some speedup). This is useful when transforming multiple times.

To-do list

  • Transforms for non-square 2-D signals
  • Boundary extensions (other than periodic)
  • Boundary orthogonal wavelets
  • Define more lifting schemes
  • WPT in 2-D
  • Wavelet scalogram

Related Wavelet Packages

  • Stationary transform
  • Wavelet Packet Decomposition
  • Autocorrelation Wavelet Transform
  • Joint Best Basis and Least Statistically-Dependent Basis
  • Local Discriminant Basis

wavelets.jl's People

Contributors

andrewgibb avatar antholzer avatar atrotier avatar cako avatar datseris avatar dependabot[bot] avatar dsweber2 avatar eloceanografo avatar gummif avatar halleysfifthinc avatar jefffessler avatar jfsantos avatar juliatagbot avatar mschauer avatar robertdj avatar tkelman avatar viralbshah avatar waldyrious avatar wheeheee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wavelets.jl's Issues

recreating scipy example

Hi, would it possible for someone to provide the Wavelets.jl code that recreates the example shown at the bottom here, the time-frequency analysis they show ?

Calculating wavelet coherency?

Could this package have a build in api for calculating wavelet coherency? it's a very import method for neuroscience :D

ERROR: DomainError with -1

Can someone explain what is needed here please?
I am already passing a float variable of which all elements are already in decimal points.

this statement wpt(x, wt, maketree(x)) return the following error

ERROR: DomainError with -1:
Cannot raise an integer x to a negative power -1.
Make x or -1 a float by adding a zero decimal (e.g., 2.0^-1 or 2^-1.0 instead of 2^-1), or write 1/x^1, float(x)^-1, x^float(-1) or (x//1)^-1

Thank you!

Make a release?

Hi, I get various deprecation messanges under Julia 0.6. It seems they are resolved on Master. Could you make release @gummif?

Thanks,

Tobi

wplotim is destructive

wplotim modifies the argument x it receives. I think either the function should be renamed to wplotim!
or on line 83 of Plot.jl xts = x should be changed to xts = copy(x) (which seems the best option to me). Thanks for your time :)

Wavelet filter definitions

Implementing #42, I noticed filter definitions are different in this package than in at least one other wavelet package I've used (wmtsa in R). The code below plots the equivalently-named wavelets from these two packages.

using Wavelets
using Plots
using RCall; R"library(wmtsa)"

julia_wavelets = [:coif6, :db2, :db4, :db6, :db8, :db10, :haar, :sym4, :sym6, :sym8]
r_wavelets = ["c6", "d2", "d4", "d6", "d8", "d10", "haar", "s4", "s6", "s8"]

subplots = []
for (wj, wr) in zip(julia_wavelets, r_wavelets)
    hr = Array(reval("wavDaubechies('$wr')")[:wavelet])
    gr = Array(reval("wavDaubechies('$wr')")[:scaling])
    p = plot(hr, color=:pink, label="Wavelet (R)", 
        title="Julia: $(String(wj)), R: $wr", 
        background_color_legend=:transparent, size=(600, 1000))
    plot!(p, gr, color=:red, label="Scaling (R)")

    g, h = @eval WT.makeqmfpair(wavelet(WT.$wj))
    plot!(p, h, color=:lightblue, label="Wavelet (Julia)")
    plot!(p, g, color=:blue, label="Scaling (Julia)")
    push!(subplots, p)
end
plot(subplots..., layout=(5,2))

wavelet_filters

This may just be a Pepsi/Coke problem with slightly different definitions, but it seemed worth double-checking.

References/further reading

I may have missed it but some references for the algorithms and wavelets implemented in the README or in other docs would be hugely helpful.

Hope this is appropriate to raise here.

Extension to Wavelets.jl for Discrete Wavelets

Hi, my team has developed an extension to your package Wavelets.jl which contains 2D-WPT, stationary transforms, group operations on signals (best basis, denoising, feature extraction). It would be really helpful if you could add a link to our package in your README.md, so that users are aware of these functions and operations in Julia.

The function is still under continuous development, but most of the functions that I've mentioned above are stable. Feel free to check out WaveletsExt.jl and its documentations and let me know if you'd be happy to add WaveletsExt.jl to your link, or if more improvements and developments are needed before you do so. Thanks!

Morlet wavelet

Morlet wavelet analysis is needed in the analysis of waves. I hope it can be implemented.

Implement 3d transforms

Hi,

Would it be hard to implement the 3d transforms? I am interested in doing 3d transforms.

Thanks

High-level API abstraction

For construction of wavelet transform types, the currect API is

wavelet("db2"; transform="filter", boundary="per")

Any thoughts whether using symbols

wavelet("db2"; transform=:filter, boundary=:per)

or types

wavelet("db2"; transform=FilterWavelet(), boundary=PerBoundary())
# or using const objects
wavelet("db2"; transform=FilterWT, boundary=PerWB)

might be better, or more elegant?

Example code not working :/

julia> y = dwt(x, wavelet(WT.cdf97, WT.Filter))
ERROR: MethodError: wavelet has no method matching wavelet(::Wavelets.WT.CDF{9,7}, ::Wavelets.WT.FilterTransform)
Closest candidates are:

Computing filters

Hi,

Would you be interested in a procedure for computing Daubechies filter coefficients? (Instead of looking them up in a dict)

Best,

Robert

where is `idwt` defined?

Thanks for this package! I'm trying to learn about the implementation details of idwt, but totally flummoxed as to where to look. I believe the key functions are defined with metaprogramming at:

for (Xwt, Xwt!, _Xwt!, fw) in ((:dwt, :dwt!, :_dwt!, true),

And they are all effectively wrappers around:

function _dwt!(y::AbstractVector{<:Number}, x::AbstractVector{<:Number},

where for dwt, fw=true and for iwt, fw=false. This leads to a key branch in the code,


where dwt uses filtdown! while idwt uses filtup!, and it seems like these two functions do much of the "actual work". Unfortunately, I can't seem to find where these two functions are actually defined. Any pointers? Thank you!

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Allow mutating versions to have differing precisions

The current implementations of the mutating versions of the transforms require that the input array x and output array y have the same eltype:

function _dwt!(y::AbstractVector{T}, x::AbstractVector{T},
                filter::OrthoFilter, L::Integer, fw::Bool) where T<:Number

It would be useful to relax this restriction, e.g.:

function _dwt!(y::AbstractVector{Ty}, x::AbstractVector{Tx},
                filter::OrthoFilter, L::Integer, fw::Bool) where {Tx<:Number, Ty<:Number}

Note that the most basic "do nothing" transform in the code reverts to simply copyto!(y,x), and copyto! itself does not require the arguments do have the same eltype. (Of course you get and InexactError if you try to copy from arbitrary Floats to Ints, or Real to Complex, but if you do precision changes like Float32 to Float64 then copyto! takes care of the conversion for you.
I'd be willing to try to make PR to provide this generality, because I think it just requires some changes to the function declarations, but I wanted to see first if there are objections or drawbacks.
Edit: I needed this for my work so I made the PR #54.

Not working with Complex types

I have tried this package (much appreciated!) with an application to compressed sensing and it seems that currently the dwt and its inverse cannot be applied to complex numbers. Would be great if this could be solved by relaxing the type definitions.

Question - DWT 3D Wavelet Coefficients Organization

I'm trying to implement a soft thresholding method for 3D data which preserves scaling (or approximation) coefficients at each level, then soft thresholds all others. Unfortunately, I have been having trouble identifying indices which correspond to the scaling coefficients. I was trying to make sense of the detailn() and detailindex() functions and it makes sense to me for 1D condition, but I don't understand how to use these to create an index list for higher dimensions, like the 3D condition that I need.

Also to complicate further, I need to handle both dyadic cube and dyadic non-cube dimensions.

Could someone help me with this?

Thanks

Potential use of fast continous wavelet transform?

Hi! I recently was reading about wavelets, and I noticed that just recently there was a paper (and corrisponding code) on an implementation of the continous wavelet transform that had performance gains of ~30-120 times faster. Not sure if this is within the scope of this package, but I figured it might be something that would be applicable :)

Dependence on SpecialFunctions version needs updated

The SpecialFunctions package is now a few versions farther along; in particular it jumped from 0.10 to 1.x.
I have tested and current Wavelets is compatible with 1.2 so it would be very helpful for packages that rely on Wavelets to have Project.toml show compatibility with 1.x. Thanks.

Document coefficient vector layout

I a hope I am not missing anything but I could not find the layout of the coefficient vector. Inspecting the size of the coefficient also does not immediately suggest a certain order to me.

Relax Dyadic requirement

Hi,

I've been working on a patch which relaxes the requirement that the signals have dyadic support, in favour of a "sufficient powers of 2" test. To compute an n-level transform, the support of the signal needs only to have 2^n as a factor. I've completed the modifications and tested them on an older version of the package, before the significant changes which have been made of the last couple of months.

The reason for this issue is this: If I integrate these changes into the current version of the package, are you likely to accept them? (Assuming you're happy with the technical quality?)

And a further question: Do you plan any further significant changes to the API soon? Ought I to wait for some upcoming change before rebasing my work?

Thanks

Andy

about WPT in 2-D

Hi, may I know if you are planning to write 2D WPT as shown in the To-do list? If so, when will it be available? Thanks.

Discrete wavelet transform behaves like identity

Apologies if I am missing something very basic (I am only just learning about wavelets), but I believe there is a bug in dwt:

n = 2^6 - 1
u = cos.(2*pi*range(0, stop=1, length=n))
wav = wavelet(WT.haar) # also tested WT.db2
w = dwt(u, wav)
display(w == u)

This code returns true. Expected behaviour is that w is the discrete wavelet transform of u, something like I get running the same experiment in Mathematica.

Version info:

Wavelets 0.9.4
Julia 1.6.3

multilevel wavelet coefficients

I am sure I am missing something but I when I run dwt I can only see the first level wavelet detail coefficients. How can I see the other levels?

Fix v0.4 deprecation warnings

I am running this package on Julia Version 0.4.1-pre+8.
When using Wavelets, four kinds of deprecation warning appear:

  • Base.String is deprecated, use AbstractString instead..
  • Base.FloatingPoint is deprecated, use AbstractFloat instead.
  • Base.Nothing is deprecated, use Void instead.
  • Union(args...) is deprecated, use Union{args...} instead.

The warnings will become errors when v0.5 lands.
What is the compatibility policy for this package ?

Normalization of Battle-Lemarie filters and symlets

Wavelet filters are typically scaled to have unit energy and sum to sqrt(2.0); this simplifies a number of equations and transforms. So why are these wavelet families different?

Battle-Lemarie filters

sumabs2(FILTERS["batt2"]) = 0.5; sum(FILTERS["batt2"]) = 1.0
sumabs2(FILTERS["batt4"]) = 0.5; sum(FILTERS["batt4"]) = 1.0
sumabs2(FILTERS["batt6"]) = 0.5; sum(FILTERS["batt6"]) = 1.0

symlets

sumabs2(FILTERS["sym4"]) = 2.0; sum(FILTERS["sym4"]) = 2.0
sumabs2(FILTERS["sym5"]) = 2.0; sum(FILTERS["sym5"]) = 2.0
sumabs2(FILTERS["sym6"]) = 2.0; sum(FILTERS["sym6"]) = 2.0
sumabs2(FILTERS["sym7"]) = 2.0; sum(FILTERS["sym7"]) = 2.0
sumabs2(FILTERS["sym8"]) = 2.0; sum(FILTERS["sym8"]) = 2.0
sumabs2(FILTERS["sym9"]) = 2.0; sum(FILTERS["sym9"]) = 2.0
sumabs2(FILTERS["sym10"]) = 2.0; sum(FILTERS["sym10"]) = 2.0

I realize that Matlab's wavelet toolbox scales symlets to have energy ~0.5, so this isn't the only wavelet toolbox that uses unusual scaling for symlets; but why this particular choice?

Extracting coefficients from filter

Hi,

Say I create a filter:

julia> using Wavelets

julia> F = waveletfilter("db2")
Wavelets.WaveletTypes.OrthoFilter{Wavelets.WaveletTypes.PerBoundary}([0.4829629131445342,0.8365163037378079,0.22414386804201344,-0.12940952255126031],"db2")

How do I extract the vector of numbers from F?

I've been looking in the code, but I can't seem to figure this out.

Thanks,

Robert

warnings in Julia 1.9+

WARNING: method definition for #computeWavelets#6 at C:\Users\gd419\.julia\packages\Wavelets\ANOxi\src\mod\WT.jl:660 declares type variable S but does not use it.
WARNING: method definition for #computeWavelets#7 at C:\Users\gd419\.julia\packages\Wavelets\ANOxi\src\mod\WT.jl:664 declares type variable S but does not use it.
WARNING: method definition for #computeWavelets#8 at C:\Users\gd419\.julia\packages\Wavelets\ANOxi\src\mod\WT.jl:670 declares type variable S but does not use it.
WARNING: method definition for cwt at C:\Users\gd419\.julia\packages\Wavelets\ANOxi\src\mod\Transforms.jl:216 declares type variable U but does not use it.

Adjoint or transpose for CDF 9/7 basis

Since the CDF 9/7 basis is not orthogonal, the inverse transform matrix is not the adjoint (or transpose) of the forward transform matrix. Would it be possible to modify the idwt() function, such that the use of idwt() with an adjoint=true flag simply returns the action of the transpose of idwt with the cdf 9/7 basis on a given vector? This would be very useful for change of basis problems where the adjoint of the inverse transform from cdf 9/7 to cartesian is required in applying the chain rule.

Question : Working on rectangular matrix -> multilevel fully separable decomposition

I am working with non-squared matrix 2D (x != y) or 3D (x != y != z).
For example an image of 220 x 160, when applying the DWT it apply a DWT of level 2 (restricted by the size 220)

  1. Is that possible to perform a multilevel fully separable decomposition WT like :
    https://pywavelets.readthedocs.io/en/latest/ref/nd-dwt-and-idwt.html#multilevel-fully-separable-decomposition-fswavedecn
    I did not find the function for that but maybe I am missing something :)

  2. An other approach will be to pad the data. In that case does the operator is still orthogonal (Adjoint = Inverse)

Thanks :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.