Is there any function in Matlab like conv(u,v) but that sums up 'u(x)' and 'v(x)' instead of multiplying them?
Imagine:
u(x) = 66*(x-6)
v(x) = 6*(x-9)
Applying this "wanted function"...
sum = wantedfunction(u,v)
So,
sum(x) = 66*(x-6) + 6*(x-9)
Any ideas?
I believe you can do what you are asking for using anonymous functions:
u = #( x ) ( 66 * (x - 6) );
v = #( x ) ( 6 * (x - 9) );
w = #( x ) ( u(x) + v(x) );
This makes w the "sum" function you wanted - if I understood your question correctly.
Example: after I keyed in the above, I found
w(1:5)
Gave
-378 -306 -234 -162 -90
It's possible I completely missed the point of your question - if so, please leave a comment.
If by "conv" function you mean convolution then the equivalent of that for your case is simply adding two functions you want and then multiply them by delta(your desired spacing on x axis) and then sum over that, gives your function. Still you need to iterate this process by a "for" loop for different delays.
Related
I'm having trouble plotting a set of complex numbers in maple.
I know what it should look like from a drawing I produced but I'd like to plot it in maple. My code is as follows;
z := x + I*y;
plots:-implicitplot([abs(z) <= 2, abs(z) >= 1, abs(arg(z)) >= Pi/4,
abs(arg(z)) <= Pi/2], x = -3...3, y = -3...3, filled = true);
The issue is that the inequalities are being plotted independently of each other rather than all together, so even the first pair of inequalities together fill the entire plane. Is there any way I can have the $4$ conditions imposed in $S$ be taken into account at the same time, rather than separately?
Didn't you mean for the second inequality to be reversed? Otherwise the first is redundant.
The command that you need is inequal, not implicitplot. Your args should be arguments. Your z expressions should be wrapped in evalc. (I don't why that's necessary, but it seems to be.) There's no need for filled= true. So, the command is
plots:-inequal(
[evalc(abs(z)) <= 2, evalc(abs(z)) >= 1,
evalc(abs(argument(z))) >= Pi/4, evalc(abs(argument(z))) <= Pi/2
], x = -3...3, y = -3...3
);
Sometimes using plots:-inequal takes a long time, in those cases I just use plots:-implicitplot with filledregions = true option. But I don't use a list of inequalities as its argument. For one plot only, implicitplot needs one equation/inequality, so what function can you use that gives you the intersection of regions for your inequalities? Very simple, just define a binary piecewise function with piecewise command. Here is how I do your plot.
f := piecewise( And( abs( x + y*I ) <= 2, abs( x + y*I ) >= 1, abs( argument( x + y*I ) ) >= Pi/4, abs( argument( x + y*I ) ) <= Pi/2 ), 1, 0 );
plots:-implicitplot( f > 1/2, x = -3..3, y = -3..3, filledregions = true, coloring = [yellow, white], view = [-3..3, -3..3] );
The output plot is the following.
Note that plots:-inequal gives a more accurate output, but plots:-implicitplot takes less time, so you should consider the trade-off between them and see which is better on your specific example.
So I'm just trying to plot 4 different subplots with variations of the increments. So first would be dx=5, then dx=1, dx=0.1 and dx=0.01 from 0<=x<=20.
I tried to this:
%for dx = 5
x = 0:5:20;
fx = 2*pi*x *sin(x^2)
plot(x,fx)
however I get the error inner matrix elements must agree. Then I tried to do this,
x = 0:5:20
fx = (2*pi).*x.*sin(x.^2)
plot(x,fx)
I get a figure, but I'm not entirely sure if this would be the same as what I am trying to do initially. Is this correct?
The initial error arose since two vectors with the same shape cannot be squared (x^2) nor multiplied (x * sin(x^2)). The addition of the . before the * and ^ operators is correct here since that will perform the operation on the individual elements of the vectors. So yes, this is correct.
Also, bit of a more advanced feature, you can use an anonymous function to aid in the expressions:
fx = #(x) 2*pi.*x.*sin(x.^2); % function of x
x = 0:5:20;
plot(x,fx(x));
hold('on');
x = 0:1:20;
plot(x,fx(x));
hold('off');
I have 3 matrices x, y and z of order 3*3. I want to create a new matrix k with value = 1./(x.^2+y.^2+z.^2) if (x.^2+y.^2+z.^2 > 1) and value = 0 otherwise.
I am trying to use this :
k(x.^2+y.^2+z.^2>1)= 1./(x.^2+y.^2+z.^2)
but it gives error : In an assignment A(I) = B, the number of elements in B and I must be the same.
Can anyone provide a simple solution in a single line where I don't need to use for loops
I am not sure why you'd want to do this as opposed to splitting it up into two operations. This way, you save the cost of computing the sum of squares twice.
x = rand(3,3);
y = rand(3,3);
z = rand(3,3);
k = 1./(x.^2+y.^2+z.^2);
k(k>1)=0;
In any case, another way to do it would be using principles of Functional Programming:
x = rand(3,3);
y = rand(3,3);
z = rand(3,3);
myfun = #(x,y,z) 1/(x^2+y^2+z^2) * (x^2+y^2+z^2>1);
k = arrayfun(myfun, x, y, z);
Alternately, you can mix everything into one line as:
k = arrayfun(#(x,y,z) 1/(x^2+y^2+z^2) * (x^2+y^2+z^2>1), x, y, z);
What this code does is maps the function myfun to each of the data elements. The function myfun is quite simple. It computes the required quantity but multiplies it with the binding condition. However, you might want to beware.
EDIT: To address the comment.
If you don't want to compute the quantity at all, we can use conditional anonymous functions. For more details, you can refer to this guide.
iif = #(varargin) varargin{2 * find([varargin{1:2:end}], 1, 'first')}();
myfun = #(x,y,z) iif( x^2+y^2+z^2 <= 1, #() 0, x^2+y^2+z^2>1 ,#() 1/(x^2+y^2+z^2));
k = arrayfun(myfun, x, y, z);
How about
k = x.^2+y.^2+z.^2;
k(k < 1) = 0;
k(k~= 0) = 1 ./ k(k~=0);
If you are trying to save some processing time (i.e. do not compute at all the sum of squares for those cases when it is less than one) then pretty much the only solution is a table lookup
Otherwise the following code should work
k=1./(x.^2+y.^2+z.^2)
k(k<=1)=0
you can cut some time (assuming x, y and z could be greater than 1)
idx0=x<1 & y<1 & z<1
k=zeros(3)
k(idx0)=1./(x(idx0).^2+y(idx0).^2+z(idx0)^2)
k(k<=1)=0
Your original solution will work if you change it to use an indexer (I haven't profiled it, but I am pretty sure it will take longer, than mine :) )
idx0=x.^2+y.^2+z.^2>1
k=zeros(3)
k(idx0)=1./(x(idx0).^2+y(idx0).^2+z(idx0)^2)
I need help debugging my median function under the if statement. I am getting an input error. Also if there is a simpler way to write the median function it will be greatly appreciated. I am writing this code to clean up the above image for a project. Thanks. Also, I am pretty new with MATLAB.
``clear
clc
format compact
filenameIN = uigetfile('.bmp','Picture');
noisyRGBarray = imread(filenameIN);
%figure(1)
%imshow(noisyRGBarray)
y = noisyRGBarray;
[m,n]=size(y)
cleanRGBarray = y;
for i = 2:m-1
for j = 2:n-1
if y(i,j) == 0 | y(i,j) == 255 % clean add new
cleanRGBarray(i,j) = median( ( y ( (i-1),(j-1) ) ) , ( y ( (i-1),(j) ) ) , ( y ( (i-1),(j+1) ) ) ; ( y ( (i),(j-1) ) ), ( y ( (i),(j) ) ) ; ( y ( (i),(j+1) ) ) ; ( y ( (i+1),(j-1) ) ), ( y ( (i+1),(j) ) ), ( y ( (i+1),(j+1) ) ) ) ;
end
end
end
You are making this very hard on yourself! The simplest way to re formulate the innermost loop is
block = y((-1:1)+i, (-1:1)+j);
cleanRGBarray(i,j) = median(block(:));
A couple of things to note:
You attempted to create a vector of arguments for median but didn't surround it with []
I used the fact that when indexing over more than one dimension, Matlab does "nested loops" to get all the numbers (so my block variable ends up being 3x3)
I feed a column vector block(:) with dimensions 9x1 into median - if you give it an N dimensional matrix, it will operate on the first non-singleton dimension only (so give it 3x3 and it returns 1x3 medians)
There are techniques for doing this much more efficiently - built in median filters, and things like blockproc - but you need the Image Processing Toolbox for those.
I hope this helps a bit.
matlab has a built-in median filter medfilt2 you can also try ordfilt2
I need to implement Lagrange iterpolation in MATLAB.
I (think I've) understood how it works. I don't get how to implement the x.
lets say I want to calculate for these point: (0,1) (1,1) (2,4)
So I need to do these:
l_0(x) = (x-1)(x-2)/(0-1)(0-2)
l_1(x) = (x-0)(x-2)/(1-0)(1-2)
l_2(x) = (x-0)(x-1)/(2-0)(2-1)
and so on...
So I want to do a MATLAB function that will receive the (x,y) points, and retrieves the coefficients of the resulting Polynomial.
In this case: ( 3/2, 3/2, 1 )
I DON'T WANT A CODE FOR AN ANSWER - just how to implement the above x variant.
Thanks
I'm not sure if this is what you need, but I think that what you are looking for is MATLAB anonymous functions
In your case, you would write
l_0 = #(x) (x-1)(x-2)/(0-1)(0-2)
l_1 = #(x) (x-0)(x-2)/(1-0)(1-2)
l_2 = #(x) (x-0)(x-1)/(2-0)(2-1)
Then you can use your Lagrange polynomials like regular functions:
val = y0 * l_0(x0) + y1 * l_1(x1) + y2 * l_2(x2)
Is that what you were looking for?
Well if you don't want code, then x is simply any value within the range of the input values of your x points. In your case, any value between 0 and 2.