Cannot use MatrixOp replace

Hi, I am trying to replace each timesort entry with another numeric value, I first tried to write a procedure using switch-case, but it doesn't work. I first thought this might be due to my bad use of the switch statement, then I tried using matrixop replace to replace the values in the wave attached.

However, what rings alert is that the command "MatrixOp newwave = replace (timesort, 0.03, 2700)" did nothing on the wave, but if I manually erase the original data point and type in 0.03 in the cell, the matrixop would work, but only on those points that I have just manually typed in.

Is there anything that gets funky of my wave? I tried "browse wave", it looks similar to the other waves.

Thanks to whomever that offers help!

Timesort.ibw (29.06 KB)
That's because the values in your wave aren't actually 0.03 (except for the ones you manually typed in).

You can see this by showing the wave in a table. Right click on the wave in the table, choose digits, and choose 16. Notice that what had previously displayed as "0.03" now displays as "0.02999999999997272".

Alternately, you cold use
print/D
to display a value from the wave:

•print/D Timesort[9]
  0.0299999999999727
aclight wrote: That's because the values in your wave aren't actually 0.03 (except for the ones you manually typed in).

You can see this by showing the wave in a table. Right click on the wave in the table, choose digits, and choose 16. Notice that what had previously displayed as "0.03" now displays as "0.02999999999997272".

Alternately, you cold use
print/D
to display a value from the wave:

•print/D Timesort[9]
  0.0299999999999727



Ah, no wonder I cannot do the thing I want, this is the reason why. Thank you aclight!! What makes me puzzled is why it has to be >= 13 digits to be able to see the difference? It looks deceptive if not going that high in digits. How does Igor display the values stored in a wave? Also what would be a good way to truncate a number to keep only the decimal part and round to only 2 or 3 decimal places?

Thank you!
aclight wrote: I don't know where your data came from, but you're probably a victim of floating point error (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

To round your data, you could use:

MatrixOp aa = round(TimeSort * 1000)/1000


Substitute different values for 1000 to change the precision of the rounding.

Thank you aclight! I think you are right in that I might be a victim in the floating point error. The funky data is after I use

Timesort = mod(Timesort, 1) 

on the Timesort wave. What I am trying to do is chop the integer and only keep the digits after the decimal point in the new wave that is attached (this wave_decimal_day looks to be a normal wave).
I also tried

wave_decimal_day = wave_decimal_day - floor(wave_decimal_day)

which gave me the same problematic wave.

Assuming the wave with the floating point error is wave_pro,
I can use

MatrixOp aa = round(wave_pro*1000)/1000

as you have suggested to round to only two decimal points,
or

wave_pro = round(wave_pro*1000)/1000

It seems both can do the job, then my question would be if there is an advantage using one over the other? Or they are essentially doing the same thing?

I came up with

function chop1(todo)
     
	wave todo
     
	variable i
	string a
	
	for (i=0;i<numpnts(todo);i+=1)
              
		sprintf a, "%.2g\r", todo[i]
		todo[i] = str2num(a)
    
	endfor
    
end


to round, but it is extremely slow compared to if a new wave is created,

function chop2(todo)
     
	wave todo
     
	variable i
	string a
	
	duplicate/o todo newwave
	newwave = nan
	
     
	for (i=0;i<numpnts(newwave);i+=1)
           
		sprintf a, "%.2g\r", todo[i]
		newwave[i] = str2num(a)
    
	endfor
    
end

Is there a glitch if I treat the wave_pro using the two chop function? And what would be the reason for the slowness?

What I ultimately want to do with the wave_decimal_day is to replace all the points ending in the same decimal parts with a same data entry in time, so I tried

constant cons1 = 0.03, cons2 = 0.07, cons3 = 0.11, cons4 = 0.16, cons5 = 0.2
constant cons6 = 0.24, cons7 = 0.28, cons8 = 0.32, cons9= 0.36, cons10 = 0.41
constant cons11 = 0.45, cons12 = 0.49, cons13 = 0.53, cons14 =0.57, cons15 = 0.61
constant cons16 = 0.66, cons17 =0.7, cons18 = 0.74, cons19 = 0.78 ,cons20 = 0.82
constant cons21 = 0.86, cons22 = 0.91, cons23=95,cons24=0.99

function numericswitch(a)
	variable a

	variable c
 
	switch(a)
		
		case cons1 :	
			c=2700		
								
			break
				
		case cons2:
			c= 6300
				
			break
	
				
		case cons3:
			c= 9900
			break
	
		case cons4:
			c= 13500
			break
       
		case cons5:
			c=17100
			break
       
		case cons6:
			c= 20700
			break
       
		case cons7:
			c=24300
			break
      
		case cons8:
			c= 27900
			break
      
		case cons9:
			c=31500
			break
      
		case cons10:
			c=35100
			break
       
		case cons11:
			c= 38700
			break
      
		case cons12:
			c= 42300
			break
        
		case cons13:
			c= 45900
			break
       
		case cons14:
			c= 49500
			break
       
		case cons15:
			c= 53100
			break
        
		case cons16:
			c= 56700
			break
                     
		case cons17:
			c= 60300
			break
                       
		case cons18:
			c=63900
			break
                       
		case cons19:
			c= 67500
			break
                        
		case cons20:
			c= 71100
			break
                        
		case cons21:
			c= 74700
			break
                      
		case cons22:
			c= 78300
			break
                      
		case cons23:
			c= 81900
			break
                      
		case cons24:
			c= 85500
			break
	endswitch
	return c           
end

and then loop through each point in the wave that has already been truncated to the two decimal points, but I can never get it right. What is it that I did wrong?

This ends up to be a bit too long, but thank you again in advance and indeed!
wave_decimal_day.ibw (18.64 KB)
mwpro wrote:
aclight wrote: I don't know where your data came from, but you're probably a victim of floating point error (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

To round your data, you could use:

MatrixOp aa = round(TimeSort * 1000)/1000


Substitute different values for 1000 to change the precision of the rounding.

Thank you aclight! I think you are right in that I might be a victim in the floating point error. The funky data is after I use

Timesort = mod(Timesort, 1) 

on the Timesort wave. What I am trying to do is chop the integer and only keep the digits after the decimal point in the new wave that is attached (this wave_decimal_day looks to be a normal wave).
I also tried

wave_decimal_day = wave_decimal_day - floor(wave_decimal_day)

which gave me the same problematic wave.

Assuming the wave with the floating point error is wave_pro,
I can use

MatrixOp aa = round(wave_pro*1000)/1000

as you have suggested to round to only two decimal points,
or

wave_pro = round(wave_pro*1000)/1000

It seems both can do the job, then my question would be if there is an advantage using one over the other? Or they are essentially doing the same thing?

I came up with

function chop1(todo)
     
	wave todo
     
	variable i
	string a
	
	for (i=0;i<numpnts(todo);i+=1)
              
		sprintf a, "%.2g\r", todo[i]
		todo[i] = str2num(a)
    
	endfor
    
end


to round, but it is extremely slow compared to if a new wave is created,

function chop2(todo)
     
	wave todo
     
	variable i
	string a
	
	duplicate/o todo newwave
	newwave = nan
	
     
	for (i=0;i<numpnts(newwave);i+=1)
           
		sprintf a, "%.2g\r", todo[i]
		newwave[i] = str2num(a)
    
	endfor
    
end

Is there a glitch if I treat the wave_pro using the two chop function? And what would be the reason for the slowness?


I'm not sure what you're asking.

Your two chop functions execute in about the same amount of time on my machine (a few ms difference).

In general, MatrixOp is much faster than a wave assignment statement which is much faster than a loop (such as your chop functions). There are exceptions to the rule depending on what exactly you are doing.


mwpro wrote:
What I ultimately want to do with the wave_decimal_day is to replace all the points ending in the same decimal parts with a same data entry in time, so I tried....


This might be what you're looking for:

MatrixOp/O bb = round((wave_decimal_day - floor(wave_decimal_day)) * 90000)

aclight wrote:
mwpro wrote:
aclight wrote: I don't know where your data came from, but you're probably a victim of floating point error (http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).

To round your data, you could use:

MatrixOp aa = round(TimeSort * 1000)/1000


Substitute different values for 1000 to change the precision of the rounding.

Thank you aclight! I think you are right in that I might be a victim in the floating point error. The funky data is after I use

Timesort = mod(Timesort, 1) 

on the Timesort wave. What I am trying to do is chop the integer and only keep the digits after the decimal point in the new wave that is attached (this wave_decimal_day looks to be a normal wave).
I also tried

wave_decimal_day = wave_decimal_day - floor(wave_decimal_day)

which gave me the same problematic wave.

Assuming the wave with the floating point error is wave_pro,
I can use

MatrixOp aa = round(wave_pro*1000)/1000

as you have suggested to round to only two decimal points,
or

wave_pro = round(wave_pro*1000)/1000

It seems both can do the job, then my question would be if there is an advantage using one over the other? Or they are essentially doing the same thing?

I came up with

function chop1(todo)
     
	wave todo
     
	variable i
	string a
	
	for (i=0;i<numpnts(todo);i+=1)
              
		sprintf a, "%.2g\r", todo[i]
		todo[i] = str2num(a)
    
	endfor
    
end


to round, but it is extremely slow compared to if a new wave is created,

function chop2(todo)
     
	wave todo
     
	variable i
	string a
	
	duplicate/o todo newwave
	newwave = nan
	
     
	for (i=0;i<numpnts(newwave);i+=1)
           
		sprintf a, "%.2g\r", todo[i]
		newwave[i] = str2num(a)
    
	endfor
    
end

Is there a glitch if I treat the wave_pro using the two chop function? And what would be the reason for the slowness?


I'm not sure what you're asking.

Your two chop functions execute in about the same amount of time on my machine (a few ms difference).

In general, MatrixOp is much faster than a wave assignment statement which is much faster than a loop (such as your chop functions). There are exceptions to the rule depending on what exactly you are doing.


mwpro wrote:
What I ultimately want to do with the wave_decimal_day is to replace all the points ending in the same decimal parts with a same data entry in time, so I tried....


This might be what you're looking for:

MatrixOp/O bb = round((wave_decimal_day - floor(wave_decimal_day)) * 90000)



That is an easy solve, thank you aclight! I was wondering if there is a procedure that functions like a pivot table in Igor? Thanks!