I'm new into matlab and my problem is that I'm trying to implement conjugate matrix transpose function('), but I have no idea how to change sign only in imaginary number. I know it may be stupid question but thanks for any tips and advice.
I tried something like this, but I got these errors:
error: complex matrix type invalid as index value
error: assignment failed, or no method for ' = matrix'
function [ result ] = transpose_matrix( a )
[Row,Col] = size(a);
result = zeros(Col, Row);
iY=1;
for iRow=1:Row
iX=iRow;
for iCol=1:Col
result(iX)=a(iY);
iX=iX+Row;
iY=iY+1;
end
end
imag(result)=imag(result)*-1;
end
MATLAB is confused because the following statement tries to treat imag as a variable with result as an index since it's on the left-hand side of the assignment.
imag(result) = imag(result) * (-1);
Also, it's important to note that imag returns a real number which is the magnitude of the imaginary component. Once you modify the output of imag, you need to multiply by sqrt(-1) to get it back to an imaginary number
imag(a) * (-1) * 1i;
Now to modify only the imaginary component of result, you'll want to simply add this new imaginary component with the real component of result.
result = real(result) + imag(result) * (-1) * 1i;
Or more simply:
result = real(result) - imag(result) * 1i;
A Potential Alternative
If you can use the normal transpose function you could replace your entire function with the following:
result = transpose(a);
result = real(result) - imag(result) * 1i;
Related
I'm writing a piece of code for submission through an online grader, as showcased below. B is some given array filled any/all integers 1 through K, and I want to extract the corresponding logical indices of matrix X and perform some operations on those elements, to be put into a return array:
for i = 1:K
A = X(B == i, :);
returnArr(i, :) = sum(A) / length(A);
end
This did not pass the grader at all, and so I looked to change my approach, instead indexing array X indirectly via first using the "find" function, as below:
for i = 1:K
C = find(B == i);
returnArr(i,:) = sum(X(C,:)) / length(C);
end
To my surprise, this code passed the grader without any issues. I know there are a plethora of variations between graders, and one might handle a particular function differently than another, but from a MATLAB functionality/coding perspective, what am I missing in terms of discrepancies between the two approaches? Thanks!
I think the problem is that:
length(C) == sum(B == i)
while
length(A) == max([sum(B == i) , size(X , 2)])
In other words, to obtain the same result of the second example with the first one, you should modify it like this:
A = X(B == i , :);
returnArr(i, :) = sum(A) / size(A,1);
The function length returns the length of largest array dimension
Assume I generate MATLAB function using symbolic expression, which sometimes can be a constant. For example, if I compute gradient of different curves, one of the vector components can be a number:
syms x y;
expr = x^2 - 4*y;
grad = gradient(expr, [x, y]);
grad_func = matlabFunction(grad, 'Vars', [x, y]);
Assume that I want to apply this to an array of points. Is there a way to make generated MATLAB function robust enough to always return an array of the same size as input, even if original analytical expression (or a certain component of it) was a constant?
I try the following:
X = [-1:0.2:1];
Y = [-1:0.2:1];
[Gx, Gy] = grad_func(X,Y);
but get the error:
Error using vertcat
Dimensions of matrices being concatenated are not consistent.
Error in symengine>makeFhandle/#(x,y)[x.*2.0;-4.0]
I also tried to use ARRAYFUN:
[Gx, Gy] = arrayfun(grad_func,X,Y);
but failed as well:
The right hand side of this assignment has too few values to satisfy the left hand side.
Error in symengine>makeFhandle/#(x,y)[x.*2.0;-4.0]
Here is how you do the array function
g = cell2mat(arrayfun(#(x,y) grad_func(x,y), X(:)',Y(:)', 'uni', 0));
Gx = reshape(g(1, :), size(X));
Gy = reshape(g(2, :), size(Y));
I would like a function to compute the following operation:
I made this function that requires a matrix at its input, and returns the distances between every two lines of it in another matrix.
RGB_dist_full definition:
function[D]=RGB_dist_full(x)
I = nchoosek(1:size(x,1),2);
D = RGB_dist(x(I(:,1),:), x(I(:,2),:));
squareform(D)
end
RGB_dist definition:
function[distance]=RGB_dist(x,y)
distance=sqrt(sum((x-y).^2*[3;4;2],2));
end
Main program looks like this:
clc
clear all
rgbImage = imread('peppers.png');
K=6;
N=uint64(K*2);
rgb_columns = reshape(rgbImage, [], 3);
[unique_colors, m, n] = unique(rgb_columns, 'rows','stable');
color_counts = accumarray(n, 1);
[max_count, idx] = max(color_counts);
Imgsize=size(rgbImage);
U=unique_colors(1:N,:)
size(U)
x=[62,29,64;
63,31,62;
65,29,60;
63,29,62;
63,31,62;];
RGB_dist_full(x);
RGB_dist_full(U);
Why do I get 'Error using *
MTIMES is not fully supported for
integer classes. At least one input
must be scalar.
To compute elementwise TIMES, use
TIMES (.*) instead.' for the second call of the function, whereas the first one returns the desired output?
For these types of calculations you want to cast to double precision , because sqrt(integer) is usually not an integer. For that just double(rgbImage) immediately after reading the image will do.
I'm attempting to generate the Laguerre polynomials, and then evaluate them elementwise over a coordinate array.
Presently my code looks something like:
[X,Y] = meshgrid(x_min:mesh_size:x_max,y_min:mesh_size:y_max);
const_p=0;
const_l=1; %At present these two values don't really matter, any integer will do
coord_r = sqrt(X.^2 + Y.^2)
lag_input = num2str(coord_r.^2)
u_pl = evalin(symengine,['orthpoly::laguerre(',num2str(const_p),',',num2str(const_l),',',lag_input,')']);
However, that returns the following error for the last line;
Error using horzcat
Dimensions of matrices being concatenated are not consistent.
I assumed that this was because the three objects being converted to strings had different sizes, but after making them the same size the problem persists.
I'd rather avoid looping through each element if I can avoid it.
I would go about this slightly differently. How about the below? Note that I changed const_p and const_l from your choices because the resulting Laguerre Polynomial is spectacularly dull otherwise.
const_p = 2;
const_l = 1;
%generate the symbolic polynomial in x
lagpoly=feval(symengine,'orthpoly::laguerre',const_p,const_l,'x');
%Find the polynomical coefficients so we can evaluate using MATLAB's poly
coeff=double(feval(symengine,'coeff',lagpoly));
%generate a matrix the same size as coord_r in the original question
x=rand(512);
%Do the evaluation
u_pl=polyval(coeff,x);
#WalkingRandomly has the best way to do this if you need fast numeric results, which is usually the case. However, if you need exact analytical values, there is a trick that at you can use to avoid a for loop: MuPAD's map function. This is how almost all MuPAD functions must be vectorized as they're usually designed for scalar symbolic variables rather than arrays of numeric values. Here's a basic example:
const_p = 2;
const_l = 1;
mesh_size = 0.2;
x_min = 0;
x_max = 1;
y_min = 0;
y_max = 1;
[X,Y] = meshgrid(x_min:mesh_size:x_max,y_min:mesh_size:y_max);
coord_r = sqrt(X.^2 + Y.^2);
lagpoly = evalin(symengine,['map(' char(sym(coord_r)) ...
',x->orthpoly::laguerre(' char(sym(const_p)) ...
',' char(sym(const_l)) ',x))'])
which returns
lagpoly =
[ 3, 121/50, 47/25, 69/50, 23/25, 1/2]
[ 121/50, 76/25 - (3*2^(1/2))/5, 31/10 - (3*5^(1/2))/5, 16/5 - (3*2^(1/2)*5^(1/2))/5, 167/50 - (3*17^(1/2))/5, 88/25 - (3*26^(1/2))/5]
[ 47/25, 31/10 - (3*5^(1/2))/5, 79/25 - (6*2^(1/2))/5, 163/50 - (3*13^(1/2))/5, 17/5 - (6*5^(1/2))/5, 179/50 - (3*29^(1/2))/5]
[ 69/50, 16/5 - (3*2^(1/2)*5^(1/2))/5, 163/50 - (3*13^(1/2))/5, 84/25 - (9*2^(1/2))/5, 1/2, 92/25 - (3*34^(1/2))/5]
[ 23/25, 167/50 - (3*17^(1/2))/5, 17/5 - (6*5^(1/2))/5, 1/2, 91/25 - (12*2^(1/2))/5, 191/50 - (3*41^(1/2))/5]
[ 1/2, 88/25 - (3*26^(1/2))/5, 179/50 - (3*29^(1/2))/5, 92/25 - (3*34^(1/2))/5, 191/50 - (3*41^(1/2))/5, 4 - 3*2^(1/2)]
Calling double(lagpoly) will convert the result to floating point and you'll see that this is the same as the solution provided by ##WalkingRandomly (given the same inputs). Of course you could probably use the symbolic polynomial or its coefficients to find the same thing manually, though it's unfortunate that polyval isn't overloaded for class sym (there's evalp but it's also not vectorized so it would need to be used in conjunction with map).
This question already has an answer here:
sum(Array) says index exceeds matrix dimensions [duplicate]
(1 answer)
Closed 3 years ago.
I am trying to find the minimum value of a function of two variables, and then find the value of the variables.
My method is to iterate the function through several values of the variables and then use the min function to find the lowest value.
minval = -10;
maxval = 10;
n = 1;
for x = minval:maxval
for y = minval:maxval
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
n=n+1;
end
end
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
fmin = min(f)
The problem is with the last line:
fmin = min(f)
I am getting the error
??? Index exceeds matrix dimensions.
Error in ==> Lab2 at 65
fmin = min(f)
Why is this? Any help is greatly appreciated.
Don't define a variable named min. Try this:
which min
What does it tell you?
Note that functions in MATLAB can be overloaded by creating variables with the same name. When you do so, you prevent the function from being accessed by MATLAB. This is RARELY a good idea, so don't do it. The solution is
clear min
So you will delete that variable you have created. Of course, if there was something important in that variable, stuff it somewhere else first.
It does indeed look like you have declared a variable called min and so Matlab now treats it like a variable and not a function so it thinks you are trying to index the variable min with the vector f.
But just a comment on your code, leaving off whatever f(442) is you could achieve the same thing in a much more matlabesque fashion without loops like this:
minval = -10;
maxval = 10;
X = minval:maxval;
Y = X;
[xx, yy] = meshgrid(X, Y);
F = abs(xx-1) + abs(yy-1) + abs(xx-3) + abs(yy-5) +abs(xx-8) + abs(yy-3);
Your f is now equivalent to F(:)' (without the final value...), prove it to yourself like this: sum(f(1:end-1) == F(:)')
F as a matrix probably makes more sense than f as a flat vector anyway and you can find the min of F like this: min(F(:))
This code runs perfectly when I plug it into my version of Matlab.
If the error is occuring on line 65, then there must be something else going on in your program. Try and turn this part of your program into a function, so that it won't be impacted by everything else that you're working on.