Arrays operations in Matlab - arrays

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.

Related

How to output the real and imaginary parts separately instead of having just one complex vector

I have a function M that outputs complex numbers taking an input range of r's. Instead of just outputting a single complex number, I would like to have the function to output two values (the real and imaginary parts separately) for all the output complex vectors. I would prefer the function to be anonymous function.
I tried the following but did not work since I am just getting single output complex values:
r = linspace(1E-10,1.5,100);
%M= (0.5*((1i*r+0.135).* (1i*r+0.651)))./((1i*r+0.0965).* (1i*r+0.4555))
M= #(r)(0.5*((1i*r+0.135).* (1i*r+0.651)))./((1i*r+0.0965).* (1i*r+0.4555))
How do I separate the real and complex parts of a vector?
Create an anonymous function with a different variable to avoid confusion i.e. create M with:
M = #(k)(0.5*((1i*k+0.135).* (1i*k+0.651)))./((1i*k+0.0965).* (1i*k+0.4555));
then create another anonymous function, say N, that extracts real and imag values and then stacks the result.
N = #(k) [real(M(k)); imag(M(k))];
Call this anonymous function with N(r) to get your expected result.
Alternately if you have already calculated M as in your commented out code then you can do:
N = #(k) [real(k); imag(k)];
and then call it with N(M).

MATLAB - Equivalent logical indexing leading to two different results

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

Fortran Array Splice Initialization

I'm trying to initialize an array with equal spacing between 0 and 1 in fortran.
My code is :
program test
double precision :: h
double precision, dimension(:), allocatable :: x
h = 1./11
if(.not. allocated(x)) allocate(x(10))
x(1:10) = [h:(1-h):h] (*)
end program
The error I am given is "The highest data type rank permitted is INTEGER(KIND=8)" at the stared line.
I've tried to change it with
x(1:10) = h:(1-h):h
x = h:(1-h):h
x(1:10) = (/(h:(1-h):h)/)
and various other forms with no luck.
The syntax you're using is not valid Fortran and implied DO loops can't have non-integer bounds. You want something like this:
x = h * real([(i,i=1,size(x))],kind(h))
For more information, look up "array constructors" in the standard or a textbook.
Don't use (1:10) on the left side - see https://software.intel.com/en-us/blogs/2008/03/31/doctor-it-hurts-when-i-do-this
This expression
[h:(1-h):h]
is, from a Fortran point of view, broken. It looks a bit like an array slice, but that would require integers, not reals, and ( and ) rather than the [ and ]. And it looks a bit like an array constructor, for which [ and ] are correct, but h:(1-h):h isn't.
Try this
x = REAL([(ix,ix=1,10)],real64)/11
(having declared ix to be an integer). The expression (ix,ix=1,10) is an implied do-loop and, inside the [ and ] produces an array with integers from 1 to 10. I trust the rest is obvious.
Incidentally, since the lhs of my suggested replacement is the whole of x you don't actually need to explicitly allocate it, Fortran will automatically do that for you. This is one of the differences between a whole array section, such as your x(1:10) and the whole array, x.
And if that doesn't produce the results you want let us know.

How to implement conjugate matrix transpose function in matlab?

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;

generalizing scalar inputs to array inputs for user-defined fucntions

The round function can take a scalar and operate on it. However it can also take an array and operate on it in expected manner.
>> round(2.3)
ans =
2
>> round([2.3,3.4])
ans =
2 3
I similarly have a function and want it to work in the ""expected"" manner for array inputs. It works well for scalar inputs. I could run a for loop and evaluate my function on each element of the array but what other smarter ways do i have available?
For further concreteness, i have:
function [a,b]=func(c,d,e,f)
And i have d,e,f but i want to evaluate the function to several values of c:-
g=[];
for i=1:10
[a,b]=func(c(i),d,e,f);
g=[g;[a,b]];
end
I am not fully sure how to apply arrayfun though i believe it is what i should use.
What you are looking for is the arrayfun function.
Here is the documentation: http://www.mathworks.com/help/matlab/ref/arrayfun.html
Say, I have this function:
function res = myTest(a,b)
size(a) % for checking that we work on each element
res = a+1;
res = res +b;
I have a matrix A
A = magic(3);
I want to apply myTest with a equal to each element in A
A1 = arrayfun(#(x) myTest(x,2),A)
(x is replaced by the elements of the array declared after the comma)

Resources