MATLAB Interview Questions with Answers
Most Asked MATLAB Interview Questions for Engineering and Data Science Roles
Introduction
MATLAB is a high‑performance language for technical computing, seamlessly integrating numerical analysis, matrix operations, and powerful visualisation. This page compiles the most frequently asked MATLAB interview questions – from fundamental syntax and data types to object‑oriented programming, parallel computing, and design patterns – essential for engineers, data scientists, and researchers.
Why MATLAB?
- Optimised for matrix and vector operations
- Rich built‑in functions for mathematics and engineering
- Powerful visualisation and plotting capabilities
- Specialised toolboxes for domain‑specific applications
- Simulink for model‑based design and simulation
- Widely adopted in academia and industry
Most Asked MATLAB Interview Questions
MATLAB (Matrix Laboratory) is a high-performance language for technical computing. It integrates computation, visualization, and programming in an easy-to-use environment.
- Matrix-based: Built around matrices and arrays
- Interactive: Command-line interface and scripts
- Visualization: Powerful plotting and graphics
- Toolboxes: Specialized application-specific functions
- Cross-platform: Windows, macOS, Linux
% Hello World in MATLAB
disp('Hello, World!')Variables in MATLAB are dynamically typed. Simply assign a value to a variable name without explicit declaration.
- Dynamic typing: No type declaration needed
- Assignments:
variable = value - whos: Show all variables in workspace
- clear: Remove variables from workspace
- Case-sensitive: Variable names are case-sensitive
% Variables in MATLAB
mutableVar = 'Hello'; % Mutable variable (dynamic typing)
immutableVar = 'World'; % Variables can be reassigned
inferred = 42; % Type inference
whos % Show all variables
% Display
disp(mutableVar)
disp(immutableVar)
disp(inferred)MATLAB has numeric, logical, character, string, cell, structure, and function handle data types.
- Numeric: double, single, int8, int16, int32, int64, uint8, etc.
- Logical: true/false
- Character: 'A'
- String: "Hello MATLAB"
- Cell array:
{1, 'Hello', 3.14} - Structure: person.name = 'Alice'
- Function handle: @(x) x^2
% Data Types in MATLAB
% Numeric types
intNum = 10; % Double by default
singleNum = single(10); % Single precision
int8Num = int8(10); % 8-bit integer
uint16Num = uint16(100); % Unsigned 16-bit
% Floating point
floatNum = 3.14;
doubleNum = 3.14159;
% Logical (Boolean)
isActive = true;
isInactive = false;
% Characters and strings
char = 'A';
str = 'Hello MATLAB';
% Arrays
arr = [1, 2, 3, 4, 5];
% Cell arrays
cellArr = {1, 'Hello', 3.14};
% Structures
person.name = 'Alice';
person.age = 25;
% Type checking
isa(intNum, 'double') % trueFunctions in MATLAB are defined using the function keyword. They can have multiple outputs and support anonymous functions.
- Basic:
function result = name(args) - Multiple outputs:
function [out1, out2] = name(args) - Default parameters:
nargincheck - Anonymous functions:
@(x) x^2 - Function handles:
@functionName
% Functions in MATLAB
% Basic function
function result = add(a, b)
result = a + b;
end
% Single-expression function
function result = subtract(a, b)
result = a - b;
end
% Default parameters
function result = greet(name)
if nargin < 1
name = 'Guest';
end
result = ['Hello, ' name '!'];
end
% Function with multiple outputs
function [quotient, remainder] = divide(a, b)
quotient = floor(a / b);
remainder = mod(a, b);
end
% Anonymous function (lambda)
multiply = @(a, b) a * b;
% Higher-order function
function result = operate(a, b, operation)
result = operation(a, b);
end
% Usage
disp(add(5, 3))
disp(subtract(10, 4))
disp(greet('Alice'))
[q, r] = divide(10, 3);
disp(q)
disp(r)
disp(operate(6, 7, multiply))Arrays are the fundamental data type in MATLAB. They can be vectors, matrices, or multidimensional.
- Creation:
[1, 2, 3]or1:3 - Matrix:
[1 2 3; 4 5 6] - Access:
arr(3)(1-indexed) - Modification:
arr(3) = 10 - Operations:
length,size,numel
% Arrays in MATLAB
% Array creation
numbers = [1, 2, 3, 4, 5];
strings = {'Apple', 'Banana', 'Orange'};
mixed = [1, 2, 3.14]; % Mixed numeric
% Matrix
matrix = [1 2 3; 4 5 6; 7 8 9];
% Access and modify
numbers(3) % Access element (1-indexed)
numbers(3) = 10; % Modify element
% Array operations
length(numbers)
size(numbers)
numel(numbers)
% Iteration
for num = numbers
disp(num)
end
% Array functions
doubled = numbers * 2; % Element-wise multiplication
filtered = numbers(numbers > 2);
sumVal = sum(numbers);
meanVal = mean(numbers);
% Cell arrays vs arrays
cellArr = {1, 2, 3};
normalArr = [1, 2, 3];
% Display
disp(doubled)
disp(filtered)
disp(sumVal)MATLAB collections include arrays, cell arrays, structures, and containers.Map for key-value pairs.
- Numeric arrays: Homogeneous numeric data
- Cell arrays: Heterogeneous data
- Structures: Named fields
- containers.Map: Dictionary-like key-value pairs
- Operations:
filter,map,reduceusing array functions
% Collections in MATLAB
% Numeric arrays
immutableList = [1, 2, 3, 4, 5];
mutableList = [1, 2, 3];
mutableList(end+1) = 4; % Append
mutableList(2) = []; % Remove element
% Cell arrays (can hold different types)
cellList = {1, 'Hello', 3.14};
cellList{end+1} = 'World';
% Structures (maps)
person.name = 'Alice';
person.age = 25;
person.city = 'NYC';
% Structure array
people(1).name = 'Alice';
people(2).name = 'Bob';
% Containers.Map (dictionary)
mapObj = containers.Map();
mapObj('key1') = 'value1';
mapObj('key2') = 'value2';
% Collection operations
numbers = [1, 2, 3, 4, 5, 6];
evens = numbers(mod(numbers, 2) == 0);
doubled = numbers * 2;
sumVal = sum(numbers);
exists = any(numbers > 10);
allEven = all(mod(numbers, 2) == 0);
disp(evens)
disp(doubled)
disp(sumVal)Structures are data containers with named fields, similar to objects in other languages.
- Creation:
person.name = 'Alice' - struct function:
struct('name', 'Bob', 'age', 30) - Access:
person.name - Arrays of structures:
people(1).name = 'Alice' - Nested structures:
person.address.city = 'NYC'
% Structures (Data Classes) in MATLAB
% Define structure
person.name = 'Alice';
person.age = 25;
person.city = 'Unknown';
% Using struct function
person2 = struct('name', 'Bob', 'age', 30, 'city', 'LA');
% Copy
person3 = person;
person3.age = 26;
% Access
disp(person.name)
disp(person.age)
% Class definition (separate file)
% classdef Person
% properties
% name
% age
% city
% end
% methods
% function obj = Person(name, age, city)
% obj.name = name;
% obj.age = age;
% obj.city = city;
% end
% end
% endMATLAB supports object-oriented programming with classes, inheritance, and encapsulation using classdef files.
- Class definition:
classdef MyClass - Properties:
propertiesblock - Methods:
methodsblock - Inheritance:
classdef Dog < Animal - Abstract classes:
classdef (Abstract) Shape
% Sealed Classes in MATLAB
% Class definition file: Result.m
% classdef (Abstract) Result
% end
% Success.m
% classdef Success < Result
% properties
% data
% end
% methods
% function obj = Success(data)
% obj.data = data;
% end
% end
% end
% Error.m
% classdef Error < Result
% properties
% message
% end
% methods
% function obj = Error(message)
% obj.message = message;
% end
% end
% end
% Loading.m
% classdef Loading < Result
% end
% Shape classes
% classdef (Abstract) Shape
% end
% Circle.m
% classdef Circle < Shape
% properties
% radius
% end
% methods
% function obj = Circle(radius)
% obj.radius = radius;
% end
% function area = getArea(obj)
% area = pi * obj.radius^2;
% end
% end
% endMATLAB uses empty arrays ([]) to represent null values. Checking for emptiness is the primary safety mechanism.
- Empty arrays:
[] - Check empty:
isempty(var) - Missing values:
missingfor tables - Try-catch: Error handling
- Default values: Check and provide defaults
% Null Safety in MATLAB
% MATLAB uses empty arrays and missing values
% Empty arrays
emptyArray = [];
nullableString = ''; % Empty string
nonNullableString = 'Hello';
% Check for empty
isempty(emptyArray) % true
% Missing values (for tables)
% Using ismissing for table data
% Safe access with try-catch
function result = safeLength(arr)
try
result = length(arr);
catch
result = 0;
end
end
% Default values
function result = elvis(value, default)
if isempty(value)
result = default;
else
result = value;
end
end
% Usage
disp(safeLength([]))
disp(elvis([], 'default'))
% Check for existence
function processString(str)
if ~isempty(str)
disp(['String is: ' str])
disp(['Length: ' num2str(length(str))])
end
endMATLAB provides standard control flow: if-else, switch, for, while, and break/continue.
- If-else:
if condition ... else ... end - Switch:
switch expression ... case ... end - For loop:
for i = 1:n ... end - While loop:
while condition ... end - Break/Continue: Control loop execution
% Control Flow in MATLAB
% If-else
age = 25;
if age < 18
status = 'Minor';
else
status = 'Adult';
end
disp(status)
% Switch (switch replacement)
grade = 'A';
switch grade
case 'A'
result = 'Excellent';
case 'B'
result = 'Good';
case 'C'
result = 'Fair';
otherwise
result = 'Needs Improvement';
end
disp(result)
% For loop
for i = 1:5
disp(i)
end
% For loop with step
for i = 1:2:10
disp(i)
end
% For loop descending
for i = 10:-1:1
disp(i)
end
% While loop
i = 0;
while i < 5
disp(i)
i = i + 1;
end
% Do-while (using while with break)
i = 0;
while true
disp(i)
i = i - 1;
if i <= 0
break
end
endMATLAB supports inheritance using classdef files. Subclasses inherit properties and methods from base classes.
- Base class:
classdef Animal - Inheritance:
classdef Dog < Animal - Superclass constructor:
obj@Animal(args) - Method override:
function makeSound(obj) - Abstract methods:
methods (Abstract)
% Classes and Inheritance in MATLAB
% Base class file: Animal.m
% classdef Animal
% properties
% name
% end
% methods
% function obj = Animal(name)
% obj.name = name;
% end
% function makeSound(obj)
% disp('Animal sound')
% end
% end
% end
% Derived class: Dog.m
% classdef Dog < Animal
% properties
% breed
% end
% methods
% function obj = Dog(name, breed)
% obj@Animal(name);
% obj.breed = breed;
% end
% function makeSound(obj)
% disp('Woof!')
% end
% end
% end
% Abstract class: Vehicle.m
% classdef (Abstract) Vehicle
% methods (Abstract)
% start(obj)
% end
% methods
% function stop(obj)
% disp('Stopped')
% end
% end
% end
% Interface simulation
% classdef Flyable
% methods (Abstract)
% fly(obj)
% end
% end
% Duck.m
% classdef Duck < Flyable
% methods
% function fly(obj)
% disp('Flying')
% end
% function swim(obj)
% disp('Swimming')
% end
% end
% endProperties are class attributes with access control, validation, and dependency features.
- Properties:
properties ... end - Access control:
properties (Access = private) - Dependent properties:
properties (Dependent) - Validation:
setmethods - Constant properties:
properties (Constant)
% Properties in MATLAB
% Class with properties
% classdef Person
% properties
% name
% age
% end
% properties (Dependent)
% fullName
% end
% properties (Access = private)
% email
% end
% methods
% function obj = Person(name, age)
% obj.name = name;
% obj.age = age;
% end
% function value = get.fullName(obj)
% value = obj.name;
% end
% function obj = set.age(obj, value)
% if value >= 0
% obj.age = value;
% end
% end
% end
% end
% Using structure for simple properties
person.name = 'Alice';
person.age = 25;
% Lazy initialization
function value = getExpensiveData()
persistent cache
if isempty(cache)
disp('Computing expensive data...')
cache = 'Expensive Result';
end
value = cache;
end
% Usage
disp(getExpensiveData())
disp(getExpensiveData())Static methods belong to the class, not instances. They are defined using methods (Static).
- Static methods:
methods (Static) - Constant properties:
properties (Constant) - Access:
ClassName.method() - Factory methods: Create instances
- Helper functions: Utility functions
% Companion Objects in MATLAB
% MATLAB doesn't have companion objects directly
% Using functions in separate files or static methods
% File: MyClass.m
% classdef MyClass
% properties (Constant)
% TAG = 'MyClass'
% end
% properties (Static)
% counter = 0
% end
% methods (Static)
% function obj = create()
% MyClass.counter = MyClass.counter + 1;
% obj = MyClass();
% end
% end
% end
% Using functions in a package
% +myclass/TAG.m
% function value = TAG()
% value = 'MyClass';
% end
% Usage
% disp(MyClass.TAG)
% MyClass.counter = MyClass.counter + 1;
% obj = MyClass.create();MATLAB uses try-catch-finally blocks for exception handling. Custom errors can be created with error.
- Try-catch:
try ... catch ME ... end - Custom errors:
error('ID', 'Message') - Finally:
finally ... end - Rethrow:
rethrow(ME) - Warning:
warning('Message')
% Exception Handling in MATLAB
% Try-catch block
function result = divide(a, b)
try
result = a / b;
catch ME
if strcmp(ME.identifier, 'MATLAB:divideByZero')
disp('Division by zero!')
result = 0;
else
rethrow(ME)
end
end
end
% Try as expression
try
x = 10 / 0;
result = 'Success';
catch
result = ['Error: ' ME.message];
end
% Custom exception
function validateAge(age)
if age < 0 || age > 150
error('InvalidAgeException:InvalidAge', 'Invalid age: %d', age);
end
end
% Finally block
function readFile()
try
disp('Reading file...')
% File operations
catch ME
disp(['Error reading file: ' ME.message])
finally
disp('Closing resources...')
end
end
% Usage
disp(divide(10, 2))
disp(divide(10, 0))
try
validateAge(200)
catch ME
disp(ME.message)
endAnonymous functions are function handles created at runtime without a separate file. They are defined using @.
- Syntax:
@(x) x^2 - Multiple inputs:
@(x, y) x + y - Function handles:
@functionName - Higher-order: Pass as arguments
- Closures: Capture workspace variables
% Lambda Expressions in MATLAB
% Basic anonymous function
square = @(x) x^2;
% Anonymous function with multiple inputs
doubled = @(x) x * 2;
% Higher-order functions
function result = performOperation(x, y, operation)
result = operation(x, y);
end
% Lambda with multiple lines (using function handle)
complexOperation = @(x) (x * 2 + 10);
% Function handle
function result = multiply(x, y)
result = x * y;
end
multiplyRef = @multiply;
% Returning anonymous function
function op = getOperation(type)
switch type
case 'add'
op = @(a, b) a + b;
case 'subtract'
op = @(a, b) a - b;
otherwise
op = @(a, b) 0;
end
end
% Usage
disp(square(5))
disp(performOperation(10, 20, @(x, y) x * y))
add = getOperation('add');
disp(add(5, 3))Cell arrays are containers that can hold different data types. They are created using .
- Creation:
{1, 'Hello', 3.14} - Access:
{ }for content,( )for cells - Operations:
cellfun,celldisp - Cell array functions:
cell2mat,mat2cell - Nested cells:
{{1, 2}, {3, 4}}
% Scope Functions in MATLAB
% Using functions for scope
% let - execute block
function processPerson(person)
if ~isempty(person)
name = person.name;
age = person.age;
disp(['Name: ' name])
person.age = 26;
end
end
% Using cellfun for apply
numbers = {1, 2, 3};
result = cellfun(@(x) x^2, numbers);
% also - perform additional operations
function processList(lst)
disp(['Before: ' mat2str(lst)])
lst(end+1) = 4;
disp(['After: ' mat2str(lst)])
end
% take-if equivalent
function result = takeIf(condition, value)
if condition(value)
result = value;
else
result = [];
end
end
% Usage
person = struct('name', 'Alice', 'age', 25);
processPerson(person)
disp(result)
takeIf(@(x) x >= 18, 25)Function handles are variables that reference functions. They allow passing functions as arguments and storing functions.
- Creation:
@functionName - Anonymous:
@(x) x^2 - Calling:
handle(args) - Function functions:
feval - Arrays of handles:
{@sin, @cos, @tan}
% Extension Functions in MATLAB
% MATLAB doesn't have extension functions directly
% Using wrapper functions
% String extensions
function result = isEmail(str)
result = contains(str, '@') && contains(str, '.');
end
function result = addPrefix(str, prefix)
result = [prefix str];
end
% Numeric extensions
function result = isEven(n)
result = mod(n, 2) == 0;
end
function result = isOdd(n)
result = mod(n, 2) ~= 0;
end
% List extensions
function result = secondOrNull(lst)
if length(lst) >= 2
result = lst(2);
else
result = [];
end
end
% String word count
function result = wordCount(str)
words = strsplit(str);
result = length(words);
end
% Usage
disp(isEmail('test@example.com'))
disp(addPrefix('Hello', 'Greeting: '))
disp(isEven(5))
disp(wordCount('Hello World'))
disp(secondOrNull([1, 2, 3]))Enumerations are defined using enumeration blocks in classdef files, providing named constants.
- Enumeration:
enumeration ... end - Values:
RED (1) - Properties: Can have associated values
- Methods: Can have custom methods
- Usage:
Color.RED
% Type Aliases in MATLAB
% MATLAB doesn't have type aliases directly
% Using function handles or wrapper functions
% Function alias
add = @(a, b) a + b;
multiply = @(a, b) a * b;
function result = execute(op, a, b)
result = op(a, b);
end
% For complex types
% Using structures
users = struct();
users.user1 = struct('name', 'Alice', 'age', 25);
users.user2 = struct('name', 'Bob', 'age', 30);
% Using containers.Map
usersMap = containers.Map();
usersMap('user1') = struct('name', 'Alice', 'age', 25);
% Usage
disp(execute(add, 5, 3))
disp(execute(multiply, 5, 3))
disp(users.user1.name)Handle classes are reference types, unlike value classes. They are defined using classdef ... < handle.
- Reference semantics: Pass by reference
- Inheritance:
classdef MyClass < handle - Events:
eventsblock - Listeners:
addlistener - Destructor:
deletemethod
% Inline Functions in MATLAB
% MATLAB doesn't have inline functions like Kotlin
% Using anonymous functions or function handles
% Regular function
function regularFunction()
disp('Regular function')
end
% Anonymous function (inlined)
inlineMeasure = @(block) (tic; block(); toc);
% Usage
inlineMeasure(@() pause(0.1));
% Type checking using isa
function result = isType(value, type)
result = isa(value, type);
end
% Filter by type
function result = filterByType(lst, type)
result = {};
for i = 1:length(lst)
if isa(lst{i}, type)
result{end+1} = lst{i};
end
end
end
mixed = {1, 'Hello', 3.14, 'World'};
strings = filterByType(mixed, 'char');
disp(strings)Higher-order functions take functions as arguments or return functions. They are implemented using function handles.
- Parameter:
function result = op(a, b, fn) - Return: Functions that return handles
- Composition:
compose(f, g) - Callbacks: Used in event-driven code
- Functional programming: Core concept
% Higher-Order Functions in MATLAB
% Function that takes a function as parameter
function result = applyOperation(a, b, operation)
result = operation(a, b);
end
% Function that returns a function
function multiplier = getMultiplier(factor)
multiplier = @(x) x * factor;
end
% Function composition
function composed = compose(f, g)
composed = @(x) f(g(x));
end
% Higher-order function with multiple lambdas
function result = processValue(value, transform, filter)
if filter(value)
result = transform(value);
else
result = [];
end
end
% Usage
result = applyOperation(10, 20, @(a, b) a + b);
disp(result)
double = getMultiplier(2);
disp(double(5))
square = @(x) x^2;
addTen = @(x) x + 10;
squareThenAddTen = compose(addTen, square);
disp(squareThenAddTen(5))
% Named function
function result = add(a, b)
result = a + b;
end
disp(applyOperation(10, 20, @add))MATLAB supports parallel computing through the Parallel Computing Toolbox, using parfor, parfeval, and spmd.
- parfor: Parallel for loops
- parfeval: Asynchronous execution
- parpool: Worker pool management
- spmd: Single program multiple data
- GPU computing:
gpuArray
% Coroutines in MATLAB (using parfor and parallel computing)
% MATLAB doesn't have built-in coroutines like Kotlin
% Using parallel computing toolbox
% Basic parallel execution
function result = fetchData()
pause(1); % Simulate network call
result = 'Data loaded';
end
% Using parfor for parallel loops
function parallelExample()
results = cell(1, 2);
parfor i = 1:2
results{i} = fetchData();
end
disp(results)
end
% Using parfeval for async execution
function asyncExample()
pool = gcp('nocreate');
if isempty(pool)
pool = parpool(2);
end
f(1) = parfeval(@fetchData, 1);
f(2) = parfeval(@fetchData, 1);
results = fetchOutputs(f);
disp(results)
end
% Timeout
function withTimeout(seconds, fn)
try
f = parfeval(fn, 1);
[~, result] = fetchNext(f, seconds);
disp(result)
catch
disp('Timed out!')
cancel(f)
end
endData stores provide access to large datasets without loading everything into memory. They support big data processing.
- tall arrays: Work with data larger than memory
- datastore: Access to large files
- ImageDatastore: Image collections
- TabularTextDatastore: Text files
- Parallel processing: Process data in parallel
% Flows in MATLAB (using dataflow and streaming)
% MATLAB doesn't have built-in flows like Kotlin
% Using functions and arrays
% Simple flow
function stream = makeNumberStream(n)
i = 0;
stream = @() (i < n && (i = i + 1; true)) && i || [];
end
% Flow operators
function result = streamFilter(stream, pred)
result = {};
while true
val = stream();
if isempty(val)
break
end
if pred(val)
result{end+1} = val;
end
end
end
function result = streamMap(stream, fn)
result = {};
while true
val = stream();
if isempty(val)
break
end
result{end+1} = fn(val);
end
end
% State simulation
state = 0;
function result = getState()
global state
result = state;
end
function setState(val)
global state
state = val;
end
function increment()
global state
state = state + 1;
endTimers execute functions at specified intervals, useful for scheduling tasks and asynchronous operations.
- Timer creation:
timer - Properties:
StartDelay,Period - Callback:
TimerFcn - Methods:
start,stop,delete - Event handling:
ErrorFcn,StopFcn
% Channels in MATLAB (using queues and parallel computing)
% MATLAB doesn't have built-in channels like Kotlin
% Using data queues
% Simple queue using cell array
function queue = createQueue()
queue.items = {};
queue.lock = false;
end
function queue = enqueue(queue, item)
while queue.lock
pause(0.001)
end
queue.lock = true;
queue.items{end+1} = item;
queue.lock = false;
end
function [queue, item] = dequeue(queue)
while queue.lock
pause(0.001)
end
queue.lock = true;
if isempty(queue.items)
item = [];
else
item = queue.items{1};
queue.items(1) = [];
end
queue.lock = false;
end
% Basic channel using parallel computing
function basicChannel()
queue = createQueue();
parfeval(@() enqueue(queue, 'Hello'), 0);
parfeval(@() enqueue(queue, 'World'), 0);
pause(0.1);
[~, item1] = dequeue(queue);
[~, item2] = dequeue(queue);
disp(item1)
disp(item2)
endEvents and listeners enable observer pattern implementation in MATLAB handle classes.
- Events:
eventsblock in handle class - Listeners:
addlistener - Notify:
notifyto trigger events - Callback: Function called on event
- Properties:
event.Property
% Sealed Classes and Enum Classes in MATLAB
% Enum class
% classdef Color < int32
% enumeration
% RED (1)
% GREEN (2)
% BLUE (3)
% end
% end
% Status enum
% classdef Status
% enumeration
% SUCCESS (200)
% ERROR (500)
% LOADING (100)
% end
% properties
% code
% end
% methods
% function obj = Status(code)
% obj.code = code;
% end
% end
% end
% Sealed class simulation using abstract classes
% classdef (Abstract) UiState
% end
% Success.m
% classdef Success < UiState
% properties
% data
% end
% end
% Error.m
% classdef Error < UiState
% properties
% message
% end
% end
% Loading.m
% classdef Loading < UiState
% end
% Handling function
function handleState(state)
if isa(state, 'Success')
disp(['Data: ' state.data])
elseif isa(state, 'Error')
disp(['Error: ' state.message])
elseif isa(state, 'Loading')
disp('Loading...')
end
endTall arrays work with data that doesn't fit in memory. They support delayed execution and parallel processing.
- Creation:
tall(datastore) - Operations: Same as regular arrays
- Delay execution:
gatherto compute - Supported functions:
mean,sum,std - Visualization:
histogram,plot
% Generics in MATLAB
% MATLAB is dynamically typed, so generics aren't needed
% Using type checking with isa
% Generic class using cell arrays
function box = createBox(value)
box.value = value;
end
% Generic function
function [second, first] = swap(first, second)
% Swap values
temp = first;
first = second;
second = temp;
end
% Generic with constraints
function result = sumNumbers(items)
result = sum(cell2mat(items));
end
% Type checking function
function processSequence(seq)
for i = 1:length(seq)
if isnumeric(seq{i})
disp(num2str(seq{i}))
else
disp(seq{i})
end
end
end
% Usage
box = createBox('Hello');
disp(box.value)
[a, b] = swap(1, 2);
disp([a, b])
disp(sumNumbers({1, 2, 3, 4, 5}))GPU arrays allow computation on graphics cards for high-performance computing.
- Creation:
gpuArray - Operations: Many functions support GPU
- Data transfer:
gatherto CPU - CUDA kernels: Custom CUDA code
- Supported functions:
arrayfun,bsxfun
% Delegation in MATLAB
% Using composition for delegation
% Repository interface
function data = getData(repo)
data = repo.getData();
end
function saveData(repo, data)
repo.saveData(data);
end
% Database repository
function repo = createDatabaseRepository()
repo.getData = @() 'Data from database';
repo.saveData = @(data) disp(['Saving to database: ' data]);
end
% Cached repository with delegation
function repo = createCachedRepository(databaseRepo)
cache = [];
repo.getData = @() getCachedData();
repo.saveData = @(data) databaseRepo.saveData(data);
function data = getCachedData()
if isempty(cache)
data = databaseRepo.getData();
cache = data;
else
data = cache;
end
end
end
% Lazy property
function value = getExpensiveValue()
persistent cache
if isempty(cache)
disp('Computing...')
cache = 'Result';
end
value = cache;
end
% Usage
db = createDatabaseRepository();
cached = createCachedRepository(db);
disp(cached.getData())
disp(cached.getData())The command pattern encapsulates requests as objects, enabling undo/redo functionality.
- Command object: Encapsulates action
- Execute method: Perform action
- Undo method: Reverse action
- History: Stack of commands
- Invoker: Executes commands
% Object Declarations and Singletons in MATLAB
% Using functions and persistent variables
% Singleton using closure
function config = createAppConfig()
apiUrl = 'https://api.example.com';
timeout = 5000;
config.getApiUrl = @() apiUrl;
config.getTimeout = @() timeout;
config.printConfig = @() disp(['API URL: ' apiUrl ', Timeout: ' num2str(timeout)]);
end
% Singleton using class
% classdef AppConfig < handle
% properties (Constant)
% API_URL = 'https://api.example.com'
% TIMEOUT = 5000
% end
% methods (Static)
% function printConfig()
% disp(['API URL: ' AppConfig.API_URL])
% disp(['Timeout: ' num2str(AppConfig.TIMEOUT)])
% end
% end
% end
% Singleton using persistent variable
function config = getAppConfig()
persistent instance
if isempty(instance)
instance = createAppConfig();
end
config = instance;
end
% Usage
config = getAppConfig();
disp(config.getApiUrl())
config.printConfig()The singleton pattern ensures a class has only one instance. Implemented using persistent variables.
- Persistent variable: Store single instance
- Instance check:
isempty(instance) - Initialization: Create on first call
- Public access: Singleton function
- Thread-safe: Not by default
% DSL (Domain Specific Language) in MATLAB
% Using functions and structures for DSL
% HTML DSL
function html(block)
fprintf('<html>
')
block()
fprintf('</html>
')
end
function body(block)
fprintf('<body>
')
block()
fprintf('</body>
')
end
function h1(text)
fprintf('<h1>%s</h1>
', text)
end
function p(text)
fprintf('<p>%s</p>
', text)
end
% Builder pattern
function builder = createUserBuilder()
builder.name = '';
builder.age = 0;
builder.email = '';
builder.build = @() struct('name', builder.name, ...
'age', builder.age, ...
'email', builder.email);
end
function user = createUser(varargin)
builder = createUserBuilder();
for i = 1:2:length(varargin)
switch varargin{i}
case 'name'
builder.name = varargin{i+1};
case 'age'
builder.age = varargin{i+1};
case 'email'
builder.email = varargin{i+1};
end
end
user = builder.build();
end
% Usage
html(@() body(@() (h1('Welcome to MATLAB DSL'), ...
p('This is a paragraph'), ...
p('Another paragraph'))))
user = createUser('name', 'Alice', 'age', 25, 'email', 'alice@example.com');
disp(user)The factory pattern creates objects without specifying the exact class. Implemented using switch statements.
- Factory function: Creates objects
- Type parameter: Specifies which class
- Return: Instance of requested class
- Decoupling: Client doesn't know concrete classes
- Extensible: Add new types easily
% Annotations in MATLAB
% MATLAB doesn't have built-in annotations like Kotlin
% Using comments and meta-data
% Custom annotation using comments
% @MyAnnotation("test")
function annotatedClass()
% This is an annotated class
end
% Using function attributes
function annotatedMethod()
% @MyAnnotation("method")
disp('Annotated method')
end
% Metadata using struct
function obj = createAnnotated(value)
obj.value = value;
obj.annotations = {'MyAnnotation'};
end
% Reading annotations
function readAnnotations(func)
lines = split(string(fileread([func '.m'])), newline);
for i = 1:length(lines)
line = strtrim(lines{i});
if startsWith(line, '% @')
disp(['Annotation: ' line(3:end)])
end
end
end
% Example usage
annotatedMethod()
% readAnnotations('annotatedMethod')The strategy pattern defines a family of algorithms and makes them interchangeable. Implemented using function handles.
- Strategy interface: Function handle
- Context: Uses strategy
- Concrete strategies: Different algorithms
- Runtime switching: Change behavior dynamically
- Decoupling: Algorithm independent of client
% Reflection in MATLAB
% Using functions for reflection
% Class for reflection examples
person.name = 'Alice';
person.age = 25;
person.city = 'Unknown';
% Basic reflection
function basicReflection()
person = struct('name', 'Alice', 'age', 25);
fields = fieldnames(person);
disp(['Class: struct'])
disp(['Fields: ' strjoin(fields, ', ')])
end
% Accessing properties
function accessProperties()
person = struct('name', 'Alice', 'age', 25);
fields = fieldnames(person);
for i = 1:length(fields)
disp([fields{i} ' = ' num2str(person.(fields{i}))])
end
end
% Calling functions dynamically
function callFunctions()
person = struct('name', 'Alice', 'age', 25);
func = @greet;
result = func(person);
disp(result)
end
function result = greet(person)
result = ['Hello, my name is ' person.name];
end
% Create instance
function createInstance()
person = struct('name', 'Bob', 'age', 30, 'city', 'NYC');
disp(person)
endThe observer pattern defines a one-to-many dependency between objects. Implemented using events and listeners.
- Subject: Maintains observers
- Observer: Receives updates
- Events:
eventsblock - Listeners:
addlistener - Notification:
notify
% Coroutine Context and Dispatchers in MATLAB
% Using parallel computing toolbox
% Different dispatchers
function dispatcherExample()
% Default - use parfor
parfor i = 1:3
disp(['Worker ' num2str(i) ': ' getenv('COMPUTERNAME')])
end
% Custom context
try
pool = gcp('nocreate');
if isempty(pool)
pool = parpool(2);
end
disp(['Number of workers: ' num2str(pool.NumWorkers)])
catch
disp('Parallel computing toolbox not available')
end
end
% ThreadLocal simulation
function threadLocalExample()
% Use parfor for thread-local data
results = cell(1, 3);
parfor i = 1:3
results{i} = ['Thread ' num2str(i) ': ' getenv('COMPUTERNAME')];
end
disp(results)
end
% Supervisor job
function supervisorExample()
try
parfor i = 1:2
if i == 1
error('Error in task 1')
else
disp('Task 2 still running')
end
end
catch ME
disp(['Caught: ' ME.message])
end
endThe decorator pattern adds behavior to objects dynamically. Implemented using wrapper functions.
- Component: Base object
- Decorator: Wraps component
- Modification: Enhance behavior
- Chaining: Multiple decorators
- Flexibility: Add features at runtime
% Shared Mutable State in Coroutines (MATLAB)
% Using parallel computing with caution
% Counter with mutex (using parallel pool)
function counterExample()
counter = 0;
lock = false;
function increment()
while lock
pause(0.001)
end
lock = true;
counter = counter + 1;
lock = false;
end
function value = getValue()
value = counter;
end
% Simulate parallel access
try
parfor i = 1:100
increment()
end
catch
disp('Parallel execution not available')
end
disp(['Final count: ' num2str(getValue())])
end
% Using atomic operations
function atomicCounterExample()
counter = 0;
for i = 1:1000
counter = counter + 1;
end
disp(['Atomic count: ' num2str(counter)])
end
% Single-threaded
function singleThreadExample()
counter = 0;
for i = 1:1000
counter = counter + 1;
end
disp(['Single thread count: ' num2str(counter)])
endThe builder pattern constructs complex objects step by step. Implemented using methods that return the builder.
- Builder: Constructs parts
- Director: Orchestrates construction
- Product: Constructed object
- Fluent interface: Method chaining
- Validation: Check before building
% Flow Operators and Transformations in MATLAB
% Using array operations
% Basic flow transformation
function flowTransformExample()
numbers = 1:10;
evens = numbers(mod(numbers, 2) == 0);
mapped = arrayfun(@(x) ['Number ' num2str(x)], evens, 'UniformOutput', false);
disp(mapped)
end
% Flow with buffer
function flowBufferExample()
for i = 1:5
disp(i)
pause(0.1)
end
end
% Flow with conflate
function flowConflateExample()
for i = 1:10
disp(i)
pause(0.05)
end
end
% Flow with collect latest
function flowCollectLatestExample()
for i = 1:10
disp(['Processing ' num2str(i)])
pause(0.1)
disp(['Done ' num2str(i)])
end
end
% FlatMap
function flowFlatMapExample()
for i = 1:3
for letter = 'ab'
disp([num2str(i) '-' letter])
end
end
endThe adapter pattern converts one interface to another. Implemented using wrapper functions.
- Target: Expected interface
- Adaptee: Existing interface
- Adapter: Bridges interfaces
- Compatibility: Makes incompatible classes work
- Reusability: Use existing code
% Coroutine Scopes and Lifecycle in MATLAB
% Using parallel computing with lifecycle management
% Custom scope
function scope = createScope()
scope.cancelled = false;
scope.tasks = {};
end
function scope = launchTask(scope, fn)
scope.tasks{end+1} = parfeval(fn, 1);
end
function cancelScope(scope)
scope.cancelled = true;
for i = 1:length(scope.tasks)
cancel(scope.tasks{i})
end
end
% Lifecycle-aware scope
function lifecycleExample()
scope = createScope();
launchTask(scope, @() (pause(1); disp('Task 1')));
launchTask(scope, @() (pause(2); disp('Task 2')));
pause(0.5);
cancelScope(scope);
end
% Global scope
function globalScopeExample()
parfeval(@() (pause(1); disp('GlobalScope')), 1);
pause(2);
end
% Scope with timeout
function timeoutScope()
try
f = parfeval(@() (pause(2); 'Success'), 1);
[~, result] = fetchNext(f, 1);
if isempty(result)
disp('Timed out')
else
disp(result)
end
catch
disp('Timed out')
end
endThe facade pattern provides a simplified interface to a complex subsystem. Implemented as a wrapper function.
- Facade: Simplified interface
- Subsystem: Complex components
- Simplification: Hide complexity
- Decoupling: Client doesn't need subsystem details
- Usage: Library APIs
% SharedFlow and StateFlow in MATLAB
% Using observers and state management
% StateFlow simulation
function flow = createStateFlow(initialValue)
flow.value = initialValue;
flow.observers = {};
end
function updateState(flow, newValue)
flow.value = newValue;
for i = 1:length(flow.observers)
flow.observers{i}(newValue);
end
end
function observeState(flow, callback)
flow.observers{end+1} = callback;
end
% SharedFlow simulation
function flow = createSharedFlow(replay)
flow.events = {};
flow.replay = replay;
flow.replayed = {};
flow.observers = {};
end
function emitEvent(flow, event)
flow.events{end+1} = event;
flow.replayed{end+1} = event;
if length(flow.replayed) > flow.replay
flow.replayed(1) = [];
end
for i = 1:length(flow.observers)
flow.observers{i}(event);
end
end
% Distinct until changed
function distinctExample(flow)
lastValue = [];
observeState(flow, @(value) (isempty(lastValue) || ~isequal(value, lastValue)) && ...
(lastValue = value; disp(value)));
end
% Combine flows
function result = combineFlows(flow1, flow2)
result = createStateFlow(0);
observeState(flow1, @(value) updateState(result, value + flow2.value));
observeState(flow2, @(value) updateState(result, flow1.value + value));
endThe composite pattern treats individual objects and compositions uniformly. Implemented using nested structures.
- Component: Interface for all
- Leaf: Individual object
- Composite: Container of children
- Operations: Work on both leaf and composite
- Tree structure: Nested hierarchies
% Coroutine Exception Handling in MATLAB
% Using try-catch with parallel computing
% Try-catch in parallel
function tryCatchExample()
try
parfeval(@() error('Error'), 1);
catch ME
disp(['Caught: ' ME.message])
end
end
% Exception handler
function exceptionHandler()
try
parfeval(@() error('Test'), 1);
pause(0.1);
catch ME
disp(['Handler caught: ' ME.message])
end
end
% Supervisor for child isolation
function supervisorExample2()
try
parfor i = 1:2
if i == 1
error('Child 1 error')
else
pause(0.2)
disp('Child 2 still running')
end
end
catch ME
disp(['Caught: ' ME.message])
end
end
% Flow exception handling
function flowException()
try
disp('1')
error('Flow error')
catch ME
disp(['Flow caught: ' ME.message])
disp('-1')
end
end
% Supervisor scope
function supervisorScopeExample()
try
parfor i = 1:2
if i == 1
error('Error')
else
pause(0.1)
disp('Still running')
end
end
catch
% Continue execution
end
endThe visitor pattern separates algorithms from object structures. Implemented using function handles.
- Visitor: Defines operations
- Element: Accepts visitors
- Double dispatch: Determines which operation
- Extensibility: Add operations without modifying elements
- Separation: Algorithm and structure separate
% Channel Producers and Consumer Patterns in MATLAB
% Using queues for producer-consumer patterns
% Producer-Consumer pattern
function producerConsumer()
queue = {};
% Producer
parfeval(@() (for i = 1:20; queue{end+1} = i; disp(['Produced: ' num2str(i)]); pause(0.1); end), 1);
% Consumer
parfeval(@() (for i = 1:20; if ~isempty(queue); val = queue{1}; queue(1) = []; disp(['Consumed: ' num2str(val)]); end; pause(0.15); end), 1);
end
% Fan-out pattern
function fanOutExample()
queue = {};
% Producer
parfeval(@() (for i = 1:20; queue{end+1} = i; end), 1);
% Multiple consumers
for id = 1:3
parfeval(@() (for i = 1:20; if ~isempty(queue); val = queue{1}; queue(1) = []; disp(['Consumer ' num2str(id) ': ' num2str(val)]); end; pause(0.1); end), 1);
end
end
% Fan-in pattern
function fanInExample()
queue = {};
% Multiple producers
for id = 1:3
parfeval(@() (for i = 1:5; queue{end+1} = ['Producer ' num2str(id) ': ' num2str(i)]; pause(0.05); end), 1);
end
% Single consumer
parfeval(@() (for i = 1:15; if ~isempty(queue); val = queue{1}; queue(1) = []; disp(val); end; end), 1);
endThe proxy pattern controls access to another object. Implemented using wrapper functions.
- Subject: Real object
- Proxy: Controls access
- Access control: Check permissions
- Lazy loading: Create on demand
- Logging: Log access
% Coroutine Cancellation in MATLAB
% Using cancellation with parallel computing
% Cooperative cancellation
function cooperativeCancellation()
cancelled = false;
parfeval(@() (for i = 1:100; if cancelled; break; end; disp(['Working: ' num2str(i)]); pause(0.05); end), 1);
pause(0.2);
cancelled = true;
end
% Cancellation with finally
function cancellationFinally()
try
parfeval(@() (for i = 1:100; disp(['Processing: ' num2str(i)]); pause(0.1); end), 1);
pause(0.25);
disp('Cleaning up')
pause(0.1)
disp('Cleanup done')
catch
disp('Cleaning up')
end
end
% Cancellation with timeout
function cancellationTimeout()
try
f = parfeval(@() (for i = 1:10; pause(0.2); disp(['Iteration: ' num2str(i)]); end), 1);
[~, result] = fetchNext(f, 1);
if isempty(result)
cancel(f)
disp('Timed out')
end
catch
disp('Timed out')
end
end
% Custom cancellation check
function customCancellation()
cancelled = false;
parfeval(@() (i = 0; while ~cancelled && i < 1000; if mod(i, 100) == 0; disp(['Still running: ' num2str(i)]); end; i = i + 1; pause(0.001); end), 1);
pause(0.1);
cancelled = true;
endThe chain of responsibility passes requests along a chain of handlers. Implemented using linked structure.
- Handler: Processes or forwards
- Chain: Linked list of handlers
- Processing: Each handler decides
- Decoupling: Sender doesn't know which handler
- Flexibility: Add/remove handlers
% Testing Coroutines in MATLAB
% Using unit testing framework
% Basic test
function testCoroutine()
result = [];
f = parfeval(@() (pause(1); 'Success'), 1);
[~, result] = fetchNext(f);
assert(strcmp(result, 'Success'), 'Test failed');
end
% Test with delay
function testWithDelay()
result = [];
f = parfeval(@() (pause(1); 'Done'), 1);
pause(1);
[~, result] = fetchNext(f);
assert(strcmp(result, 'Done'), 'Test failed');
end
% Test multiple coroutines
function testMultipleCoroutines()
results = {};
f1 = parfeval(@() (pause(0.5); 'Task 1'), 1);
f2 = parfeval(@() (pause(0.3); 'Task 2'), 1);
[~, r1] = fetchNext(f1);
[~, r2] = fetchNext(f2);
results = {r1, r2};
assert(isequal(results, {'Task 1', 'Task 2'}), 'Test failed');
end
% Time control test
function timeControlTest()
counter = 0;
f = parfeval(@() (for i = 1:5; pause(1); counter = counter + 1; end), 1, counter);
pause(3);
cancel(f);
assert(counter <= 4, 'Test failed');
endThe memento pattern captures and restores object state. Implemented using structures.
- Memento: Stores state
- Originator: Creates/restores mementos
- Caretaker: Manages mementos
- Undo/Redo: Restore previous states
- Encapsulation: State is external
% MATLAB Multiplatform
% MATLAB runs on multiple platforms with platform-specific features
% Platform-specific code
function name = platformName()
if ispc
name = 'Windows';
elseif ismac
name = 'macOS';
elseif isunix
name = 'Linux';
else
name = 'Unknown';
end
end
function greet()
disp(['Hello from ' platformName()])
end
% Platform-specific class
function version = getVersion()
version = ver('MATLAB');
disp(['MATLAB version: ' version(1).Version])
end
% Platform info
function getInfo()
disp([greet() ' version ' getVersion()])
end
% Serialization
function str = encodeUser(user)
str = sprintf('%d
%s
%s', user.id, user.name, user.email);
end
function user = decodeUser(str)
lines = strsplit(str, '
');
user = struct('id', str2double(lines{1}), ...
'name', lines{2}, ...
'email', lines{3});
endReverse a string using fliplr or manual iteration.
- Built-in:
fliplr(str) - Manual: Loop from end to start
- Complexity: O(n) time
% Reverse a string
function result = reverseString(str)
result = fliplr(str);
end
disp(reverseString('hello')) % "olleh"
% Manual implementation
function result = reverseStringManual(str)
result = '';
for i = length(str):-1:1
result = [result str(i)];
end
endCheck if a string is a palindrome using fliplr or two-pointer approach.
- Method:
strcmp(cleaned, fliplr(cleaned)) - Two-pointer: Compare from both ends
- Case insensitive:
lower - Ignore non-alphanumeric:
isstrprop
% Check palindrome
function result = isPalindrome(str)
cleaned = lower(str(isstrprop(str, 'alphanum')));
result = strcmp(cleaned, fliplr(cleaned));
end
disp(isPalindrome('racecar')) % true
disp(isPalindrome('hello')) % false
% Two-pointer approach
function result = isPalindromeTwoPointer(str)
cleaned = lower(str(isstrprop(str, 'alphanum')));
left = 1;
right = length(cleaned);
result = true;
while left < right
if cleaned(left) ~= cleaned(right)
result = false;
return;
end
left = left + 1;
right = right - 1;
end
endFind maximum using max or manual iteration.
- Built-in:
max(arr) - Manual: Iterate and track max
- Empty array: Returns []
% Find max in array
function result = findMax(arr)
result = max(arr);
end
disp(findMax([1, 5, 3, 9, 2])) % 9
% Manual implementation
function result = findMaxManual(arr)
result = arr(1);
for i = 2:length(arr)
if arr(i) > result
result = arr(i);
end
end
endRemove duplicates using unique.
- Built-in:
unique(arr) - Preserve order:
unique(arr, 'stable') - Complexity: O(n log n)
% Remove duplicates
function result = removeDuplicates(arr)
result = unique(arr);
end
disp(removeDuplicates([1, 2, 2, 3, 3, 4])) % [1, 2, 3, 4]
% Using set
function result = removeDuplicatesSet(arr)
result = unique(arr);
endMerge arrays using concatenation.
- Method:
[arr1, arr2]orhorzcat - Vertical:
[arr1; arr2] - Unique:
union
% Merge arrays
function result = mergeArrays(arr1, arr2)
result = [arr1, arr2];
end
disp(mergeArrays([1, 2], [3, 4])) % [1, 2, 3, 4]
% Alternative
function result = mergeArraysPlus(arr1, arr2)
result = horzcat(arr1, arr2);
endConvert using str2double.
- toNumber:
str2double(str) - Safe: Check
isnan - Error handling: Returns NaN on failure
% Convert string to number
function result = stringToNumber(str)
result = str2double(str);
end
disp(stringToNumber('42')) % 42
% Safe conversion
function result = stringToNumberSafe(str)
result = str2double(str);
if isnan(result)
result = [];
end
endIterate through structure using fieldnames.
- Method:
fieldnamesand loop - Alternative:
forloop with dynamic field names - Keys:
fieldnames - Values:
struct2cell
% Loop through map (structure)
function loopMap(map)
fields = fieldnames(map);
for i = 1:length(fields)
disp([fields{i} ' => ' num2str(map.(fields{i}))])
end
end
% Alternative
function loopMapAlternate(map)
fn = fieldnames(map);
for i = 1:numel(fn)
disp([fn{i} ' => ' num2str(map.(fn{i}))])
end
end
data = struct('name', 'Alice', 'age', 25, 'city', 'NYC');
loopMap(data)Delay using pause or timers.
- Pause:
pause(seconds) - Timer:
timerobject - Async:
timerwith callback
% Delay function execution
function delayedExecution(delayMs, block)
pause(delayMs / 1000);
block();
end
% Example usage
delayedExecution(2000, @() disp('After 2 seconds'));
% Using timer
function delayedExecutionTimer(delayMs, block)
t = timer('StartDelay', delayMs / 1000, 'TimerFcn', block);
start(t);
endMake HTTP GET using webread or urlread.
- webread:
webread(url) - Options:
weboptions - Error handling:
try-catch
% HTTP GET request
function data = fetchData(url)
try
options = weboptions('Timeout', 10);
data = webread(url, options);
catch ME
disp(['Error: ' ME.message])
data = [];
end
end
% Using urlread (older versions)
function data = fetchDataOld(url)
try
data = urlread(url);
catch ME
disp(['Error: ' ME.message])
data = [];
end
end
% Example
% data = fetchData('https://api.example.com/data');Create a Deferred using structures and polling.
- Structure: State and result
- Polling: Check done flag
- Error handling: Store error
% Create a promise-like Deferred
function deferred = createDeferred(shouldResolve)
deferred.result = [];
deferred.done = false;
try
if shouldResolve
pause(1);
deferred.result = 'Success!';
else
error('Failed!');
end
catch ME
deferred.error = ME;
end
deferred.done = true;
end
% Usage
deferred = createDeferred(true);
while ~deferred.done
pause(0.1);
end
if isfield(deferred, 'error')
disp(['Caught: ' deferred.error.message])
else
disp(deferred.result)
endCalculate factorial using recursion or iteration.
- Recursive:
if n <= 1, 1 else n * factorial(n-1) - Iterative:
prod(1:n) - Edge cases: 0! = 1
% Factorial
function result = factorial(n)
if n <= 1
result = 1;
else
result = n * factorial(n - 1);
end
end
disp(factorial(5)) % 120
% Iterative version
function result = factorialIterative(n)
result = 1;
for i = 2:n
result = result * i;
end
endCalculate Fibonacci using recursion, iteration, or memoization.
- Recursive:
if n <= 1, n else fib(n-1) + fib(n-2) - Iterative: Loop with variables
- Memoization:
containers.Map
% Fibonacci
function result = fibonacci(n)
if n <= 1
result = n;
else
result = fibonacci(n - 1) + fibonacci(n - 2);
end
end
disp(fibonacci(8)) % 21
% Iterative version
function result = fibonacciIterative(n)
if n <= 1
result = n;
return;
end
a = 0;
b = 1;
for i = 2:n
temp = a + b;
a = b;
b = temp;
end
result = b;
endFizzBuzz using if-else with modulo operations.
- Modulo:
modfunction - Order: Check 15 first
- Range:
forloop
% FizzBuzz
function fizzBuzz(n)
for i = 1:n
if mod(i, 15) == 0
disp('FizzBuzz')
elseif mod(i, 3) == 0
disp('Fizz')
elseif mod(i, 5) == 0
disp('Buzz')
else
disp(i)
end
end
end
fizzBuzz(15)Find missing number using formula or XOR.
- Formula:
total - sum - XOR method: XOR all numbers and indices
- Edge cases: Empty array
% Find missing number
function result = findMissing(arr)
n = length(arr) + 1;
total = n * (n + 1) / 2;
sumArr = sum(arr);
result = total - sumArr;
end
disp(findMissing([1, 2, 4, 5, 6])) % 3Find duplicates using unique and accumarray.
- Method:
uniquewith counts - Filter:
counts > 1 - Complexity: O(n log n)
% Find duplicates
function result = findDuplicates(arr)
[uniqueVals, ~, idx] = unique(arr);
counts = accumarray(idx, 1);
result = uniqueVals(counts > 1);
end
disp(findDuplicates([1, 2, 3, 2, 4, 3])) % [2, 3]
% Manual implementation
function result = findDuplicatesManual(arr)
seen = [];
duplicates = [];
for i = 1:length(arr)
if any(seen == arr(i))
duplicates = [duplicates, arr(i)];
else
seen = [seen, arr(i)];
end
end
result = unique(duplicates);
endCalculate sum using sum or manual iteration.
- Built-in:
sum(arr) - Manual: Loop and accumulate
- Empty array: Returns 0
% Sum of array
function result = sumArray(arr)
result = sum(arr);
end
disp(sumArray([1, 2, 3, 4, 5])) % 15
% Manual implementation
function result = sumArrayManual(arr)
result = 0;
for i = 1:length(arr)
result = result + arr(i);
end
endCalculate average using mean or manual division.
- Built-in:
mean(arr) - Manual:
sum(arr) / length(arr) - Empty array: Returns NaN
% Average of array
function result = averageArray(arr)
result = mean(arr);
end
disp(averageArray([1, 2, 3, 4, 5])) % 3
% Manual implementation
function result = averageArrayManual(arr)
result = sum(arr) / length(arr);
endSort using sort.
- Built-in:
sort(arr) - Non-mutating:
sortreturns new array - Complexity: O(n log n)
% Sort array ascending
function result = sortAscending(arr)
result = sort(arr);
end
disp(sortAscending([5, 2, 8, 1, 9])) % [1, 2, 5, 8, 9]
% In-place sorting
function sortAscendingInPlace(arr)
sort(arr);
endSort descending using sort with 'descend'.
- Built-in:
sort(arr, 'descend') - Alternative:
sort(arr, 'descend') - Complexity: O(n log n)
% Sort array descending
function result = sortDescending(arr)
result = sort(arr, 'descend');
end
disp(sortDescending([5, 2, 8, 1, 9])) % [9, 8, 5, 2, 1]
% In-place sorting
function sortDescendingInPlace(arr)
sort(arr, 'descend');
endFlatten using recursion or cell2mat.
- Recursive: Check if cell
- cell2mat: For numeric cells
- Complexity: O(n) time
% Flatten nested array
function result = flattenArray(arr)
result = [];
for i = 1:length(arr)
if iscell(arr{i})
result = [result, flattenArray(arr{i})];
else
result = [result, arr{i}];
end
end
end
disp(flattenArray({1, {2, {3, 4}, 5}, 6})) % [1, 2, 3, 4, 5, 6]
% Using cellfun
function result = flattenArrayCell(arr)
result = arr(cellfun(@iscell, arr));
if ~isempty(result)
result = flattenArray(result);
end
endSplit array into chunks using mat2cell or manual slicing.
- mat2cell:
mat2cell(arr, 1, indices) - Manual: Loop and slice
- Use case: Batch processing
% Chunk array
function result = chunkArray(arr, size)
result = {};
for i = 1:size:length(arr)
endIdx = min(i + size - 1, length(arr));
result{end+1} = arr(i:endIdx);
end
end
disp(chunkArray([1, 2, 3, 4, 5, 6], 2)) % {[1, 2], [3, 4], [5, 6]}
% Using mat2cell
function result = chunkArrayMat2cell(arr, size)
n = length(arr);
indices = diff([0, size:size:n]);
result = mat2cell(arr, 1, indices);
endBinary search on sorted array using manual implementation.
- Manual: While loop with left/right pointers
- Time: O(log n)
- Requirement: Array must be sorted
% Binary search
function result = binarySearch(arr, target)
left = 1;
right = length(arr);
while left <= right
mid = floor((left + right) / 2);
if arr(mid) == target
result = mid;
return;
elseif arr(mid) < target
left = mid + 1;
else
right = mid - 1;
end
end
result = -1;
end
disp(binarySearch([1, 2, 3, 4, 5, 6, 7], 5)) % 5
% Using built-in
function result = binarySearchBuiltIn(arr, target)
result = find(arr == target);
if isempty(result)
result = -1;
else
result = result(1);
end
endQuick sort using pivot-based partitioning.
- Algorithm: Choose pivot, partition, recurse
- Time: O(n log n) average
- Implementation: Recursive
% Quick sort
function result = quickSort(arr)
if length(arr) <= 1
result = arr;
return;
end
pivot = arr(1);
left = arr(arr < pivot);
right = arr(arr > pivot);
result = [quickSort(left), pivot, quickSort(right)];
end
disp(quickSort([5, 3, 8, 4, 2, 7, 1, 6]))
% In-place quick sort
function quickSortInPlace(arr, low, high)
if nargin < 2
low = 1;
high = length(arr);
end
if low < high
pi = partition(arr, low, high);
quickSortInPlace(arr, low, pi - 1);
quickSortInPlace(arr, pi + 1, high);
end
end
function pi = partition(arr, low, high)
pivot = arr(high);
i = low - 1;
for j = low:high-1
if arr(j) <= pivot
i = i + 1;
temp = arr(i);
arr(i) = arr(j);
arr(j) = temp;
end
end
temp = arr(i + 1);
arr(i + 1) = arr(high);
arr(high) = temp;
pi = i + 1;
endMerge sort using divide-and-conquer.
- Algorithm: Divide, sort, merge
- Time: O(n log n)
- Space: O(n) auxiliary space
% Merge sort
function result = mergeSort(arr)
if length(arr) <= 1
result = arr;
return;
end
mid = floor(length(arr) / 2);
left = mergeSort(arr(1:mid));
right = mergeSort(arr(mid+1:end));
result = merge(left, right);
end
function result = merge(left, right)
i = 1;
j = 1;
result = [];
while i <= length(left) && j <= length(right)
if left(i) <= right(j)
result = [result, left(i)];
i = i + 1;
else
result = [result, right(j)];
j = j + 1;
end
end
if i <= length(left)
result = [result, left(i:end)];
end
if j <= length(right)
result = [result, right(j:end)];
end
endBubble sort with early termination.
- Algorithm: Compare adjacent, swap
- Time: O(n²) worst case
- Optimization: Stop if no swaps
% Bubble sort
function result = bubbleSort(arr)
result = arr;
for i = 1:length(result) - 1
for j = 1:length(result) - i
if result(j) > result(j + 1)
temp = result(j);
result(j) = result(j + 1);
result(j + 1) = temp;
end
end
end
end
% Optimized bubble sort
function result = bubbleSortOptimized(arr)
result = arr;
for i = 1:length(result) - 1
swapped = false;
for j = 1:length(result) - i
if result(j) > result(j + 1)
temp = result(j);
result(j) = result(j + 1);
result(j + 1) = temp;
swapped = true;
end
end
if ~swapped
break;
end
end
endFind common elements using intersect.
- Built-in:
intersect(arr1, arr2) - Alternative:
ismember - Complexity: O(n log n)
% Intersection of arrays
function result = intersection(arr1, arr2)
result = intersect(arr1, arr2);
end
disp(intersection([1, 2, 3, 4], [3, 4, 5, 6])) % [3, 4]
% Using ismember
function result = intersectionIsmember(arr1, arr2)
result = arr1(ismember(arr1, arr2));
endCombine arrays with unique elements using union.
- Built-in:
union(arr1, arr2) - Alternative:
unique([arr1, arr2]) - Complexity: O(n log n)
% Union of arrays
function result = unionArrays(arr1, arr2)
result = union(arr1, arr2);
end
disp(unionArrays([1, 2, 3], [3, 4, 5])) % [1, 2, 3, 4, 5]
% Using setdiff
function result = unionSetdiff(arr1, arr2)
result = [arr1, setdiff(arr2, arr1)];
endFind elements in first array not in second using setdiff.
- Built-in:
setdiff(arr1, arr2) - Symmetric:
setdiff(arr1, arr2) ∪ setdiff(arr2, arr1) - Complexity: O(n log n)
% Difference of arrays
function result = difference(arr1, arr2)
result = setdiff(arr1, arr2);
end
disp(difference([1, 2, 3, 4], [3, 4, 5, 6])) % [1, 2]
% Symmetric difference
function result = symmetricDifference(arr1, arr2)
result = [setdiff(arr1, arr2), setdiff(arr2, arr1)];
endGroup structures by property using containers.Map.
- Method:
containers.Map - Key: Property value
- Value: Array of structures
% Group by property
function result = groupByProperty(items, key)
result = containers.Map();
for i = 1:length(items)
if isfield(items(i), key)
keyValue = items(i).(key);
if isKey(result, keyValue)
result(keyValue) = [result(keyValue), items(i)];
else
result(keyValue) = items(i);
end
end
end
end
% Usage
data(1).type = 'fruit';
data(1).name = 'apple';
data(2).type = 'fruit';
data(2).name = 'banana';
data(3).type = 'veg';
data(3).name = 'carrot';
groups = groupByProperty(data, 'type');
keys = groups.keys();
for i = 1:length(keys)
disp([keys{i} ': ' num2str(length(groups(keys{i}))) ' items'])
endDeep clone by recursively copying structures.
- Method: Recursive function
- Structures: Copy all fields
- Cell arrays: Copy all elements
% Deep clone object
function result = deepClone(obj)
if isstruct(obj)
result = struct();
fields = fieldnames(obj);
for i = 1:length(fields)
result.(fields{i}) = deepClone(obj.(fields{i}));
end
elseif iscell(obj)
result = cell(size(obj));
for i = 1:numel(obj)
result{i} = deepClone(obj{i});
end
else
result = obj;
end
end
% Usage
person.name = 'Alice';
person.address.city = 'NYC';
person.address.zip = '10001';
cloned = deepClone(person);
cloned.name = 'Bob';
disp(person.name) % Alice
disp(cloned.name) % BobPerform immutable updates on nested structures.
- Method: Copy and update path
- Path: Dot notation
- Use case: Functional programming
% Immutable update
function result = updateImmutable(obj, path, value)
parts = strsplit(path, '.');
if length(parts) == 1
result = obj;
result.(parts{1}) = value;
else
result = obj;
result.(parts{1}) = updateImmutable(obj.(parts{1}), ...
strjoin(parts(2:end), '.'), value);
end
end
state.user.name = 'Alice';
state.user.age = 25;
newState = updateImmutable(state, 'user.age', 26);
disp(state.user.age) % 25
disp(newState.user.age) % 26Pipe composes functions from left to right.
- Method:
pipe(fns...) - Implementation: Loop with function handles
- Direction: Left to right
% Pipe function
function result = pipe(varargin)
fns = varargin;
result = @(value) applyPipe(value, fns);
end
function value = applyPipe(value, fns)
for i = 1:length(fns)
value = fns{i}(value);
end
end
% Usage
double = @(x) x * 2;
addTen = @(x) x + 10;
square = @(x) x^2;
process = pipe(double, addTen, square);
disp(process(5)) % (5*2+10)^2 = 400Compose functions from right to left.
- Method:
compose(fns...) - Implementation: Loop with function handles
- Direction: Right to left
% Compose function
function result = compose(varargin)
fns = varargin;
result = @(value) applyCompose(value, fns);
end
function value = applyCompose(value, fns)
for i = length(fns):-1:1
value = fns{i}(value);
end
end
% Usage
process2 = compose(square, addTen, double);
disp(process2(5)) % (5*2+10)^2 = 400Cache function results based on arguments.
- Method:
containers.Map - Key: Arguments as string
- Trade-off: Memory for speed
% Memoization
function memoFn = memoize(fn)
cache = containers.Map();
memoFn = @(arg) memoizedCall(arg);
function result = memoizedCall(arg)
key = mat2str(arg);
if isKey(cache, key)
result = cache(key);
else
result = fn(arg);
cache(key) = result;
end
end
end
% Usage
fibonacciMemo = memoize(@(n) (n <= 1) * n + (n > 1) * ...
(fibonacciMemo(n - 1) + fibonacciMemo(n - 2)));
disp(fibonacciMemo(10))Ensure a function is called only once.
- Method: Use flag and closure
- Implementation: Track if called
- Use case: Initialization
% Once function
function onceFn = once(fn)
called = false;
result = [];
onceFn = @() onceCall();
function value = onceCall()
if ~called
called = true;
result = fn();
end
value = result;
end
end
% Usage
initialize = once(@() (disp('Initialized'), struct('id', 1, 'name', 'App')));
disp(initialize()) % Prints "Initialized"
disp(initialize()) % Returns cached resultDebounce with leading edge executes immediately then waits.
- Method: Track last call time
- Implementation: Timer and flag
- Use case: Save actions, API calls
% Debounce with leading edge
function debounced = debounceLeading(delayMs, fn)
lastCall = 0;
timer = [];
debounced = @() debounceCall();
function debounceCall()
now = toc();
if now - lastCall < delayMs / 1000
if ~isempty(timer)
stop(timer)
delete(timer)
end
timer = timer('StartDelay', delayMs / 1000, ...
'TimerFcn', @(~,~) (lastCall = toc(); fn()));
start(timer)
else
lastCall = now;
fn()
end
end
endThrottle with leading edge executes at most once per time period.
- Method: Track last call time
- Implementation: Check time difference
- Use case: Scroll events
% Throttle with leading edge
function throttled = throttleLeading(delayMs, fn)
lastCall = 0;
throttled = @() throttleCall();
function throttleCall()
now = toc();
if now - lastCall >= delayMs / 1000
lastCall = now;
fn()
end
end
endDeep equality comparison for nested structures.
- Method: Recursive comparison
- Structures: Compare fields
- Cell arrays: Compare elements
% Deep equal
function result = deepEqual(obj1, obj2)
if isequal(obj1, obj2)
result = true;
return;
end
if isstruct(obj1) && isstruct(obj2)
fields1 = fieldnames(obj1);
fields2 = fieldnames(obj2);
if ~isequal(fields1, fields2)
result = false;
return;
end
for i = 1:length(fields1)
if ~deepEqual(obj1.(fields1{i}), obj2.(fields2{i}))
result = false;
return;
end
end
result = true;
elseif iscell(obj1) && iscell(obj2)
if length(obj1) ~= length(obj2)
result = false;
return;
end
for i = 1:length(obj1)
if ~deepEqual(obj1{i}, obj2{i})
result = false;
return;
end
end
result = true;
else
result = isequal(obj1, obj2);
end
endObservable pattern for event notification.
- Observable: Maintains subscribers
- Subscribe: Add callback
- Notify: Call all subscribers
% Observable pattern
function observable = createObservable()
observable.subscribers = {};
observable.subscribe = @(callback) addSubscriber(callback);
observable.notify = @(data) notifySubscribers(data);
function unsubscribe = addSubscriber(callback)
observable.subscribers{end+1} = callback;
unsubscribe = @() removeSubscriber(callback);
end
function removeSubscriber(callback)
idx = find(cellfun(@(x) isequal(x, callback), observable.subscribers));
observable.subscribers(idx) = [];
end
function notifySubscribers(data)
for i = 1:length(observable.subscribers)
observable.subscribers{i}(data);
end
end
end
% Usage
obs = createObservable();
unsubscribe = obs.subscribe(@(data) disp(['Received: ' data]));
obs.notify('Hello') % Received: Hello
unsubscribe()
obs.notify('World') % Nothing happensSingleton pattern using persistent variable.
- Method: Persistent variable
- Thread-safe: Single-threaded
- Global access: Through function
% Singleton pattern
function singleton = getSingleton()
persistent instance
if isempty(instance)
instance.data = containers.Map();
instance.set = @(key, value) setData(key, value);
instance.get = @(key) getData(key);
singleton = instance;
else
singleton = instance;
end
function setData(key, value)
instance.data(key) = value;
end
function value = getData(key)
if isKey(instance.data, key)
value = instance.data(key);
else
value = [];
end
end
end
% Usage
singleton = getSingleton();
singleton.set('name', 'Alice');
disp(singleton.get('name')) % AliceFactory pattern using switch statement.
- Method:
createUserfunction - Benefits: Decouples creation
- Structures: Return different types
% Factory pattern
function user = createUser(type, name)
switch type
case 'admin'
user = struct('type', 'admin', 'name', name);
case 'guest'
user = struct('type', 'guest', 'name', name);
otherwise
user = struct('type', 'regular', 'name', name);
end
end
% Usage
admin = createUser('admin', 'Alice');
disp(admin)Strategy pattern using function handles.
- Interface: Function handle
- Context: Uses strategy
- Benefits: Runtime switching
% Strategy pattern
function strategy = createPaymentStrategy(type)
switch type
case 'credit'
strategy.pay = @(amount) disp(['Paid $' num2str(amount) ' with Credit Card']);
case 'paypal'
strategy.pay = @(amount) disp(['Paid $' num2str(amount) ' with PayPal']);
case 'crypto'
strategy.pay = @(amount) disp(['Paid $' num2str(amount) ' with Crypto']);
otherwise
strategy.pay = @(amount) disp(['Paid $' num2str(amount) ' with Unknown']);
end
end
function executePayment(strategy, amount)
strategy.pay(amount);
end
% Usage
credit = createPaymentStrategy('credit');
paypal = createPaymentStrategy('paypal');
executePayment(credit, 100);
executePayment(paypal, 50);Observer pattern using functions.
- Subject: Maintains observers
- Observer: Receives updates
- Benefits: Loose coupling
% Observer pattern
function subject = createSubject()
subject.observers = {};
subject.state = '';
subject.attach = @(observer) attachObserver(observer);
subject.detach = @(observer) detachObserver(observer);
subject.setState = @(newState) setState(newState);
function attachObserver(observer)
subject.observers{end+1} = observer;
end
function detachObserver(observer)
idx = find(cellfun(@(x) isequal(x, observer), subject.observers));
subject.observers(idx) = [];
end
function setState(newState)
subject.state = newState;
notifyObservers();
end
function notifyObservers()
for i = 1:length(subject.observers)
subject.observers{i}.update(subject.state);
end
end
end
function observer = createObserver(name)
observer.name = name;
observer.update = @(data) disp([name ' received: ' data]);
end
% Usage
subject = createSubject();
observer1 = createObserver('Observer1');
observer2 = createObserver('Observer2');
subject.attach(observer1);
subject.attach(observer2);
subject.setState('Hello World')Decorator pattern using wrapper functions.
- Component: Base object
- Decorator: Wraps component
- Benefits: Flexible extension
% Decorator pattern
function coffee = createCoffee()
coffee.cost = 5.0;
coffee.description = 'Coffee';
end
function coffee = milkDecorator(coffee)
coffee.cost = coffee.cost + 2.0;
coffee.description = [coffee.description ', Milk'];
end
function coffee = sugarDecorator(coffee)
coffee.cost = coffee.cost + 1.0;
coffee.description = [coffee.description ', Sugar'];
end
% Usage
coffee = createCoffee();
coffee = milkDecorator(coffee);
coffee = sugarDecorator(coffee);
disp(coffee.description) % Coffee, Milk, Sugar
disp(coffee.cost) % 8.0Command pattern using functions.
- Command: Encapsulates request
- Invoker: Executes commands
- Benefits: Undo/redo
% Command pattern
function command = createAddCommand(receiver, value)
command.execute = @() executeAdd();
command.undo = @() undoAdd();
function executeAdd()
receiver(end+1) = value;
end
function undoAdd()
receiver(end) = [];
end
end
% Usage
receiver = [1, 2, 3];
cmd = createAddCommand(receiver, 4);
cmd.execute()
disp(receiver) % [1, 2, 3, 4]
cmd.undo()
disp(receiver) % [1, 2, 3]Memento pattern for state restoration.
- Originator: Creates/restores mementos
- Memento: Stores state
- Caretaker: Manages mementos
% Memento pattern
function memento = createMemento(state)
memento.state = state;
end
function originator = createOriginator()
originator.state = '';
originator.saveState = @() createMemento(originator.state);
originator.restoreState = @(memento) setState(memento.state);
function setState(newState)
originator.state = newState;
disp(['State set to: ' newState])
end
end
function caretaker = createCaretaker()
caretaker.mementos = {};
caretaker.addMemento = @(memento) addMemento(memento);
caretaker.getMemento = @(index) getMemento(index);
function addMemento(memento)
caretaker.mementos{end+1} = memento;
end
function memento = getMemento(index)
memento = caretaker.mementos{index};
end
end
% Usage
originator = createOriginator();
caretaker = createCaretaker();
originator.state = 'State 1';
caretaker.addMemento(originator.saveState());
originator.state = 'State 2';
caretaker.addMemento(originator.saveState());
originator.state = 'State 3';
originator.restoreState(caretaker.getMemento(1));
disp(originator.state) % State 1Mediator pattern for centralized communication.
- Mediator: Encapsulates communication
- Colleague: Communicates through mediator
- Benefits: Loose coupling
% Mediator pattern
function mediator = createMediator()
mediator.colleagues = {};
mediator.register = @(colleague) registerColleague(colleague);
mediator.send = @(message, sender) sendMessage(message, sender);
function registerColleague(colleague)
mediator.colleagues{end+1} = colleague;
end
function sendMessage(message, sender)
for i = 1:length(mediator.colleagues)
if ~isequal(mediator.colleagues{i}, sender)
mediator.colleagues{i}.receive(message);
end
end
end
end
function colleague = createColleague(name, mediator)
colleague.name = name;
colleague.mediator = mediator;
colleague.send = @(message) sendMessage(message);
colleague.receive = @(message) receiveMessage(message);
mediator.register(colleague);
function sendMessage(message)
mediator.send(message, colleague);
end
function receiveMessage(message)
disp([name ' received: ' message])
end
end
% Usage
mediator = createMediator();
alice = createColleague('Alice', mediator);
bob = createColleague('Bob', mediator);
alice.send('Hello Bob!')Chain of Responsibility using functions.
- Handler: Processes or forwards
- Chain: Linked list of handlers
- Benefits: Decoupling
% Chain of Responsibility
function handler = createHandler()
handler.nextHandler = [];
handler.setNext = @(next) setNextHandler(next);
handler.handle = @(request) handleRequest(request);
end
function setNextHandler(handler, next)
handler.nextHandler = next;
end
function authHandler = createAuthHandler()
authHandler = createHandler();
authHandler.handle = @(request) handleAuth(request);
function handleAuth(request)
if isfield(request, 'token')
disp('Authentication passed')
if ~isempty(authHandler.nextHandler)
authHandler.nextHandler.handle(request);
end
else
disp('Authentication failed')
end
end
end
function loggerHandler = createLoggerHandler()
loggerHandler = createHandler();
loggerHandler.handle = @(request) handleLog(request);
function handleLog(request)
disp(['Logging request: ' request.url])
if ~isempty(loggerHandler.nextHandler)
loggerHandler.nextHandler.handle(request);
end
end
end
% Usage
auth = createAuthHandler();
logger = createLoggerHandler();
auth.setNext(logger);
auth.handle(struct('token', 'valid', 'url', '/api'))State pattern using switch or functions.
- Context: Maintains state
- State: Defines behavior
- Benefits: Clean state management
% State pattern
function context = createContext()
context.state = 'ready';
context.request = @() handleRequest();
function handleRequest()
switch context.state
case 'ready'
disp('Ready: Waiting for input')
case 'processing'
disp('Processing: Working on task')
case 'completed'
disp('Completed: Task finished')
end
end
end
% Usage
context = createContext();
context.request() % Ready: Waiting for input
context.state = 'processing';
context.request() % Processing: Working on task
context.state = 'completed';
context.request() % Completed: Task finishedProxy pattern using functions.
- Subject: Real object
- Proxy: Controls access
- Benefits: Access control
% Proxy pattern
function realSubject = createRealSubject()
realSubject.request = @() disp('RealSubject: Handling request');
end
function proxy = createProxy()
proxy.realSubject = [];
proxy.request = @() proxyRequest();
function proxyRequest()
if checkAccess()
if isempty(proxy.realSubject)
proxy.realSubject = createRealSubject();
end
proxy.realSubject.request();
logAccess();
end
end
function access = checkAccess()
disp('Proxy: Checking access')
access = true;
end
function logAccess()
disp('Proxy: Logging access')
end
end
% Usage
proxy = createProxy();
proxy.request()Flyweight pattern for sharing objects.
- Flyweight: Shared object
- Factory: Manages flyweights
- Benefits: Memory optimization
% Flyweight pattern
function flyweight = createFlyweight(sharedState)
flyweight.sharedState = sharedState;
flyweight.operation = @(uniqueState) flyweightOperation(uniqueState);
function flyweightOperation(uniqueState)
disp(['Shared: ' sharedState ', Unique: ' uniqueState])
end
end
function factory = createFlyweightFactory()
factory.flyweights = containers.Map();
factory.getFlyweight = @(sharedState) getFlyweight(sharedState);
function fw = getFlyweight(sharedState)
if isKey(factory.flyweights, sharedState)
fw = factory.flyweights(sharedState);
else
fw = createFlyweight(sharedState);
factory.flyweights(sharedState) = fw;
end
end
end
% Usage
factory = createFlyweightFactory();
fw1 = factory.getFlyweight('state1');
fw2 = factory.getFlyweight('state1');
fw3 = factory.getFlyweight('state2');
fw1.operation('unique1');
fw2.operation('unique2');
fw3.operation('unique3')Bridge pattern for separating abstraction from implementation.
- Abstraction: High-level interface
- Implementation: Low-level operations
- Benefits: Separation of concerns
% Bridge pattern
function implA = createImplementationA()
implA.operation = @() disp('ConcreteImplementationA: Operation');
end
function implB = createImplementationB()
implB.operation = @() disp('ConcreteImplementationB: Operation');
end
function abstraction = createAbstraction(impl)
abstraction.impl = impl;
abstraction.operation = @() abstractionOperation();
function abstractionOperation()
disp('Abstraction: Additional logic')
abstraction.impl.operation();
end
end
% Usage
implA = createImplementationA();
implB = createImplementationB();
abstraction1 = createAbstraction(implA);
abstraction2 = createAbstraction(implB);
abstraction1.operation();
abstraction2.operation()Adapter pattern for converting interfaces.
- Target: Expected interface
- Adaptee: Existing interface
- Adapter: Bridges interfaces
% Adapter pattern
function target = createTarget()
target.request = @() disp('Target: Request');
end
function adaptee = createAdaptee()
adaptee.specificRequest = @() disp('Adaptee: Specific Request');
end
function adapter = createAdapter(adaptee)
adapter.adaptee = adaptee;
adapter.request = @() adapterRequest();
function adapterRequest()
adaptee.specificRequest();
end
end
% Usage
adaptee = createAdaptee();
adapter = createAdapter(adaptee);
adapter.request()Facade pattern for simplifying subsystems.
- Facade: Simplified interface
- Subsystem: Complex components
- Benefits: Simplified interface
% Facade pattern
function subsystemA = createSubsystemA()
subsystemA.operation = @() disp('SubsystemA: Operation');
end
function subsystemB = createSubsystemB()
subsystemB.operation = @() disp('SubsystemB: Operation');
end
function facade = createFacade()
facade.subsystemA = createSubsystemA();
facade.subsystemB = createSubsystemB();
facade.operation = @() facadeOperation();
function facadeOperation()
facade.subsystemA.operation();
facade.subsystemB.operation();
disp('Facade: Complex operation')
end
end
% Usage
facade = createFacade();
facade.operation()Composite pattern for tree structures.
- Component: Interface for all
- Leaf: Individual object
- Composite: Container
% Composite pattern
function leaf = createLeaf(name)
leaf.name = name;
leaf.operation = @() disp(['Leaf ' name ': Operation']);
end
function composite = createComposite(name)
composite.name = name;
composite.children = {};
composite.add = @(component) addComponent(component);
composite.remove = @(component) removeComponent(component);
composite.operation = @() compositeOperation();
function addComponent(component)
composite.children{end+1} = component;
end
function removeComponent(component)
idx = find(cellfun(@(x) isequal(x, component), composite.children));
composite.children(idx) = [];
end
function compositeOperation()
disp(['Composite ' name ': Operation'])
for i = 1:length(composite.children)
composite.children{i}.operation();
end
end
end
% Usage
leaf1 = createLeaf('A');
leaf2 = createLeaf('B');
composite = createComposite('Root');
composite.add(leaf1);
composite.add(leaf2);
composite.operation()Visitor pattern for adding operations.
- Visitor: Defines operations
- Element: Accepts visitors
- Benefits: Adding operations without modifying
% Visitor pattern
function elementA = createElementA()
elementA.accept = @(visitor) visitor.visitA(elementA);
end
function elementB = createElementB()
elementB.accept = @(visitor) visitor.visitB(elementB);
end
function visitor = createVisitor()
visitor.visitA = @(element) disp('Visiting ElementA');
visitor.visitB = @(element) disp('Visiting ElementB');
end
% Usage
visitor = createVisitor();
elementA = createElementA();
elementB = createElementB();
elementA.accept(visitor);
elementB.accept(visitor)Iterator pattern for sequential access.
- Iterator: Traverses collection
- Aggregate: Creates iterator
- Benefits: Uniform traversal
% Iterator pattern
function iterator = createIterator(collection)
iterator.collection = collection;
iterator.index = 1;
iterator.next = @() nextItem();
iterator.hasNext = @() hasNextItem();
function item = nextItem()
if hasNextItem()
item = iterator.collection{iterator.index};
iterator.index = iterator.index + 1;
else
item = [];
end
end
function result = hasNextItem()
result = iterator.index <= length(iterator.collection);
end
end
function collection = createCollection()
collection.items = {};
collection.add = @(item) addItem(item);
collection.getIterator = @() createIterator(collection.items);
function addItem(item)
collection.items{end+1} = item;
end
end
% Usage
collection = createCollection();
collection.add('A');
collection.add('B');
collection.add('C');
iterator = collection.getIterator();
while iterator.hasNext()
disp(iterator.next())
endTemplate Method for algorithm skeletons.
- AbstractClass: Defines template
- ConcreteClass: Implements steps
- Benefits: Code reuse
% Template Method pattern
function abstractClass = createAbstractClass()
abstractClass.templateMethod = @() templateMethod();
abstractClass.step1 = @() disp('Step 1');
abstractClass.step3 = @() disp('Step 3');
end
function concreteClass = createConcreteClass()
concreteClass = createAbstractClass();
concreteClass.step2 = @() disp('Concrete Step 2');
end
function templateMethod(obj)
obj.step1();
obj.step2();
obj.step3();
end
% Usage
concrete = createConcreteClass();
concrete.templateMethod()Builder pattern for constructing complex objects.
- Builder: Constructs parts
- Director: Orchestrates construction
- Product: Constructed object
% Builder pattern
function product = createProduct()
product.parts = {};
product.add = @(part) addPart(part);
product.listParts = @() disp(strjoin(product.parts, ', '));
function addPart(part)
product.parts{end+1} = part;
end
end
function builder = createBuilder()
builder.product = createProduct();
builder.reset = @() resetBuilder();
builder.buildStepA = @() buildA();
builder.buildStepB = @() buildB();
builder.getResult = @() builder.product;
function resetBuilder()
builder.product = createProduct();
end
function buildA()
builder.product.add('Part A');
end
function buildB()
builder.product.add('Part B');
end
end
function director = createDirector(builder)
director.builder = builder;
director.buildMinimal = @() buildMinimal();
director.buildFull = @() buildFull();
function buildMinimal()
builder.buildStepA();
end
function buildFull()
builder.buildStepA();
builder.buildStepB();
end
end
% Usage
builder = createBuilder();
director = createDirector(builder);
director.buildMinimal();
product = builder.getResult();
product.listParts()Prototype pattern for cloning objects.
- Prototype: Cloneable object
- Clone: Creates a copy
- Benefits: Performance
% Prototype pattern
function prototype = createPrototype(name, nested)
prototype.name = name;
prototype.nested = nested;
prototype.clone = @() clonePrototype();
prototype.deepClone = @() deepClonePrototype();
function clone = clonePrototype()
clone = createPrototype(prototype.name, prototype.nested);
end
function clone = deepClonePrototype()
clone = createPrototype(prototype.name, deepCopy(prototype.nested));
end
function copied = deepCopy(obj)
if isstruct(obj)
copied = struct();
fields = fieldnames(obj);
for i = 1:length(fields)
copied.(fields{i}) = deepCopy(obj.(fields{i}));
end
elseif iscell(obj)
copied = cell(size(obj));
for i = 1:numel(obj)
copied{i} = deepCopy(obj{i});
end
else
copied = obj;
end
end
end
% Usage
original = createPrototype('Original', struct('value', 42));
copy = original.clone();
copy.name = 'Copy';
copy.nested.value = 99;
disp(original.name) % Original
disp(original.nested.value) % 42 (shallow copy)
deepCopy = original.deepClone();
deepCopy.nested.value = 100;
disp(original.nested.value) % 42 (deep copy)