Is there any performance comparison among those three variants for input checking/default initializaion?
It would be useful a comparison on a recent version e.g. R2014b and and older one R2012b.
An example:
function foo(a,b)
if nargin < 1, a = 1; end
if nargin < 2, b = 2; end
end
versus
function foo(a,b)
if exist('a','var'), a = 1; end
if exist('b','var'), b = 2; end
end
versus
function foo(varargin)
p = inputParser;
addOptional(p,'a',1)
addOptional(p,'b',2)
parse(p,varargin{:})
end
Using Amro's testing suite, on R2014b:
func nargs time
_________________ _____ __________
'foo_nargin' 0 2.3674e-05
'foo_exist' 0 3.1339e-05
'foo_inputparser' 0 9.6934e-05
'foo_nargin' 1 2.4437e-05
'foo_exist' 1 3.2157e-05
'foo_inputparser' 1 0.0001307
'foo_nargin' 2 2.3838e-05
'foo_exist' 2 3.0492e-05
'foo_inputparser' 2 0.00015775
Here is some code to test the three approaches:
function t = testArgParsing()
args = {1, 2};
fcns = {
#foo_nargin ;
#foo_exist ;
#foo_inputparser
};
% parameters sweep
[f,k] = ndgrid(1:numel(fcns), 0:numel(args));
f = f(:); k = k(:);
% test combinations of functions and number of input args
t = cell(numel(f), 3);
for i=1:size(t,1)
t{i,1} = func2str(fcns{f(i)});
t{i,2} = k(i);
t{i,3} = timeit(#() feval(fcns{f(i)}, args{1:k(i)}), 2);
end
% format results in table
t = cell2table(t, 'VariableNames',{'func','nargs','time'});
end
function [aa,bb] = foo_nargin(a,b)
if nargin < 1, a = 1; end
if nargin < 2, b = 2; end
aa = a;
bb = b;
end
function [aa,bb] = foo_exist(a,b)
if ~exist('a','var'), a = 1; end
if ~exist('b','var'), b = 2; end
aa = a;
bb = b;
end
function [aa,bb] = foo_inputparser(varargin)
p = inputParser;
addOptional(p,'a',1);
addOptional(p,'b',2);
parse(p, varargin{:});
aa = p.Results.a;
bb = p.Results.b;
end
Here is what I get in R2014a on my machine:
>> t = testArgParsing
t =
func nargs time
_________________ _____ __________
'foo_nargin' 0 3.4556e-05
'foo_exist' 0 5.2901e-05
'foo_inputparser' 0 0.00010254
'foo_nargin' 1 2.5531e-05
'foo_exist' 1 3.7105e-05
'foo_inputparser' 1 0.0001263
'foo_nargin' 2 2.4991e-05
'foo_exist' 2 3.6772e-05
'foo_inputparser' 2 0.00015148
And a pretty plot to view the results:
tt = unstack(t, 'time', 'func');
names = tt.Properties.VariableNames(2:end);
bar(tt{:,2:end}.')
set(gca, 'XTick',1:numel(names), 'XTickLabel',names, 'YGrid','on')
legend(num2str(tt{:,1}, 'nargin=%d'))
ylabel('Time [sec]'), xlabel('Functions')
Related
I am using the following lines of code for edge detection using canny edge detector :
I=imread('bradd.tif');
figure,imshow(I);
IDtemp = im2double(I);
[r c]=size(I);
ID(r,c) = 0;
IDx(r,c) = 0;
IDfil(r,c) = 0;
IDxx(r,c) = 0;
IDy(r,c) = 0;
IDyy(r,c) = 0;
mod(r,c) = 0;
for i= 1 : r+4
for j = 1:c+4
if(i<=2 || j<=2 || i>=r+3 || j>=c+3)
ID(i,j) = 0;
else
ID(i,j) = IDtemp(i-2,j-2);
end;
end
end
%figure,imshow(ID);
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
for i=1:5
for j=1:5
filter(i,j)=filter(i,j)/159;
end
end
%figure,imshow(filter);
for v = 3 : r
for u = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
%figure,imshow(IDx);
IDxtemp = IDx;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
IDfil(i,j) = 0;
else
IDfil(i,j) = IDxtemp(i-1,j-1);
end;
end
end
%figure,imshow(IDfil);
Mx = [-1 0 1; -2 0 2; -1 0 1]; % Sobel Mask in X-Direction
My = [-1 -2 -1; 0 0 0; 1 2 1]; % Sobel Mask in Y-Direction
for u = 2:r
for v = 2:c
sum1 = 0;
for i=-1:1
for j=-1:1
sum1 = sum1 + IDfil(u + i, v + j)* Mx(i + 2,j + 2);
end
end
IDxx(u,v) = sum1;
end;
end
%figure,imshow(IDxx);
for u = 2:r
for v = 2:c
sum2 = 0;
for i=-1:1
for j=-1:1
sum2 = sum2 + IDfil(u + i, v + j)* My(i + 2,j + 2);
end
end
IDyy(u,v) = sum2;
end
end
%figure,imshow(IDyy);
for u = 1:r
for v = 1:c
mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2) ;
%mod(u,v) = sqrt(IDxx(u,v)^2 + IDyy(u,v)^2);
end
end
%figure,imshow(mod);
modtemp = mod;
for i= 1 : r+2
for j = 1:c+2
if(i<=1 || j<=1 || i>=r || j>=c)
mod(i,j) = 0;
else
mod(i,j) = modtemp(i-1,j-1);
end;
end
end
%figure,imshow(mod);
theta(u,v) = 0;
supimg(u,v) = 0;
ntheta(u,v) = 0;
for u = 2 : r
for v = 2 : c
theta(u,v) = atand(IDyy(u,v)/IDxx(u,v));
if ((theta(u,v) > 0 ) && (theta(u,v) < 22.5) || (theta(u,v) > 157.5) && (theta(u,v) < -157.5))
ntheta(u,v) = 0;
end
if ((theta(u,v) > 22.5) && (theta(u,v) < 67.5) || (theta(u,v) < -112.5) && (theta(u,v) > -157.5))
ntheta(u,v) = 45;
end
if ((theta(u,v) > 67.5 && theta(u,v) < 112.5) || (theta(u,v) < -67.5 && theta(u,v) > 112.5))
ntheta(u,v) = 90;
end
if ((theta(u,v) > 112.5 && theta(u,v) <= 157.5) || (theta(u,v) < -22.5 && theta(u,v) > -67.5))
ntheta(u,v) = 135;
end
if (ntheta(u,v) == 0)
if (mod(u, v) > mod(u, v-1) && mod(u, v) > mod(u, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 45)
if (mod(u, v) > mod(u+1, v-1) && mod(u, v) > mod(u-1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 90)
if (mod(u, v) > mod(u-1, v) && mod(u, v) > mod(u+1, v))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
if (ntheta(u,v) == 135)
if (mod(u, v) > mod(u-1, v-1) && mod(u, v) > mod(u+1, v+1))
supimg(u,v) = mod(u,v);
else supimg(u,v) = 0;
end
end
end
end
%figure,imshow(ntheta);
th = 0.2;
tl = 0.1;
resimg(u,v)= 0;
for u = 2 : r-1
for v = 2 : c-1
if(supimg(u,v) > th)
resimg(u,v) = 1;
else
if(supimg(u,v) >= tl && supimg(u,v) <= th )
resimg(u,v) = 1;
else
if (supimg(u,v) < tl)
resimg(u,v) = 0;
end
end
end
if (supimg(u-1,v-1) > th || supimg(u,v-1) > th || supimg(u+1,v-1) > th || supimg(u+1,v) > th || supimg(u+1,v+1) > th || supimg(u,v+1) > th || supimg(u-1,v+1) > th || supimg(u-1,v) > th)
resimg(u,v) = 1;
else
resimg(u,v) = 0;
end
end
end
figure,imshow(supimg);
figure,imshow(resimg);
However, for some of the images it is working fine, while for others it is showing the following error :
Index exceeds matrix dimensions.
Error in canny_edge (line 45)
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
Can someone help me sort out this problem ??
Thanks and Regards.
Your loop ranges are in the wrong order leading to the error. If you modify your loop ranges to this
for u = 3 : r
for v = 3 : c
sum = 0;
for i = -2 : 2
for j = -2 : 2
sum = sum + (ID(u+i, v+j) * filter(i+3, j+3));
end
end
IDx(u,v) = sum;
end
end
the problem is solved.
My guess is that the code worked only for square images with c==r.
Note you are not making use of Matlab's vectorization capability, which allows you to shorten the first steps to:
ID = [zeros(2,c+4) ; [zeros(r,2) IDtemp zeros(r,2)]; zeros(2,c+4)];
filter=[2 4 5 4 2;4 9 12 9 4;5 12 15 12 5;4 9 12 9 4;2 4 5 4 2];
filter=filter/159;
for u = 1 : r
for v = 1 : c
IDx(u,v) = sum(reshape(ID(u+[0:4], v+[0:4]).* filter,25,1));
end
end
and this last loop can also be collapsed further but that might make readability an issue.
(edit) The loop can (for instance) be replaced with
IDx = conv2(ID, filter,'same');
I'm using matlab to implement a multilayer neural network. In the code I represent
the value of each node AS netValue{k}
the weight between layer k and k + 1 AS weight{k}
etc.
Since these data is three-dimensional, I have to use cell to hold a 2-D matrix to enable matrix multiply.
So it becomes really really slow to train the model, which I expect to have resulted from the usage of cell.
Can anyone tell me how to accelerate this code? Thanks
clc;
close all;
clear all;
input = [-2 : 0.4 : 2;-2:0.4:2];
ican = 4;
depth = 4; % total layer - 1, by convension
[featureNum , sampleNum] = size(input);
levelNum(1) = featureNum;
levelNum(2) = 5;
levelNum(3) = 5;
levelNum(4) = 5;
levelNum(5) = 2;
weight = cell(0);
for k = 1 : depth
weight{k} = rand(levelNum(k+1), levelNum(k)) - 2 * rand(levelNum(k+1) , levelNum(k));
threshold{k} = rand(levelNum(k+1) , 1) - 2 * rand(levelNum(k+1) , 1);
end
runCount = 0;
sumMSE = 1; % init MSE
minError = 1e-5;
afa = 0.1; % step of "gradient ascendence"
% training loop
while(runCount < 100000 & sumMSE > minError)
sumMSE = 0; % sum of MSE
for i = 1 : sampleNum % sample loop
netValue{1} = input(:,i);
for k = 2 : depth
netValue{k} = weight{k-1} * netValue{k-1} + threshold{k-1}; %calculate each layer
netValue{k} = 1 ./ (1 + exp(-netValue{k})); %apply logistic function
end
netValue{depth+1} = weight{depth} * netValue{depth} + threshold{depth}; %output layer
e = 1 + sin((pi / 4) * ican * netValue{1}) - netValue{depth + 1}; %calc error
assistS{depth} = diag(ones(size(netValue{depth+1})));
s{depth} = -2 * assistS{depth} * e;
for k = depth - 1 : -1 : 1
assistS{k} = diag((1-netValue{k+1}).*netValue{k+1});
s{k} = assistS{k} * weight{k+1}' * s{k+1};
end
for k = 1 : depth
weight{k} = weight{k} - afa * s{k} * netValue{k}';
threshold{k} = threshold{k} - afa * s{k};
end
sumMSE = sumMSE + e' * e;
end
sumMSE = sqrt(sumMSE) / sampleNum;
runCount = runCount + 1;
end
x = [-2 : 0.1 : 2;-2:0.1:2];
y = zeros(size(x));
z = 1 + sin((pi / 4) * ican .* x);
% test
for i = 1 : length(x)
netValue{1} = x(:,i);
for k = 2 : depth
netValue{k} = weight{k-1} * netValue{k-1} + threshold{k-1};
netValue{k} = 1 ./ ( 1 + exp(-netValue{k}));
end
y(:, i) = weight{depth} * netValue{depth} + threshold{depth};
end
plot(x(1,:) , y(1,:) , 'r');
hold on;
plot(x(1,:) , z(1,:) , 'g');
hold off;
Have you used the profiler to find out what functions are actually slowing down your code? It shows what lines take the most time to execute.
I am running the loop in this method for around 1 million times but it is taking a lot of time maybe due O(n^2) , so is there any way to improve these two modules :-
def genIndexList(length,ID):
indexInfoList = []
id = list(str(ID))
for i in range(length):
i3 = (str(decimalToBase3(i)))
while len(i3) != 12:
i3 = '0' + i3
p = (int(str(ID)[0]) + int(i3[0]) + int(i3[2]) + int(i3[4]) + int(i3[6]) + int(i3[8]) + int(i3[10]))%3
indexInfoList.append(str(ID)+i3+str(p))
return indexInfoList
and here is the method for to convert number to base3 :-
def decimalToBase3(num):
i = 0
if num != 0 and num != 1 and num != 2:
number = ""
while num != 0 :
remainder = num % 3
num = num / 3
number = str(remainder) + number
return int(number)
else:
return num
I am using python to make a software and these 2 functions are a part of it.Please suggest why these 2 methods are so slow and how to improve efficiency of these methods.
The first function can be reduced to:
def genIndexList(length, ID):
indexInfoList = []
id0 = str(ID)[0]
for i in xrange(length):
i3 = format(decimalToBase3(i), '012d')
p = sum(map(int, id0 + i3[::2])) % 3
indexInfoList.append('{}{}{}'.format(ID, i3, p))
return indexInfoList
You may want to make it a generator instead:
def genIndexList(length, ID):
id0 = str(ID)[0]
for i in xrange(length):
i3 = format(decimalToBase3(i), '012d')
p = sum(map(int, id0 + i3[::2])) % 3
yield '{}{}{}'.format(ID, i3, p)
The second function could be:
def decimalToBase3(num):
if 0 <= num < 3: return num
result = ""
while num:
num, digit = divmod(num, 3)
result = str(digit) + result
return int(result)
Next step; you are just generating a sequence of base-3 digits. Just generate these directly:
from itertools import product, imap
def base3sequence(l=12, digits='012'):
return imap(''.join, product(digits, repeat=l))
This produces base3 values, 0-padded to 12 digits:
>>> gen = base3sequence()
>>> for i in range(10):
... print next(gen)
...
000000000000
000000000001
000000000002
000000000010
000000000011
000000000012
000000000020
000000000021
000000000022
000000000100
and genIndexList() becomes:
from itertools import islice
def genIndexList(length, ID):
id0 = str(ID)[0]
for i3 in islice(base3sequence(), length):
p = sum(map(int, id0 + i3[::2])) % 3
yield '{}{}{}'.format(ID, i3, p)
I basically have a few variables
0 < na < 250
0 < max <= 16
nb = (na + max - 1) / max
n has the following characterstics
0 <= i < nb - 1 => n = max
i = nb - 1 => n = na - i * max
Is there an easy way to do this without the ternary operator?
for (i = 0; i<nb;i++) {
n = ((i + 1) * max > na ? na - (i * max) : max);
}
Examples
na = 5
max = 2
nb = 3
i = 0 => n = 2
i = 1 => n = 2
i = 2 => n = 1
na = 16
max = 4
nb = 4
i = 0 => n = 4
i = 1 => n = 4
i = 2 => n = 4
i = 3 => n = 4
na = 11
max = 3
nb = 4
i = 0 => n = 3
i = 1 => n = 3
i = 2 => n = 3
i = 3 => n = 2
The question is not very clear. Perhaps you're looking for something like this:
for (i=0;i < nb;++i)
{
n = i < nb - 1 ? max : (na - 1) % max + 1;
}
You don't need to calculate nb. This is one way you could do it (C#):
int na = 11;
int max = 4;
for (int i = 0, x = 0; x < na; i++, x += max)
{
int n = Math.Min(max, na - x);
Console.WriteLine("i = {0}, n = {1}", i, n);
}
Output:
i = 0, n = 4
i = 1, n = 4
i = 2, n = 3
Just to add more confusion to the thread:
If only you print max in the first two cases, then you could do something like: (not in any particular language)
//for 0
printf("i = %d, n = %d\n",i,max)
//for 1
printf("i = %d, n = %d\n",i,max)
//for the rest
for (i = 2; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}
You can avoid the operator doing two for loops
for (i = 0; (i + 1) * max) > na AND i < nb;i++) {
printf("i = %d, n = %d\n",i,0);
}
for (; i<nb;i++) {
printf("i = %d, n = %d\n",i,na - (i * max));
}
procedure DoSomething(a_1, ... a_n)
p = a_1
for i = 2 to n
temp = p
for j = 1 to a_i
p = p * temp
DoSomething(10,2,2,2)
We are getting mixed results. One of us got 10^7, the other 10^27.
I Think I found my error... I keep substituting 10 for p every time, instead of the new value for temp.
EDIT: here's my work:
{10, 2, 2, 2}
p = 10
i = 2 to 4
temp = p = 10
j = 1 to 2
p = 10 * 10 = 10^2
p = 10^2 * 10 = 10^3
i = 3 to 4
temp = 10^3
j = 1 to 2
p = 10^3 * 10 = 10^4
p = 10^4 * 10 = 10^5
i = 4 to 4
temp = 10^5
j = 1 to 2
p = 10^5 * 10 = 10^6
p = 10^6 * 10 = 10^7
10^7
It's 10^27 as shown by this bit of python code:
a = [10,2,2,2]
p = a[0]
for i in range(1,len(a)):
temp = p
for j in range(a[i]):
p *= temp
print p
1,000,000,000,000,000,000,000,000,000
The problems with your code as posted are:
in your 10^7 solution, you're always multiplying by 10, not temp (which is increased to the final value of p after the j loop).
You're setting temp to arr[i], not p, in your PHP code (which I'll include here so my answer still makes sense after you edited it out of your question :-).
$arr = array(10, 2, 2, 2);
$p = $arr[0];
$temp = 0;
for($i = 1; $i <= 3; $i++)
{
$temp = $arr[$i];
for($j = 0; $j <= $arr[$i]; $j++)
{
$p = $p * $temp;
}
}
echo $p;
I entered the program into my TI-89 and got an answer of 1e27 for the value of p.
t(a)
Func
Local i,j,p,tmp
a[1]->p
For i,2,dim(a)
p->tmp
For j,1,a[i]
p*tmp->p
EndFor
EndFor
Return p
EndFunc
t({10,2,2,2}) 1.E27
Isn't it ((10^3)^4)^5 = 10 ^ 60 ?
Seems to be a function to calculate
(((a_1^(a_2+1))^(a_3+1))^(a_4+1)...
Thus we get ((10^3)^3)^3 = 10^(3^3) = 10^27
There is an error in your computation for 10^7, See below. The correct answer is 10^27
{10, 2, 2, 2}
p = 10
i = 2 to 4
temp = p = 10
j = 1 to 2
p = 10 * 10 = 10^2
p = 10^2 * 10 = 10^3
i = 3 to 4
temp = 10^3
j = 1 to 2
p = 10^3 * 10 = 10^4 -- p=p*temp, p=10^3 and temp=10^3, hence p=10^3 * 10^3.
p = 10^4 * 10 = 10^5 -- Similarly for other steps.
i = 4 to 4
temp = 10^5
j = 1 to 2
p = 10^5 * 10 = 10^6
p = 10^6 * 10 = 10^7
There's a reason folks have called Python "executable pseudocode":
>>> def doSomething(*args):
... args = list(args);
... p = args.pop(0)
... for i in range(len(args)):
... temp = p
... for j in range(args[i]):
... p *= temp
... return p
...
>>> print doSomething(10,2,2,2)
1000000000000000000000000000
In C:
#include <stdio.h>
double DoSomething(double array[], int count)
{
double p, temp;
int i, j;
p = array[0];
for(i=1;i<count;i++)
{
temp = p;
for(j=0; j<array[i];j++)
{
printf("p=%g, temp=%g\n", p, temp); /* useful to see what's going on */
p = p * temp;
}
}
return p; /* this isn't specified, but I assume it's the procedure output */
}
double array[4] = {10.0,2.0,2.0,2.0};
int main(void)
{
printf("%g\n", DoSomething(array, 4));
return 0;
}
And, as others have indicated, 10e27. Note that the above is very verbose from your pseudo code - it could be simplified in many ways.
I used the Tiny C Compiler - very small, lightweight, and easy to use for simple stuff like this.
-Adam