Let's say i have an array:
A = [0, -2, 0, 0, -3, 0, -1, 0];
And I want to see if it can fit any of the patterns below:
B = [1, 1, 1 , 0, 0 , 0 , 0, 0,];
C= [1, 1, 0 , 1, 0 , 0 , 0, 0,]
D= [0, 1, 0 , 1, 0 , 1 , 0, 0];
Where 1 means that the number is unique and 0 means that the number remains the same until another 1 is met but is different from the number before.. Here are some examples:
[-3, -2, -1, 0, 0, 0, 0, 0]; --- A matches B.
[-3, -2, -1, -1, 0, 0, 0, 0]; -- This matches C
[-3, -3, 3, 3, -2, -2, 0, 0]; -- This matches D
Is there any Matlab function for this or must I think up my own way? Any advice, I am very new to Matlab.
There is something wrong about your rule, you seem to treat 0 as a special case (i.e. it is not a number or something).
you could just do something like this:
A=[-3, -2, -1, -1, 0, 0, 0, 0];
[ia ib] = unique(A);
R = zeros(1,8);
R(ib) = 1
>> R =
1 1 0 1 0 0 0 1
and match this, this is assuming that you treat 0 as a number just as you state in the rule.
If you wanted 0 to be special case, you need to :
A=[-3, -2, -1, -1, 0, 0, 0, 0];
[ia ib] = unique(A);
ib(ia==0)=[];
R = zeros(1,8);
R(ib) = 1
>> R =
1 1 0 1 0 0 0 0
and simply match this vector to your B,C,D etc. The second method matches your desired answer, but does not match the rule you state. The first method matches the rule you state but not your desired output.
=============EDIT============
I am on 2010b and some time along the time line, the way unique works changed, you now need to add legacy if you are using any version above 2012b.
Sorry I forgot to mention this:
just change it to :
[ia ib] = unique(A,'legacy');
and it should work fine.
Related
I have created a 5x4 matrix with entries only 1 and -1. I have also created the code which gives me randomly possible configurations for this kind of matrix. Every time I check manually if the determinant of the D'*D product is equal to 512 or not. Until now, I have only got the results of determinants 0, +-64, 192 and +-128.
I want to get the matrix configurations automatically:
whose determinant is equal to 512,
whose determinant is between 0 and 512.
So far I have done this line of code. It is right, even though I have to run the code by myself after each calculation.
valueset = [1,-1];
desiredsize = [5, 4];
desiredmatrix = valueset(randi(numel(valueset), desiredsize))
b=desiredmatrix.'
a=desiredmatrix.'*D
det(a)
and I got these kinds of calculations:
>desired
desiredmatrix =
1 -1 1 -1
1 -1 1 -1
-1 -1 1 -1
1 -1 -1 -1
1 1 -1 -1
b =
1 1 -1 1 1
-1 -1 -1 -1 1
1 1 1 -1 -1
-1 -1 -1 -1 -1
a =
1 3 3 1
-1 1 -3 -5
-1 -3 1 3
-3 -1 -5 -3
ans = 64
> desired
desiredmatrix =
-1 1 1 1
1 1 1 1
-1 -1 1 1
1 -1 -1 -1
1 -1 -1 -1
b =
-1 1 -1 1 1
1 1 -1 -1 -1
1 1 1 -1 -1
1 1 1 -1 -1
a =
3 1 1 -1
-3 -1 -1 1
-1 -3 1 3
-1 -3 1 3
ans = 0
etc, etc
It takes me around 23 milliseconds to compute first such matrix. And about 29-30 seconds to find all such matrices.
Now, we have 20 values in a matrix, so we have 2^20=1048576 such matrices.
So I run a for loop first to iterate through all these numbers (0 to 1048575). Now we go to fill the matrix. Now each i in the first for loop, I take the binary representation of i and pad it with 0s till I get a 20-element binary list.
So, 140 whose binary is 10001100 will become a list of 0000 0000 0000 1000 1100 (spaces added for visibility) which will be,
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0] (say its named bin_list)
Now, to fill the 20 elements of my matrix (say 0 to 19) I fill
the jth element as valueset[bin_list[j]] so if the element of bin_list is 0, the corresponding element of my array A is 1 and if its 1 then A gets the value (-1). So, for the case of 140, the matrix A will be
[[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[-1, 1, 1, 1],
[-1, -1, 1, 1]]
Note: I have to convert A into a matrix using numpy.matrix since we need to calculate transpose and determinant.
This is depreciated as pointed out by user S Guogeon. So, for matrix multiplication, one can directly use # instead of * with numoy.array
After calculating this matrix A, I calculate the transpose using numpy.transpose(), say it is B. now I calculate the determinant using numpy.linalg.det(B*A). Now due to the return datatype of numpy.linalg.det(), I round it off to the nearest integer.
I check if this determinant is 512. If it is, bingo, I have the correct matrix.
The first solution I have is 854 (i=854)
The bin_list for this would be,
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0]
The matrix A would be,
matrix([[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, -1, -1],
[ 1, -1, 1, -1],
[ 1, -1, -1, 1]])
A'*A will be,
matrix([[5, 1, 1, 1],
[1, 5, 1, 1],
[1, 1, 5, 1],
[1, 1, 1, 5]])
The determinant of this will be 512 (after converting the determinant into an int)
The code for converting 140 to the binary list is:
def int_to_binlist(n, b = 8):
res=[]
strb = str(b)+'b'
str1 = format(n, strb)
res = list(map(int, list(str1)))
return res
The code snippet for filling the matrix A with the bits of 1 and -1 is,
n_mat = desiredsize[0]*desiredsize[1] #so 5*4=20
for j in range(n_mat):
a[int(j/4)][j%4] = valueset[li[j]]
References:
numpy.linalg.det documentation
numpy.matrix documentation
I try to run this example, which uses ANN Toolbox for Scilab
https://burubaxair.wordpress.com/2014/03/12/artificial-neural-networks-in-scilab/
This is code:
T = [
1 1 1 1 1
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
]';
U = [
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
]';
N = [35 10 2];
W = ann_FF_init(N);
x = [1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
0, 1, 1, 1, 0]';
t_t = [1 0]';
t_u = [0 1]';
t = [t_t, t_u];
lp = [0.01, 1e-4];
epochs = 3000;
W = ann_FF_Std_batch(x,t,N,W,lp,epochs);
y = ann_FF_run(x,N,W)
disp(y)
But i receive an error:
-->exec('D:\Учёба\Задачи\Recognition.sce', -1)
!--error 15
Подматрица задана некорректно (Submatrix is incorrect).
at line 37 of function ann_FF_grad_BP called by :
at line 25 of function ann_FF_Std_batch called by :
W = ann_FF_Std_batch(x,t,N,W,lp,epochs);
at line 33 of exec file called by :
exec('D:\Учёба\Задачи\Recognition.sce', -1)
An error may be in T and U matrix, but i don't understand why. Could you tell be what i do wrong? Thank you!
You've made 2 errors in your code:
You should not mix testing and training sets.
Testing input must be a single column.
Your first error was x = [ 1.... ] because it contained a single image, whereas you specified in N that you had two output neurons.
As stated in the example, you should have x = [T,U];
Your second error was to give x as a test to ann_FF_run. This function takes test input as a single column. But since you trained your NN with x just before it was a 5x7 matrix. Just change it to a column vector.
Here a corrected and commented code :
T = [...
1 1 1 1 1 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
0 0 1 0 0 ...
]';
U = [...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
1 0 0 0 1 ...
0 1 1 1 0 ...
]';
// setting the traing set of two image
xtrain = [T,U];
// so each image as 35 pixels so N(1) is 35
// and we have two images so N($) is 2
N = [35 10 2];
// training the NN
W = ann_FF_init(N);
// The expected response for T : 1 for T, 0 for U
t_t = [1 0]';
// The expected response for T : 1 for T, 0 for U
t_u = [0 1]';
// the overall response
t = [t_t, t_u];
// some parameters
lp = [0.01, 1e-4];
epochs = 3000;
// getting the weight of the trained NN
W = ann_FF_Std_batch(xtrain,t,N,W,lp,epochs);
// testing the traing set.
y = ann_FF_run(xtrain,N,W)
disp('Testing the traing set')
disp(y) //should get something close to t ~ [1 0 ; 0 1]
// testing a distord U
xtest1 = matrix([1, 0, 0, 0, 1;
1, 1, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
1, 0, 0, 0, 1;
0, 1, 1, 1, 1]',-1,1);
y = ann_FF_run(xtest1,N,W)
disp('Testing a distored U')
disp(y) //should get something close to t_u ~ [0 1]
//testing something different from T and U. should get nothing
xtest2 = matrix([1, 0, 0, 0, 1;
1, 1, 0, 0, 1;
1, 0, 1, 0, 1;
1, 0, 1, 0, 1;
0, 0, 1, 1, 1;
0, 0, 1, 0, 1;
0, 1, 1, 1, 1]',-1,1);
y = ann_FF_run(xtest2,N,W)
disp('Testing something neither T nor U')
disp(y)
and the output from scilab's console
Testing the traing set
0.8538757 0.1075397
0.1393287 0.8957439
Testing a distored U
0.1078667
0.9007755
Testing something neither T nor U
0.3433933
0.6306797
I want to set precision for all element of a matrix. Below is what I did:
>>A
A =
0 1.0000 0 0 0 0
-137.0830 0 0 0 0 0
0 0 0 1.0000 0 0
365.5546 0 0 0 0 0
0 0 0 0 0 1.0000
365.5546 0 0 0 0 0
>> vpa(A,2)
ans =
[ 0, 1.0, 0, 0, 0, 0]
[ -144.0, 0, 0, 0, 0, 0]
[ 0, 0, 0, 1.0, 0, 0]
[ 377.0, 0, 0, 0, 0, 0]
[ 0, 0, 0, 0, 0, 1.0]
[ 377.0, 0, 0, 0, 0, 0]
The result is not my desire, it should be:
-137.08, 365.55, 365.55 in the first column.
Please help to suggest me how to get it.
Thank you so much!
You are not using vpa correctly. From the docs:
vpa(x,d) uses at least d significant digits
Nota that it says at least. That is why you still get 377 when you only asked for 2 significant digits.
It seems that you don't know what significant digits are. From Wikipedia:
The significant figures of a number are digits that carry meaning
contributing to its measurement resolution. This includes all digits
except:
All leading zeros;
Trailing zeros when they are merely placeholders to indicate the scale of the number (exact rules are explained at identifying
significant figures); and
Spurious digits introduced, for example, by calculations carried out to greater precision than that of the original data, or measurements
reported to a greater precision than the equipment supports.
So you want this
>> vpa(365.5546, 5)
ans =
365.55
Now, to be consistent, you need to find out what is the maximum of your matrix and compute the desired number of significant digits from there.
max_number = floor(log10(max(abs(A(:))+1)) + 1);
decimals = 2;
vpa(A, max_number + decimals)
Here, max_number is the maximum number of integer digits that your matrix has, and decimals is the number of decimal places that you want to have.
The second input to vpa is the number of significant digits which is not the same as the number of values after the radix point. The number -137.08 actually has five signficant digits so you'll want to use a second input of 5
vpa(A, 5)
% [ 0, 1.0, 0, 0, 0, 0]
% [ -137.08, 0, 0, 0, 0, 0]
% [ 0, 0, 0, 1.0, 0, 0]
% [ 365.55, 0, 0, 0, 0, 0]
% [ 0, 0, 0, 0, 0, 1.0]
% [ 365.55, 0, 0, 0, 0, 0]
vpa(x,d) :
d is significant digits, not decimal places.
pvalue = vpa(-137.0830);
twopvalue = vpa(-137.0830,2);
% pvalue = -137.08299999999999840838427189738
% twopvalue = -144.0
If you want to get -137.08, 365.55, 365.55 in the first column. You can use roundn(A,-2)
roundn(A,-2)
ans =
0 1.0000 0 0 0 0
-137.0800 0 0 0 0 0
0 0 0 1.0000 0 0
365.5500 0 0 0 0 0
0 0 0 0 0 1.0000
365.5500 0 0 0 0 0
Here is the initial question:
About the output value range of LeGall 5/3 wavelet
Today I found actually the transform can be seen as a matrix multiplication. It is easy to calculate the wavelet coefficients as a matrix (in order to estimate the value, all the Rounded down action is ignored which will not affect the estimation of the max value).
The 1st level of DWT2 has two steps which is to perform the LeGall 5/3 filter on two directions. If we see the I as the input 8*8 matrix and A as the wavelet coefficients matrix.
For the horizontal direction:
output1 = I.A
Then the vertical direction is calculated:
In fact, it can be represented as output2 = output1'.A (use the transpose of output1 to multiply A again) which will get the transpose of the result we want.
Transpose the output2.
output_lvl1 = output2' = (output1'.A)' = ((I.A)'.A)' = (A'.I'.A)'=A'.I.A (I put details here to make it clear without the math symbol...)
And the 2nd level of the wavelet is only performed at the LL area which is the output_lvl1(1:4,1:4). And basically the process is the same (let the coefficients matrix represented as B).
Here is the coefficients of the matrix A and B based on my calculation (hope it is correct...)
A = [0.75 -0.125 0 0 -0.5 0 0 0;
0.5 0.25 0 0 1 0 0 0;
-0.25 0.75 -0.125 0 -0.5 -0.5 0 0;
0 0.25 0.25 0 0 1 0 0;
0 -0.125 0.75 -0.125 0 -0.5 -0.5 0
0 0 0.25 0.25 0 0 1 0;
0 0 -0.125 0.625 0 0 -0.5 -1;
0 0 0 0.25 0 0 0 1];
B = [0.75 -0.125 -0.5 0;
0.5 0.25 1 0;
-0.25 0.75 -0.5 -1;
0 0.125 0 1];
And now the question became:
1. if we know A and the range of Input(matrix I) which is -128 to +127, what is the value range of output_lvl1 = A'.I.A?
if we use the output_lvl1(1:4,1:4) as input I2, what is value range of B'.I2.B?
I really need some math help here. Thank you in advance.
Well finally I found a way to solve this.
SymPy lib is what I really need.
As the max value could only be possible in results of B'.I2.B. So a program will do this.
from sympy import *
def calcu_max(strin):
x=0
strin1 = str(strin).replace('*',' ').replace('+',' ').replace('-',' ')
strin1 = strin1.split(' ')
for ele in strin1:
if '[' in ele or ']' in ele or ele =='':
continue
x = x + float(ele)
return x
DWT1 = Matrix(8, 8, [0.75, -0.125, 0, 0,-0.5, 0, 0, 0, 0.5, 0.25, 0, 0, 1, 0, 0, 0, -0.25, 0.75, -0.125, 0, -0.5, -0.5, 0, 0, 0, 0.25, 0.25, 0, 0, 1, 0, 0, 0,-0.125, 0.75, -0.125, 0, -0.5, -0.5, 0, 0, 0, 0.25, 0.25, 0, 0, 1, 0, 0, 0, -0.125, 0.625, 0, 0, -0.5, -1, 0, 0, 0, 0.25, 0, 0, 0, 1])
Input1 = MatrixSymbol('A',8,8)
DWT1_t = Transpose(DWT1)
output_lvl1_1d = DWT1_t*Input1
output_lvl1_2d = output_lvl1_1d* DWT1
#print 'output_lvl1_2d[0,0]: '
#print simplify(output_lvl1_2d[0,0])
#bulit 2nd lvl input from the lvl1 output (1:4,1:4)
input_lvl2 = output_lvl1_2d[0:4,0:4]
DWT2 = Matrix(4, 4, [0.75, -0.125, -0.5, 0, 0.5, 0.25, 1, 0, -0.25, 0.75, -0.5, -1, 0, 0.125, 0, 1])
DWT2_t = Transpose(DWT2)
output_lvl2_1d = DWT2_t*input_lvl2
output_lvl2_2d = output_lvl2_1d * DWT2
#Lvl 2 calculate max
max_lvl2 = zeros(4,4)
for i in range(4):
for j in range(4):
max_lvl2[i,j]=128.0*calcu_max(simplify(output_lvl2_2d[i,j]))
print str(i)+' '+str(j)+' '+str(max_lvl2[i,j])
#print max_lvl2[i,j]
print max_lvl2
Well, here is the result (putting all possible max values in one matrix, and min values are correspondingly negative):
[338.000000000000, 266.500000000000, 468.000000000000, 468.000000000000],
[266.500000000000, 210.125000000000, 369.000000000000, 369.000000000000],
[468.000000000000, 369.000000000000, 648.000000000000, 648.000000000000],
[468.000000000000, 369.000000000000, 648.000000000000, 648.000000000000]
Then 648 is what I am looking for.
i would like to find 8 neighbors. In an algorithm it is written as
int Nx[] = {-1, 1, 0, 0, -1, -1, 1, 1}; //8-neighbors
int Ny[] = {0, 0, -1, 1, 1, -1, 1, -1};
how 3*3 matrix is interpreted like this?
These are relative x- and y- coordinates. It becomes clearer if you convert this to coordinate pairs:
x y neighbour
----------------------
-1 0 left
1 0 right
0 -1 bottom
0 1 top
-1 1 left-top
-1 -1 left-bottom
1 1 right-top
1 -1 right-bottom