# Matlab to Julia: Random number generators

**URL:** <https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937>\
**Category:** General Usage\
**Tags:** question, random\
**Created:** [June 16, 2025, 5:12pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937 "2025-06-16T17:12:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [June 16, 2025, 5:12pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/1 "2025-06-16T17:12:42Z")

</div>

I am writing unit tests for Matlab and Julia functions (Julia translated from Matlab), and both use the `randn()` function. Is there a way to get the same sequence of random numbers both in Matlab and Julia?

Without that it is difficult to write unit tests that give the same results for both languages.

Example of a function I want to test:

```julia
"""
    getWindDirT(::Direction_Constant_wErrorCov, WindDir, iT)

Return wind direction in SOWFA-deg for the requested turbine(s).

# Arguments
- `WindDir`: Struct with fields
    - `Data::Float64`: wind direction value
    - `CholSig::AbstractMatrix`: Cholesky factor of covariance matrix (nT x nT)
- `iT`: Vector of turbine indices (can be any indexable collection)

# Returns
- `phi`: Vector of wind directions for the selected turbines, including random perturbation
"""
function getWindDirT(::Direction_Constant_wErrorCov, WindDir, iT)
    n = length(iT)
    phi = fill(WindDir.Data, n)
    # randn(n) gives a vector of n normal random numbers
    # WindDir.CholSig should
    @assert issquare(WindDir.CholSig)
    phi .= phi .+ WindDir.CholSig * randn(n)
    return phi
end

```

Unit test in Julia:

```julia
    using Random
  
    Random.seed!(1234)
    dir_mode = Direction_Interpolation_wErrorCov()

    # Example wind direction data (time, phi)
    wind_data = [
        0.0 10.0;
        5.0 20.0;
        10.0 30.0
    ]

    # Example Cholesky factor (for 2 turbines)
    chol_sig = cholesky([1.0 0.5; 0.5 1.0]).L

    # Create WindDir instance
    WindDir = WindDirMatrix(wind_data, chol_sig)

    # Example turbine indices (for 2 turbines)
    iT = [1, 2]

    # Example time
    t = 7.0

    # Call the function
    phi = getWindDirT(dir_mode, WindDir, iT, t)
    @test size(phi) == (2,1)
    @test phi[1] ≈ 24.92903352636283
    @test phi[2] ≈ 24.363944731838128

```

But if I translate this unit test to Matlab it will not work, because the sequence of random numbers is different.

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [June 16, 2025, 5:25pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/2 "2025-06-16T17:25:30Z")

</div>

Record them in a file?

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [June 16, 2025, 5:27pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/3 "2025-06-16T17:27:58Z")

</div>

Ok, but then I need to replace the standard `randn(n)` function with a version that reads this file, but only for the unit tests.

How would you do that?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 16, 2025, 5:42pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/4 "2025-06-16T17:42:04Z")

</div>

Something like this could do the ticket:

```julia
const DNG = Iterators.Stateful(parse(Float64, x) for x in eachline("rng-output.csv"))
randn() = popfirst!(DNG)
randn(n) = collect(Iterators.take(DNG, n))

```

Edit: oh, but that’ll only work if your `randn` calls are entirely in the scope of your unit test, which it looks like they’re called from your source. In such a case, I think you’d want to explicitly pass a RNG object instead of using the global one… and then you’d need to do a bit more work to satisfy the RNG interface. That’s more complicated, but I think there may be some existing RNG types that could do the ticket?

> **[Random Numbers · The Julia Language](https://docs.julialang.org/en/v1/stdlib/Random/#rand-api-hook)**
>
> Documentation for The Julia Language.

---

<div class="post-metadata">

**Author:** ![mihalybaci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mihalybaci/32/13528_2.png) [@mihalybaci](https://discourse.julialang.org/u/mihalybaci)\
**Post date:** [June 16, 2025, 6:01pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/5 "2025-06-16T18:01:59Z")

</div>

Would it be possible to use MATLAB.jl to call MATLAB’s version of `randn` directly in Julia?

---

<div class="post-metadata">

**Author:** ![Maucejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maucejo/32/39090_2.png) [@Maucejo](https://discourse.julialang.org/u/Maucejo)\
**Post date:** [June 16, 2025, 6:11pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/6 "2025-06-16T18:11:19Z")

</div>

For similar purpose, I generally save the sequence generated by Matlab in a `.mat` file and open it in Julia `using MAT`.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 16, 2025, 6:17pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/7 "2025-06-16T18:17:18Z")

</div>

The [MATLAB docs](https://www.mathworks.com/help/matlab/ref/rng.html) say that it uses a Mersenne Twister RNG with seed 0 by default. So perhaps setting

```julia
julia> mersenne = Random.MersenneTwister(0)
MersenneTwister(0)

```

and using that

```julia
julia> randn(mersenne, 5)
5-element Vector{Float64}:
 -0.7587307822993239
  0.03249717326229417
  0.04868971510118324
  0.426553609186312
 -0.6455341387712752

```

could reproduce MATLAB’s sequence?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [June 16, 2025, 6:24pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/8 "2025-06-16T18:24:50Z")

</div>

I would wager that the exact method of going from the MersenneTwister’s “native” output (32 or 52 or 64 raw bits) to a normal distribution is going to be sufficiently complicated to not match. Saving the outputs to a one-column CSV would likely be simplest. For the purposes of unit-testing, you could probably get away with something like this:

```Julia
struct DeterministicNumberGenerator{T}
    iter::T
end
DeterministicNumberGenerator(filename::String) = DeterministicNumberGenerator(Iterators.Stateful(parse(Float64, x) for x in eachline(filename)))
Random.randn(dng::DeterministicNumberGenerator) = popfirst!(dng.iter)
Random.randn(dng::DeterministicNumberGenerator, n) = collect(Iterators.take(dng.iter, n))

```

And then making your signatures accept an `rng` argument, calling `randn(rng, n)`.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [June 16, 2025, 6:54pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/9 "2025-06-16T18:54:55Z")

</div>

Well, it might be possible, but I want to have the unit tests of our Julia package [FLORIDyn.jl](https://github.com/ufechner7/FLORIDyn.jl) running on Github without access to Matlab. So this is not a good option. The other way round it would be easier, but still more complicated than just sharing a file with values.

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [June 16, 2025, 7:00pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/10 "2025-06-16T19:00:29Z")

</div>

@mbauman solution seems best to me

---

<div class="post-metadata">

**Author:** ![mihalybaci](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mihalybaci/32/13528_2.png) [@mihalybaci](https://discourse.julialang.org/u/mihalybaci)\
**Post date:** [June 16, 2025, 7:14pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/11 "2025-06-16T19:14:05Z")

</div>

ahhhh, right. I forgot that you would need to be paying for access to the MATLAB runtime…

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [June 16, 2025, 7:35pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/12 "2025-06-16T19:35:25Z")

</div>

You can always write your own simple RNG that you use for both Julia and matlab test cases.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [June 16, 2025, 7:54pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/13 "2025-06-16T19:54:01Z")

</div>

There’s always

> **[Random Number](https://xkcd.com/221/)**

---

<div class="post-metadata">

**Author:** ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)\
**Post date:** [June 16, 2025, 8:18pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/14 "2025-06-16T20:18:46Z")

</div>

You can also try to design your test in a way that they don’t depend on specific random numbers..

---

<div class="post-metadata">

**Author:** ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)\
**Post date:** [June 16, 2025, 9:53pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/15 "2025-06-16T21:53:24Z")

</div>

IMO if the test depends on randomness, the “fix seed and use `approx`” combo is unreliable and might miss edge cases (what if all other seeds break everything?).

You could follow a statistical approach:

1. In Matlab, run the test’s code with different seeds many times (1000x, the more the better). Modify the code to compute averages of quantities of interest (`phi` in your case) or write out all 1000 `phi`s to a file.
2. In Julia, run the code the same number of times, again computing the mean. Suppose `phi_mean` holds the mean of the vector `phi`. Then, `@test abs(phi_mean[1] - phi_mean_matlab[1]) < 0.01`. Same for the other component. The `0.01` here is an arbitrary small number that somehow depends on the number of samples (more samples =\> could use 0.005 as the threshold).
3. Ideally, put the entire sample computed by Matlab in the file with your Julia tests and test the hypothesis `E(phi_Julia[1] - phi_Matlab[1]) == 0` (same for `phi[2]`) with a two-sample test using HypothesisTests.jl.
4. Since there’s a Normal distribution involved, perhaps it’s possible to compute the expected value exactly. Then you don’t even need Matlab: simply test whether `phi_mean` is sufficiently close to that true expectation.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 17, 2025, 2:39am UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/16 "2025-06-17T02:39:46Z")

</div>

Octave is easier to access though, and there’s some code [here](https://stackoverflow.com/a/71853621) to patch over initialisation differences between it and MATLAB, and have Octave produce a MATLAB compatible sequence. So that’s another option worth keeping in mind.

---

<div class="post-metadata">

**Author:** ![colintbowers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/colintbowers/32/8033_2.png) [@colintbowers](https://discourse.julialang.org/u/colintbowers)\
**Post date:** [June 17, 2025, 6:38am UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/17 "2025-06-17T06:38:44Z")

</div>

Not much to add to the discussion other than that I asked this exact question over a decade ago now, but in the context of Julia and R. I got a response from Dirk Eddelbuettel [here](https://stackoverflow.com/questions/29482411/generate-identical-random-numbers-in-r-and-julia).

---

<div class="post-metadata">

**Author:** ![araujoms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/araujoms/32/217734_2.png) [@araujoms](https://discourse.julialang.org/u/araujoms)\
**Post date:** [June 17, 2025, 6:51am UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/18 "2025-06-17T06:51:36Z")

</div>

If the random numbers don’t need to be high quality it will be easier to implement your own [linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator?wprov=sfla1).

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [June 17, 2025, 12:29pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/19 "2025-06-17T12:29:56Z")

</div>

I am now using this Matlab script to create a sequence of random numbers:

```matlab
clear all
rng(1234);
N=1000;

vec=randn(1,N);
filename = 'test/randn.mat';
save(filename, 'vec')

```

And this code to create a file based pseudo-random number generator in Julia:

```julia
# Copyright (c) 2025 Uwe Fechner
# SPDX-License-Identifier: BSD-3-Clause

using FLORIDyn
using Test
using LinearAlgebra
using MAT
using Random

if basename(pwd()) == "test"
    cd("..")
end

filename="test/randn.mat"
randn_vec=vec(matread(filename)["vec"])

mutable struct FileRNG <: AbstractRNG
    const data::Vector{Float64}
    idx::Int
end

FileRNG(data::Vector{Float64}) = FileRNG(data, 1)

function Base.rand(rng::FileRNG)
    x = rng.data[rng.idx]
    rng.idx += 1
    return x
end

function Base.rand(rng::FileRNG, ::Type{Float64})
    return rand(rng)
end

function Base.rand(rng::FileRNG, ::Type{T}) where {T}
    error("FileRNG only supports Float64")
end

Random.randn(rng::FileRNG) = rand(rng)

rng = FileRNG(randn_vec)
FLORIDyn.set_rng(rng)

include("test_windfield.jl")

```

In my package I defined:

```julia
# global variables
RNG::AbstractRNG = Random.default_rng()

function set_rng(rng)
    global RNG
    RNG = rng
end

```

This means, normally the default RNG is used, but for the unit tests the FileRNG is used.

---

<div class="post-metadata">

**Author:** ![jdad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdad/32/4739_2.png) [@jdad](https://discourse.julialang.org/u/jdad)\
**Post date:** [June 17, 2025, 1:33pm UTC](https://discourse.julialang.org/t/matlab-to-julia-random-number-generators/129937/20 "2025-06-17T13:33:34Z")

</div>

Possibly you could try to use [StableRNGs](https://github.com/JuliaRandom/StableRNGs.jl/tree/master) which is really a [https://en.wikipedia.org/wiki/Lehmer\_random\_number\_generator](https://en.wikipedia.org/wiki/Lehmer_random_number_generator) and as such seems to have a Matlab implementation [https://fr.mathworks.com/matlabcentral/fileexchange/46174-a-function-to-implement-the-prng-using-lehmer-random-number-generator-algorithm](https://fr.mathworks.com/matlabcentral/fileexchange/46174-a-function-to-implement-the-prng-using-lehmer-random-number-generator-algorithm)

Caveat emptor : I have not tested they are really same (I dot not have a Matlab instance on my laptop)

Hope it could help,
