calling setter with an extra argument? - MATLAB - matlab

In a class with the dependent property c, I would like to call c's setter with a third argument that equals 'a' or 'b', choosing which independent property to alter in order to set c.
The code is
classdef test < handle
properties
a
b
end
properties (Dependent = true)
c
end
methods
function c = get.c(obj)
c = obj.a + obj.b;
end
function obj = set.c(obj, value, varargin)
if(nargin == 2)
obj.a = value - obj.b;
end
if(nargin == 3 && argin(3) == 'a') % how do I enter this loop?
obj.a = value - obj.b;
end
if(nargin == 3 && argin(3) == 'b') % or this?
obj.b = value - obj.a;
end
end
end
end
This call works:
myobject.c = 5
But how do I call the setter with a third parameter equaling 'a' or 'b'?

You can't. set always accepts only two arguments. You could work around it with an additional dependent property:
classdef test < handle
properties
a
b
end
properties (Dependent = true)
c
d
end
methods
function c = get.c(obj)
c = obj.a + obj.b;
end
function d = get.d(obj)
d = c;
end
function obj = set.c(obj, value)
obj.a = value - obj.b;
end
function obj = set.d(obj, value)
obj.b = value - obj.a;
end
end
end
or by choosing a different syntax and/or approach:
myObject.set_c(5,'a') %// easiest; just use a function
myObject.c = {5, 'b'} %// easy; error-checking will be the majority of the code
myObject.c('a') = 5 %// hard; override subsref/subsasgn; good luck with that
or something else creative :)

Related

In matlab, I got different values in a method of class and out

In the matlab, I defined a class and instantiated the class in another script, but I got different values in and out of the method. My matlab code are shown bellow:
test_add.m
classdef test_add
properties
a
b
end
methods
function obj = test_add(a, b)
obj.a = a;
obj.b = b;
end
function c = add_1(obj)
c = obj.a + 1;
end
function inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
end
end
main.m
tt = test_add(1,2);
tt.inter(3);
fprintf('Out of the method:\n');
fprintf('a = %d\n',tt.a);
fprintf('b = %d\n',tt.b);
output:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 1
b = 2
In Matlab there are two type of classes: handle class and Value class. If you said nothing you get the Value class. Most of the OO languages out there are using handle class semantic.
So, you have two options:
Change you class to handle class by inheriting from handle
classdef test_add < handle
Stay with Value class and change your inter function to return obj.
But then, in main call obj=tt.inter(3) to get the updated object.
function obj = inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
It's a problem of value class vs handle class, the solution is:
test_add.m
classdef test_add < handle
...
end
Then, the output is:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 4
b = 2

matlab how to call a class method that changes prop from another class method

If I call a method (receiving and returning obj) it changes my property.
But if I call that method from another method it fails. I tried all kinds of ways but still failing.
classdef AClass
properties
A;
end
methods
function obj = ChangeA(obj, v)
obj.A = v;
end
function obj = CallChangeA(obj)
obj.ChangeA(4);
%obj = obj.ChangeA(4);
%ChangeA(obj, 4);
%obj = ChangeA(obj, 4);
% none of these works
end
end
end
% ------ script:
a1 = AClass;
a1.A = 1;
a1.ChangeA(2); % a1.A = 2
a2 = AClass;
a2.A = 3;
a2.CallChangeA(); % a2.A = 3 !!! not four
How do I write the code so calling from 1 method to the other updates the property?
Other than the obvious typos in your example code, as I commented above, I would highly suggest taking a look at the difference between MATLAB's Handle and Value classes. By default, MATLAB classes are value classes, so each time the object is passed to a function an independent copy is created. If you're making changes to this object then you need to return it as an output:
classdef AClass
properties
A;
end
methods
function obj = ChangeA(obj, a)
obj.A = a;
end
function obj = CallChangeA(obj)
obj = obj.ChangeA(4);
end
end
end
Which functions as expected:
>> a1 = AClass;
>> a1.A = 1
a1 =
AClass with properties:
A: 1
>> a1 = a1.CallChangeA()
a1 =
AClass with properties:
A: 4
Handle classes, on the other hand, are references to a single underlying object, allowing for (among other things) in place modification of the object:
classdef AClass < handle
properties
A;
end
methods
function ChangeA(obj, a)
obj.A = a;
end
function CallChangeA(obj)
obj.ChangeA(4);
end
end
end
Which also functions as expected:
>> a1 = AClass;
>> a1.A = 1;
>> a1.A
ans =
1
>> a1.CallChangeA()
>> a1.A
ans =
4

Use one set method for multiple properties MATLAB

I have several properties that use essentially the same set method:
classdef MyClass
properties
A
B
end
methods
function mc = MyClass(a,b) % Constructor
mc.A = a;
mc.B = b;
end
function mc = set.A(mc, a) % setter for A
if a > 5
mc.A = a;
else
error('A should be larger than 5');
end
end
function mc = set.B(mc, b) %setter for B
if b > 5
mc.B = b;
else
error('B should be larger than 5');
end
end
end
end
Is there a way to use only one set function for variables A and B? (Please note that the error function use the property names as strings.)
Is it suggested to use only one set function? What are the possible drawbacks of using one set function?
The only real way is to extract the common code to another function, and call it from the setters:
classdef MyClass
properties
A
B
end%public properties
methods
function mc = MyClass(a,b) % Constructor
mc.A = a;
mc.B = b;
end
function mc = set.A(mc, value) % setter for A
mc = mc.commonSetter(value, 'A');
end
function mc = set.B(mc, value) %setter for B
mc = mc.commonSetter(value, 'B');
end
end%public methods
methods(protected = true)
function mc = commonSetter(mc, property, value)
if value <= 5;
error([property ' should be less than 5');
end
mc.(property) = value;
end%commonSetter()
end%protected methods
end%classdef

Class for A = K * B in MATLAB (non-dependent properties with dependent behavior)

I want to implement a class for the function A = K * B, where all properties are non-dependent. However, I would like to change a property dynamically when one of the other properties changes.
I have started from a very simple class and ended up with the following. Is there an easier or more strong way (e.g. software pattern, use special set/get approaches etc..) to do this in MATLAB? (MATLAB gives lots of warnings in the setter functions)
classdef AeqKxB
properties
A
B
K
Kstate
end
properties (Access = private)
i % i=0 during construnction, i=1 normal operation
ia % ia = 1 to trick the setter function of B
ib % ib = 1 to trick the setter function of A
end
methods
function obj = MyClass2(a, k, kstate) % Constructor
obj.i = 0; % Construction starts
obj.A = a;
obj.B = obj.A*k;
obj.K = k;
obj.Kstate = kstate;
obj.i = 1; % Construction complete, ready for normal operation
obj.ia = 0; % Do not trick Set.B function for now
obj.ib = 0; % Do not trick Set.A function for now
end
function obj = set.A(obj, a) % setter for A
if obj.i == 0 % During construnction use normal operation
obj.A = a;
elseif obj.i == 1 % After construction
if obj.ia == 0 && obj.ib == 0
obj.A = a;
obj.ia = 1; % Get ready to Trick Set.B function
obj.B = obj.A / obj.K;
obj.ia = 0; % Trick finished, return to original
elseif obj.ia == 0 && obj.ib == 1
% Tricked Set.A function
obj.A = a;
end
end
end
function obj = set.B(obj, b) % setter for B
if obj.i == 0 % During construnction use normal operation
obj.B = b;
elseif obj.i == 1 % After construction
if obj.ia == 0 && obj.ib == 0;
obj.B = b;
obj.ib = 1; % Get ready to Trick Set.A function
obj.A = obj.B * obj.K;
obj.ib = 0; % Trick finished, return to original
elseif obj.ia == 1 && obj.ib == 0;
% Tricked Set.B function
obj.B = b;
end
end
end
function obj = set.K(obj,k) % setter for K
if obj.i == 0
obj.K = k;
elseif obj.i == 1
if strcmp(obj.Kstate, 'FixB')
obj.K = k;
obj.A = obj.B * obj.K;
elseif strcmp(obj.Kstate, 'FixA')
obj.K = k;
obj.B = obj.A / obj.K;
end
end
end
function obj = set.Kstate(obj,kstate)
obj.Kstate = kstate;
end
end
end
The question is answered here. I post his response:
"where all properties are non-dependent" Why? Your properties are obviously dependent, so why not use them.
The warnings are telling you that if an object is saved in a mat file it may not be restored properly due to random initialisation order. In practice, with your design, that shouldn't be a problem as the properties' values should always be consistent, so I guess you could just disable the warnings.
However, I can't help but greatly dislike this design, particularly the i state variable. You could achieve a cleaner design, using dependent variables, with no impact on performance:
classdef AeqKxB
properties(Dependent)
A;
B;
K;
end
properties
Kstate;
end
properties (Access = private)
A_;
B_;
K_;
end
methods
function obj = AeqKxB(a, k, kstate) % Constructor
obj.A_ = a;
obj.B_ = a*k;
obj.K_ = k;
obj.Kstate = kstate;
end
function a = get.A(obj)
a = obj.A_;
end
function obj = set.A(obj, a) % setter for A
obj.A_ = a;
obj.B_ = a / obj.K_;
end
function b = get.B(obj)
b = obj.B_;
end
function obj = set.B(obj, b) % setter for B
obj.B_ = b;
obj.A_ = b * obj.K_;
end
function obj = set.K(obj,k) % setter for K
obj.K_ = k;
if strcmp(obj.Kstate, 'FixB')
obj.A_ = obj.B_ * k;
elseif strcmp(obj.Kstate, 'FixA')
obj.B_ = obj.A_ / k;
end
end
function obj = set.Kstate(obj,kstate)
obj.Kstate = kstate;
end
end
end

Use a property of a classdef in another .m file?

Here is my code:
f.m:
classdef f < handle
properties (Access = public)
functionString = '';
x;
end
methods
function obj = f
if nargin == 0
syms s;
obj.x = input('Enter your function: ');
obj.functionString = ilaplace(obj.x);
end
end
function value = subsref(obj, a)
t = a.subs{:};
value = eval(obj.functionString);
end
function display(obj)
end
end
end
test.m:
syms s t;
[n d] = numden(f.x); % Here I want to use x, which is the user input, How can I do such thing?
zeros = solve(n);
poles = solve(d);
disp('The Poles:');
disp(poles);
disp('The Zeros:');
disp(zeros);
disp('The Result:');
disp(z(t));
disp('The Initial Value:');
disp(z(0));
disp('The Final Value:');
disp(z(Inf));
When I type test in the command window, it tells me the following:
>> test
??? The property 'x' in class 'f' must be accessed from a class instance because it
is not a Constant property.
As Alex points out, you need an instance of f to access the member property x, like so:
myf = f();
f.x
You do not need an accessor method to get at x as it is defined as a public property. If you chose to make x private, then you'd need an accessor method something like this:
function x = getX( obj )
x = obj.x;
end