1666359000
Hyper-dual numbers can be used to compute first and second derivatives numerically without the cancellation errors of finite-differencing schemes.
The initial Julia implementation (up to v3.0.1) is directly based on the C++ implementation by Jeffrey Fike and Juan J Alonso, both of Stanford University, department of Aeronautics and Astronautics as described in the paper:
The Development of Hyper-Dual Numbers for Exact Second Derivative Calculations
Up to v3.0.1 the Julia versions have been derived/written by Rob J Goedman (goedman@icloud.com).
HyperDualNumbers.jl v4.0.0 has been completely redone by Benoit Pasquier and follows the structure of the JuliaDiff/DualNumbers package.
For a quick intro, see STEPBYSTEP.md
Latest tagged versions:
For details see VERSION.md
The following functions are specific to hyperdual numbers:
Hyper
,Hyper256
,Hyper128
,ishyper
,y2hyper_show
realpart
,ε₁part()
, replaces eps1,ε₂part()
, replaces eps2,ε₁ε₂part()
, replaces eps1eps2In the future it is my intention to deprecate:
hyper
,hyper256
,hyper128
,eps1
,eps2
,eps1eps2
Question and contributions are very welcome, as are feature requests and suggestions. Please open an issue if you encounter any problems or have a question.
Author: JuliaDiff
Source Code: https://github.com/JuliaDiff/HyperDualNumbers.jl
License: View license
1666359000
Hyper-dual numbers can be used to compute first and second derivatives numerically without the cancellation errors of finite-differencing schemes.
The initial Julia implementation (up to v3.0.1) is directly based on the C++ implementation by Jeffrey Fike and Juan J Alonso, both of Stanford University, department of Aeronautics and Astronautics as described in the paper:
The Development of Hyper-Dual Numbers for Exact Second Derivative Calculations
Up to v3.0.1 the Julia versions have been derived/written by Rob J Goedman (goedman@icloud.com).
HyperDualNumbers.jl v4.0.0 has been completely redone by Benoit Pasquier and follows the structure of the JuliaDiff/DualNumbers package.
For a quick intro, see STEPBYSTEP.md
Latest tagged versions:
For details see VERSION.md
The following functions are specific to hyperdual numbers:
Hyper
,Hyper256
,Hyper128
,ishyper
,y2hyper_show
realpart
,ε₁part()
, replaces eps1,ε₂part()
, replaces eps2,ε₁ε₂part()
, replaces eps1eps2In the future it is my intention to deprecate:
hyper
,hyper256
,hyper128
,eps1
,eps2
,eps1eps2
Question and contributions are very welcome, as are feature requests and suggestions. Please open an issue if you encounter any problems or have a question.
Author: JuliaDiff
Source Code: https://github.com/JuliaDiff/HyperDualNumbers.jl
License: View license
1664946660
This Julia package implements the Barycentric formula for polynomial interpolation on equispaced points and Chebyshev points of the first and second kind. The formulae used are taken from the paper of Berrut and Trefethen, SIAM Review, 2004.
This is not a general purpose interpolation package but is intended to be used as a base for other numerical methods, such as numerical collocation. For a general use interpolation package see Interpolations.jl
There are various types of polynomials defined based on the locations of their nodes (zeros).
Equispaced{N}()
) — a common choice when data is equispaced but suffers from Runge phenomenon for high degree polynomials. When used as part of a collocation scheme with Gauss-Legendre collocation points, they provide the benefit of super-convergence. By default the nodes are equispaced over [-1, +1].Chebyshev1{N}()
) — nodes distributed according to cos(π(2j + 1)/(2N + 2)) where N is the degree of the polynomial, for j in [0, N].Chebyshev2{N}()
) — nodes distributed according to cos(πj/N) where N is the degree of the polynomial, for j in [0, N].Legendre{N}()
) — nodes distributed according to the zeros of the corresponding Legendre polynomial where N is the degree of the polynomial.ArbitraryPolynomial(nodes)
) — nodes distributed as specified.By default, each of the polynomials are defined over the range [-1, +1]. This can be modified by specifying a start and stop for the range, e.g., Equispaced{10}(0, 1)
will generate a 10th order polynomial with equispaced nodes over the range [0, 1].
Polynomials with nodes asymptotically clustered towards the end points (such as Chebyshev) are optimal for avoiding the Runge phenomenon (see Trefethen, Spectral Methods in MATLAB, SIAM 2000).
Once a polynomial has been defined it can be used with the nodes(poly)
and weights(poly)
functions to return the locations of the nodes and the values of the Barycentric weights respectively. To interpolate a set of y
values (defined at the nodes) use interpolate(poly, y, x_new)
; x_new
can be either a scalar or a vector. If x_new
is omitted, the interpolate
function returns a function y(x)
which can be used to evaluate the interpolant at any point.
To obtain the interpolant as a linear combination of the y
values, use interpolation_matrix(poly, x)
; this returns a matrix which can be multiplied by a vector of y
values to calculate the interpolated value.
Finally, the derivative of the polynomial at the nodes can be obtained using differentiation_matrix(poly)
. Similar to interpolation_matrix
, this returns a matrix which can be multiplied by a vector of y
values to calculate the derivative of y
.
using BarycentricInterpolation
p = Chebyshev2{20}() # create a Chebyshev type 2 polynomial of order 20
x = nodes(p) # get the nodes
y = sinpi.(x) # generate y values at the nodes
x_new = rand()*2 -1 # a random number in [-1, +1]
println(interpolate(p, y, x_new) ≈ sinpi(x_new)) # hopefully true!
D = differentiation_matrix(p) # get the differentiation matrix
println(interpolate(p, D*y, x_new) ≈ pi*cospi(x_new)) # hopefully true!
For an example with Barycentric.jl applied to the simulation of a PDE (in combination with DifferentialEquations.jl) see https://cityinthesky.co.uk/posts/2018/barycentricinterpolation.jl/.
Author: Dawbarton
Source Code: https://github.com/dawbarton/BarycentricInterpolation.jl
License: View license
1656510600
ProtoBuf.jl
Protocol buffers are a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols, data storage, and more.
ProtoBuf.jl is a Julia implementation for protocol buffers.
ProtoBuf.jl includes the protoc
compiler version 3 binary appropriate for your operating system. The Julia code generator plugs in to the protoc
compiler. It is implemented as ProtoBuf.Gen
, a sub-module of ProtoBuf
. The callable program (as required by protoc
) is provided as the script plugin/protoc-gen-julia
for unix like systems and plugin/protoc-gen-julia_win.bat
for Windows.
For convenience, ProtoBuf.jl exports a protoc(args)
command that will setup the PATH
and environment correctly for the included protoc
. E.g. to generate Julia code from proto/plugin.proto
, run the command below which will create a corresponding file jlout/plugin.jl
, simply run (from a Julia REPL):
julia> using ProtoBuf
julia> ProtoBuf.protoc(`-I=proto --julia_out=jlout proto/plugin.proto`)
Each .proto
file results in a corresponding .jl
file, including one each for other included .proto
files. Separate .jl
files are generated with modules corresponding to each top level package.
If a field name in a message or enum matches a Julia keyword, it is prepended with an _
character during code generation.
If a package contains a message which has the same name as the package itself, optionally set the JULIA_PROTOBUF_MODULE_POSTFIX=1
environment variable when running protoc
, this will append _pb
to the module names.
ProtoBuf map
types are generated as Julia Dict
types by default. They can also be generated as Array
of key-value
s by setting the JULIA_PROTOBUF_MAP_AS_ARRAY=1
environment variable when running protoc
.
.proto Type | Julia Type | Notes |
---|---|---|
double | Float64 | |
float | Float32 | |
int32 | Int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. |
int64 | Int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. |
uint32 | UInt32 | Uses variable-length encoding. |
uint64 | UInt64 | Uses variable-length encoding. |
sint32 | Int32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. |
sint64 | Int64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. |
fixed32 | UInt32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. |
fixed64 | UInt64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. |
sfixed32 | Int32 | Always four bytes. |
sfixed64 | Int64 | Always eight bytes. |
bool | Bool | |
string | ByteString | A string must always contain UTF-8 encoded or 7-bit ASCII text. |
bytes | Array{UInt8,1} | May contain any arbitrary sequence of bytes. |
map | Dict | Can be generated as Array of key-value by setting environment variable JULIA_PROTOBUF_MAP_AS_ARRAY=1 |
The protocol buffers well known types are pre-generated and included in the package as a sub-module ProtoBuf.google.protobuf
. The version of the code included with this package have additional changes to make them compatible with Julia.
You can refer to them in your code after including the following statements:
using ProtoBuf
using ProtoBuf.google.protobuf
While generating code for your .proto
files that use well-known types, add ProtoBuf/gen
to the list of includes, e.g.:
julia> using ProtoBuf
julia> ProtoBuf.protoc(`-I=proto -I=ProtoBuf/gen --julia_out=jlout proto/msg.proto`)
Though this would generate code for the well-known types along with your messages, you just need to use the files generated for your messages.
The Julia code generator generates code for generic services if they are switched on for either C++ (cc_generic_services)
, Python (py_generic_services)
or Java (java_generic_services)
.
To use generic services, users provide implementations of the RPC controller, RPC channel, and service methods.
The RPC Controller must be an implementation of ProtoRpcController
. It is not currently used by the generated code except for passing it on to the RPC channel.
The RPC channel must implement call_method(channel, method_descriptor, controller, request)
and return the response.
RPC method inputs or outputs that are defined as stream
type, are generated as Channel
of the corresponding type.
Service stubs are Julia types. Stubs can be constructed by passing an RPC channel to the constructor. For each service, two stubs are generated:
Int32
types in the generated code. For every enum, a separate named tuple is generated with fields matching the enum values. The lookup
method can be used to verify valid values.]activate; add ProtoBuf
).Julia code for protobuf message types can be generated via protoc (see "Generating Julia Code from .proto Specifications"). Generated Julia code for a protobuf message look something like:
mutable struct Description <: ProtoType
# a bunch of internal fields
...
function Description(; kwargs...)
# code to initialize the internal fields
end
end # mutable struct Description
const __meta_Description = Ref{ProtoMeta}()
function meta(::Type{Description})
# code to initialize the metadata
__meta_Description[]
end
function Base.getproperty(obj::Description, name::Symbol)
# code to get properties
end
Reading and writing data structures using ProtoBuf is similar to serialization and deserialization. Methods writeproto
and readproto
can write and read Julia types from IO streams.
julia> using ProtoBuf # include protoc generated package here
julia> mutable struct MyType <: ProtoType # a Julia composite type generated from protoc that
... # has intval::Int and strval::String as properties
function MyType(; kwargs...)
...
end
end
...
julia> iob = PipeBuffer();
julia> writeproto(iob, MyType(; intval=10, strval="hello world")); # write an instance of it
julia> data = readproto(iob, MyType()); # read it back into another instance
julia> data.intval
10
julia> data.strval
"hello world"
Reading message from a file is very similar to reading from a stream. Here's an example that writes a message to file and then reads it back.
julia> include("test_type.jl")
julia> mktemp() do path, io
tt1 = TestType(; a="abc", b=true) # construct a message
writeproto(io, tt1) # write message to file
close(io) # close the file handle
open(path) do io2 # open the file we just wrote in read mode
tt2 = readproto(io2, TestType()) # read message from the file
@info("read back from file", tt1.a, tt1.b, tt2.a, tt2.b) # print written and read messages
end
end
┌ Info: read back from file
│ tt1.a = "abc"
│ tt1.b = true
│ tt2.a = "abc"
└ tt2.b = true
Contents of the generated code in test_type.jl:
using ProtoBuf
import ProtoBuf.meta
mutable struct TestType <: ProtoType
__protobuf_jl_internal_meta::ProtoMeta
__protobuf_jl_internal_values::Dict{Symbol,Any}
__protobuf_jl_internal_defaultset::Set{Symbol}
function TestType(; kwargs...)
obj = new(meta(TestType), Dict{Symbol,Any}(), Set{Symbol}())
values = obj.__protobuf_jl_internal_values
symdict = obj.__protobuf_jl_internal_meta.symdict
for nv in kwargs
fldname, fldval = nv
fldtype = symdict[fldname].jtyp
(fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
end
obj
end
end #type TestType
const __meta_TestType = Ref{ProtoMeta}()
function meta(::Type{TestType})
if !isassigned(__meta_TestType)
__meta_TestType[] = target = ProtoMeta(TestType)
allflds = Pair{Symbol,Union{Type,String}}[:a => AbstractString, :b => Bool]
meta(target, TestType, allflds, [:a], ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
end
__meta_TestType[]
end
function Base.getproperty(obj::TestType, name::Symbol)
if name === :a
return (obj.__protobuf_jl_internal_values[name])::AbstractString
elseif name === :b
return (obj.__protobuf_jl_internal_values[name])::Bool
else
getfield(obj, name)
end
end
Types used as protocol buffer structures are regular Julia types and the Julia syntax to set and get fields can be used on them. The generated type constructor makes it easier to set large types with many fields by passing name value pairs during construction: T(; name=val...)
.
Fields that are marked as optional may not be present in an instance of the struct that is read. Also, you may want to clear a set property from an instance. The following methods are exported to assist doing this:
propertynames(obj)
: Returns a list of property names possiblesetproperty!(obj, fld::Symbol, v)
: Sets obj.fld
.getproperty(obj, fld::Symbol)
: Gets obj.fld
if it has been set. Throws an error otherwise.hasproperty(obj, fld::Symbol)
: Checks whether property fld
has been set in obj
.clear(obj, fld::Symbol)
: clears property fld
of obj
.clear(obj)
: Clears all properties of obj
.julia> using ProtoBuf
julia> mutable struct MyType <: ProtoType # a Julia composite type
... # intval::Int
...
end
julia> mutable struct OptType <: ProtoType # and another one to contain it
... #opt::MyType
...
end
julia> iob = PipeBuffer();
julia> writeproto(iob, OptType(opt=MyType(intval=10)));
julia> readval = readproto(iob, OptType());
julia> hasproperty(readval, :opt)
true
julia> writeproto(iob, OptType());
julia> readval = readproto(iob, OptType());
julia> hasproperty(readval, :opt)
false
The isinitialized(obj::Any)
method checks whether all mandatory fields are set. It is useful to check objects using this method before sending them. Method writeproto
results in an exception if this condition is violated.
julia> using ProtoBuf
julia> import ProtoBuf.meta
julia> mutable struct TestType <: ProtoType
... # val::Any
...
end
julia> mutable struct TestFilled <: ProtoType
... # fld1::TestType (mandatory)
... # fld2::TestType
...
end
julia> tf = TestFilled();
julia> isinitialized(tf) # false, since fld1 is not set
false
julia> tf.fld1 = TestType(fld1="");
julia> isinitialized(tf) # true, even though fld2 is not set yet
true
It is possible for fields marked as optional to be in an "unset" state. Even bits type fields (isbitstype(T) == true
) can be in this state though they may have valid contents. Such fields should then not be compared for equality or used for computing hash values. All ProtoBuf compatible types, by virtue of extending abstract ProtoType
type, override hash
, isequal
and ==
methods to handle this.
copy!{T}(to::T, from::T)
: shallow copy of objectsisfilled(obj)
: same as isinitialized
lookup(en, val::Integer)
: lookup the name (symbol) corresponding to an enum valueenumstr(enumname, enumvalue::Int32)
: returns a string with the enum field name matching the valuewhich_oneof(obj, oneof::Symbol)
: returns a symbol indicating the name of the field in the oneof
group that is filledMost of the book-keeping data for a protobuf struct is kept inside the struct instance. So that does not hinder thread safe usage. However struct instances themselves need to be locked if they are being read and written to from different threads, as is expected of any regular Julia struct.
Protobuf metadata for a struct (the information about fields and their properties as mentioned in the protobuf IDL definition) however is best initialized once and reused. It was not possible to generate code in such a way that it could be initialized when code is loaded and pre-compiled. This was because of the need to support nested and recursive struct references that protobuf allows - metadata for a struct could be defined only after the struct and all of its dependencies were defined. Metadata initialization had to be deferred to the first constructor call. But in order to reuse the metadata definition, it gets stored into a Ref
that is set once. A process wide lock is used to make access to it thread safe. There is a small cost to be borne for that, and it should be negligible for most usages.
If an application wishes to eliminate that cost entirely, then the way to do it would be to call the constructors of all protobuf structs it wishes to use first and then switch the lock off by calling ProtoBuf.enable_async_safety(false)
. Once all metadata definitiions have been initialized, this would allow them to be used without any further locking overhead. This can also be set to false
for a single threaded synchronous application where it is known that no parallelism is possible.
Both version 2 and 3 of the protobuf specification language are supported.
Author: JuliaIO
Source Code: https://github.com/JuliaIO/ProtoBuf.jl
License: View license
1666109100
A general framework for fast Fourier transforms (FFTs) in Julia.
This package is mainly not intended to be used directly. Instead, developers of packages that implement FFTs (such as FFTW.jl or FastTransforms.jl) extend the types/functions defined in AbstractFFTs
. This allows multiple FFT packages to co-exist with the same underlying fft(x)
and plan_fft(x)
interface.
To define a new FFT implementation in your own module, you should
Define a new subtype (e.g. MyPlan
) of AbstractFFTs.Plan{T}
for FFTs and related transforms on arrays of T
. This must have a pinv::Plan
field, initially undefined when a MyPlan
is created, that is used for caching the inverse plan.
Define a new method AbstractFFTs.plan_fft(x, region; kws...)
that returns a MyPlan
for at least some types of x
and some set of dimensions region
. The region
(or a copy thereof) should be accessible via fftdims(p::MyPlan)
(which defaults to p.region
).
Define a method of LinearAlgebra.mul!(y, p::MyPlan, x)
(or A_mul_B!(y, p::MyPlan, x)
on Julia prior to 0.7.0-DEV.3204) that computes the transform p
of x
and stores the result in y
.
Define a method of *(p::MyPlan, x)
, which can simply call your mul!
(or A_mul_B!
) method. This is not defined generically in this package due to subtleties that arise for in-place and real-input FFTs.
If the inverse transform is implemented, you should also define plan_inv(p::MyPlan)
, which should construct the inverse plan to p
, and plan_bfft(x, region; kws...)
for an unnormalized inverse ("backwards") transform of x
.
You can also define similar methods of plan_rfft
and plan_brfft
for real-input FFTs.
The normalization convention for your FFT should be that it computes yₖ = ∑ⱼ xⱼ exp(-2πi jk/n) for a transform of length n, and the "backwards" (unnormalized inverse) transform computes the same thing but with exp(+2πi jk/n).
Author: JuliaMath
Source Code: https://github.com/JuliaMath/AbstractFFTs.jl
License: MIT license
1658930280
NGram
This implementation uses the linear interpolation to build the model. For example, with a simple trigram model
p("book" | "the", "green") = count("the green book") / count("the green")
But there are some limitations
The idea is then to combine the results of trigram
with bigram
and unigram
. We can generalize by saying that to compute ngram, we also use the results of (n-1)gram
, ..., bigram
, unigram
. Here is an exemple in the case of a trigram model.
p("book" | "the", "green") = a * count("the green book") / count("the green")
+ b * count("the green") / count("the")
+ c * count("the") / count()
where
a + b + c = 1
a >= 0
b >= 0
c >= 0
# For example: a = b = c = 1 / 3
using NGram
texts = String["the green book", "my blue book", "his green house", "book"]
# Train a trigram model on the documents
model = NGramModel(texts, 3)
# Query on the model
# p(book | the, green)
model["the green book"]
Author: Remusao
Source Code: https://github.com/remusao/NGram.jl
License: View license