From octave-maintainers-request at bevo dot che dot wisc dot edu Fri Aug 18 13:08:51 2000 Subject: Re: proper lvalues and whatnot From: "Ross A. Lippert" To: "John W. Eaton" CC: "octave-maintainers at bevo dot che dot wisc dot edu" Date: Fri, 18 Aug 2000 12:05:33 -0600 "John W. Eaton" wrote: > Hmm. Because the result of an assingment is not an lvalue, even in C? You know, I'm a bonehead sometimes. I could have sworn C let you do (x=y)=z in addition to x=(y=z). You are right, thanks. I should also take it back that this would be a desirable feature in octave for what I'm doing. > octave:1> v = 1:10 > v = > 1 2 3 4 5 6 7 8 9 10 > octave:2> v([3, 4])++ > ans = > 3 4 > octave:3> v > v = > 1 2 4 5 5 6 7 8 9 10 > That seems reasonable, doesn't it? Yes, that seems totally reasonable. > But your example was > octave:4> v = [1, 1] > v = > 1 1 > octave:5> v([1, 1, 2])++ > ans = > 1 1 1 > octave:6> v > v = > 2 2 > > which doesn't do exactly what you seem to expect. Does the actual > Octave behavior make sense though? I think it does, if you think > about it in the following way: YEs the behavior does make sense. I dipped into the ov.cc code and found that an assign_op gets implemented by doing a bin_op followed by a simple_assign, and it is the simple_assign which does the subscripting. To me, and maybe not to anyone else, what seems mmore logical is v(I) += x(I) should be implemented as for i=1:length(I), v(I(i)) += x(I(i)); end > | OK, so maybe I am a sick puppy. But this is what I am really after. > | > | > [i,j,nz] = find(M); > | > (y=zeros(max(i),1))(i) += nz.*x(j) > | and have > | y = M*x > > I guess I'm dense, but I don't understand what the purpose of this is, > or how it is equivalent to y = M*x. Actually, I don't need to assignment as lvalue thing bc I could just do the following octave> zeros(max(i),1)(i) += nz.*x(j) ans = M*x The purpose of this is that if M has only a few nonzero entries then one could matrix multiply by tmp = zeros(max(i),1); for p=1:length(i), tmp(i(p)) += nz(p)*x(j(p)); end If lvalue subscripting had the do-loop interpretation that I'd like, then the above loop could be replaced with that += expression. I think that vectors and matrices exist as types in order to cut down on the amount of explicit looping required to express common things. I think the interpretation I have for indexing an lvalue has a do-loop interpretation which could be useful for doing common operations. > Are you using an actual sparse matrix data type or trying to emulate > them using full storage (but trying to avoid operations on zeros)? If > the latter, wouldn't it make more sense to work on a sparse matrix > data type instead? That latter. The reason I think a sparse matrix type would be a bad idea is 1) different sparse matrix formats are used by different people for different reasons and no one would be happy. 2) constructs exist (almost) in octave which allow me to do what I need to do without having to really bend over that far backwards. 3) I think that giving a specific behavior subscripted lvalues would be useful not just to sparse matrix computations but for other purposes. That just happens to be the place where I currently find myself in the need. > Seems to me that it is somewhat difficult to pin down exactly what > these operations should do, and then arrange for everyone to agree. I agree. I'd like for someone to tell me if they have something essential that depends on a specified looping behavior for subscripted lvalues. Or perhaps to point out just how this hasn't been well thought out. I have noticed that the ov.cc file contains a readme for its assign_op function suggesting that someone turn it into more than just a bin_op simple_assign wrapper. This indicates that there is some need for a rewrite anyhow. I'd volunteer to try if no one cries out that my looping idea would be a really bad one. -r