Related
This code it's an Integration method used to accept as input parameters the values from integration nodes.(Excuse my bad english)
This is part of least approach method.
function s = simpson(x,y)
n = length(x);
h = x(2)-x(1);
s = h/3*(y(1)+y(n)+4*sum(y(2:2n-1))+2*sum(y(3:2:n-2)));
I'm trying to run the code on octave online and opens a windows to insert the value of X and Y but... this is what gives to me...
error: invalid use of script /home/oo/Simpson.m in index expression
I don't know what to do, please I really needsome help!
Explain to me like you were talking to a little kid... (This is because of my lack of english skillss)
Thanks From the buttom of my hearth :3
your code is almost OK but in last line by refer to this link there was a little error so change this line as follow
s = h/3*(y(1)+y(n)+4*sum(y(2:2:n-1))+2*sum(y(3:2:n-2)));
and for test your function suppose we have two vector x=[1 2 3] and y=[2 3 4] then we type below code in command windoe
x = [1 2 3];
y = [2 3 4];
simpson(x,y)
ans=
6
I am trying to run a MATLAB code in Octave but got stuck at the following point:
I is an empty matrix, dimensions 0x4,
a = 2;
The command, belonging to a for-loop, is:
I = [I a];
MATLAB output: I = 2
Octave output: "horizontal dimensions mismatch (0x4 vs 1x1)"
I have found a way to work around this error but I would also like to understand: Why does MATLAB accept those different dimensions whereas Octave prints an error?
Is there a different definition regarding empty matrices and extending those? (Specially because it is not a "normal" empty matrix but a 0x4 empty matrix?)
Matlab issues a warning, alerting you to the fact that this will become an error in future releases:
>> I = magic(4);
>> I(1:4,:) = []
I =
Empty matrix: 0-by-4
>> [I 2]
Warning: This concatenation operation includes an empty array with an incorrect number of rows.
Concatenation including empty arrays will require all arrays to have the same number of rows in a future release.
ans =
2
Same code on Octave:
>> I = magic(4);
>> I(1:4,:)=[]
I = [](0x4)
>> [I 2]
error: horizontal dimensions mismatch (0x4 vs 1x1)
So essentially it's the same issue, except Matlab allows it with a warning for the time being, and is being slightly more informative as to which dimension is actually at fault here, whereas octave is stricter about it and hopes you figure out what it meant 😛. But in essence the behaviour is the same.
It is also very reasonable behaviour, since attempting to concatenate two matrices of different sizes / dimensions is more likely to have come from a bug rather than intended behaviour, even if one of the arrays has become empty in the process, so matlab is wise to go down the octave path here (so to speak).
PS. Note that in this scenario, something like [I;2 2 2 2] is perfectly valid and correct code on both interpreters: i.e. you're concatenating vertically a 4-column matrix with one row to a 4-column matrix with no rows, hence the number of columns is consistent.
I must to use angle = atan2(norm(cross(a,b)),dot(a,b)), for calculating the angle between two vectors a,b and these are double type and norm is undefined for this type. How do I resolve this problem? I need to calculate the angle between two vectors this way.
In your comments, you have shown us how you are actually writing out the angle calculation and it is not the same as how you have put it in your post.
atan2(norm(cross(I(i,j,:),I_avg)),dot(I(i,j,:),I_avg));
I is an image you are loading in. I'm assuming it's colour because of the way you are subsetting I. Because I is a 3D matrix, doing I(i,j,:) will give you a 1 x 1 x 3 vector when in fact this has to be a 1D vector. norm does not recognize this structure which is why you're getting this error. Therefore, you need to use squeeze to remove the singleton dimensions so that this will become a 3 x 1 vector, rather than a 1 x 1 x 3 vector. As such, you need to rewrite your code so that you're doing this instead. Bear in mind that in your comments, angle is always overwritten inside the for loop, so you probably want to save the results of each pixel. With this, you probably want to create a 2D array of angles that will store these results. In other words:
I=imread('thesis.jpg');
I = double(I);
angles = zeros(m,n);
I_avg = squeeze(I_avg); %// Just in case
for i=1:m
for j=1:n
pixels = squeeze(I(i,j,:)); %// Add this statement and squeeze
angles(i,j) = atan2(norm(pixels,I_avg)),dot(pixels,I_avg)); %// Change
end
end
Minor note
MATLAB has a built-in function called angle that determines the angle from the origin to a complex number in the complex plane. It is not recommended you call your variable angle as this will unintentionally shadow over the angle function, and any other code that you create from this point onwards may rely on that actual angle function, and you will get unintended results.
Another minor note
Using i and j as loop variables is not recommended. These letters are reserved for the complex number, and this can produce unintentional results. Take a look at this question and post by Shai here - Using i and j as variables in Matlab. As such, it is suggested you use other variable names instead.
As #rayryeng has successfully answered this question, I would like to turn my post into a more general one by sharing my experience in debugging in Matlab. I hope anyone who somehow managed to find this post get more or less thinking about the habits a good programmer should have.
The question goes like: "How would I do if I get errors?"
Here's an excellent article by Eric in which he lists the rule-of-thumbs when you encounter a bug and wish to get rid of it. It's originally been cited by Stackoverflow, and that's the reason I read it.
If you still get no clue / idea how you can play with your code, see how this person does:
Pin-point the buggy line
(The number should start with 0) Make sure before running a script, you clear out any previously stored variables, including the notorious i and j's (you should never see them in any workspace). If any one is needed for the buggy code to run, save('buggy.mat','importantvar') before clear and load('buggy.mat') after clear.
By doing so, you can isolate your buggy code from anything else, which could have bad influences. For example, in a previously called script, there is a line
double = [2,4,6]; % you should never name a variable `double`
and in the next script, you have
>> e = str2num('uint8(200)')
e =
200
>> double(e)
Index exceeds matrix dimensions.
>>
>> f = single(2.36)
f =
2.3600
>> double(f)
Subscript indices must either be real positive integers or
logicals.
>>
The reason is double is no longer an inbuild function, but a user-defined variable. Too bad to pick up a name carelessly!
....anyway, let's clear the workspace and get rid of double.
>> clear
Read the error message, thoroughly.
Now let's begin with OP's problem. The original code (trimmed) goes like this -
img = imread('peppers.png');
a = img(300,200,:);
b = img(200,300,:);
d = norm(cross(a,b));
.... hence the error
Undefined function 'norm' for input arguments of type 'uint8'.
Error in untitled (line 6)
d = norm(cross(a,b));
Most beginners are only interested in the first line of the error message, which by it alone usually doesn't provide any useful help, or only in the red color, which leads to the famous question "my code does not work!"
But think twice. You still have another 2 lines unread! Error in untitled (line 6) says I'm running a script named untitled and the (first) error lies in line 6, and the code in that line is d = norm(cross(a,b));.
Now, at least you know a little more about your code - "My code d = norm(cross(a,b)); doesn't work!"
Although most likely we may also vote this kind of question to get closed, it's still much much better than a simply "It does not work!".
Now we can pin-point the buggy line
try
% this line will raise an error
d = norm(cross(a,b));
catch err
disp(err.message)
end
Look into the functions
First, make sure the inner function cross works as expected -
>> cross(a,b)
ans(:,:,1) =
0
ans(:,:,2) =
255
ans(:,:,3) =
0
>>
Good. So now we can even narrow down the error to the outer norm.
One more thing to mention. You can always find Mathworks' documentation for any in-build function, by typing "matlab function", such as "matlab norm" in Google (or any other search engine) and clicking on the first result. If you prefer, you can also type in Matlab command window doc _function_ such as doc norm and read the doc in Matlab. It's of course a pleasure of us on Stackoverflow to give you the reference by doing the same thing, but it takes a longer time because a human is, in this aspect, always slower than a search engine.
The error reads Undefined function 'norm' for input arguments of type 'uint8'.. So the input for norm should not be uint8, unsigned 8-bit integer. But what should it be?
% why `norm` "does not work"?
% this line runs perfectly well
norm(cross([1,2,3], [4,5,6]))
% so what is working?
class([1,2,3]) % so `norm` works for `double`
One thing we can do now is convert a and b to double precision. Let's try it now.
% try fixing 'uint8' error
a2 = double(a);
b2 = double(b);
whos a b % now they are double, which `norm` should work for
try
% this line will raise an error
d = norm(cross(a2,b2));
catch err
disp(err.message)
end
Now the error becomes Input must be 2-D.. What's wrong with the input?
% what is "must be 2-D" error?
size(a2) % a2 is 3-D
disp(b2) % b2 is also 3-D
This gives output in command window
ans =
1 1 3
(:,:,1) =
255
(:,:,2) =
150
(:,:,3) =
0
In OP's problem, he/she is trying to calculate something about color difference (to the best of my knowledge) which involves the angle between two color vectors in RGB space. So the vectors are needed. With imread, each pixel of the image is stored as 3 elements in the matrix, first 2 dimension being its physical position, the 3 dimension being RGB channel components. Hence pixel(200,300) with color rgb[255,150,0] is stored by us in variable b wihch is a 3-D vector.
By understanding what we need and what Matlab can do, we can combine these two points into one. We need the norm of the cross product of a and b, while the useful information (the 3 component values) is stored in the 3rd dimension. Matlab can calculate the norm of the cross product of a vector with all its information in the 1st dimension. (Here, "dimension" refers to that of the Matlab variable; a vector with 3 elements in its 1st dimension is physically a 3-D vector).
After thinking twice, we are now able to debug our code - just put all 3 elements into the 1st dimension.
% so we want the 3 elements in the 3rd dimension become in the 1st dim
a3 = squeeze(a2);
b3 = reshape(b2,numel(b2),[]);
try
d = norm(cross(a3,b3));
catch err
disp(err.message)
end
d
Bonus: If by default Matlab treats a 3-D vector as a "1-D array", then most probably the cross function has not been working correctly. Let's make a check -
>> clear
>> a = [1,2,3]
a =
1 2 3
>> b=[4,5,6]
b =
4 5 6
>> cross(a,b)
ans =
-3 6 -3
>>
The result should be the same as the one we can get by calculating by hand.
Now if we put the components into the 3rd dimension of the variable -
>> clear
>> a(1,1,:)=[1,2,3]
a(:,:,1) =
1
a(:,:,2) =
2
a(:,:,3) =
3
>> b(1,1,:)=[4,5,6]
b(:,:,1) =
4
b(:,:,2) =
5
b(:,:,3) =
6
>> cross(a,b)
ans(:,:,1) =
-3
ans(:,:,2) =
6
ans(:,:,3) =
-3
>>
.... seems OK. cross also puts the result in the 3rd dimension. In fact, Mathworks' documentation says
If A and B are vectors, then they must have a length of 3.
If A and B are matrices or multidimensional arrays, then they must
have the same size. In this case, the cross function treats A and B as
collections of three-element vectors. The function calculates the
cross product of corresponding vectors along the first array dimension
whose size equals 3.
At last, one thing is always correct to anyone who wants to do something with programming - be cautious and prudent when writing your code.
So I have a lot of cell manipulation in code I'm writing right now where it helps greatly to have cell functions of two arguments (e.g., to concatenate arrays in cells of the same size). However, MatLab is reacting confusingly to even simple uses of multiple-input cellfun calls, so I'd like to find out what I'm doing wrong (as I'm just following the MatLab function reference). For instance,
B = {[1 2;3 4] , [5 6;7 8]}
cellfun(mtimes,B,B)
returns
??? Error using ==> mtimes
Not enough input arguments.
In fact, it returns the same message if I input
cellfun(mtimes,B)
or
cellfun(mtimes,B,B,B,B)
Help?
As per the MATLAB CELLFUN documentation the first argument to CELLFUN has to be a function handle, not just the "raw" name of a function. So, something like this...
B = {[1 2;3 4] , [5 6;7 8]}
cellfun(#mtimes,B,B)
(notice the # sign in front of mtimes on the second line).
By putting in a "raw" mtimes, MATLAB is trying to evaluate the function MTIMES on no arguments, and use the result of that as the first argument to CELLFUN. But, as the error messages indicate, MTIMES acting on no arguments is an error.
Instead, use #mtimes to mean the function handle that "points to" the MTIMES function.
I am trying to do following in MATLAB,
global a b c d e f g h l;
A=[1 3;3 2];
B=[a 0;0 b];
C=[d 0;e f];
Ctranspose=transpose(C);
D=[sqrt(d) 0;0 sqrt(f)];
E=Ctranspose/D;
Etranspose=transpose(E);
K=A+E;
M=E*D*Etranspose;
for a=1:10
for b=1:10
if K==M
print(a);
print(b);
print(d);
print(e);
print(f);
end
end
end
I get following errors:
a)
Error using +
Matrix dimensions must agree.
Error in trial (line 6)
K=A+B
b)
Error using vertcat
CAT arguments dimensions are not consistent.
Error in trial (line 5)
C=[d 0;e f];
What is wrong here?
(Kindly note that I am new to MATLAB)
Thanks
Ouch! OUCH! Let me just jump right in there and interrupt you before you continue down this path!
I know you're not a programmer, but at some point in life (apparently, this is yours!), you have to face the facts and become one, however momentarily. So know that programming is not really a science, it's an art, a craftsmanship if you will, and one that is all too easy to get wrong. Know also that there have been millions upon millions of programmers before you, who paved the way for you and found out which methods work best, and which methods lead to certain disaster.
I will describe six of these "roads-to-certain-doom" that are present in your code.
First on the list, is the use of global. DON'T USE GLOBAL VARIABLES!! Sure, they are all-right for small, simple things, but the better, much more manageable, more durable, robust, much less error-prone way of passing data around is to do it manually. As a rule of thumb, create all top-level functions with as little dependencies to other functions/variables as possible. This is because global variables create a tight coupling between a program's state and a function's output, which makes reproducing any errors hard, if not impossible, and debugging (which is actually what any programmer spends most of his/her time on) a complete nightmare. Also, any function other than the one running can change them, so that
function testMe
global a;
a = 5*rand;
someFunction;
b = 4*a; % ERROR! or...will it?
function someFunction
global a;
a = a/5;
if a < 0.5
someOtherFunction; end
function someOtherFunction;
global a;
a = {'my string'};
will sometimes work, and sometimes fail. An example of something worse that can happen:
function testMe
global a, b;
a = 5; b = 6;
result = someCalculation;
result = a*b*result;
function someFunction
global a;
a = sin(pi/rand); % INTENTIONAL
% do LOTS of stuff here
for a = 1:10 % OOPS! unintentional use of variable name
% do stuff
if (some weird condition)
break; end
end
There will be no error, no warning, nothing, but your results will still be garbage. And as your functions grow larger (and they WILL, usually), this error gets harder and harder and harder to find. It's not uncommon to spend a good few days on finding this sort of mistake.
In your code, you also change the global variables a and b inside the loops. This means that any function/script that uses a and b, that gets called after this one completes, will see a=10 and b=10. Now suppose you call a function inside those loops, that changes the value of a. What will the value of a be on the next iteration of the a-loop? Suppose also you get erroneous results. How would you go about finding that error?
Code like this is usually called "spaghetti code", for obvious reasons. Perhaps it will work, and is easy to code, but in the end it will always slow you down tremendously (not to mention the one who inherits your code).
A much better approach that prevents most of this is to collect data in larger containers, and explicitly pass them around. Say we use a struct for the data a-l:
data = struct(...
'a', a,...
'b', b,...
'c', c,...
'd', d,...
'e', e,...
'f', f,...
'g', g,...
'h', h,...
'l', l);
So that you can say
result = myFunction(data);
Accessing data inside myFunction goes like this: data.a to get the value for a, or data.f for the value of f, etc. Saying data.k = 5; in myFunction will not change the result, or the original data passed to the function -- you have broken the tight coupling and prevented all the aforementioned problems.
Type help struct or help cell in the Matlab command window to learn about these sorts of generic containers.
Second on the list is using the variable name l. It's somewhat silly, and I can be short about this: don't do that :) Contrary to what most people (and even some programmers) believe, you write a line of code only once, but you read it hundreds, if not thousands of times. The best practice is to make the reading as easy as possible, not the writing. The l just looks like the 1, doesn't it? The bug k=1 vs k=l is simply harder to spot than k=m vs k=1.
Third on the list is the keyword transpose. It's kinda verbose, isn't it? In math, you would use AT, which is much easier on the eyes than writing the full definition all of the time:
B = { Aij ➝ Aji ∀ i < m ⋏ j < n
you normally just say B = AT. Same in Matlab. The transpose of a matrix can be accomplished like so:
Actrans = A' ; % conjugate transpose
Atrans = A.'; % regular transpose
which reduces your code to the much less verbose
A = [1 3;3 2];
B = [a 0;0 b];
C = [d 0;e f];
D = [sqrt(d) 0;0 sqrt(f)];
E = C.'/D;
K = A+E;
M = E*D*E.';
Fourth on the list is the equality K==M. As it stands here, K and M are matrices. The expression K==M is evaluated element-wise, for reasons that will become obvious later in your programming career :) This means that K==M will be again a matrix, the same size as K and M, containing 0 if corresponding elements in K and M are not equal, and 1 if these elements are equal. So, what will an if-statement do with such a matrix? In Matlab, it will be true whenever the first element is true (in my opinion, it should throw an error, but oh well).
This is obviously not what you want. what I think you want is that all elements in both matrices are equal. It's best you use this:
if all( abs(K(:)-M(:)) < eps )
where the (:)-notation means that the matrix K and M should be expanded to column-vectors prior to the comparison. This is because all() works down a single dimension, so all(K==M) would still be a matrix (vector, actually, but that's a different name for a special case of the same thing). Notice that I don't use equality (==), but rather check whether their difference is smaller than some tiny value (eps). This is because in floating-point arithmetic (which all computers use), operations like multiplication and square root usually suffer from things like round-off error and approximation/interpolation error. An equality is a very tough demand, too tough to evaluate to true in most cases where it mathematically speaking should. You can prevent this failure to detect the equality by comparing the difference of the two to a tiny value that's related to round-off error (eps).
Fifth on the list is the way you print things. The print statement, by itself, will send a figure to the system's default printer, you know, that moody machine that spits out paper with ink on it if it feels like cooperating today :) Now, I assume you were trying to display things on the screen. Doing it like the way you set out to display things is not the best way: you'll get a dozen times this list of unnamed, unstructured values:
1 % which would be the value of 'a'
1 % which would be the value of 'b'
3 % which would be the value of 'd'
4 % which would be the value of 'e'
5 % which would be the value of 'f'
...
Seeing only the values appear makes reading and interpreting what's going on rather tedious. Better use something more descriptive:
if all( abs(K(:)-M(:)) < eps )
% option 1
a
b
d % NOTE: not terminating with semicolon
e
f
% option 2
fprintf(...
'a: %d\n, b: %d\n, d: %d\n, e: %d\n, f: %d\n\n', a,b,d,e,f);
end
Option 1 will just show
a =
1
b =
1
etc.
which at least also shows the variable's name alongside its value. Option 2 is the nicer one:
a: 1
b: 1
d: 3
e: 4
f: 5
a: 1
b: 2
d: 3
e: 4
f: 5
etc.
(As an aside, the values a,b,d,e,f never change in the loops, so why would you want to show them in the first place?)
Sixth (and last!) on the list, is one that is specific to Matlab: for-loops. Matlab is an interpreted, matrix-based language. Its matrix nature simply means that every variable is in essence, a matrix. Interpreted means that your code will not directly be seen by the computer's processor, it will have to go through a series of interpretations and translations before anything gets calculated. This coin has two sides:
it can speed things up (like coding, or doing "trivial" things like solving linear systems, FFT, comparisons of matrices, etc.)
it can slow things down (like repeated execution of statements, like in a loop)
In light of performance, the for-loop is notorious in Matlab for bringing operations to a crawl. The way to go in Matlab is usually vectorized code, e.g., use the fact that all variables are matrices, and use matrix/tensor operations on them instead of loops. This is not a very common approach in most programming languages (and you'll see a lot of strong, heated resistance to it in programmers not accustomed to it), but in a mathematical context it makes a whole lot of sense. Always try to use matrix/tensor operations as a first line of attack (and Matlab has a lot of them, mind you!) before resorting to for-loops.
So, that's what's wrong with your code :) Oh yeah, and as Andreas Hangauer already mentioned, place the statements referring to a through l, and all that needs to be re-calculated accordinly, inside the loop, and you'll be fine.
You didn't specify what the values of a b c d e f g h l are, you specify that they are global variables.
a) First error: Given that you get an error in line 6, it is either that a or b isn't a scalar.
b) Second error: (error is in line 4 rather than line 5). Here again one of d, e or f is not a scalar. What happens here is that d and e might be scalars, but f isn't, f is instead a vector or a matrix. So the first row of the matrix has a different length than the second row, hence the error.
What is the intend of the for loops? M==K will return true only if all elements of M and K are equal, but the element in the second row and first column will never be the same. And if somehow M and K were the same matrix, then the code would just print d, e and f for all the combinations of values of a and b. (Note that a and b are redefined in the for loop.)
You have to change the order of your program.
d = 4567; % some value necessary
e = 1234; % some value necessary
f = 4567; % some value necessary
for a=1:10
for b=1:10
A=[1 3;3 2];
B=[a 0;0 b];
C=[d 0;e f];
Ctranspose=transpose(C);
D=[sqrt(d) 0;0 sqrt(f)];
E=Ctranspose/D;
Etranspose=transpose(E);
K=A+E;
M=E*D*Etranspose;
if K==M
print(a);
print(b);
print(d);
print(e);
print(f);
end
end
end
You not seem to have correctly understood the basic concept of a programming language. In a programming language (unlike mathematical notation) the statements are commands that are executed sequencially, one after another. All values that are needed in a computation have to be available when that command is executed, hence the updated execution order is necessary for intended operation.
In addition to everything mentioned here, please do format the code nicely (note: the code below is the OP's code, so it's programmatically wrong):
global a b c d e f g h l;
A = [1 3; 3 2];
B = [a 0; 0 b];
C = [d 0; e f];
Ctranspose = transpose(C);
D = [sqrt(d) 0; 0 sqrt(f)];
E = Ctranspose / D;
Etranspose = transpose(E);
K = A + E;
M = E * D * Etranspose;
for a = 1:10
for b = 1:10
if K == M
print(a);
print(b);
print(d);
print(e);
print(f);
end
end
end
This spares you time and mental resources when reading your code, which actually takes much more time than writing it.