Created by: pkuyym
ref: #1 and #89
This is a more general implementation than current paddle version.