I inherited a complete toolbox, last revised in 2006, and I must update it to the latest version of Matlab. This toolbox defines some classes and defines methods for built in classes. More specifically, it creates some extra methods for objects of the control systems toolbox classes lti, ss, zpk and tf.
The first part, rebuilding the new classes, is already done. I am having troubles with the new methods for existing classes.
Since the code was written in an older version of Matlab, it uses class folders like #lti, #ss, #zpk to define the new methods. Now I need to keep the functionality, but using the new OOP model, in which not all #-folders are visible.
Does anybody know how to do that?
Since I had no luck trying to find a solution, I had to find one on my own. This is the method I came up with.
The toolbox had three new method for the zpk class. I created a new class, called sdzpk, and declared it to be a subclass of the built in zpk class. Then, wherever any of the new methods were used, I first converted the object to the new class before passing it to the method.
The following code may ilustrate that better:
Class definition file:
classdef sdzpk < zpk & sdlti
methods (Access = public)
function obj = sdzpk(varargin)
% Constructor method. Long code here to perform data validation
% and pass information to the zpk constructor
obj = obj#zpk(args{:});
end
% Existing methods
% This are the old files I inherited. No need to edit them.
tsys = ctranspose(sys);
sys = delay2z(sys);
sysr = minreal(sys,tol);
F = minreals(F,tol);
FP = setpoles(F,p);
F = symmetr(F,type,tol);
F = z2zeta(F,tol);
end
end
At several locations within the toolbox, the function minreals is called. All those calls were replaced with:
minreals(sdzpk(obj))
In that way, I make sure the new class is used and the correct method is applied.
I hope this helps somebody.
Related
My code use apache.ml.clustering.GaussianMixture, but its init method private def initRandom(...) does not work well, so I want to customize a new init method.
At first I want to "extends" class GuassianMixture, but initRandom is a private method.
Then I tried another way, it is to set initial GMM, but sadly source code says that TODO: SPARK-15785 Support users supplied initial GMM.
I've also tried to copy the code of class GuassianMixture for my custom class, but there are too many things attached to it. GaussianMixture.scala comes with sort of classes and traits, some of which are only accessible within ML packages.
I solved it by myself. Here is my solution.
I created class CustomGaussianMixture which extends GaussianMixture from official package org.apache.spark.ml.clustering.
And within my project, I created a new package, also named as org.apache.spark.ml.clustering(to prevent deal with scope of sort of complexity classes/traits/objects in org.apache.spark.ml.clustering). And place my custom class in it.
The next thing is to override the method(fit) call initRandom, a non-private method, so I can override it. Specifically, Just write my new init method in class CustomGaussianMixture, and copy method fit from official source code in GaussianMixture.scala to class CustomGaussianMixture, remember to modify code in CustomGaussianMixture.fit() to call my custom init method.
At last, just use CustomGaussianMixture instead of GaussianMixture when needed.
I'd like to cc & bcc in matlab without any external components (File Ex has a solution that has a .jar file). Any references to do so?
As I thought, it involves Java, and it's not entirely straightforward, thanks to Matlab's love-hate relationship with Java.
Looking at ML's sendmail() function, the key line is:
msg.addRecipient(getRecipientTypeTo(msg), getInternetAddress(to{i}));
where getRecipientTypeTo() is a function to get a static class instance from Java for the recipient type:
function recipientTypeTo = getRecipientTypeTo(msg)
%getRecipientTypeTo Return the static RecipientType.TO.
% Get the class loader for the Message class.
cl = msg.getClass.getClassLoader;
% Returns a Class object pointing to RecipientType using that ClassLoader.
rt = java.lang.Class.forName('javax.mail.Message$RecipientType', false, cl);
% Returns a Field object pointint to TO.
field = rt.getField('TO');
% Gets the static instance of TO.
recipientTypeTo = field.get([]);
So, modify the static one is getting (CC and BCC are supported, entirely unsurprisingly), and use addRecipient().
I am writing some code using MATLAB object oriented programming, trying to build a system simulator.
I am trying to create a class that represents the full system. The system depends on 2 sub-modules: transmitter and receiver.
These 2 modules I also implemented using classes as they might be useful in other future scenarios.
My problem is that I want some of the properties of transmitter and receiver to have (SetAccess = public) only when they are created as independent instances, and not from withing the system class. This because when part of the full system, changes should not be done on the separate modules alone by the user.
I tried to put (SetAccess = protected) to the instances of transmitter and receiver in my system class but this does not prevent me to change their parameters from the commandwindow by doing for example:
system.transmitter.memory = value.
Is there any way for me to implement such behavior without creating a different definition of transmitter and receiver classes?
I am quite new to OOP so let me know if this the behavior I want to achieve is wrong.
Edit: I was only putting (SetAccess = protected) because I would like the properties of my child-class to be readable but not writable
You need to set both SetAccess and GetAccess as protected. The operation
system.transmitter.memory = value;
first gets the property transmitter for which you have public GetAccess and then sets memory property on the transmitter which has public access to memory property.
Setting only SetAccess in System only stops public setting of transmitter property. So,
system.transmitter = Transmitter;
will throw error.
Suppose I have a class uicontrolWrapper, which is a wrapper for a uicontrol (but does not subclass it). The uicontrol stuff is kept in a private property for uicontrolWrapper. Basically, I want to be able to do set/get against the wrapper, and calls would feed into uicontrol.
I could do this:
classdef uicontrolWrapper < handle
properties (Access = private)
uic
end
properties (Dependent)
Style
String
Value
...
end
methods
function set.Style(obj, val)
obj.uic.Style = val;
end
function val = get.Style(obj)
val = obj.uic.Style;
end
...
end
but hardcoding like this is obviously pretty ugly.
Or, I could do dynamically generate properties dependent on what I'm trying to wrap:
classdef uicontrolWrapper < dynamicprops
properties (Access = private)
uic
end
methods
function obj = uicontrolWrapper(hObj)
obj.uic = hObj;
cellfun(#(prop) obj.createProperty(prop, fields(get(hObj));
end
function createProperty(obj, prop)
p = addprop(obj, prop);
p.Dependent = true;
p.SetMethod = #setUicontrolProp;
p.GetMethod = #getUicontrolProp;
function setUicontrolProp(obj, val)
obj.uic.(prop) = value;
end
function val = getUicontrolProp(obj)
val = obj.uic.(prop);
end
end
end
end
The whole point is to avoid violating the Law of Demeter by not "reaching into" the property we're trying to adjust.
I don't know if this is a design pattern, but I've used this type of thing to wrap objects of different types when subclassing is for some reason or another inappropriate. (For instance, the matlab.ui.control.UIControl class is Sealed and cannot be subclassed.) Does this have an actual name and intended typical use?
This is the Decorator Pattern -- creating a tool that decorates new functionality onto existing objects (at possibly many different times) specifically without affecting any other instances of the same type (or affecting them in an explicit way if desired).
This differs from Proxy pattern in the sense that you're not defering the task of dispatching the right operation to the proxy, you're actually grafting new functionality onto the object.
I believe you're asking about the Proxy design pattern here (provide an interface to other objects by creating a wrapper class as the proxy).
A couple of its benefits are adding security access and simplifying the API to the wrapped object (the proxy can provide a simple API so that the client code does not have to deal with the complexity of the object of interest).
Suppose I have two classes, a < matlab.mixin.Copyable and b < handle.
Here's a:
classdef a < matlab.mixin.Copyable
properties
hListener
end
methods
function obj = a(b)
obj.newListener(b);
end
function newListener(obj, b)
obj.hListener = addlistener(b, 'bEvent', #(o,e) disp('Received bEvent'));
end
function sobj = saveobj(obj)
sobj = copy(obj);
delete(sobj.hListener);
sobj.hListener = [];
end
end
end
and b:
classdef b < handle
events
bEvent
end
methods
function obj = b
end
function raiseEvent(obj)
notify(obj, 'bEvent');
end
end
end
I use saveobj in a to delete the listener upon save. I will manually re-instantiate a listener when I load the classes later.
a inherits from matlab.mixin.Copyable so I can do a copy during the saveobj operation - this way I can make a copy of the original object and change it, without affecting the original, and then save that to a MAT-file. (Supposedly - this is where my question is going.)
Now I run the following at the command line:
>> bob = b; alice = a(bob);
>> bob.raiseEvent
Received bEvent
Everything works. Now, let's save:
>> save ab alice bob
and try to raise the event again:
>> bob.raiseEvent
% NOTHING HAPPENS!
Turns out the listener is gone!
>> alice.hListener
handle to deleted listener
What is going on here? Why is the listener object shared between sobj and obj in the saveobj method?
In researching this question I discovered the answer. I figured I'd add to the body of knowledge around these parts.
Per the documentation for matlab.mixin.Copyable,
Given a call to the matlab.mixin.Copyable copy method of the form:
B = copy(A);
Under the following conditions, produces the described results:
A has dynamic properties — copy does not copy dynamic properties. You can implement dynamic-property copying in the subclass if needed.
A has no non-Dependent properties — copy creates a new object with no property values without calling the class constructor to avoid introducing side effects.
A contains deleted handles — copy creates deleted handles of the same class in the output array.
A has attached listeners — copy does not copy listeners. (emphasis added)
A contains objects of enumeration classes — Enumeration classes cannot subclass matlab.mixin.Copyable.
A delete method calls copy — copy creates a legitimate copy, obeying all the behaviors that apply in any other usage.
What I took this to mean originally was that a copy call would skip over a property whose value is a listener handle. Apparently what it means is that rather than skipping the property altogether, copy makes a reference to the original listener object, i.e., it copies the handle to the listener but not the listener itself.
Of course, when you load the copied object and it has that reference to listener, it'll complain:
Warning: Cannot load an object of class 'listener':
No matching constructor signature found.
Warning: During load:
An invalid default object has been detected while loading a heterogeneous array of
class event.listener. An empty array of class event.listener will be returned.
The easiest thing to do, then, is to modify saveobj:
function sobj = saveobj(obj)
sobj = copy(obj);
sobj.hListener = [];
end
Here, I don't explicitly call delete on the listener, as this would delete the actual object. Instead, I just clear the reference to that object.