Re-posted from: https://blog.glcs.io/juliacon-2025
This post is a cleaned-up transcriptof the JuliaCon 2025 talkIntegrating Julia and MATLAB: Julia and MATLAB Can Coexistby Steven Whitaker.Check out the submission pagefor the talk abstract and summary.To download a PowerPoint of the talk slides, click here.
Introduction
Thank you for the introduction.I’m going to be talking about Julia-MATLAB integration.I’ll start bytalking about why we might want to dothis. Why not just stick with MATLAB orwhy not transition entirely to Julia?I’ll talk about how to actually do theintegration and I’ll walk through anexample model. I’ll show youthe MATLAB code, show how it needs to betranslated to Julia and thenreintegrated back into the MATLABworkflow that we’re working with.And I’ll demonstrate some benchmark resultsfrom before and after doing the Julia-MATLAB integration.
MATLAB Is Everywhere, Julia Is Fast
To begin, I do want to say that fromour perspective MATLAB is greatsoftware. It’s used by businesses andpeople all over the world, and it haswithstood the test of time. MATLAB hasexcellent tooling and documentation. Ithas been the go-to for scientificcomputing and engineering, and it isubiquitous in modeling and simulation.By a quick raise of hands, who herehas written a model or a function in MATLAB?I think literally everyone (in the JuliaCon audience).Me too.Engineers have had time toamass decades worth of MATLAB modelsand workflows, which is to say MATLABisn’t going anywhere.
But is MATLAB the best option in allcases? Now, there’s this trade-offbetween speed and what I’ll callreputation. MATLAB has an incrediblygood reputation. It has excellenttooling. It’s robust and it has a ton ofother awesome features. It has gained areputation for being reliable and it isan established industry standard. Largecompanies may have hundreds of MATLABmodels and thousands upon thousands oflines of MATLAB code. But that makes itimpractical to switch all this MATLAB codeentirely over to Julia all atonce.
However, there may be instances whereMATLAB isn’t the best choice to use.For example, if you have performancecritical or large-scale models where speedis absolutely paramount,a language like Julia may be moresuitable for those cases.Let’s look at some concrete numbers.
Benchmark Comparisons
I pulled some benchmarks from theSciML benchmarks website. And as an aside forthose of you who haven’t heard about theSciML ecosystem, the Julia scientificmachine learning ecosystem isincredible. So check it out if youhaven’t yet.
So what these benchmarks do iscompare ODE solvers from variouslanguages for various ODEs and just seehow fast these ODE solvers compare.So for one example we have a non-stiffproblem here. We’re plotting how long ittakes these ODE solvers to solve thisnon-stiff problem. The Julia solvers arein green, MATLAB in orange. And lookingat this plot, we see that for thisparticular non-stiff problem, Julia is10 to 1000 times faster than MATLAB.

Now what about a stiff problem?Similar story for this particularstiff problem. Julia is 10 to 1000times faster than MATLAB.

Now consider if your long simulationsor parameter optimizations take hours oreven days to run in MATLAB.You have to start asking yourself: is itworth using MATLAB when time is money?Does the reputation of MATLAB reallyoutweigh the cost in time?
Introducing Julia with Minimal Disruptions
The key question is:How do we get Julia’s speedbut without rewriting all of our MATLABcode in Julia? How can we get that speedwithout major disruption, withoutcompletely retooling everything?
So another question: does anyone here bythe raise of hands work with large MATLAB codebases?All right, a few of you (in the JuliaCon audience).Like I said,companies have had decades to masstons of MATLAB code. And so if you’reworking at a company that has a largeMATLAB codebase, if you use MATLABevery day, your colleagues useMATLAB every day, and, frankly, the codeworks, it runs, it gives the resultsthat you needthese are allvalid reasons for sticking with MATLAB.But the speedJulia is fast! Andsome might say that Julia is thesuperior language. That’s whywe’re here at JuliaConwe want touse Julia!
The good news is that thereis a way to introduce Julia into yourMATLAB workflows, and you can do thiswith minimal disruption.You want to start small. Pinpoint theparticular pain point in your MATLABworkflow and starttargeting that area. You want to keepyour existing MATLAB workflows intact.That way you help keep people on boardwith your project. But mostimportantly, you also want to showmeaningful performance wins becausethat ultimately gets people’sattention.
Example Model
For the rest of my talk,I will walk through the process ofdoing Julia-MATLAB integrationusing an example model.The example model that I’ll useincludes 50 equations and statevariables along with 37 modelparameters.
We’ll also have discreteevents and continuous events.For the discrete events, we willupdate one of the parameters at fourspecific time points along thesimulation. An example of this inpractice might be injecting a dose ofmedicine or modifying the thrustprovided by a rocket.
We’ll also have a continuous event wherewe modify a state variable when itreaches a certain value. Aclassic example is when modelingthe velocity of objects that collidewith boundaries. For example, if youdrop a ball, that ball is going to falluntil it hits the ground. And when ithits the ground, it doesn’t keepfalling. There’s an event that occursthat causes the ball to bounce.That’s the sort of thing that’s capturedby these continuous events.
For our example, we’ll look at twoproblems of interest. One is just simplysolving the ODE one time. How long doesit take to do that? But then inpractice, we don’t normally solve an ODEa single time and then call itquits. Normally, we’re solving ODEs many,many times. So, we’re also going to lookat doing a parameter sweep where we’llsolve this example model ODE withabout 200,000 different sets of modelparameters and then choose the one touse in production.
Model Plots

To illustrate this model a bit more,here are three of the state variablesplotted over time. The first plot is astate variable of interest. Thismight representthe position of a mechanical part, ormaybe it’s the temperature of concreteor some other substance that we’remodeling over time.
The second plot illustrates the discreteevents. At these particular timepoints, we’re changing one of the modelparameters, and we see how thatinfluences the time course for the statevariable.
And then the third plotillustrates the continuous events where,when this state variable reaches a valueof -10 or -2, we negate its derivativeand we see how the time course isinfluenced as a result.
Looking back at the first statevariable here, I’m plotting it for twodifferent sets of model parameters. Thefirst set of model parameters results inthese large oscillations while thesecond set of model parameters hasvirtually no oscillations.

MATLAB ODE Solve Timing
The first question is how long did ittake to solve this ODE one time so we couldget this plot.Solving this ODE in MATLAB took about 20milliseconds. Okay, so maybe that’s notso bad.
Now, going back to this plot,like I mentioned, this state variablemight represent the position of amechanical part. And so if we have theseoscillations, we can imagine that thoseoscillations cause wear on thismechanical part. And as a result, wewould love to use the second set ofmodel parameters so that there’s lesswear on that part, which means we don’thave to replace it as often, which savesour company money. The problem is wedon’t know what those parametersare beforehand. Okay. So, what we’ll dois pick 200,000 differentsets of parameter values. We’ll solvethe ODE with each of those sets ofparameter values and choose theparameter set that minimizes theoscillations so that we don’t have toreplace this part so often.
Now, if we do this parameter sweep inMATLAB, it takes about five hours torun on my laptop.
Now, if you run this exactly one time,maybe that’s not such a huge deal. Butif this is part of continuousintegration or testing or if you do aparameter sweep for many differentmodels and many different workflows, youcan see how the time starts to add upquickly.
So, we want to see how Julia can fare inthis situation.What we’re going to do is we’re goingto take our MATLAB parameter sweep andtranslate thatinto Julia but then reconnect it intoour MATLAB workflow.
Julia vs MATLAB for Simulations
The first thing to mention whenconverting from MATLAB to Julia is thesyntax. MATLAB and Juliahave a very similar syntax. MATLABwas the language that I used primarilybefore I started using Julia, and when Istarted learning Julia it almost didn’tfeel like I was learning a new language.That’s how similar the syntax was to me.
In terms of the dynamics, Julia isdesigned for performance. In MATLAB,every time the ODE solver calls out to yourdynamics function it has to allocate newmemory to store the results ofthe computed state derivatives. Whereasin Julia, you can allocate that memoryup front and then every time the ODEsolver calls out to your dynamicsfunction, it can reuse that memory,which boosts performance.
Events and Callbacks
I found that in Julia working withevents and callbacks was more intuitiveand easier to do. For this particularexample, I could define them infewer lines of code in Julia. Juliaprovides for better code organizationand it also provides many pre-builtcallbacks that you can use out of thebox.
So, looking more into events andcallbacks:here’s some example code in MATLABand in Julia for defining events andcallbacks.
%% MATLAB% In events_func.mv(n+1) = u(u49) + 2;v(n+2) = u(u49) + 10;% In callback_func.mif any(ismember([n + 1, n + 2], ie)) u(u50) = -u(u50);end
# Julia# In callbacks.jlevent1(u, t, integrator) = u[u49] + 2event2(u, t, integrator) = u[u49] + 10callback!(integrator) = integrator.u[u50] = -integrator.u[u50]ContinuousCallback(event1, callback!)ContinuousCallback(event2, callback!)
In MATLAB we have one file for theevents and then a separate file for allthe callbacks. Whereas in Julia we candefine the events and the correspondingcallbacks together in the same filewhich allows for better codeorganization.
Additionally, in MATLAB we have a singlefunction that defines all of the eventsand then we have a single function thatdefines all of the callbacks. In Juliawe can be more modular. We can define asingle function per event, a singlefunction per callback.
And then finally,in MATLAB there’s more bookkeeping thatwe have to do on our own. We have tokeep track of indexes of the events. Wehave to manually check if events occurand manually call the correct callbacksif those events occur. Whereas Juliatakes care of all of that for us. InJulia, all we have to do is explicitlypair an event with its callback and thenJulia takes care of the rest. Julia willcheck if the event occurs. It will thencall the correct callback that youassigned it and we don’t have to worryabout that ourselves.
So again, I foundthat working with events and callbacksin Julia was more intuitive andeasier to do.
Julia Is Easy to Learn
Now, another consideration when adoptinga new software is how much learningyou have to do to get up andrunning with it. I already mentionedthe syntax. Julia syntax is similar toMATLAB, and so that isn’t much of abarrier to entry.
Then there’s also what packages areavailable and how quickly can Ilearn those packages. For thisparticular example I only needed to usetwo Julia packages to get it up andrunning. I used DiffEqCallbacks.jl forthe events and callbacks andOrdinaryDiffEq.jl for setting up and solving theODE.
And then perhaps more importantly:part of learning the package is goingthrough its documentation andlearning how to use the package from thedocumentation. So how good is thedocumentation?
Particularly for the SciML ecosystem,but also other ecosystems in Julia, thedocumentation is excellent. So if youlook at the OrdinaryDiffEq.jl documentationit will clearly go through how to set upan ODE problem, how to solve it, and whatoptions are available for solving. Italso has a list of differentsolvers and shows you how to swapout different solvers with essentiallyjust a single line of code change inJulia.
Then the DiffEqCallbacks.jl documentationis similarly good. Itdescribes quite a few ready-to-usecallbacks that you can use. There’s thePresetTimeCallback for the discreteevents at specific times. There are alsomore advanced callbacks such as thosefor step size control.
And then kind of the cherry on top forconverting from MATLAB to Julia isthere’s one of the pages of thedocumentation that is a solver comparison.And so basically what it does is itlists the MATLAB solvers andthen it says what are the correspondingJulia solvers you can use. So if in MATLAByou’re using the ode45 solver, thisweb page will say, “okay, the correspondingJulia solver is DP5, but then there arealso these other solvers you might wantto try that might perform better.”
So, the excellent documentation, theexcellent package ecosystem and thesimilar syntax between Julia and MATLABreally makes transitioning from MATLABto Julia a breeze.
Julia-MATLAB Integration Demo
Doing the actual integration we usethe MATFrost.jl package. MATFrost.jl is apackage that was developed by ASML. So,thank you to ASML for developing thepackage and open sourcing it for theJulia community to use. And I willillustrate the process of integratingJulia back into MATLAB via a live demo.So, I’m going to switch over to MATLAB.
% demo.m[u0, tspan, p] = get_inputs();[p_opt_indexes, grid_vals, lb_cons, ub_cons] = get_gridsearch_inputs();ticp_opt = gridsearch(u0, tspan, p, p_opt_indexes, grid_vals, lb_cons=lb_cons, ub_cons=ub_cons);tocsol0 = solve(u0, tspan, p);p.p(p_opt_indexes) = p_opt;sol = solve(u0, tspan, p);plot(sol0.Time, sol0.Solution(1,:), Color="r", LineWidth=2);hold onplot(sol.Time, sol.Solution(1,:), Color="b", LineWidth=2);hold offlegend("Before", "After");title("u1 Before and After Parameter Sweep");xlabel("Time");ylabel("Value");
Alright. So, here’s the MATLABworkflow we’re going to work with.In this case, it’s fairly minimal.That’s for demonstration purposes, butthe main point is we have someworkflow, but there’s a particular partof the workflow that’s causing us grief,and we want that to be faster, but wewant to make it faster without entirelydestroying or disrupting our workflow.
So, I’m going to start this running.
The Workflow
In this workflow, we have somepre-processing. We’re just gettinginputs ready for our computation. Thecore computation in this workflow isthis gridsearch function.This gridsearch function is ourimplementation of that parameter sweepthat I mentioned.And then once we have the output, we dosome post-processing. In this case,we’re just plotting values.
But again,the main point is that we have aworkflow, but there’s a pain point inthat workflow that we want to be better.We want to make it better with Julia.
MATLAB Results

So there are our results.Alright, so here I’m plotting the firststate variable before the parametersweep and after the parameter sweep. Andas expected, we see that theoscillations are smaller than before.And then if we look at the elapsed time,it took about 40 seconds for this to runin MATLAB.
Translating to Julia
Okay. So now we want Julia. So, the firststep is to take the part of the workflowthat we want to improve, and we’re goingto translate that intoJulia.
# JuliaModel/src/gridsearch.jlfunction gridsearch( u0::Vector{Float64}, tspan::Vector{Float64}, p::Vector{Float64}, cb_times::Vector{Float64}, cb_values::Vector{Float64}, p_opt_indexes::Vector{Int64}, grid_vals::NTuple{5, Vector{Float64}}, lb_cons::Float64, ub_cons::Float64, abstol::Float64, reltol::Float64,) # `p` is updated in place during the callbacks, # so take a copy that will be used to re-initialize `p` # at the start of each loop iteration below. p_original = copy(p) callback = get_callbacks(cb_times, cb_values) prob = ODEProblem{true}(dynamics!, u0, (tspan[1], tspan[2]), p) solver = DP5() sol0 = OrdinaryDiffEq.solve(prob, solver; callback, abstol, reltol) loss0 = max_variation(sol0) losses = Array{Float64, length(grid_vals)}(undef, length.(grid_vals)...) loss_opt = loss0 p_opt = p_original[p_opt_indexes] for (i, p_vals) in enumerate(Iterators.product(grid_vals...)) p .= p_original p[p_opt_indexes] .= p_vals new_prob = remake(prob; p) sol = OrdinaryDiffEq.solve(new_prob, solver; callback, abstol, reltol) if constraints_met(sol, lb_cons, ub_cons) l = max_variation(sol) if l < loss_opt loss_opt = l p_opt .= p_vals end losses[i] = l else losses[i] = Inf end end return (p_opt, loss_opt, loss0, losses)end
So, we take the gridsearchfunction, we look at its implementation,we translate it into Julia, and we end upwith a Julia function. I’m calling itgridsearch just like the MATLABfunction. It takes the same inputs.It does the parameter sweep. It returnsthe same outputs as the MATLAB version.So the same computation, just now writtenin Julia instead of MATLAB.
And then we’re going to house thisfunction inside of a Julia package. Inthis case I called the Julia packageJuliaModel. So now we have a Juliapackage. It has our Julia implementationof gridsearch, our parameter sweep.
Using MATFrost.jl
Nowwe need to build a bridge using MATFrost.jl.So, MATFrost.jl needs to be a dependencyof our Julia package, even if thepackage doesn’t use it at all, becausewhat we’re going to do isinstantiate our Julia package’s packageenvironment. Then importMATFrost.jl and then callMATFrost.install.And what this does is it takes our Juliapackage and creates a MATLAB class outof that package, and in this case and ituses the same name.
So now we havea JuliaModel Julia package, but nowwe have a JuliaModel MATLAB class,which we’ll use to interface withJulia. So this is what MATFrost.jlcreated for us.
Minimizing Disruptions
So now that we have that MATLAB class,now we need to start using this code tostart interfacing with Julia. Now, wecould add this directly to the workflowitself, but again, we want to minimizedisruptions to the workflow, especiallyif we have colleagues that are alsoworking on this workflow simultaneouslywith us.
So, the key idea here is we wantcalling out to Julia to bean implementation detail from theperspective of the workflow. So we don’twant the workflow to care that we’recalling out to Julia. We want theworkflow to work as is.
So, what we’regoing to do is we’re going tocreate a new MATLAB function,but within that function wecall out to Julia. This MATLABfunction I’m going to call gridsearch_julia,and importantly it needs the sameAPI as whatever function we’rereplacing. So, I’m going to have it takethe same inputs. It’s going to returnthe same output,but then internally there’s not much toit, again, because all the functionalityis in Julia.
% gridsearch_julia.mfunction [p_opt, loss_opt, loss0, losses] = gridsearch_julia(u0, tspan, p, p_opt_indexes, grid_vals, options) arguments u0 tspan p p_opt_indexes grid_vals options.lb_cons = 1.65 options.ub_cons = 2.25 options.abstol = 1e-7 options.reltol = 1e-7 end jl = get_julia(); out = jl.gridsearch(u0, tspan, p.p, p.cb_times, p.cb_values, p_opt_indexes, grid_vals, ... options.lb_cons, options.ub_cons, options.abstol, options.reltol); [p_opt, loss_opt, loss0, losses] = out{:};end
What this function isgoing to do is I have this function get_juliawhich is a function I wrote thatinstantiates a JuliaModel object. Thenwith that object I can interface withJulia. So if I do jl.gridsearch righthere, this gridsearch is not the MATLABfunction. This is the gridsearch that Iwrote in Julia in my Julia package. Sowhat we’re doing here is takingour MATLAB values and passingthem over to Julia. Julia is going torun the gridsearch function I definedin Julia. It’ll do the parameter sweepand then it will return a Tuple ofvalues which is a cell array in MATLAB.So I just unpack that cell array to getthe appropriate output for thisfunction.
But again the main point tominimize disruption for the workflow isthat this new function needs tohave the same API so that fromthe workflow’s perspective nothingchanges.
Julia-MATLAB Results
Let’s see how this works. So,I’m just going to change the onefunction.(Change gridsearch to gridsearch_julia in demo.m.)Importantly I’m not changing any of thepre-processing or post-processing. I’mnot changing any of the inputs oroutputs. And then if I run it I get myresult.The plot looks pretty much the same aslast time, maybe exactly the same.And if we look at the timing, it was100 times faster.

So, from the workflow’s perspective,essentially nothing changed. I calledout to a new function, but didn’t haveto change any the pre- orpost-processing,but now the workflow runs 100 timesfaster than before.
So this was a 40-second version ofthe parameter sweep, not the five hourversion. So, does it scale? Let’s lookat some other benchmarks.
ODE Solve Timing: MATLAB vs Julia-MATLAB
Alright, first looking at a single ODEsolve.If we just did a single ODE solve inJulia and then did the Julia-MATLABintegration, that ODE solve takes 10milliseconds. So, it’s twice as fast asthe pure MATLAB version. I will notethat there is a significant overhead tousing MATFrost.jl for the first call, butsubsequent calls are faster. So a 2xspeed up, that’s something, but it’s notthe 10 to 1000 times speed up thatwe were seeing with the SciML benchmarks.But again, we don’t typically solvean ODE a single time.
So what about theparameter sweep? You’ll recall that inMATLAB the parameter sweep with 200,000ODE solves took about five hours to run.In Julia, that time dropped to less than two minutes.So that’s 163 times faster than thepure MATLAB version.

So I think that’sfast enough for this meme. I am speed.Julia is speed. So that’s amazing. Wetook our workflow,we created a new MATLAB functionthat called out to Julia internally (butfrom the workflow’s perspective nothingreally changed) but now it’s 163 timesfaster.
Uncompromised Simulation Accuracy
Okay, so it’s faster, but now the otherquestion is are the results still goodor are they garbage now.
The resultsare still good. Here, I’m plotting thefirst state variable before and afterthe parameter sweep; the MATLAB resultsare in red, the blue dots arethe Julia results. And we see that theJulia results align with the MATLABresults.

I also checked all the otherstate variables, and in all cases all ofthe Julia-MATLAB integrated resultsare within 1/100th of a percent comparedto the MATLAB results. So, weachieve the accuracy that we want forour simulations at a fraction of thecomputational cost.
Julia-MATLAB Integration with GLCS
So now if you want these speed ups inyour code, but you’re not quite sure how tostart, feel free to reach out to us atGLCS. We have an approach for helpingclients pinpoint these areas of concernin their MATLAB workflows. We helptranslate the code to Julia andreintegrate it back into MATLAB and weensure that we meet the accuracy andperformance metrics that we need to.

Conclusion
So, unlock up to 100 times faster performanceby integrating Julia. Intoday’s example, we saw even faster than100 times faster. Adopt Juliaseamlessly. Integrate it step by stepwithout disrupting your MATLABworkflows. So, enhance the MATLAB codethat you have. Elevate its capabilitiesby integrating Julia and takingadvantage of its speed and flexibility.
Thank you.
Q&A
-
Audience:Can you show us that
get_juliafunction you mentioned?Yeah. So we want to see the
get_juliafunction that I wrote in MATLAB.So yes,here it is.So basically I made use of a persistentvariable to make sure I’m notreinitializingthe Julia instance every time.So I’m reusing the same Julia instanceevery time I call this function. But thefirst time there’s that overhead that Imentioned.Audience:Your MATLAB code isn’t showing.
function jl = get_julia() persistent jl_ if isempty(jl_) mjl = JuliaModel(); jl_ = mjl.JuliaModel; end jl = jl_;endOh, thank you. I need to actuallyget me out of the slideshow.There we go.Okay. Persistent variable. So that wayon subsequent calls to the function, I’musing the same initialization of theJulia runtime. So we’re not wastingresources every time.But yeah, here is where we’re actuallyinitializing the
JuliaModelMATLABobject.Yeah, there’s nothing to it. There’s noparameters toI mean you can change the Julia versionif you want but if you have everythingset up in your PATH you don’t need topass anything to it. -
Audience:Just a quick question, about how long didit take to, when you call MATFrost.jlto install
JuliaModel, how longdoes that take?That’s a good question. I don’t rememberoff the top of my head.
Audience:Well, it was quick, I’m assuming, orit just builds a little bit of MATLABcode, right?
Right, if I remember correctly, itwas on order of seconds, maybe minutes, butnothing terrible.
-
Audience:Does MATFrost.jl work with Linux oris it still like only for Windows?
As far as I know, it’s only supportedfor Windows.
-
Audience:Some of these numbers scare me a littlewith the performance comparisonsbetween Julia and MATLAB. I knowthere’s a huge difference in LAPACKand BLAS versioning, right, MATLABtypically goes for a more numericalstable version of LAPACK versus ifJulia will use OpenBLAS by default, Ithink (I might be wrong on that). Couldyou tell me what version of each you’reusing for both?
I do not know what versions I’musing.
Audience:You just, in the MATLAB terminal, justdo
version -lapack.There’s an “i” in “version”.Oh, thank you. Is it capital LAPACK orlower?
Audience:That’s correct. Yeah.Okay, that is a faster one. Okay.
-
Audience:Can you actually like create structs ormore complicated types than arrays withthis?
So can you create structs and arrays inJulia, are you saying?
Audience:No no, like in MATLAB can you like createstructs from Julia? Like if you define adata type in Julia can you like createit here in MATLAB?
Yeah. So one of the key things toworking with MATFrost.jl is everythingneeds to be concretely typed.So, like, if you create a struct, you canhave nested structs and they basicallyget translated to MATLAB structs, but youneed to concretely type it as a
Float64or anIntdepending on whatever datatype you have. So, no abstract types,and thefunction calls also need to be typed. -
Audience:I remember a long time agowhen I was calling C code from MATLAB ithad to use these MEX files. Is thatwhat it’s using under the hood here oris there some new fancier way of callingexternal code and MEX files that this isusing?
Yeah, so MATFrost.jl does use a MEXfile to work.
Additional Links
- JuliaCon Talk Submission Page
- Submission page for the talk,including an abstract and summary.
- Julia and MATLAB Integration at GLCS
- Our web page detailing our Julia and MATLAB integration service.
MATLAB is a registered trademarkof The MathWorks, Inc.
Cover image:The JuliaCon 2025 logowas obtained from https://juliacon.org/2025/.
]]>

