Sorry about the formatting, i pasted and then applied the {} control but it still looks mangled. Please educate me if i'm misusing the tool somehow.
I have a base class:
classdef SystemNode < matlab.mixin.Heterogeneous
properties (Abstract)
description
quantity
parent
unit_cost
learning_curve
average_cost
total_cost
children
end
end
I have a descendant:
classdef Subsystem < models.system.SystemNode
properties
description
quantity
parent
children
key
end
properties (Dependent)
unit_cost
learning_curve
average_cost
total_cost
end
methods
function self = Subsystem(description, quantity, parent)
% TODO: Validate Inputs
self.description = description;
self.quantity = quantity;
self.parent = parent;
self.children = [];
self.key = char(java.util.UUID.randomUUID().toString());
end
function add_child(self, node)
% TODO: Validate Inputs
self.children = [self.children node];
end
function unit_cost = get.unit_cost(self)
% Cost if there were only one.
unit_cost = 0;
for child = self.children
unit_cost = child.unit_cost;
end
unit_cost = unit_cost*self.quantity;
end
function learning_curve = get.learning_curve(self)
learning_curve = 0;
end
I can't get .add_child() to work.
for example:
>> ss = models.system.Subsystem('test', 1, []);
>> ss.add_child('a')
>> ss.children
ans =
[]
If i descendend my abstract class from handle instead of the Mixin this works fine. What am i doing wrong??
BTW. I am using Matlab 2011b
Thanks in advance.
It's handle that makes the object behave in a pass-by-reference manner. If you want this kind of behavior, try the following:
classdef SystemNode < matlab.mixin.Heterogeneous & handle
If you do not inherit from handle, you get normal Matlab pass-by-value behavior. In this case, if you want to update the state of an object, you have to return the updated object from the setter method, and store the returned updated value.
So the setter has to return the updated self.
function self = add_child(self, node)
self.children = [self.children node];
end
And calls to it store the returned updated object.
ss = ss.add_child('a')
If you don't store a new value in ss, you're still looking at the value of ss from before the add_child call, with no children.
I am trying to create a class 'Deck' that has methods shuffle and deal, however, I do not know why my function for 'shuffle' isn't running. I get the error message :
Undefined function or method 'shuffle' for input arguments of type 'cell'.
Can someone please explain why the function is not running? thank you very much.
I am calling upon a previously created classdef 'Card'
classdef Deck < handle;
properties;
diamond;
spade
heart;
club;
end;
methods;
function obj=create(deck);
for k=1:13;
%Designate a number to each suit to create the deck
obj(k).diamond=cards('D','R',k);
obj(k).spade=cards('S','B',k);
obj(k).heart=cards('H','R',k);
obj(k).club=cards('C','B',k);
end
%Create a vector of each suit and number accordingly until we
%have 52 cards. 13 of each suit.
obj={obj.diamond obj.spade obj.heart obj.club};
end
%%
function obj=shuffle(obj);
shuff=randperm(52);
for k=1:52;
hf=shuff(k);
obj(k)=obj(hf);
end
end
end
end
You do not need the last line in the constructor:
obj = { obj.diamond obj.spade obj.heart obj.club }
This line turns your object into a cell (?). Try remove this line.
Try this classdef instead
classdef Deck
properties
cards
end
methods
function obj = Deck()
% do your stuff here, but no obj. before diamond/spade/heart/club
obj.cards = { diamond, spade, heart, club };
end
function obj =shuffle ( obj )
obj.cards = obj.cards( randperm(52) );
end
end
I think you want to have a property which is an array of Card objects. See the MATLAB documentation for object arrays. Here's how I would solve this problem:
classdef Deck < handle
properties
% This will be an object array of Card objects.
CardArray
end
properties (Dependent)
nCards
end
methods
function This = Deck()
% preallocate arrays.
% the constructor for Card should accept 0 arguments.
Diamond(13) = Card('D', 'R', 13);
Spade(13) = Card('S', 'B', 13);
Heart(13) = Card('H', 'R', 13);
Club(13) = Card('C', 'B', 13);
% now fill in the rest of each suit
for iVal = 1:12
Diamond(iVal) = Card('D', 'R', iVal);
Spade(iVal) = Card('S', 'B', iVal);
Heart(iVal) = Card('H', 'R', iVal);
Club(iVal) = Card('C', 'B', iVal);
end
% finally concatenate them into a single array
This.CardArray = [Diamond, Spade, Heart, Club];
end
function shuffle(This)
This.CardArray = This.CardArray(randperm(This.nCards));
end
function n = get.nCards(This)
n = length(This.CardArray);
end
end
end
You need to make sure that your Card constructor accepts zero arguments. For example, you could do the following:
classdef Card < handle
properties
symbol = 'D'
color = 'R'
value = 1;
end
methods
function This = Card(varargin)
if nargin >= 1
This.symbol = varargin{1};
end
if nargin >= 2
This.color = varargin{2};
end
if nargin >= 3
This.value = varargin{3};
end
end
end
end
In Matlab, I would like to perform some operations on private members of a class. I would also like to perform this exact same task on other classes as well. The obvious solution is to write a function in a separate M file that all the classes call in order to perform this task. However, that seems impossible in Matlab (see below). Is there another way to accomplish this?
Here is the problem specifically: suppose I have one m file with the contents
classdef PrivateTest
properties (Access=private)
a
end
methods
function this = directWrite(this, v)
this.a = v;
end
function this = sameFileWrite(this, v)
this = writePrivate(this, v);
end
function this = otherFileWrite(this, v)
this = otherFileWritePrivate(this, v);
end
function print(this)
disp(this.a);
end
end
end
function this = writePrivate(this, v)
this.a = v;
end
...and another m file with the contents
function this = otherFileWritePrivate(this, v)
this.a = v;
end
After instantiating p = PrivateTest, both of these commands work fine (as expected):
p = p.directWrite(1);
p = p.sameFileWrite(2);
...but this command doesn't work even though it's the same code, just in a different m file:
p = p.otherFileWrite(3);
So, it seems like any code that performs operations on private properties of a class MUST be in the same m file as the classdef that defines those private properties. Another possibility might be to have all the classes inherit a class with the writing method, but Matlab doesn't allow this either. In one m file, I would have this code:
classdef WriteableA
methods
function this = inheritWrite(this, v)
this.a = v;
end
end
end
...and in another m file I would have this code:
classdef PrivateTestInherit < WriteableA
properties (Access=private)
a
end
end
However, after instantiating p = PrivateTestInherit;, the command p.inheritWrite(4) causes the same error message as before: "Setting the 'a' property of the 'PrivateTestInherit' class is not allowed."
In light of this, How is it possible to generalize code that manipulates private properties in Matlab, or is it possible?
It is not possible to manipulate private properties outside of the class, that is why they are called private. This idea is called encapsulation.
You can in solve it in many ways:
Define public property that wraps the private, and change it. (See code below)
(Inheritance pattern) Do a common father class, your other classes inherit the function
classdef PrivateTest
properties (Access=private)
a
end
properties(Access=public,Dependent)
A
end
methods
function this = set.A(this,val)
this.a = val;
end
function val = get.A(this)
val = this.a;
end
function this = directWrite(this, v)
this.a = v;
end
function this = sameFileWrite(this, v)
this = writePrivate(this, v);
end
function this = otherFileWrite(this, v)
this = otherFileWritePrivate(this, v);
end
function print(this)
disp(this.a);
end
end
end
function this = writePrivate(this, v)
this.A = v;
end
I want to create a subclass, ess say, to the built-in ss class. I'd like to be able to convert an existing ss object to an ess object and at the same time add the missing properties, e.g. w, by something like this
sys=ss(a,b,c,d);
esys=ess(sys,w);
but I can't figure out how to setup the constructor correctly. What is the best way to achieve this? My code currently looks like this
classdef ess < ss
properties
w
end
methods
function obj = ess(varargin)
if nargin>0 && isa(varargin{1},'StateSpaceModel')
super_args{1} = sys;
else
super_args = varargin;
end
obj = obj#ss(super_args{:});
end
end
end
But this does not work as I get the following error:
>> ess(ss(a,b,c,d))
??? When constructing an instance of class 'ess', the constructor must preserve
the class of the returned object.
Of course I could copy all the object properties by hand but it seems to me that there should be some better way.
Here is an example of what I had in mind:
classdef ss < handle
properties
a
b
end
methods
function obj = ss(varargin)
args = {0 0}; %# default values
if nargin > 0, args = varargin; end
obj.a = args{1};
obj.b = args{2};
end
end
end
and:
classdef ess < ss
properties
c
end
methods
function obj = ess(c, varargin)
args = {};
if nargin>1 && isa(varargin{1}, 'ss')
args = getProps(varargin{1});
end
obj#ss(args{:}); %# call base-class constructor
obj.c = c;
end
end
end
%# private function that extracts object properties
function props = getProps(ssObj)
props{1} = ssObj.a;
props{2} = ssObj.b;
end
Lets test those classes:
x = ss(1,2);
xx = ess(3,x)
I get:
xx =
ess handle
Properties:
c: 3
a: 1
b: 2
Methods, Events, Superclasses
I'm writing a function to find triangle numbers and the natural way to write it is recursively:
function triangle (x)
if x == 0 then return 0 end
return x+triangle(x-1)
end
But attempting to calculate the first 100,000 triangle numbers fails with a stack overflow after a while. This is an ideal function to memoize, but I want a solution that will memoize any function I pass to it.
Mathematica has a particularly slick way to do memoization, relying on the fact that hashes and function calls use the same syntax:
triangle[0] = 0;
triangle[x_] := triangle[x] = x + triangle[x-1]
That's it. It works because the rules for pattern-matching function calls are such that it always uses a more specific definition before a more general definition.
Of course, as has been pointed out, this example has a closed-form solution: triangle[x_] := x*(x+1)/2. Fibonacci numbers are the classic example of how adding memoization gives a drastic speedup:
fib[0] = 1;
fib[1] = 1;
fib[n_] := fib[n] = fib[n-1] + fib[n-2]
Although that too has a closed-form equivalent, albeit messier: http://mathworld.wolfram.com/FibonacciNumber.html
I disagree with the person who suggested this was inappropriate for memoization because you could "just use a loop". The point of memoization is that any repeat function calls are O(1) time. That's a lot better than O(n). In fact, you could even concoct a scenario where the memoized implementation has better performance than the closed-form implementation!
You're also asking the wrong question for your original problem ;)
This is a better way for that case:
triangle(n) = n * (n - 1) / 2
Furthermore, supposing the formula didn't have such a neat solution, memoisation would still be a poor approach here. You'd be better off just writing a simple loop in this case. See this answer for a fuller discussion.
I bet something like this should work with variable argument lists in Lua:
local function varg_tostring(...)
local s = select(1, ...)
for n = 2, select('#', ...) do
s = s..","..select(n,...)
end
return s
end
local function memoize(f)
local cache = {}
return function (...)
local al = varg_tostring(...)
if cache[al] then
return cache[al]
else
local y = f(...)
cache[al] = y
return y
end
end
end
You could probably also do something clever with a metatables with __tostring so that the argument list could just be converted with a tostring(). Oh the possibilities.
In C# 3.0 - for recursive functions, you can do something like:
public static class Helpers
{
public static Func<A, R> Memoize<A, R>(this Func<A, Func<A,R>, R> f)
{
var map = new Dictionary<A, R>();
Func<A, R> self = null;
self = (a) =>
{
R value;
if (map.TryGetValue(a, out value))
return value;
value = f(a, self);
map.Add(a, value);
return value;
};
return self;
}
}
Then you can create a memoized Fibonacci function like this:
var memoized_fib = Helpers.Memoize<int, int>((n,fib) => n > 1 ? fib(n - 1) + fib(n - 2) : n);
Console.WriteLine(memoized_fib(40));
In Scala (untested):
def memoize[A, B](f: (A)=>B) = {
var cache = Map[A, B]()
{ x: A =>
if (cache contains x) cache(x) else {
val back = f(x)
cache += (x -> back)
back
}
}
}
Note that this only works for functions of arity 1, but with currying you could make it work. The more subtle problem is that memoize(f) != memoize(f) for any function f. One very sneaky way to fix this would be something like the following:
val correctMem = memoize(memoize _)
I don't think that this will compile, but it does illustrate the idea.
Update: Commenters have pointed out that memoization is a good way to optimize recursion. Admittedly, I hadn't considered this before, since I generally work in a language (C#) where generalized memoization isn't so trivial to build. Take the post below with that grain of salt in mind.
I think Luke likely has the most appropriate solution to this problem, but memoization is not generally the solution to any issue of stack overflow.
Stack overflow usually is caused by recursion going deeper than the platform can handle. Languages sometimes support "tail recursion", which re-uses the context of the current call, rather than creating a new context for the recursive call. But a lot of mainstream languages/platforms don't support this. C# has no inherent support for tail-recursion, for example. The 64-bit version of the .NET JITter can apply it as an optimization at the IL level, which is all but useless if you need to support 32-bit platforms.
If your language doesn't support tail recursion, your best option for avoiding stack overflows is either to convert to an explicit loop (much less elegant, but sometimes necessary), or find a non-iterative algorithm such as Luke provided for this problem.
function memoize (f)
local cache = {}
return function (x)
if cache[x] then
return cache[x]
else
local y = f(x)
cache[x] = y
return y
end
end
end
triangle = memoize(triangle);
Note that to avoid a stack overflow, triangle would still need to be seeded.
Here's something that works without converting the arguments to strings.
The only caveat is that it can't handle a nil argument. But the accepted solution can't distinguish the value nil from the string "nil", so that's probably OK.
local function m(f)
local t = { }
local function mf(x, ...) -- memoized f
assert(x ~= nil, 'nil passed to memoized function')
if select('#', ...) > 0 then
t[x] = t[x] or m(function(...) return f(x, ...) end)
return t[x](...)
else
t[x] = t[x] or f(x)
assert(t[x] ~= nil, 'memoized function returns nil')
return t[x]
end
end
return mf
end
I've been inspired by this question to implement (yet another) flexible memoize function in Lua.
https://github.com/kikito/memoize.lua
Main advantages:
Accepts a variable number of arguments
Doesn't use tostring; instead, it organizes the cache in a tree structure, using the parameters to traverse it.
Works just fine with functions that return multiple values.
Pasting the code here as reference:
local globalCache = {}
local function getFromCache(cache, args)
local node = cache
for i=1, #args do
if not node.children then return {} end
node = node.children[args[i]]
if not node then return {} end
end
return node.results
end
local function insertInCache(cache, args, results)
local arg
local node = cache
for i=1, #args do
arg = args[i]
node.children = node.children or {}
node.children[arg] = node.children[arg] or {}
node = node.children[arg]
end
node.results = results
end
-- public function
local function memoize(f)
globalCache[f] = { results = {} }
return function (...)
local results = getFromCache( globalCache[f], {...} )
if #results == 0 then
results = { f(...) }
insertInCache(globalCache[f], {...}, results)
end
return unpack(results)
end
end
return memoize
Here is a generic C# 3.0 implementation, if it could help :
public static class Memoization
{
public static Func<T, TResult> Memoize<T, TResult>(this Func<T, TResult> function)
{
var cache = new Dictionary<T, TResult>();
var nullCache = default(TResult);
var isNullCacheSet = false;
return parameter =>
{
TResult value;
if (parameter == null && isNullCacheSet)
{
return nullCache;
}
if (parameter == null)
{
nullCache = function(parameter);
isNullCacheSet = true;
return nullCache;
}
if (cache.TryGetValue(parameter, out value))
{
return value;
}
value = function(parameter);
cache.Add(parameter, value);
return value;
};
}
}
(Quoted from a french blog article)
In the vein of posting memoization in different languages, i'd like to respond to #onebyone.livejournal.com with a non-language-changing C++ example.
First, a memoizer for single arg functions:
template <class Result, class Arg, class ResultStore = std::map<Arg, Result> >
class memoizer1{
public:
template <class F>
const Result& operator()(F f, const Arg& a){
typename ResultStore::const_iterator it = memo_.find(a);
if(it == memo_.end()) {
it = memo_.insert(make_pair(a, f(a))).first;
}
return it->second;
}
private:
ResultStore memo_;
};
Just create an instance of the memoizer, feed it your function and argument. Just make sure not to share the same memo between two different functions (but you can share it between different implementations of the same function).
Next, a driver functon, and an implementation. only the driver function need be public
int fib(int); // driver
int fib_(int); // implementation
Implemented:
int fib_(int n){
++total_ops;
if(n == 0 || n == 1)
return 1;
else
return fib(n-1) + fib(n-2);
}
And the driver, to memoize
int fib(int n) {
static memoizer1<int,int> memo;
return memo(fib_, n);
}
Permalink showing output on codepad.org. Number of calls is measured to verify correctness. (insert unit test here...)
This only memoizes one input functions. Generalizing for multiple args or varying arguments left as an exercise for the reader.
In Perl generic memoization is easy to get. The Memoize module is part of the perl core and is highly reliable, flexible, and easy-to-use.
The example from it's manpage:
# This is the documentation for Memoize 1.01
use Memoize;
memoize('slow_function');
slow_function(arguments); # Is faster than it was before
You can add, remove, and customize memoization of functions at run time! You can provide callbacks for custom memento computation.
Memoize.pm even has facilities for making the memento cache persistent, so it does not need to be re-filled on each invocation of your program!
Here's the documentation: http://perldoc.perl.org/5.8.8/Memoize.html
Extending the idea, it's also possible to memoize functions with two input parameters:
function memoize2 (f)
local cache = {}
return function (x, y)
if cache[x..','..y] then
return cache[x..','..y]
else
local z = f(x,y)
cache[x..','..y] = z
return z
end
end
end
Notice that parameter order matters in the caching algorithm, so if parameter order doesn't matter in the functions to be memoized the odds of getting a cache hit would be increased by sorting the parameters before checking the cache.
But it's important to note that some functions can't be profitably memoized. I wrote memoize2 to see if the recursive Euclidean algorithm for finding the greatest common divisor could be sped up.
function gcd (a, b)
if b == 0 then return a end
return gcd(b, a%b)
end
As it turns out, gcd doesn't respond well to memoization. The calculation it does is far less expensive than the caching algorithm. Ever for large numbers, it terminates fairly quickly. After a while, the cache grows very large. This algorithm is probably as fast as it can be.
Recursion isn't necessary. The nth triangle number is n(n-1)/2, so...
public int triangle(final int n){
return n * (n - 1) / 2;
}
Please don't recurse this. Either use the x*(x+1)/2 formula or simply iterate the values and memoize as you go.
int[] memo = new int[n+1];
int sum = 0;
for(int i = 0; i <= n; ++i)
{
sum+=i;
memo[i] = sum;
}
return memo[n];