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
I want to build an recommender system using Simon Funks' algorithm.
The idea is to first construct the model offline in Matlab to perform some evaluation on the results to what number of features (or dimensions) gives the best performance.
I have a matrix with users x items, where the rating '0' means that the user has not given a rating for that item.
So far I have tried to implement Simon Funks' algorithm in Matlab (see source-code) below, but it performs really (!) bad. By accident I found Matlab's SVDS function to fill the empty ratings and it actually performs better and faster then my Simon Funks' function
Could someone tell me what could be cause of this? Or tell me what stupid mistake I have made in Matlab function? :P
function ratings = simon_funk(original_ratings, dimensions) % To construct a complete rating matrix
% See: http://www.timelydevelopment.com/demos/NetflixPrize.aspx
% Variables
global max_features; max_features = dimensions;
global init; init = 0.1;
min_epochs = 2;
max_epochs = 16;
min_improvement = 0.001;
lrate = 0.01;
k = 0.015;
respondent_count = size(original_ratings, 1);
item_count = size(original_ratings, 2);
rating_count = 0;
data = [];
for r=1:respondent_count
for i=1:item_count
rating = original_ratings(r,i);
if(rating > 0)
data = [data; [r, i, rating, 0]];
rating_count = rating_count + 1;
end
end
end
% Now data contain all ratings in the form [user_id, item_id, rating, cache (default 0)]
ratings = zeros(respondent_count, item_count);
global item_features; item_features = zeros(max_features, item_count);
global respondent_features; respondent_features = zeros(max_features, respondent_count);
% Init
item_features(:,:) = init;
respondent_features(:,:) = init;
% CalcFeatures
rmse_last = 2.0;
rmse = 2.0;
for f=1:max_features
for e=1:max_epochs
sq = 0;
rmse_last = rmse;
for r=1:rating_count
% for i=1:item_count
respondent = data(r,1);
item = data(r,2);
rating = data(r,3);
% Predict rating
p = simon_funk_predict_rating(data(r,:), f, 1);
err = (1.0 * rating - p);
sq = sq + err*err;
rf = respondent_features(f,respondent);
mf = item_features(f, item);
% Cross-train the features
respondent_features(f, respondent) = respondent_features(f,respondent) + (lrate * (err * mf - k * rf));
item_features(f, item) = item_features(f, item) + (lrate * (err * rf - k * mf));
% end
end
rmse = sqrt(sq/rating_count);
%if (e >= min_epochs && rmse > (rmse_last - min_improvement))
if ((e >= min_epochs) && ((rmse_last - rmse) < min_improvement))
break;
end
end
% Caching
for r=1:rating_count
data(r, 4) = simon_funk_predict_rating(data(r,:), f, 0);
end
end
% return new ratings set
for r=1:respondent_count
for i=1:item_count
sum = 1;
for f=1:max_features
sum = sum + item_features(f,i) * respondent_features(f,r);
if(sum > 10)
% sum = 10;
end
if(sum < 1)
% sum = 1;
end
end
ratings(r,i) = sum;
end
end
And the function to predict an individual rating:
function sum = simon_funk_predict_rating(rating, f, bTrailing)
global item_features;
global respondent_features;
global max_features;
global init;
respondent = rating(1,1);
item = rating(1,2);
cache_value = rating(1,4);
sum = 1;
if(cache_value > 0)
sum = cache_value;
end
sum = sum + (item_features(f,item) * respondent_features(f,respondent));
if (sum > 10)
%sum = 10;
end
if (sum < 1)
%sum = 1;
end
if (bTrailing == 1)
sum = sum + (max_features - f - 1) * (init * init);
if (sum > 10)
sum = 10;
end
if (sum < 1)
sum = 1;
end
end
Thank you very much!
I am Trying to convert a MATLAB code to C++ using MATLAB coder but this error apears:
Error indenting generated C code
The error points to the name of the function itself and has no more explanations in it. can someone tell me what is this error?
here is the function i want to conver:
function [Report_Clustered,ClusterCounter_new]=InitClusterGenerator_test(Report_In,~,FreqEpsilon,DegreeEpsilon,~,ClusterCounter_old, BlockCount, Report_old)
Report_M = zeros(size(Report_In,1),size(Report_In,2),4);
for i=1:size(Report_In,1)
for j=1:size(Report_In,2)
Report_M(i,j,1)=Report_In(i,j,1);
Report_M(i,j,2)=Report_In(i,j,2);
Report_M(i,j,3)=0; % Cluster number that the point belongs to.
Report_M(i,j,4)=0;
Report_In{i,j}
end
end
ClusterCounter = 0;
for i=1:size(Report_M,1)
for j=1:size(Report_M,2)
if (Report_M(i,j,3) == 0)
ClusterCounter = ClusterCounter + 1;
Report_M(i,j,3) = ClusterCounter;
for ii=1:size(Report_M,1)
for jj=1:size(Report_M,2)
if (Report_M(ii,jj,3) == 0)
if (abs(Report_M(i,j,1)-Report_M(ii,jj,1))<FreqEpsilon &&...
(abs(Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon ||...
abs(-360 + Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon ||...
abs(360 + Report_M(i,j,2)-Report_M(ii,jj,2)) <DegreeEpsilon))
Report_M(ii,jj,3) = ClusterCounter;
end
end
end
end
end
end
end
if (BlockCount> 20 && ClusterCounter<4)
warning = 1;
end
ClusterCounter_new = ClusterCounter;
%clear Report_new;
flag = 0;
Report_new = zeros(ClusterCounter,size (Report_M, 2),4);
index = zeros(1, ClusterCounter_new);
for i = 1: size (Report_M, 1)
for j = 1: size (Report_M, 2)
for k = 1: ClusterCounter_new
if (Report_M(i,j,3) == k)
index(1,k) = index(1,k) + 1;
Report_new(k,index(1,k), 1:3) = Report_M(i,j,1:3);
flag = flag + 1;
end
end
end
end
for j = 1: size (Report_new, 2)
for i = 1: size (Report_new, 1)
if (Report_new(i,j,1) == 0)
Report_new(i,j,1:3) = Report_new(i,1,1:3);
end
end
end
%Report_new = Report;
MedoidF_old = zeros(1, size(Report_old,1));
MedoidA_old = zeros(1, size(Report_old,1));
for i=1:size(Report_old,1)
SumF = 0;
SumA = 0;
MinAngle = 361;
MaxAngle = -1;
for j=1:size(Report_old,2)
SumF = SumF + Report_old(i,j,1);
SumA = SumA + Report_old(i,j,2);
if Report_old(i,j,2) > MaxAngle
MaxAngle = Report_old(i,j,2);
elseif Report_old(i,j,2) < MinAngle
MinAngle = Report_old(i,j,2);
end
end
MedoidF_old(1, i) = SumF/size(Report_old,2);
if (MaxAngle - MinAngle) > 350
MedoidA_old(1, i) = 0;
else
MedoidA_old(1, i) = SumA/size(Report_old,2);
end
end
MedoidF_new = zeros(1, size(Report_new,1));
MedoidA_new = zeros(1, size(Report_new,1));
for i=1:size(Report_new,1)
SumF = 0;
SumA = 0;
MinAngle = 361;
MaxAngle = -1;
for j=1:size(Report_new,2)
SumF = SumF + Report_new(i,j,1);
SumA = SumA + Report_new(i,j,2);
if Report_new(i,j,2) > MaxAngle
MaxAngle = Report_new(i,j,2);
elseif Report_new(i,j,2) < MinAngle
MinAngle = Report_new(i,j,2);
end
end
MedoidF_new(1, i) = SumF/size(Report_new,2);
if (MaxAngle - MinAngle) > 350
MedoidA_new(1, i) = 0;
else
MedoidA_new(1, i) = SumA/size(Report_new,2);
end
end
TempCluster = zeros(1, size(Report_new, 1));
CurrentCluster = ClusterCounter_old;
for i = 1: 1: size(Report_new,1)
for j = 1: 1: size(Report_old,1)
if (abs(MedoidF_old(1,j)-MedoidF_new(1,i))<FreqEpsilon &&...
(abs(MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(360 + MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(-360 + MedoidA_old(1,j)-MedoidA_new(1,i))<DegreeEpsilon)) %%if the new cluster is the rest of an old cluster use the old one's index for it
TempCluster(1,i) = Report_old(j,1,3);
end
end
%%this part is for seperating the clusters which where in the collision state in the past time
if (TempCluster(1,i)>0) %%if the new cluster is one of the old ones the index should be set
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1;% Alive
end
else %%first search if the new cluster is a part of a newly found cluster found before this one
for j = 1: 1: i-1
if (abs(MedoidF_new(1,j)-MedoidF_new(1,i))<FreqEpsilon &&...
(abs(MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(360 + MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon ||...
abs(-360 + MedoidA_new(1,j)-MedoidA_new(1,i))<DegreeEpsilon)) %%if the new cluster is the rest of an old cluster use the old one's index for it
TempCluster(1,i) = Report_new(j,1,3);
end
end
end
if (TempCluster(1,i)>0) %%if the new cluster is one of the old ones the index should be set
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1;% Alive
end
else %%new cluster is just began so it needs a new index
CurrentCluster = CurrentCluster + 1;
ClusterCounter_new = CurrentCluster;
TempCluster(1,i) = CurrentCluster;
for j = 1:1:size(Report_new, 2)
Report_new(i,j,3) = TempCluster(1,i);
Report_new(i,j,4) = 1; % Alive
end
end
end
NewClusters = zeros(1, size (Report_new, 1));
for i = 1: size(Report_new, 1)
NewClusters (1,i) = Report_new(i,1,3);
end
OldClusters = zeros(1, size (Report_old, 1));
OldClustersLine = zeros(1, size (Report_old, 1));
for i = 1: size(Report_old, 1)
OldClusters (1,i) = Report_old(i,1,3);
OldClustersLine (1, i) = i;
end
NumberOfDead = 0;
%clear AddDead;
AddDead = zeros (16,size(Report_new, 2),4);
if (BlockCount>10)
for i = 1: size (OldClusters, 2)
IsDead = 1;
for j = 1: size (NewClusters, 2)
if OldClusters(1, i) == NewClusters(1,j)
IsDead = 0;
end
end
if (IsDead == 1)
NumberOfDead = NumberOfDead + 1;
%clear TempLine;
TempLine = zeros(1, size(Report_old,2), 4);
TempLine(1,:,1:3) = Report_old(OldClustersLine(1, i),:,1:3);
for k= 1: size(TempLine, 2)
TempLine(1,k,4) = 0; % Dead
end
TempSize = size(TempLine, 2);
Thresh = size(Report_new, 2);
if (TempSize >= Thresh)
AddDead (NumberOfDead, 1:Thresh, 1:4) = TempLine(1,1:Thresh, 1:4);
else
for l = 1: Thresh-TempSize
TempLine(1, TempSize+l, 1:4) = TempLine(1, TempSize, 1:4);
end
AddDead (NumberOfDead, 1:Thresh, 1:4) = TempLine(1,1:Thresh, 1:4);
end
end
end
xR = size (Report_new,1);
if (NumberOfDead == 0)
Report_Clustered = zeros (size(Report_new,1),size(Report_new,2),size(Report_new,3));
else
Report_Clustered = zeros (size(Report_new,1) + NumberOfDead,size(Report_new,2),size(Report_new,3));
end
Report_Clustered (1:size(Report_new,1), :, :) = Report_new(:,:,:);
for i = 1: NumberOfDead
Report_Clustered(xR + i, :) = AddDead(i, :);
end
end
and I'm using matlab 2012a
Tnx.
From what you've said in the comments, it appears that you simply need to call
clear functions
from the command line before recompiling the function to allow Matlab to overwrite the files. See this Matlab forum or the documentation for clear for more detail.
main.m
counter = 1;
n = 8;
board = zeros(1,n);
back(0, board);
disp(counter);
sol.m
function value = sol(board)
for ( i = 1:(length(board)))
for ( j = (i+1): (length(board)-1))
if (board(i) == board(j))
value = 0;
return;
end
if ((board(i) - board(j)) == (i-j))
value = 0;
return;
end
if ((board(i) - board(j)) == (j-i))
value = 0;
return;
end
end
end
value = 1;
return;
back.m
function back(depth, board)
disp(board);
if ( (depth == length(board)) && (sol2(board) == 1))
counter = counter + 1;
end
if ( depth < length(board))
for ( i = 0:length(board))
board(1,depth+1) = i;
depth = depth + 1;
solv2(depth, board);
end
end
I'm attempting to find the maximum number of ways n-queen can be placed on an n-by-n board such that those queens aren't attacking eachother. I cannot figure out the problem with the above matlab code, i doubt it's a problem with my logic since i've tested out this logic in java and it seems to work perfectly well there. The code compiles but the issue is that the results it produces are erroneous.
Java Code which works:
public static int counter=0;
public static boolean isSolution(final int[] board){
for (int i = 0; i < board.length; i++) {
for (int j = i + 1; j < board.length; j++) {
if (board[i] == board[j]) return false;
if (board[i]-board[j] == i-j) return false;
if (board[i]-board[j] == j-i) return false;
}
}
return true;
}
public static void solve(int depth, int[] board){
if (depth == board.length && isSolution(board)) {
counter++;
}
if (depth < board.length) { // try all positions of the next row
for (int i = 0; i < board.length; i++) {
board[depth] = i;
solve(depth + 1, board);
}
}
}
public static void main(String[] args){
int n = 8;
solve(0, new int[n]);
System.out.println(counter);
}
Worked code:
function queen
clc;
counter = 0;
n = 8;
board = zeros(1,n);
[board,counter] = back(1, board,counter);
fprintf('Solution count: %d\n',counter);
%%
function value = isSolution(board)
for i = 1:length(board)
for j = (i+1): length(board)
if abs(board(i) - board(j)) == abs(i-j)
value = false;
return;
end
end
end
value = true;
%%
function [board,counter] = back(depth, board,counter)
if (depth == length(board)+1) && isSolution(board)
counter = counter + 1;
disp(board);
end
if ( depth <= length(board))
for i = 1:length(board)
if ~any(board==i)
board(1,depth) = i;
[~,counter] = back(depth+1, board,counter);
end
end
end
I add line if ~any(board==i), without this check, I think your java solution slower than this Matlab code. For fastest solution google "Dancing links".
There are many problems with your code.
Here are just a few:
you initialize board as 1-by-8 array
you call functions sol2 and solv2 that are undefined
no output is captured for solv2, or back (remember, Matlab passes variables by value, not by reference)
there are no comments in the code that would explain what you think you're doing and why you'd want to do that.
Also: While Matlab has a JIT compiler that, among others, helps speed up loops, Matlab code can't be said to "compile" (unless you're doing something dramatically wrong).