I'm trying to use LU method to solve Ax=B, and when I do start doing so, using:
(P, L, U := LUDecomposition(A))
to create my three different matrices (P, L, U) I get the error
Error, cannot split rhs for multiple assignment
which doesn't make sense since LUDecomposition creates 3 matrices, which correspond to my P, L, U.
If you do either of the following then the call will return an expression sequence of containing three Matrices, and it will work for input A a Matrix.
with(LinearAlgebra):
P, L, U := LUDecomposition(A);
Or,
P, L, U := LinearAlgebra:-LUDecomposition(A);
But if you don't load the LinearAlgebra package and you also don't use the long-form name of that package's export then you're simply making a function call to an undefined name.
And, if you are in fact accidentally simply calling the undefined name LUDecomposition (because you have not used one of the mentioned methods for calling the package export of that name), then the result will be an unevaluated function call. And you cannot assign that single thing to three names on the left-hand-side of an assignment statement.
restart;
A := Matrix([[1,2],[3,5]]):
# Look, this next one does no computation.
# The return value is a single thing, an unevaluated
# function call.
LUDecomposition(A);
/[1 2]\
LUDecomposition|[ ]|
\[3 5]/
P, L, U := LUDecomposition(A);
Error, cannot split rhs for multiple assignment
But this would return the actual result,
LinearAlgebra:-LUDecomposition(A);
[1 0] [1 0] [1 2]
[ ], [ ], [ ]
[0 1] [3 1] [0 -1]
And so those three Matrices could be assigned to three names.
P, L, U := LinearAlgebra:-LUDecomposition(A);
[1 0] [1 0] [1 2]
P, L, U := [ ], [ ], [ ]
[0 1] [3 1] [0 -1]
Another way to do it is to first load the whole package, so that you can utilize the short-form command name,
with(LinearAlgebra):
LUDecomposition(A);
[1 0] [1 0] [1 2]
[ ], [ ], [ ]
[0 1] [3 1] [0 -1]
P, L, U := LUDecomposition(A);
[1 0] [1 0] [1 2]
P, L, U := [ ], [ ], [ ]
[0 1] [3 1] [0 -1]
I have two lists, which are both list of lists of the same lengths
list1 [[1 3 5 7] [2 5 1 6]]
list2 [[0.5 0.3 0.7 0.1] [0.1 0.4 0.6 0.2]]
My task is: if a number in list2 is <= e.g 0.2, remove items at corresponding position from list1. So based on the above example items in list2 which are <= 0.2 are [[3] [0 3]] and the final list1 should look like this [[1 3 5] [5 1]]. The same items should then be removed from list2 so its final version would look like [[0.5 0.3 0.7] [0.4 0.6]].
The below code works well but becomes very slow if the list is long (which is the case in my model)
Is the any efficient way of doing it without running loop of a loop?
let k 0
foreach list2
[
x ->
let each_element_list2 x
let each_element_list1 k list1
(foreach each_element_list2
[
i ->
if i <= 0.2
[
let rem_pos position i each_element_list2
set each_element_list2 remove-item rem_pos each_element_list2
set each_element_list1 remove-item rem_pos each_element_list1
]
]
)
set list2 replace-item k list2 each_element_list2
set list1 replace-item k list1 each_element_list1
set k k + 1
]
Thanx in advance,
Magda
This is not the most elegant code, and I don't have time to explain it step by step, but something like this should work:
to remove-items
let list1 [[1 3 5 7 ] [2 5 1 6 ]]
let list2 [[0.5 0.3 0.7 0.1] [0.1 0.4 0.6 0.2]]
if length list1 != length list2 [ error "lists should be of equal length" ]
foreach range length list1 [ i ->
let sl1 item i list1 ; extract sublist 1
let sl2 item i list2 ; extract sublist 2
let indices-to-keep (
map first ; extract the index from the pair
filter [ p -> last p > 0.2 ] ; keep the pairs where the item is <= 0.2
(map list range (length sl2) sl2) ; build a list of index/item pairs
)
let replace-sublist [ [l sl] ->
replace-item i l (map [ j -> item j sl ] indices-to-keep)
]
set list1 (runresult replace-sublist list1 sl1)
set list2 (runresult replace-sublist list2 sl2)
]
print list1
print list2
end
Just one quick note: notice that I inverted the condition (i.e., > 0.2 instead of <= 0.2), as it's easier to use a list of the indices we want to keep instead of those we want to remove.
H = [500 500 500 450 450 450 400 400 350 350 350 300 300 300];
I = [-0.0019 -0.0018 -0.0017 -0.0019 -0.0018 -0.0017 -0.0019 -0.0018 -0.0017]
V = [-7.54E-06 -7.23E-06 -6.93E-06 -7.53E-06 -7.21E-06 -6.89E-06 -6.60E-06 -7.50E-06 -7.23E-06 -6.90E-06]
Need to sort through the data and get an IV for each value but lump then off the uniqueness of their value, e.g., I want all the IVs for the H at 400, etc. I know there is a unique function in Matlab, but that only gives me a single element of the array that is unique. Is there a way to loop through the unique values to get the IV values? I already know about the unique function in Matlab.
Thanks!
Assuming your vectors have the same number of elements (i.e. every value in H has a corresponding value in I and V), one way you can do this is by using unique to get index values for groupings in H and splitapply to collect I and V values in a cell array based on that index:
>> I = [I 0 0 0 0 0]; V = [V 0 0 0 0]; % Pad your sample data with zeroes at the end
>> [Hvalues, ~, index] = unique(H);
>> IV = splitapply(#(x) {x}, [I(:) V(:)], index)
IV =
5×1 cell array
[3×2 double]
[3×2 double]
[2×2 double]
[3×2 double]
[3×2 double]
>> IV{Hvalues == 400} % I (first column) and V (second column) values for H = 400
ans =
-0.001900000000000 -0.000006600000000
-0.001800000000000 -0.000007500000000
I have the following code for drawing a picture:
%scamp data
[flipedBV, flipeddepth] = flipit(depthi, BVsurf_int_ens);
i=linspace(0,5,100);
edges_eps=10.^(-i);
logedg_BV= log10(fliplr(edges_eps));
[n_BV,xout_BV] = histc(histazza(log10(flipedBV)), logedg_BV);
x = logedg_BV;
%model data
[n_BVn,xout_BVn] = histc(histazza(log10(sqrt(-BVsurf_Num_ens))), logedg_BV);
BVsurfF = figure;hold on
h=area(x,n_BV/sum(n_BV),'facecolor',[1 0 0]); %%red area where the problem gonna be
legend('SCAMP')
xlabel('$$ N~[1/s]$$','Interpreter','latex','fontsize',18)
set(gca,'fontsize',14,'ygrid','on')
alpha(.5) %%translucency of the red area
%%add new data
addLineToFig('KEPflu', [0 0 1], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('KEPflu2', [0 1 1], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('GASflu', [0 0 0], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('GASflu2', [1 0 1 ], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('EPSmin', [1 1 0], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('GASmin', [.5 .5 0], BVsurfF, 'BVsurf_Num_ens', logedg_BV);
addLineToFig('canuto', [.5 .5 .5]', BVsurfF, 'BVsurf_Num_ens', logedg_BV);
the subroutine addLineToFig consists in:
function addLineToFig(name, ccol, fighandle, variab, x)%, flippo, depthi)
cd(['E:\SIMULATIONS\',name,'\COMPARED\ensamble']);
load([name,'_ensamble'], variab);
[n_BVn, xout_BVn] = histc(histazza(log10(sqrt(-BVsurf_Num_ens))), x); %%new data
figure(fighandle)
[LEGHbv,OBJHbv,OUTHbv,OUTMbv] = legend;
P=plot(x,n_BVn/sum(n_BVn),'color',ccol,'linewidth',2); %%plot new data
legend([OUTHbv;P],OUTMbv{:},name) %%update legend
end
Basically, I create a plot of the red area and then add data with addLineToFig and correctly obtain:
The problem arises when I try to duplicate the figure:
h1=gcf;
h2=figure;
objects=allchild(h1);
copyobj(get(h1,'children'),h2);
set(gca,'yscale','log')
As you can see the translucency of the red distribution is not duplicated and the legend has some problems.
The problem appears to be the last line where I set the yscale to log. If I comment it the code works fine. Does anyone know a workaround?
Minimal code
i=linspace(0,5,100);
edges_eps=10.^(-i);
logedg_BV= log10(fliplr(edges_eps));
a = 1e-5;
b = 1e-2;
r = (b-a).*rand(1000,1) + a;
[n_BV,xout_BV] = histc(histazza(log10(r)), logedg_BV);
x = logedg_BV;
%model data
r2 = (b-a).*rand(1000,1) + a;
[n_BVn,xout_BVn] = histc(histazza(log10(r2)), logedg_BV);
BVsurfF = figure;hold on
h=area(x,n_BV/sum(n_BV),'facecolor',[1 0 0]); %%red area where the problem gonna be
legend('SCAMP')
xlabel('$$ N~[1/s]$$','Interpreter','latex','fontsize',18)
set(gca,'fontsize',14,'ygrid','on')
alpha(.5) %%translucency of the red area
%%add new data
r3 = (b-a).*randn(1000,1) + a;
[n_BVn,xout_BVn] = histc(histazza(log10(r3)), logedg_BV);
figure(BVsurfF)
[LEGHbv,OBJHbv,OUTHbv,OUTMbv] = legend;
P=plot(x,n_BVn/sum(n_BVn),'color','k','linewidth',2);
legend([OUTHbv;P],OUTMbv{:},'data2')
%%add new data
r4 = (b-a).*rand(1000,1) + a;
[n_BVn,xout_BVn] = histc(histazza(log10(r4)), logedg_BV);
figure(BVsurfF)
[LEGHbv,OBJHbv,OUTHbv,OUTMbv] = legend;
P=plot(x,n_BVn/sum(n_BVn),'color','y','linewidth',2);
legend([OUTHbv;P],OUTMbv{:},'data3')
h1=gcf;
h2=figure;
objects=allchild(h1);
copyobj(get(h1,'children'),h2);
I solved the problem by setting the renderer of the original figure to 'OpenGL':
set(BVsurfF,'renderer','OpenGL')
I am cheema and want to save values that are in matrix form (in column) to a saved matrix in .dat file.
Actually, I can successfully add new values preserving the previous one's when I have only one scalar value, but want to add up a complete column to the saved matrix preserving the previous values. So that I can plot all the values from start to end. The main theme is described in the code:
for i=1:100
k=i+5;
l=i+2;
a=[k l];
b=[k1 l1];
c=abs(a-b);
h=(k+k1)/2;
h1=(h+k1)/2;
h2=(h+k)/2;
h3=(h1+k1)/2;
h4=(h+h1)/2;
h5=(h+h2)/2;
h6=(h2+k)/2;
h7=(h3+k1)/2;
h8=(h1+h3)/2;
h9=(h1+h4)/2;
h10=(h+h4)/2;
h11=(h+h5)/2;
h12=(h5+h2)/2;
h13=(h2+h6)/2;
h14=(h6+k)/2;
g=(l+l1)/2;
g1=(g+l1)/2;
g2=(g+l)/2;
g3=(g1+l1)/2;
g4=(g+g1)/2;
g5=(g+g2)/2;
g6=(g2+l)/2;
g7=(g3+l1)/2;
g8=(g1+g3)/2;
g9=(g1+g4)/2;
g10=(g+g4)/2;
g11=(g+g5)/2;
g12=(g5+g2)/2;
g13=(g2+g6)/2;
g14=(g6+l)/2;
if c>=[0 0] & c<[8 5]
k2=k;
l2=l;
elseif c>=[8 0]& c<[12 5]
k2=[h;k];
l2=[l;l];
elseif c>=[12 0] & c<[25 5]
k2=[h1;h;h2;k];
l2=[l;l;l;l];
elseif c>=[25 0] & c<[50 5]
k2=[h3;h1;h4;h;h5;h2;h6;k];
l2=[l;l;l;l;l;l;l;l];
elseif c>=[0 5] & c<[8 10]
k2=[k;k];
l2=[g;l];
elseif c>=[0 10] & c<[8 25]
k2=[k;k;k;k];
l2=[g1;g;g2;l];
elseif c>=[0 25] & c<[8 50]
k2=[h;h;h;h;h;h;h;h];
l2=[g3;g1;g4;g;g5;g2;g6;l];
elseif c>=[8 5] & c<[12 10]
k2=[h;k];
l2=[g;l];
elseif c>=[8 10] & c<[12 25]
k2=[h;h;k;k];
l2=[g1;g;g2;l];
elseif c>=[8 25] & c<[12 50]
k2=[h;h;h;h;k;k;k;k];
l2=[g3;g1;g4;g;g5;g2;g6;l];
elseif c>=[12 5] & c<[25 10]
k2=[h1;h;h2;k];
l2=[g;g;l;l];
elseif c>=[12 10] & c<[25 25]
k2=[h1;h;h2;k];
l2=[g1;g;g2;l];
elseif c>=[12 25] & c<[25 50]
k2=[h1;h1;h;h;h2;h2;k;k];
l2=[g3;g1;g4;g;g5;g2;g6;l];
elseif c>=[25 5] & c<[50 10]
k2=[h3;h1;h4;h;h5;h2;h6;k];
l2=[g;g;g;g;l;l;l;l];
elseif c>=[25 10] & c<[50 25]
k2=[h3;h1;h4;h;h5;h2;h6;k];
l2=[g1;g1;g;g;g2;g2;l;l];
elseif c>=[25 25] & c<[50 50]
k2=[h3;h1;h4;h;h5;h2;h6;k];
l2=[g3;g1;g4;g;g5;g2;g6;l];
else
k2=[h7;h3;h8;h1;h9;h4;h10;h;h11;h5;h12;h2;h13;h6;h14;k];
l2=[g7;g3;g8;g1;g9;g4;g10;g;g11;g5;g12;g2;g13;g6;g14;l];
end
q(i,:)=[k2 l2];
save path.dat q -ascii;
x=path(:,1);
y=path(:,2);
plot(x,y,'-o')
k1=k;
l1=l;
end
I am getting error:
In an assignment A(I) = B, the number of elements in B and I must be the same.
q(i,:)=[k2 l2];
I would be very thankful for any suggestion.
q(i,:)=[k2 l2]; does not work because both k2 and 12 are nx1 matrix and you are assigning it q(i,:), which should basically be row matrix. So q(i,:) = [k2' l2']; will be more accurate..
Just a suggestion, your code can be easier to if you calculate a and b inside the loop and do the other calculations outside the loop.
Code:
A = [1 ;2; 3; 4; 5; 6; 7];
A = [A ;8 ;9];