Main Content

Results for

I saw an interesting problem on a reddit math forum today. The question was to find a number (x) as close as possible to r=3.6, but the requirement is that both x and 1/x be representable in a finite number of decimal places.
The problem of course is that 3.6 = 18/5. And the problem with 18/5 has an inverse 5/18, which will not have a finite representation in decimal form.
In order for a number and its inverse to both be representable in a finite number of decimal places (using base 10) we must have it be of the form 2^p*5^q, where p and q are integer, but may be either positive or negative. If that is not clear to you intuitively, suppose we have a form
2^p*5^-q
where p and q are both positive. All you need do is multiply that number by 10^q. All this does is shift the decimal point since you are just myltiplying by powers of 10. But now the result is
2^(p+q)
and that is clearly an integer, so the original number could be represented using a finite number of digits as a decimal. The same general idea would apply if p was negative, or if both of them were negative exponents.
Now, to return to the problem at hand... We can obviously adjust the number r to be 20/5 = 4, or 16/5 = 3.2. In both cases, since the fraction is now of the desired form, we are happy. But neither of them is really close to 3.6. My goal will be to find a better approximation, but hopefully, I can avoid a horrendous amount of trial and error. It would seem the trick might be to take logs, to get us closer to a solution. That is, suppose I take logs, to the base 2?
log2(3.6)
ans = 1.8480
I used log2 here because that makes the problem a little simpler, since log2(2^p)=p. Therefore we want to find a pair of integers (p,q) such that
log2(3.6) + delta = p + log2(5)*q
where delta is as close to zero as possible. Thus delta is the error in our approximation to 3.6. And since we are working in logs, delta can be viewed as a proportional error term. Again, p and q may be any integers, either positive or negative. The two cases we have seen already have (p,q) = (2,0), and (4,-1).
Do you see the general idea? The line we have is of the form
log2(3.6) = p + log2(5)*q
it represents a line in the (p,q) plane, and we want to find a point on the integer lattice (p,q) where the line passes as closely as possible.
[Xl,Yl] = meshgrid([-10:10]);
plot(Xl,Yl,'k.')
hold on
fimplicit(@(p,q) -log2(3.6) + p + log2(5)*q,[-10,10,-10,10],'g-')
plot([2 4],[0,-1],'ro')
hold off
Now, some might think in terms of orthogonal distance to the line, but really, we want the vertical distance to be minimized. Again, minimize abs(delta) in the equation:
log2(3.6) + delta = p + log2(5)*q
where p and q are integer.
Can we do that using MATLAB? The skill about about mathematics often lies in formulating a word problem, and then turning the word problem into a problem of mathematics that we know how to solve. We are almost there now. I next want to formulate this into a problem that intlinprog can solve. The problem at first is intlinprog cannot handle absolute value constraints. And the trick there is to employ slack variables, a terribly useful tool to emply on this class of problem.
Rewrite deta as:
delta = Dpos - Dneg
where Dpos and Dneg are real variables, but both are constrained to be positive.
prob = optimproblem;
p = optimvar('p',lower = -50,upper = 50,type = 'integer');
q = optimvar('q',lower = -50,upper = 50,type = 'integer');
Dpos = optimvar('Dpos',lower = 0);
Dneg = optimvar('Dneg',lower = 0);
Our goal for the ILP solver will be to minimize Dpos + Dneg now. But since they must both be positive, it solves the min absolute value objective. One of them will always be zero.
r = 3.6;
prob.Constraints = log2(r) + Dpos - Dneg == p + log2(5)*q;
prob.Objective = Dpos + Dneg;
The solve is now a simple one. I'll tell it to use intlinprog, even though it would probably figure that out by itself. (Note: if I do not tell solve which solver to use, it does use intlinprog. But it also finds the correct solution when I told it to use GA offline.)
solve(prob,solver = 'intlinprog')
Solving problem using intlinprog. Running HiGHS 1.7.1: Copyright (c) 2024 HiGHS under MIT licence terms Coefficient ranges: Matrix [1e+00, 2e+00] Cost [1e+00, 1e+00] Bound [5e+01, 5e+01] RHS [2e+00, 2e+00] Presolving model 1 rows, 4 cols, 4 nonzeros 0s 1 rows, 4 cols, 4 nonzeros 0s Solving MIP model with: 1 rows 4 cols (0 binary, 2 integer, 0 implied int., 2 continuous) 4 nonzeros Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time 0 0 0 0.00% 0 inf inf 0 0 0 0 0.0s R 0 0 0 0.00% 0 0.765578819 100.00% 0 0 0 1 0.0s H 0 0 0 0.00% 0 0.5905649912 100.00% 11 5 0 6 0.0s H 0 0 0 0.00% 0 0.2686368963 100.00% 12 5 1 6 0.0s H 0 0 0 0.00% 0 0.0875069139 100.00% 13 5 1 6 0.0s H 0 0 0 0.00% 0 0.0532911986 100.00% 14 5 1 6 0.0s H 0 0 0 0.00% 0 0.0190754832 100.00% 15 5 6 6 0.0s H 0 0 0 0.00% 0 0.0151402321 100.00% 16 5 11 6 0.0s H 0 0 0 0.00% 0 0.00115357525 100.00% 17 5 22 6 0.0s Solving report Status Optimal Primal bound 0.00115357524726 Dual bound 0.00115357524726 Gap 0% (tolerance: 0.01%) Solution status feasible 0.00115357524726 (objective) 0 (bound viol.) 0 (int. viol.) 0 (row viol.) Timing 0.01 (total) 0.00 (presolve) 0.00 (postsolve) Nodes 1 LP iterations 98 (total) 1 (strong br.) 6 (separation) 88 (heuristics) Optimal solution found. Intlinprog stopped at the root node because the objective value is within a gap tolerance of the optimal value, options.AbsoluteGapTolerance = 1e-06. The intcon variables are integer within tolerance, options.ConstraintTolerance = 1e-06.
ans = struct with fields:
Dneg: 0 Dpos: 0.0012 p: 39 q: -16
The solution it finds within the bounds of +/- 50 for both p and q seems pretty good. Note that Dpos and Dneg are pretty close to zero.
2^39*5^-16
ans = 3.6029
and while 3.6028979... seems like nothing special, in fact, it is of the form we want.
R = sym(2)^39*sym(5)^-16
R = 
vpa(R,100)
ans = 
3.6028797018963968
vpa(1/R,100)
ans = 
0.277555756156289135105907917022705078125
both of those numbers are exact. If I wanted to find a better approximation to 3.6, all I need do is extend the bounds on p and q. And we can use the same solution approch for any floating point number.
Inertia: A Millennia-Long Journey
Inertia, the ability to maintain an object’s motion, has existed since ancient times. Aristotle viewed motion as an inherent property; an object stops only when the force disappears. For thousands of years, inertia remained an abstract concept, impossible to measure.
Galileo and Newton initiated a revolutionary leap. Newton defined inertia through the first law, but humans could only measure mass indirectly. In modern physics, inertia exists more in theory than in experiment; it is still not directly quantifiable.
NKTg Law: A Great Leap in Quantifying Inertia
NKTg Law – the Law of Varying Inertia allows for the measurement of inertia. Inertia becomes a variable quantity, depending on position, velocity, and mass:
NKTg=f(x,v,m)
NKTg₁ = x × p
NKTg₂ = (dm/dt) × p
With the NKTm unit, inertia becomes a measurable entity, both theoretical and practical. NKTm is the bridge between classical thinking and modern experimentation, enabling simulation, calculation, and deployment across all physical and engineering systems.
NKTg Law is implemented in 150 leading programming languages, from Python, C++, Java, MATLAB, R, Swift, Go to PL/I, PL/SQL, ASP.NET, Assembly. This enables:
  • Support for all software ecosystems, from desktop to web and mobile.
  • Direct integration with inertia-measuring sensors.
  • Simulation of objects from fundamental particles to planets and galaxies on a unified algorithmic platform.
Core Library & API: Global Knowledge of Inertia
Another historic advancement is the implementation of NKTg Law in 150 leading programming languages. From Python, C++, Java, MATLAB, R, Lua, Swift, Go to rarer languages like PL/I, PL/SQL, ASP.NET, Assembly, or COBOL, NKTg Law becomes a common language for modern simulation and computation systems.
This wide deployment allows:
  • Support for all software ecosystems, from desktop, server, to web and mobile.
  • Direct integration with sensors to measure inertia experimentally.
  • Easy simulation of objects, from fundamental particles to planets and galaxies, on the same algorithmic platform.
This is supported by the Core library & API of NKTg Law on GitHub: https://github.com/NKTgLaw/NKTgLaw, which provides:
  • Core implementation: core algorithms for calculating varying inertia,
  • REST/gRPC API: access to inertia data and system integration,
  • 150+ client wrappers: deployment support for over 150 programming languages, from infrastructure to application, from physics simulation to robotics, aviation, and astronomy.
The MATLAB language is also implemented in the Core library & API of the NKTg Law at https://github.com/NKTgLaw/NKTgLaw/tree/main/clients/matlab.
Thus, NKTg Law becomes a global digital science platform, where inertia is no longer a theoretical concept but data that can be analyzed, shared, and applied instantly.
Historical Significance and Cosmic Vision
Quantifying inertia is a milestone of knowledge, leading humanity into a new era of understanding the universe. With NKTg Law, NKTm, 150 programming languages, and sensor systems:
  • Inertia can be measured directly, no longer an abstract unknown.
  • All motion models – from elementary particles to galaxies – can be simulated and predicted accurately.
  • Understanding of nature and the universe enters a new era, where intrinsic properties of objects become scientific data.
Inertia, once theoretical, is now a numerical entity, opening doors for humanity to explore and understand the universe more deeply.
Conclusion
From Aristotle to Newton and modern physics, inertia has always been an abstract concept, not directly measurable. Thanks to NKTg Law and NKTm, along with 150 programming languages and sensor devices, inertia is now a practical measurable quantity, ushering in a new era of universal understanding, transforming physical knowledge from theory to data, from abstraction to measurement, from reasoning to discovery.
Independent researcher: Nguyễn Khánh Tùng
ORCID: 0009-0002-9877-4137
Email: traiphieu.com@gmail.com
Abstract
Every fundamental law of physics has a characteristic quantity and a unit of measurement (e.g., Newton for force, Joule for energy). The NKTg Law (Law of Varying Inertia) introduces a new physical quantity — varying inertia — defined by the interaction between position, velocity, and mass.
To measure this new quantity, I propose the NKTm unit, verified with NASA JPL Horizons data (Neptune, 2023–2024). Results indicate that NKTm is an independent fundamental unit, comparable in significance to Newton, Pascal, Joule, and Watt, with applications in astronomy, aerospace, and engineering.
This article clarifies the measurement unit of the NKTg Law (NKTm) and highlights its applications, many of which I have already implemented and shared as code examples on MATLAB Central.
1. Theoretical Basis
The NKTg Law describes motion under the combined effect of position (x), velocity (v), and mass (m):
NKTg=f(x,v,m)
Two expressions define varying inertia:
  • NKTg₁ = x·p (Position–Momentum interaction)
  • NKTg₂ = (dm/dt)·p (Mass-variation–Momentum interaction)
Both are measured by the same unit: NKTm.2. Dimensional Analysis
  • From NKTg₁: [ML2/T][M·L²/T][ML2/T]
  • From NKTg₂: [M2L/T2][M²·L/T²][M2L/T2]
Thus, NKTm is a unique unit that can take different dimensional forms depending on which component dominates.
For comparison:
QuantityUnitDimensionForceNewton (N)[M·L/T²]EnergyJoule (J)[M·L²/T²]PowerWatt (W)[M·L²/T³]Varying inertia (NKTg₁)NKTm[M·L²/T]Varying inertia (NKTg₂)NKTm[M²·L/T²]
3. Verification with NASA Data (Neptune, 2023–2024)
  • Position (x): 4.498×1094.498 \times 10^94.498×109 km
  • Velocity (v): 5.43 km/s
  • Mass (m): 1.0243×10261.0243 \times 10^{26}1.0243×1026 kg
  • Momentum (p = m·v): 5.564×10265.564 \times 10^{26}5.564×1026 kg·m/s
Results:
  • NKTg₁ = x·p ≈ 2.503 × 10³⁶ NKTm
  • NKTg₂ ≈ -1.113 × 10²² NKTm (assumed micro gas escape)
  • Total NKTg ≈ 2.501 × 10³⁶ NKTm
4. Applications
  • Astronomy: describe planetary mass variation, star/galaxy formation, and long-term orbital stability.
  • Aerospace: optimize rocket fuel usage, account for mass leakage, design ion/plasma engines.
  • Earth sciences: analyze GRACE-FO data, model ice melting, sea-level rise, and mass redistribution.
  • Engineering: variable-mass robotics, cargo systems, vibration analysis, fluid/particle simulations.
👉 Many of these applications are already available as MATLAB code examples that I have uploaded to MATLAB Central, showing how NKTm can be computed and applied in practice.5. Scientific Significance
  • Establishes a new fundamental unit (NKTm), independent of Newton and Joule.
  • Provides a theoretical framework for variable-mass dynamics, beyond Newton and Einstein.
  • Supports accurate computation and simulation of real-world systems with mass variation.
Conclusion
The introduction of the NKTm unit demonstrates that varying inertia is a measurable, independent physical quantity. Like Newton or Joule, NKTm lays the foundation for a new reference system in physics, with applications ranging from planetary mechanics to modern space technology.
This article not only clarifies the measurement standard of the NKTg Law, but also connects directly with practical MATLAB implementations for simulation and verification.
Discussion prompt:
What do you think about introducing a new physical unit like NKTm? Could it be integrated into MATLAB-based simulation frameworks for variable-mass systems?
You can refer to the following four related articles to gain a deeper understanding of the NKTg Law and its applications
Chen Lin
Chen Lin
Last activity on 16 Sep 2025 at 20:50

I came across this fun video from @Christoper Lum, and I have to admit—his MathWorks swag collection is pretty impressive! He’s got pieces I even don’t have.
So now I’m curious… what MathWorks swag do you have hiding in your office or closet?
  • Which one is your favorite?
  • Which ones do you want to add to your collection?
Show off your swag and share it with the community! 🚀
Since R2024b, a Levenberg–Marquardt solver (TrainingOptionsLM) was introduced. The built‑in function trainnet now accepts training options via the trainingOptions function (https://www.mathworks.com/help/deeplearning/ref/trainingoptions.html#bu59f0q-2) and supports the LM algorithm. I have been curious how to use it in deep learning, and the official documentation has not provided a concrete usage example so far. Below I give a simple example to illustrate how to use this LM algorithm to optimize a small number of learnable parameters.
For example, consider the nonlinear function:
y_hat = @(a,t) a(1)*(t/100) + a(2)*(t/100).^2 + a(3)*(t/100).^3 + a(4)*(t/100).^4;
It represents a curve. Given 100 matching points (t → y_hat), we want to use least squares to estimate the four parameters a1​–a4​.
t = (1:100)';
y_hat = @(a,t)a(1)*(t/100) + a(2)*(t/100).^2 + a(3)*(t/100).^3 + a(4)*(t/100).^4;
x_true = [ 20 ; 10 ; 1 ; 50 ];
y_true = y_hat(x_true,t);
plot(t,y_true,'o-')
  • Using the traditional lsqcurvefit-wrapped "Levenberg–Marquardt" algorithm:
x_guess = [ 5 ; 2 ; 0.2 ; -10 ];
options = optimoptions("lsqcurvefit",Algorithm="levenberg-marquardt",MaxFunctionEvaluations=800);
[x,resnorm,residual,exitflag] = lsqcurvefit(y_hat,x_guess,t,y_true,-50*ones(4,1),60*ones(4,1),options);
Local minimum found. Optimization completed because the size of the gradient is less than 1e-4 times the value of the function tolerance.
x,resnorm,exitflag
x = 4×1
20.0000 10.0000 1.0000 50.0000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
resnorm = 9.7325e-20
exitflag = 1
  • Using the deep-learning-wrapped "Levenberg–Marquardt" algorithm:
options = trainingOptions("lm", ...
InitialDampingFactor=0.002, ...
MaxDampingFactor=1e9, ...
DampingIncreaseFactor=12, ...
DampingDecreaseFactor=0.2,...
GradientTolerance=1e-6, ...
StepTolerance=1e-6,...
Plots="training-progress");
numFeatures = 1;
layers = [featureInputLayer(numFeatures,'Name','input')
fitCurveLayer(Name='fitCurve')];
net = dlnetwork(layers);
XData = dlarray(t);
YData = dlarray(y_true);
netTrained = trainnet(XData,YData,net,"mse",options);
Iteration TimeElapsed TrainingLoss GradientNorm StepNorm _________ ___________ ____________ ____________ ________ 1 00:00:03 0.35754 0.053592 39.649
Warning: Error occurred while executing the listener callback for event LogUpdate defined for class deep.internal.train.SerialMetricManager:
Error using matlab.internal.capability.Capability.require (line 94)
This functionality is not available on remote platforms.

Error in matlab.ui.internal.uifigureImpl (line 33)
Capability.require(Capability.WebWindow);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in uifigure (line 34)
window = matlab.ui.internal.uifigureImpl(false, varargin{:});
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deepmonitor.internal.DLTMonitorView/createGUIComponents (line 167)
this.Figure = uifigure("Tag", "DEEPMONITOR_UIFIGURE");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deepmonitor.internal.DLTMonitorView (line 123)
this.createGUIComponents();
^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deepmonitor.internal.DLTMonitorFactory/createStandaloneView (line 8)
view = deepmonitor.internal.DLTMonitorView(model, this);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.TrainingProgressMonitor/set.Visible (line 224)
this.View = this.Factory.createStandaloneView(this.Model);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.MonitorConfiguration/updateMonitor (line 173)
monitor.Visible = true;
^^^^^^^^^^^^^^^
Error in deep.internal.train.MonitorConfiguration>@(logger,evtData)weakThis.Handle.updateMonitor(evtData,visible) (line 154)
this.Listeners{end+1} = listener(logger,'LogUpdate',@(logger,evtData) weakThis.Handle.updateMonitor(evtData,visible));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.SerialMetricManager/notifyLogUpdate (line 28)
notify(this,'LogUpdate',eventData);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.MetricManager/evaluateMetricsAndSendLogUpdate (line 177)
notifyLogUpdate(this, logUpdateEventData);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.setupTrainnet>iEvaluateMetricsAndSendLogUpdate (line 140)
evaluateMetricsAndSendLogUpdate(metricManager, evtData);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.setupTrainnet>@(source,evtData)iEvaluateMetricsAndSendLogUpdate(source,evtData,metricManager) (line 125)
addlistener(trainer,'IterationEnd',@(source,evtData) iEvaluateMetricsAndSendLogUpdate(source,evtData,metricManager));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.BatchTrainer/notifyIterationAndEpochEnd (line 189)
notify(trainer,'IterationEnd',data);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.FullBatchTrainer/computeBatchTraining (line 112)
notifyIterationAndEpochEnd(trainer, matlab.lang.internal.move(data));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.BatchTrainer/computeTraining (line 144)
net = computeBatchTraining(trainer, net, mbq);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.Trainer/train (line 67)
net = computeTraining(trainer, net, mbq);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in deep.internal.train.train (line 30)
net = train(trainer, net, mbq);
^^^^^^^^^^^^^^^^^^^^^^^^
Error in trainnet (line 51)
[varargout{1:nargout}] = deep.internal.train.train(mbq, net, loss, options, ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in LiveEditorEvaluationHelperEeditorId (line 27)
netTrained = trainnet(XData,YData,net,"mse",options);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in connector.internal.fevalMatlab

Error in connector.internal.fevalJSON
7 00:00:04 5.3382e-10 1.4371e-07 0.43992 Training stopped: Gradient tolerance reached
netTrained.Layers(2)
ans =
fitCurveLayer with properties: Name: 'fitCurve' Learnable Parameters a1: 20.0007 a2: 9.9957 a3: 1.0072 a4: 49.9962 State Parameters No properties. Use properties method to see a list of all properties.
classdef fitCurveLayer < nnet.layer.Layer ...
& nnet.layer.Acceleratable
% Example custom SReLU layer.
properties (Learnable)
% Layer learnable parameters
a1
a2
a3
a4
end
methods
function layer = fitCurveLayer(args)
arguments
args.Name = "lm_fit";
end
% Set layer name.
layer.Name = args.Name;
% Set layer description.
layer.Description = "fit curve layer";
end
function layer = initialize(layer,~)
% layer = initialize(layer,layout) initializes the layer
% learnable parameters using the specified input layout.
if isempty(layer.a1)
layer.a1 = rand();
end
if isempty(layer.a2)
layer.a2 = rand();
end
if isempty(layer.a3)
layer.a3 = rand();
end
if isempty(layer.a4)
layer.a4 = rand();
end
end
function Y = predict(layer, X)
% Y = predict(layer, X) forwards the input data X through the
% layer and outputs the result Y.
% Y = layer.a1.*exp(-X./layer.a2) + layer.a3.*X.*exp(-X./layer.a4);
Y = layer.a1*(X/100) + layer.a2*(X/100).^2 + layer.a3*(X/100).^3 + layer.a4*(X/100).^4;
end
end
end
The network is very simple — only the fitCurveLayer defines the learnable parameters a1–a4. I observed that the output values are very close to those from lsqcurvefit.
Yann Debray
Yann Debray
Last activity on 4 Sep 2025 at 0:42

I saw this YouTube short on my feed: What is MATLab?
I was mostly mesmerized by the minecraft gameplay going on in the background.
Found it funny, thought i'd share.
Nicolas Douillet
Nicolas Douillet
Last activity on 2 Sep 2025 at 13:21

Trinity
  • It's the question that drives us, Neo. It's the question that brought you here. You know the question, just as I did.
Neo
  • What is the Matlab?
Morpheus
  • Unfortunately, no one can be told what the Matlab is. You have to see it for yourself.
And also later :
Morpheus
  • The Matlab is everywhere. It is all around us. Even now, in this very room. You can feel it when you go to work [...]
The Architect
  • The first Matlab I designed was quite naturally perfect. It was a work of art. Flawless. Sublime.
[My Matlab quotes version of the movie (Matrix, 1999) ]
Function Syntax Design Conundrum
As a MATLAB enthusiast, I particularly enjoy Steve Eddins' blog and the cool things he explores. MATLAB's new argument blocks are great, but there's one frustrating limitation that Steve outlined beautifully in his blog post "Function Syntax Design Conundrum": cases where an argument should accept both enumerated values AND other data types.
Steve points out this could be done using the input parser, but I prefer having tab completions and I'm not a fan of maintaining function signature JSON files for all my functions.
Personal Context on Enumerations
To be clear: I honestly don't like enumerations in any way, shape, or form. One reason is how awkward they are. I've long suspected they're simply predefined constructor calls with a set argument, and I think that's all but confirmed here. This explains why I've had to fight the enumeration system when trying to take arguments of many types and normalize them to enumerated members, or have numeric values displayed as enumerated members without being recast to the superclass every operation.
The Discovery
While playing around extensively with metadata for another project, I realized (and I'm entirely unsure why it took so long) that the properties of a metaclass object are just, in many cases, the attributes of the classdef. In this realization, I found a solution to Steve's and my problem.
To be clear: I'm not in love with this solution. I would much prefer a better approach for allowing variable sets of membership validation for arguments. But as it stands, we don't have that, so here's an interesting, if incredibly hacky, solution.
If you call struct() on a metaclass object to view its hidden properties, you'll notice that in addition to the public "Enumeration" property, there's a hidden "Enumerable" property. They're both logicals, which implies they're likely functionally distinct. I was curious about that distinction and hoped to find some functionality by intentionally manipulating these values - and I did, solving the exact problem Steve mentions.
The Problem Statement
We have a function with an argument that should allow "dual" input types: enumerated values (Steve's example uses days of the week, mine uses the "all" option available in various dimension-operating functions) AND integers. We want tab completion for the enumerated values while still accepting the numeric inputs.
A Solution for Tab-Completion Supported Arguments
Rather than spoil Steve's blog post, let me use my own example: implementing a none() function. The definition is simple enough tf = ~any(A, dim); but when we wrap this in another function, we lose the tab-completion that any() provides for the dim argument (which gives you "all"). There's no great way to implement this as a function author currently - at least, that's well documented.
So here's my solution:
%% Example Function Implementation
% This is a simple implementation of the DimensionArgument class for implementing dual type inputs that allow enumerated tab-completion.
function tf = none(A, dim)
arguments(Input)
A logical;
dim DimensionArgument = DimensionArgument(A, true);
end
% Simple example (notice the use of uplus to unwrap the hidden property)
tf = ~any(A, +dim);
end
I like this approach because the additional work required to implement it, once the enumeration class is initialized, is minimal. Here are examples of function calls, note that the behavior parallels that of the MATLAB native-style tab-completion:
%% Test Data
% Simple logical array for testing
A = randi([0, 1], [3, 5], "logical");
%% Example function calls
tf = none(A, "all"); % This is the tab-completion it's 1:1 with MATLABs behavior
tf = none(A, [1, 2]); % We can still use valid arguments (validated in the constructor)
tf = none(A); % Showcase of the constructors use as a default argument generator
How It Works
What makes this work is the previously mentioned Enumeration attribute. By setting Enumeration = false while still declaring an enumeration block in the classdef file, we get the suggested members as auto-complete suggestions. As I hinted at, the value of enumerations (if you don't subclass a builtin and define values with the someMember (1) syntax) are simply arguments to constructor calls.
We also get full control over the storage and handling of the class, which means we lose the implicit storage that enumerations normally provide and are responsible for doing so ourselves - but I much prefer this. We can implement internal validation logic to ensure values that aren't in the enumerated set still comply with our constraints, and store the input (whether the enumerated member or alternative type) in an internal property.
As seen in the example class below, this maintains a convenient interface for both the function caller and author the only particuarly verbose portion is the conversion methods... Which if your willing to double down on the uplus unwrapping context can be avoided. What I have personally done is overload the uplus function to return the input (or perform the identity property) this allowss for the uplus to be used universally to unwrap inputs and for those that cant, and dont have a uplus definition, the value itself is just returned:
classdef(Enumeration = false) DimensionArgument % < matlab.mixin.internal.MatrixDisplay
%DimensionArgument Enumeration class to provide auto-complete on functions needing the dimension type seen in all()
% Enumerations are just macros to make constructor calls with a known set of arguments. Declaring the 'all'
% enumeration member means this class can be set as the type for an input and the auto-completion for the given
% argument will show the enumeration members, allowing tab-completion. Declaring the Enumeration attribute of
% the class as false gives us control over the constructor and internal implementation. As such we can use it
% to validate the numeric inputs, in the event the 'all' option was not used, and return an object that will
% then work in place of valid dimension argument options.
%% Enumeration members
% These are the auto-complete options you'd like to make available for the function signature for a given
% argument.
enumeration(Description="Enumerated value for the dimension argument.")
all
end
%% Properties
% The internal property allows the constructor's input to be stored; this ensures that the value is store and
% that the output of the constructor has the class type so that the validation passes.
% (Constructors must return the an object of the class they're a constructor for)
properties(Hidden, Description="Storage of the constructor input for later use.")
Data = [];
end
%% Constructor method
% By the magic of declaring (Enumeration = false) in our class def arguments we get full control over the
% constructor implementation.
%
% The second argument in this specific instance is to enable the argument's default value to be set in the
% arguments block itself as opposed to doing so in the function body... I like this better but if you didn't
% you could just as easily keep the constructor simple.
methods
function obj = DimensionArgument(A, Adim)
%DimensionArgument Initialize the dimension argument.
arguments
% This will be the enumeration member name from auto-completed entries, or the raw user input if not
% used.
A = [];
% A flag that indicates to create the value using different logic, in this case the first non-singleton
% dimension, because this matches the behavior of functions like, all(), sum() prod(), etc.
Adim (1, 1) logical = false;
end
if(Adim)
% Allows default initialization from an input to match the aforemention function's behavior
obj.Data = firstNonscalarDim(A);
else
% As a convenience for this style of implementation we can validate the input to ensure that since we're
% suppose to be an enumeration, the input is valid
DimensionArgument.mustBeValidMember(A);
% Store the input in a hidden property since declaring ~Enumeration means we are responsible for storing
% it.
obj.Data = A;
end
end
end
%% Conversion methods
% Applies conversion to the data property so that implicit casting of functions works. Unfortunately most of
% the MathWorks defined functions use a different system than that employed by the arguments block, which
% defers to the class defined converter methods... Which is why uplus (+obj) has been defined to unwrap the
% data for ease of use.
methods
function obj = uplus(obj)
obj = obj.Data;
end
function str = char(obj)
str = char(obj.Data);
end
function str = cellstr(obj)
str = cellstr(obj.Data);
end
function str = string(obj)
str = string(obj.Data);
end
function A = double(obj)
A = double(obj.Data);
end
function A = int8(obj)
A = int8(obj.Data);
end
function A = int16(obj)
A = int16(obj.Data);
end
function A = int32(obj)
A = int32(obj.Data);
end
function A = int64(obj)
A = int64(obj.Data);
end
end
%% Validation methods
% These utility methods are for input validation
methods(Static, Access = private)
function tf = isValidMember(obj)
%isValidMember Checks that the input is a valid dimension argument.
tf = (istext(obj) && all(obj == "all", "all")) || (isnumeric(obj) && all(isint(obj) & obj > 0, "all"));
end
function mustBeValidMember(obj)
%mustBeValidMember Validates that the input is a valid dimension argument for the dim/dimVec arguments.
if(~DimensionArgument.isValidMember(obj))
exception("JB:DimensionArgument:InvalidInput", "Input must be an integer value or the term 'all'.")
end
end
end
%% Convenient data display passthrough
methods
function disp(obj, name)
arguments
obj DimensionArgument
name string {mustBeScalarOrEmpty} = [];
end
% Dispatch internal data's display implementation
display(obj.Data, char(name));
end
end
end
In the event you'd actually play with theres here are the function definitions for some of the utility functions I used in them, including my exception would be a pain so i wont, these cases wont use it any...
% Far from my definition isint() but is consistent with mustBeInteger() for real numbers but will suffice for the example
function tf = isint(A)
arguments
A {mustBeNumeric(A)};
end
tf = floor(A) == A
end
% Sort of the same but its fine
function dim = firstNonscalarDim(A)
arguments
A
end
dim = [find(size(A) > 1, 1), 0];
dim(1) = dim(1);
end
Yann Debray
Yann Debray
Last activity on 26 Aug 2025

Hello MATLAB Central, this is my first article.
My name is Yann. And I love MATLAB.
I also love HTTP (i know, weird fetish)
So i started a conversation with ChatGPT about it:
gitclone('https://github.com/yanndebray/HTTP-with-MATLAB');
cd('HTTP-with-MATLAB')
http_with_MATLAB
data = struct with fields:
data: [1×1 struct]
btcPrice = 1.0949e+05
age = struct with fields:
count: 27549 name: 'Yann' age: 51
Error using loadenv (line 27)
Unable to find or open '.env'. Check the path and filename or file permissions.

Error in http_with_MATLAB (line 18)
loadenv(".env")
^^^^^^^^^^^^^^^
I'm not sure that this platform is intended to clone repos from github, but i figured I'd paste this shortcut in case you want to try out my live script http_with_MATLAB.m
A lot of what i program lately relies on external web services (either for fetching data, or calling LLMs).
So I wrote a small tutorial of the 7 or so things I feel like I need to remember when making HTTP requests in MATLAB.
Let me know what you think
Ceci
Ceci
Last activity on 10 Sep 2025 at 19:08

I designed and stitched this last week! It uses a total of 20 DMC thread colors, and I frequently stitched with two colors at once to create the gradient.
Did you know that function double with string vector input significantly outperforms str2double with the same input:
x = rand(1,50000);
t = string(x);
tic; str2double(t); toc
Elapsed time is 0.276966 seconds.
tic; I1 = str2double(t); toc
Elapsed time is 0.244074 seconds.
tic; I2 = double(t); toc
Elapsed time is 0.002907 seconds.
isequal(I1,I2)
ans = logical
1
Recently I needed to parse numbers from text. I automatically tried to use str2double. However, profiling revealed that str2double was the main bottleneck in my code. Than I realized that there is a new note (since R2024a) in the documentation of str2double:
"Calling string and then double is recommended over str2double because it provides greater flexibility and allows vectorization. For additional information, see Alternative Functionality."
Independent researcher: Nguyễn Khánh Tùng
ORCID: 0009-0002-9877-4137
Email: traiphieu.com@gmail.com
The NKTg Law (Law of Variable Inertia) not only holds value in physics but also opens up wide possibilities for applications in programming and simulation. The remarkable point here is that the same law, the same formula, can be implemented across a wide range of different programming languages.
In the content below, you will find a collection of 150 code snippets, each corresponding to one of the world’s leading programming languages:
Python, C++, Java, C, C#, JavaScript, TypeScript, PHP, Ruby, Swift, Go, Rust, Kotlin, Dart, Scala, R, MATLAB, Julia, Haskell, Perl, Shell, SQL, Visual Basic, Assembly, Ada, Fortran, Prolog, Scheme, Lisp, Scratch, Smalltalk, Pascal, Groovy, PowerShell, Apex, ABAP, ActionScript, Algol, Alice, AmbientTalk, AngelScript, APL, Arc, Arduino, ASP.NET, AssemblyScript, ATS, AWK, Ballerina, BASIC, VHDL, Verilog, Assembly, AutoHotkey, AutoLISP, AWK, Bash, bc, Boo, Clojure, COBOL, Common Lisp, Crystal, D, Delphi/Object Pascal, Dylan, Eiffel, Elixir, Elm, Emacs Lisp, Erlang, F#, Factor, Falcon, Fantom, Felix, Forth, Fortress, Frink, Gambas, GAMS, GAP, Genie, GLSL, Hack, Haxe, HDL, HLSL, Hope, HTML, HyperTalk, Icon, IDL, Inform, Io, Ioke, J, J#, JScript, JavaFX Script, Io, Ioke, J, J#, JScript, Julia, Kotlin, LabVIEW, Ladder Logic, Lasso, Lava, Lisp, LiveCode, Logo, Lua, M4, Magik, Maple, Mathematica, MATLAB, Mercury, Modula-2, Modula-3, MoonScript, Nemerle, NetLogo, Nim, Nix, Objective-C, Objective-J, OCaml, OpenCL, OpenEdge ABL, Oz, PL/I, PL/SQL, PostScript, Promela, Pure, Q#, Racket, RAPID, REBOL, Red, Rexx, Ring, Solidity, SPARK, SPSS, Squirre
All the code snippets illustrate how to calculate the fundamental quantities of The NKTg Law on Varying Inertia:
The movement tendency of an object in space depends on the relationship between its position, velocity, and mass.
NKTg = f(x, v, m)
In which:
  • x is the position or displacement of the object relative to the reference point.
  • v is the velocity.
  • m is the mass.
The movement tendency of the object is determined by the following basic product quantities:
NKTg₁ = x × p
NKTg₂ = (dm/dt) × p
In which:
  • p is the linear momentum, calculated by p = m × v.
  • dm/dt is the rate of mass change over time.
  • NKTg₁ is the quantity representing the product of position and momentum.
  • NKTg₂ is the quantity representing the product of mass variation and momentum.
  • The unit of measurement is NKTm, representing a unit of varying inertia.
The sign and value of the two quantities NKTg₁ and NKTg₂ determine the movement tendency:
  • If NKTg₁ is positive, the object tends to move away from the stable state.
  • If NKTg₁ is negative, the object tends to move toward the stable state.
  • If NKTg₂ is positive, the mass variation has a supporting effect on the movement.
  • If NKTg₂ is negative, the mass variation has a resisting effect on the movement.
The stable state in this law is understood as the state in which the position (x), velocity (v), and mass (m) of the object interact with each other to maintain the movement structure, helping the object avoid losing control and preserving its inherent movement pattern.
# Python:
versatile, easy to learn, strong for AI and data science
x, v, m, dm_dt = 2.0, 3.0, 5.0, 0.1
p = m * v
NKTg1 = x * p
NKTg2 = dm_dt * p
print(f"p={p}, NKTg1={NKTg1}, NKTg2={NKTg2}")
Java
// Java: enterprise applications, Android
public class NKTgLaw {
public static void main(String[] args) {
double x=2, v=3, m=5, dm_dt=0.1;
double p = m*v, NKTg1 = x*p, NKTg2 = dm_dt*p;
System.out.printf(
"p=%.2f NKTg1=%.2f NKTg2=%.2f%n", p, NKTg1, NKTg2);
}
}
Implementing the same law across 150 programming ecosystems demonstrates its universality and flexibility, while also confirming that any language—whether general-purpose and popular, or specialized and classical—can apply the NKTg Law to simulate, analyze, and handle practical problems.
Full list of 150 programming languages (complete) — due to post size limits I placed the complete list on an external page for easy viewing and download:
You can refer to the following four related articles to gain a deeper understanding of the NKTg Law and its applications
t = turtle(); % Start a turtle
t.forward(100); % Move forward by 100
t.backward(100); % Move backward by 100
t.left(90); % Turn left by 90 degrees
t.right(90); % Tur right by 90 degrees
t.goto(100, 100); % Move to (100, 100)
t.turnto(90); % Turn to 90 degrees, i.e. north
t.speed(1000); % Set turtle speed as 1000 (default: 500)
t.pen_up(); % Pen up. Turtle leaves no trace.
t.pen_down(); % Pen down. Turtle leaves a trace again.
t.color('b'); % Change line color to 'b'
t.begin_fill(FaceColor, EdgeColor, FaceAlpha); % Start filling
t.end_fill(); % End filling
t.change_icon('person.png'); % Change the icon to 'person.png'
t.clear(); % Clear the Axes
classdef turtle < handle
properties (GetAccess = public, SetAccess = private)
x = 0
y = 0
q = 0
end
properties (SetAccess = public)
speed (1, 1) double = 500
end
properties (GetAccess = private)
speed_reg = 100
n_steps = 20
ax
l
ht
im
is_pen_up = false
is_filling = false
fill_color
fill_alpha
end
methods
function obj = turtle()
figure(Name='MATurtle', NumberTitle='off')
obj.ax = axes(box="on");
hold on,
obj.ht = hgtransform();
icon = flipud(imread('turtle.png'));
obj.im = imagesc(obj.ht, icon, ...
XData=[-30, 30], YData=[-30, 30], ...
AlphaData=(255 - double(rgb2gray(icon)))/255);
obj.l = plot(obj.x, obj.y, 'k');
obj.ax.XLim = [-500, 500];
obj.ax.YLim = [-500, 500];
obj.ax.DataAspectRatio = [1, 1, 1];
obj.ax.Toolbar.Visible = 'off';
disableDefaultInteractivity(obj.ax);
end
function home(obj)
obj.x = 0;
obj.y = 0;
obj.ht.Matrix = eye(4);
end
function forward(obj, dist)
obj.step(dist);
end
function backward(obj, dist)
obj.step(-dist)
end
function step(obj, delta)
if numel(delta) == 1
delta = delta*[cosd(obj.q), sind(obj.q)];
end
if obj.is_filling
obj.fill(delta);
else
obj.move(delta);
end
end
function goto(obj, x, y)
dx = x - obj.x;
dy = y - obj.y;
obj.turnto(rad2deg(atan2(dy, dx)));
obj.step([dx, dy]);
end
function left(obj, q)
obj.turn(q);
end
function right(obj, q)
obj.turn(-q);
end
function turnto(obj, q)
obj.turn(obj.wrap_angle(q - obj.q, -180));
end
function pen_up(obj)
if obj.is_filling
warning('not available while filling')
return
end
obj.is_pen_up = true;
end
function pen_down(obj, go)
if obj.is_pen_up
if nargin == 1
obj.l(end+1) = plot(obj.x, obj.y, Color=obj.l(end).Color);
else
obj.l(end+1) = go;
end
uistack(obj.ht, 'top')
end
obj.is_pen_up = false;
end
function color(obj, line_color)
if obj.is_filling
warning('not available while filling')
return
end
obj.pen_up();
obj.pen_down(plot(obj.x, obj.y, Color=line_color));
end
function begin_fill(obj, FaceColor, EdgeColor, FaceAlpha)
arguments
obj
FaceColor = [.6, .9, .6];
EdgeColor = [0 0.4470 0.7410];
FaceAlpha = 1;
end
if obj.is_filling
warning('already filling')
return
end
obj.fill_color = FaceColor;
obj.fill_alpha = FaceAlpha;
obj.pen_up();
obj.pen_down(patch(obj.x, obj.y, [1, 1, 1], ...
EdgeColor=EdgeColor, FaceAlpha=0));
obj.is_filling = true;
end
function end_fill(obj)
if ~obj.is_filling
warning('not filling now')
return
end
obj.l(end).FaceColor = obj.fill_color;
obj.l(end).FaceAlpha = obj.fill_alpha;
obj.is_filling = false;
end
function change_icon(obj, filename)
icon = flipud(imread(filename));
obj.im.CData = icon;
obj.im.AlphaData = (255 - double(rgb2gray(icon)))/255;
end
function clear(obj)
obj.x = 0;
obj.y = 0;
delete(obj.ax.Children(2:end));
obj.l = plot(0, 0, 'k');
obj.ht.Matrix = eye(4);
end
end
methods (Access = private)
function animated_step(obj, delta, q, initFcn, updateFcn)
arguments
obj
delta
q
initFcn = @() []
updateFcn = @(~, ~) []
end
dx = delta(1)/obj.n_steps;
dy = delta(2)/obj.n_steps;
dq = q/obj.n_steps;
pause_duration = norm(delta)/obj.speed/obj.speed_reg;
initFcn();
for i = 1:obj.n_steps
updateFcn(dx, dy);
obj.ht.Matrix = makehgtform(...
translate=[obj.x + dx*i, obj.y + dy*i, 0], ...
zrotate=deg2rad(obj.q + dq*i));
pause(pause_duration)
drawnow limitrate
end
obj.x = obj.x + delta(1);
obj.y = obj.y + delta(2);
end
function obj = turn(obj, q)
obj.animated_step([0, 0], q);
obj.q = obj.wrap_angle(obj.q + q, 0);
end
function move(obj, delta)
initFcn = @() [];
updateFcn = @(dx, dy) [];
if ~obj.is_pen_up
initFcn = @() initializeLine();
updateFcn = @(dx, dy) obj.update_end_point(obj.l(end), dx, dy);
end
function initializeLine()
obj.l(end).XData(end+1) = obj.l(end).XData(end);
obj.l(end).YData(end+1) = obj.l(end).YData(end);
end
obj.animated_step(delta, 0, initFcn, updateFcn);
end
function obj = fill(obj, delta)
initFcn = @() initializePatch();
updateFcn = @(dx, dy) obj.update_end_point(obj.l(end), dx, dy);
function initializePatch()
obj.l(end).Vertices(end+1, :) = obj.l(end).Vertices(end, :);
obj.l(end).Faces = 1:size(obj.l(end).Vertices, 1);
end
obj.animated_step(delta, 0, initFcn, updateFcn);
end
end
methods (Static, Access = private)
function update_end_point(l, dx, dy)
l.XData(end) = l.XData(end) + dx;
l.YData(end) = l.YData(end) + dy;
end
function q = wrap_angle(q, min_angle)
q = mod(q - min_angle, 360) + min_angle;
end
end
end
I would like to zoom directly on the selected region when using on my image created with image or imagesc. First of all, I would recommend using image or imagesc and not imshow for this case, see comparison here: Differences between imshow() and image()? However when zooming Stretch-to-Fill behavior happens and I don't want that. Try range zoom to image generated by this code:
fig = uifigure;
ax = uiaxes(fig);
im = imread("peppers.png");
h = imagesc(im,"Parent",ax);
axis(ax,'tight', 'off')
I can fix that with manualy setting data aspect ratio:
daspect(ax,[1 1 1])
However, I need this code to run automatically after zooming. So I create zoom object and ActionPostCallback which is called everytime after I zoom, see zoom - ActionPostCallback.
z = zoom(ax);
z.ActionPostCallback = @(fig,ax) daspect(ax.Axes,[1 1 1]);
If you need, you can also create ActionPreCallback which is called everytime before I zoom, see zoom - ActionPreCallback.
z.ActionPreCallback = @(fig,ax) daspect(ax.Axes,'auto');
Code written and run in R2025a.
I am thrilled python interoperability now seems to work for me with my APPLE M1 MacBookPro and MATLAB V2025a. The available instructions are still, shall we say, cryptic. Here is a summary of my interaction with GPT 4o to get this to work.
===========================================================
MATLAB R2025a + Python (Astropy) Integration on Apple Silicon (M1/M2/M3 Macs)
===========================================================
Author: D. Carlsmith, documented with ChatGPT
Last updated: July 2025
This guide provides full instructions, gotchas, and workarounds to run Python 3.10 with MATLAB R2025a (Apple Silicon/macOS) using native ARM64 Python and calling modules like Astropy, Numpy, etc. from within MATLAB.
===========================================================
Overview
===========================================================
- MATLAB R2025a on Apple Silicon (M1/M2/M3) runs as "maca64" (native ARM64).
- To call Python from MATLAB, the Python interpreter must match that architecture (ARM64).
- Using Intel Python (x86_64) with native MATLAB WILL NOT WORK.
- The cleanest solution: use Miniforge3 (Conda-forge's lightweight ARM64 distribution).
===========================================================
1. Install Miniforge3 (ARM64-native Conda)
===========================================================
In Terminal, run:
curl -LO https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh
bash Miniforge3-MacOSX-arm64.sh
Follow prompts:
- Press ENTER to scroll through license.
- Type "yes" when asked to accept the license.
- Press ENTER to accept the default install location: ~/miniforge3
- When asked:
Do you wish to update your shell profile to automatically initialize conda? [yes|no]
Type: yes
===========================================================
2. Restart Terminal and Create a Python Environment for MATLAB
===========================================================
Run the following:
conda create -n matlab python=3.10 astropy numpy -y
conda activate matlab
Verify the Python path:
which python
Expected output:
/Users/YOURNAME/miniforge3/envs/matlab/bin/python
===========================================================
3. Verify Python + Astropy From Terminal
===========================================================
Run:
python -c "import astropy; print(astropy.__version__)"
Expected output:
6.x.x (or similar)
===========================================================
4. Configure MATLAB to Use This Python
===========================================================
In MATLAB R2025a (Apple Silicon):
clear classes
pyenv('Version', '/Users/YOURNAME/miniforge3/envs/matlab/bin/python')
py.sys.version
You should see the Python version printed (e.g. 3.10.18). No error means it's working.
===========================================================
5. Gotchas and Their Solutions
===========================================================
❌ Error: Python API functions are not available
→ Cause: Wrong architecture or broken .dylib
→ Fix: Use Miniforge ARM64 Python. DO NOT use Intel Anaconda.
❌ Error: Invalid text character (↑ points at __version__)
→ Cause: MATLAB can’t parse double underscores typed or pasted
→ Fix: Use: py.getattr(module, '__version__')
❌ Error: Unrecognized method 'separation' or 'sec'
→ Cause: MATLAB can't reflect dynamic Python methods
→ Fix: Use: py.getattr(obj, 'method')(args)
===========================================================
6. Run Full Verification in MATLAB
===========================================================
Paste this into MATLAB:
% Set environment
clear classes
pyenv('Version', '/Users/YOURNAME/miniforge3/envs/matlab/bin/python');
% Import modules
coords = py.importlib.import_module('astropy.coordinates');
time_mod = py.importlib.import_module('astropy.time');
table_mod = py.importlib.import_module('astropy.table');
% Astropy version
ver = char(py.getattr(py.importlib.import_module('astropy'), '__version__'));
disp(['Astropy version: ', ver]);
% SkyCoord angular separation
c1 = coords.SkyCoord('10h21m00s', '+41d12m00s', pyargs('frame', 'icrs'));
c2 = coords.SkyCoord('10h22m00s', '+41d15m00s', pyargs('frame', 'icrs'));
sep_fn = py.getattr(c1, 'separation');
sep = sep_fn(c2);
arcsec = double(sep.to('arcsec').value);
fprintf('Angular separation = %.3f arcsec\n', arcsec);
% Time difference in seconds
Time = time_mod.Time;
t1 = Time('2025-01-01T00:00:00', pyargs('format','isot','scale','utc'));
t2 = Time('2025-01-02T00:00:00', pyargs('format','isot','scale','utc'));
dt = py.getattr(t2, '__sub__')(t1);
seconds = double(py.getattr(dt, 'sec'));
fprintf('Time difference = %.0f seconds\n', seconds);
% Astropy table display
tbl = table_mod.Table(pyargs('names', {'a','b'}, 'dtype', {'int','float'}));
tbl.add_row({1, 2.5});
tbl.add_row({2, 3.7});
disp(tbl);
===========================================================
7. Optional: Automatically Configure Python in startup.m
===========================================================
To avoid calling pyenv() every time, edit your MATLAB startup:
edit startup.m
Add:
try
pyenv('Version', '/Users/YOURNAME/miniforge3/envs/matlab/bin/python');
catch
warning("Python already loaded.");
end
===========================================================
8. Final Notes
===========================================================
- This setup avoids all architecture mismatches.
- It uses a clean, minimal ARM64 Python that integrates seamlessly with MATLAB.
- Do not mix Anaconda (Intel) with Apple Silicon MATLAB.
- Use py.getattr for any Python attribute containing underscores or that MATLAB can't resolve.
You can now run NumPy, Astropy, Pandas, Astroquery, Matplotlib, and more directly from MATLAB.
===========================================================
Hey MATLAB enthusiasts!
I just stumbled upon this hilariously effective GitHub repo for image deformation using Moving Least Squares (MLS)—and it’s pure gold for anyone who loves playing with pixels! 🎨✨
  1. Real-Time Magic
  • Precomputes weights and deformation data upfront, making it blazing fast for interactive edits. Drag control points and watch the image warp like rubber! (2)
  • Supports affine, similarity, and rigid deformations—because why settle for one flavor of chaos?
  1. Single-File Simplicity 🧩
  • All packed into one clean MATLAB class (mlsImageWarp.m).
  1. Endless Fun Use Cases 🤹
  • Turn your pet’s photo into a Picasso painting.
  • "Fix" your friend’s smile... aggressively.
  • Animate static images with silly deformations (1).
Try the Demo!
You are not a jedi yet !
20%
We not grant u the rank of master !
0%
Ready are u? What knows u of ready?
0%
May the Force be with you !
80%
5 votes