Passing additional iteration-dependent inputs to ode45 - matlab

I'm trying to solve differential equation using the ode45 function. Consider the following code,
[t1,X2] = ode45(#(t,x)fun(t,x,C1,C2,C3,C4),t0,X01);
where parameters C1, C2, C3 and C4 are column vectors, which should be available to the function that ode45 is referring to (fun.m). I want the values to change after every iteration, so for example, at the beginning the entry of C1 I want in is C1(1), in the next iteration it's C1(2), etc.
How can I implement that?

You may have noticed that the official docs are not too helpful in this scenario (as they pretty much force you to use global variables - which is doable, but discouraged). Instead, I'll show you how this can be done with classes and function handles. Consider the following:
classdef SimpleQueue < handle
%SIMPLEQUEUE A simple FIFO data structure.
properties (Access = private)
data
position
end
methods (Access = public)
function obj = SimpleQueue(inputData)
%SIMPLEQUEUE Construct an instance of this class
obj.data = inputData;
rewind(obj);
end % constructor
function out = pop(obj, howMany)
%POP return the next howMany elements.
if nargin < 2
howMany = 1; % default amount of values to return
end
finalPosition = obj.position + howMany;
if finalPosition > numel(obj.data)
error('Too many elements requested!');
end
out = obj.data(obj.position + 1 : obj.position + howMany);
obj.position = finalPosition;
end % pop
function [] = rewind(obj)
%REWIND restarts the element tracking
% Subsequent calls to pop() shall return elements from the beginning.
obj.position = 0;
end % rewind
end % methods
end % classdef
How to use this? Simple:
C1q = SimpleQueue(C1);
C2q = SimpleQueue(C2);
C3q = SimpleQueue(C3);
C4q = SimpleQueue(C4);
[t1,X2] = ode45(#(t,x)fun(t,x,#C1q.pop,#C2q.pop,#C3q.pop,#C4q.pop),t0,X01);
As you can see, inside fun we use C1q() instead of C1.

Related

Matlab class dynamic filling of a property

I'm trying to dynamically fill a property in a Matlab class.
I pass vectors to a method function and then compute various parameters. I would like to fill the properties in a for loop, see code example. The OwnClassFunction is just an example of a further function in the class, but is not implemented in the code example. How can I do this correctly?
classdef Sicherung < handle
properties
x = ([],1)
end
methods
function examplefunction(object,...
single_parameter_vector) % (n,1) n can be any size
for i=1:length(param_vector)
[object.x(i,1)] = object.OwnClassFunction(single_parameter_vector(i,1));
end
end
end
end
If i try something like that
...
properties
x = []
end
...
function ...(object,parameter)
for i=1:length(parameter)
[object.x(i)] = function(parameter(i));
end
I get the error message Subscripted assignment dimension mismatch.
I don’t have MATLAB in hand to test, but the following should work.
Your code is pretty close to a correctly functioning method. Change it as follows:
classdef Sicherung < handle
properties
x = [] % initialize to empty array
end
methods
function examplefunction(object,param_vector)
if ~isvector(param_vector)
error('vector expected') % check input
end
n = numel(param_vector)
object.x = zeros(n,1); % preallocate
for i=1:n
object.x(i) = object.OwnClassFunction(param_vector(i));
end
end
end
end

MATLAB: Conditionally define get/set class methods

I have created some MATLAB classes to do some error-checking when I use certain types of structures. This improve development time by preventing errors in the code, but significantly slow down execution time.
One way to get around this is to comment out the set methods inside the class. Is it possible to do this programmatically? For example, only define these methods if a parameter in the constructor is true.
classdef MWE
%MWE Minimum working example
properties
A
B
C
end
methods
function obj = MWE(A, B, C)
if nargin ~= 3
error('A, B and C must all be provided.');
end
obj.A = A;
obj.B = B;
obj.C = C;
end
% function obj = set.A(obj, value)
% validate(obj, value, 'A');
% obj.A = value;
% end
%
% function obj = set.B(obj, value)
% validate(obj, value, 'B');
% obj.B = value;
% end
%
% function obj = set.C(obj, value)
% validate(obj, value, 'C');
% obj.C = value;
% end
end
methods (Access = private)
function validate(obj, value, name)
% Code here
end
end
end
Is it possible to do this programmatically? For example, only define these methods if a parameter in the constructor is true.
After some discussion, I see there are different ways of looking at your question. And, indeed, it may be that you cannot do what you are asking as interpreted by some. Here are two cases, however, that may suffice.
Case 1
You have computationally intensive or otherwise time consuming methods, that you use to "do some error-checking", in a development setting, but want to turn off in a production environment. And, these checks occur when the class is instantiated.
Place these methods in a wrapper function that is called from the constructor.
Here's an example
classdef classFoo
properties(Access=private)
fbar;
end
methods
function this = classFoo(arg1, argN, debugMode)
if(nargin>2 && debugMode)
if(~this.verifyStuff(arg1, argN))
throw(MException('classFoo:ConstructFailure','Could not verify'));
else
this.fbar = timeConsumingFunction();
end
else
this.fbar = 42; % defaultValue;
end
% continue construction
end
function didVerify = verifyStuff(this, varargin)
% complex code
didVerify = randi(2)-1; % 50/50
end
end
end
Then when creating objects you can choose to pass the debug mode flag as true like this:
a=classFoo(1,2,true)
or as false, like this:
a=classFoo(1,2,false)
or not at all, which is the same as the false case, like this:
a=classFoo(1,2)
Case 2
You have two different versions of a get/set method that you are commenting out depending on your development environment.
Add a private member parameter (e.g. isDebugging) and set it at time of construction. Now, instead of commenting out code in your get and set methods, you can handle the different cases with a simple if/else, predicated on your debug state like this:
classdef classFoo
properties(Access=private)
fbar;
isDebugging;
end
methods
function this = classFoo(debugMode)
if(nargin<1 || ~islogical(debugMode))
debugMode = false;
end
this.isDebugging = debugMode;
end
function setfbar(this, fIn)
if(this.isDebugging)
this.fbar = timeConsumingFunction(fIn);
else
this.fbar = fIn; % defaultValue;
end
end
end
end

Transform equal function handles to other equal function handles

Minimalistic Example:
classdef MyClass
properties
arr
handArr
end
properties(Dependent)
rowAcc
colAcc
end
methods
function obj = MyClass(arr, handRow, handCol)
obj.arr = arr;
obj.handArr{1} = handRow;
if ~isequal(handRow, handCol)
obj.handArr{2} = handCol;
end
end
function r = get.rowAcc(obj)
r = obj.handArr{1}(obj.arr);
end
function c = get.colAcc(obj)
c = obj.handArr{end}(obj.arr);
end
end
end
Now assume I pass equal functions to the constructor, I want the row and col access would also be the same:
f=#(x)#(y) y;
x=MyClass(1, f, f);
isequal(x.rowAcc, x.colAcc) //should be 1
Is this possible?
I have a good reason for this 'insane' requirement:
I have several algorithms which run with 100+ MBs of input and takes those two functions as input, and when they are equal they can be optimized very efficiently; to call the algorithms I need to make transformations to the input functions which are encapsulated inside this class. I can't change the algorithms (not my code) and they use isequal on they're own functions to dispatch.
Two variables pointing to the same anonymous function are considered to be equal
f = #(x)x;
g = f;
isequal(f, g)
% 1
However, if you define the anonymous functions at different times, then they are not considered to be equal because the internal workspaces of the two functions could differ.
f = #(x)x;
g = #(x)x;
isequal(f, g)
% 0
In order to have your property return equal handles, you could have some "shadow" property (accessors_) which caches the accessors and you update these cached values whenever the arr property is changed.
classdef MyClass
properties
arr
handArr
end
properties (Access = 'protected')
accessors_ % An array of accessor functions for rows & columns
end
properties (Dependent)
rowAcc
colAcc
end
methods
function set.arr(obj, value)
% Set the value
obj.arr = value;
% Update the accessors_
self.accessors_ = obj.handArr{1}(obj.arr);
% Only assign another accessor if we have a second one
if numel(obj.handArr) > 1
self.accessors_(2) = obj.handArr{2}(obj.arr);
end
end
function res = get.rowAcc(obj)
res = obj.accessors_(1);
end
function res = get.colAcc(obj)
% If only one was stored, this will return a duplicate of it
res = obj.accessors_(end);
end
end
end
This also has the added benefit that you aren't creating function handles every time that colAcc and rowAcc are retrieved.

creating rational class constructor in matlab

suppose we have following class,i want to declare rational number class in matlab,i am beginner of object oriented programming in matlab languages and i want to learn basics
classdef ratnum %rational number class
properties (Access=protected)
n %numerator
d %denomerator
end
methods
function r=ratnum(numerator,denomenator)
r.n=numerator;
r.d=denomenator;
end
end
end
how can i create constructor with specific values in matlab main part?should i use name of class ?thanks in advance
To instantiate an object of this class you can use: num1 = ratnum(2,3)
Since MATLAB doesn't have method overloading that is based on the amount of passed inputs, you could use nargin to select the correct scenario, as follows:
classdef ratnum %rational number class
properties (Access=protected)
n %//numerator
d %//denominator
end
methods
function r = ratnum(numerator,denominator)
switch nargin
case 2
r.n=numerator;
r.d=denominator;
case 0
%//whatever you want the defaults to be
end
end
end
end
A simple debug trick is to do num1_str=struct(num1) which allows you to see the contents of the object. However, you should create some public methods to get the values (instead of turning the object to a struct every time).
To overload the default summation of MATLAB you need to understand that whenever you write a+b it is automatically translated into plus(a,b). When defining custom classes with custom summation you should make a folder that has the name #classname (in your case #ratnum) and in it:
ratnum.m: the class definition file (which is the code you wrote)
a file named plus.m which looks something like:
.
function sum = plus(ratnum1,ratnum2)
ratnum1 = ratnum(ratnum1);
ratnum2 = ratnum(ratnum2);
sum = (...
ratnum1.r*ratnum2.d + ...
ratnum2.r*ratnum1.d )/ ...
(ratnum1.d * ratnum2.d);
end
Then, when you use + to add ratnums it will use the correct plus function.
Here's some helpful reading: MATLAB Documntation: Implementing Operators for Your Class
To call class methods, even from within other class methods, you must always write the class name first: ratnum.sum(ratnum1). Here's an example:
classdef ratnum %rational number class
properties (Access=public)
n %//numerator
d %//denominator
end
methods (Access = public)
function r = ratnum(numerator,denominator)
switch nargin
case 2
r.n=numerator;
r.d=denominator;
case 0
%whatever you want the defaults to be
end
end
end
methods (Access = public, Static)
function out = sum(ratnum)
out = ratnum.n + ratnum.d;
end
end
end
then:
>> a = ratnum(1,1)
a =
ratnum with properties:
n: 1
d: 1
>> ratnum.sum(a)
ans =
2
If you want to overload constructor with many different forms you'll have to initialize missing parameters with default value (or use varargin for more complex overloads):
function [r] = ratnum(num, den, varargin)
% Showing initializing missing parameters
if (nargin < 2), den = 42; end
if (nargin < 1), num = 7; end
% Showing working with varargin
if (nargin == 3)
...
elseif((nargin > 1) && (ischar(varargin{1}))
...
else
...
end
end
If you want to create named initializers for clarification of their meaning, you'll have to do it with Static methods:
methods (Static)
function [r] = TwoThird()
r = ratnum(2, 3);
end
function [r] = Half()
r = ratnum(1, 2);
end
end
Which can be used like this:
dummy = ratnum.Half(); % Ratio is 1/2
dummy = ratnum.TwoThird(); % Ratio is 2/3
dummy = ratnum(42, 666); % Ratio can be any custom one

Matlab - Function taking no arguments within a class

As I do not seem to be able to edit my old question (Matlab - Function taking no arguments but not static), here it is again:
I am trying to implement the following:
classdef asset
properties
name
values
end
methods
function AS = asset(name, values)
AS.name = name;
AS.values = values;
end
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
end
But I am getting the error that somefunction1 should be static. But if it's static then it can't access the properties anymore. How would I resolve this issue?
Basically I want to be able to write something like this:
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
as opposed to writing
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1(AS);
For accessing the properties of an object in a method, you need to pass that object as argument to the method. If you don't need a specific object in order to perform a function, then make it static (belongs to the class, but does not operate on a specific object).
So, compare the original code:
methods
% ...
function out = somefunction1
ret = somefunction2(asset.values);
out = mean(ret);
return
end;
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end
return
end
end
with the correct code:
methods
% ...
% this function needs an object to get the data from,
% so it's not static, and has the object as parameter.
function out = somefunction1(obj)
ret = asset.somefunction2(obj.values);
out = mean(ret);
end;
end;
methods(Static)
% this function doesn't depend on a specific object,
% so it's static.
function rets = somefunction2(vals)
n = length(vals);
rets = zeros(1,n-1);
for i=1:(n-1)
rets(i) = vals(i)/vals(i+1);
end;
end;
end;
To call the method, you'd write indeed (please test):
AS = asset('testname',[1 2 3 4 5]);
output = AS.somefunction1();
because, in MATLAB, this is 99.99% of cases equivalent to:
AS = asset('testname',[1 2 3 4 5]);
output = somefunction1(AS);
The differences appear when you're overriding subsref for the class, or when the object passed to the method is not the first in the argument list (but these are cases that you should not concern with for now, until you clarify the MATLAB class semantics).