Piecewise function parameters for SED or Bandpass in GalSim - galsim

Is there a way to pass a piecewise (discontinuous) function for the "spec" parameter of SED or the "throughput" parameter of Bandpass? I tried passing a delta function and a triangular function using numpy, but galsim would not accept either as a valid python function.
I want to try drawing an object at a single wavelength, and thought I should modify the SED or the bandpass to have a value only at a single wavelength. If there are better ways to do this, please let me know!

There's a better way to do this.
If you already have a ChromaticObject with some SED, you can get a GSObject corresponding to that ChromaticObject at a single wavelength using the ChromaticObject.evaluateAtWavelength() method. Once you have that GSObject, you can draw it into an image. For example:
sed = galsim.SED('wave**0.2')
sed2 = galsim.SED('wave**1.0')
obj = galsim.Gaussian(sigma=0.1)*sed + galsim.Gaussian(sigma=0.5)*sed2
foo = obj.evaluateAtWavelength(800.0) # argument is wavelength in nm
You can do this and find that obj is chromatic, while foo is not. And you can do this easily for any number of wavelengths without having to redefine SEDs.

Related

How can I pass multiple parameters to a parallel operation in Octave?

I wrote a function that acts on each combination of columns in an input matrix. It uses multiple for loops and is very slow, so I am trying to parallelize it to use the maximum number of threads on my computer.
I am having difficulty finding the correct syntax to set this up. I'm using the Parallel package in octave, and have tried several ways to set up the calls. Here are two of them, in a simplified form, as well as a non-parallel version that I believe works:
function A = parallelExample(M)
pkg load parallel;
# Get total count of columns
ct = columns(M);
# Generate column pairs
I = nchoosek([1:ct],2);
ops = rows(I);
slice = ones(1, ops);
Ic = mat2cell(I, slice, 2);
## # Non-parallel
## A = zeros(1, ops);
## for i = 1:ops
## A(i) = cmbtest(Ic{i}, M);
## endfor
# Parallelized call v1
A = parcellfun(nproc, #cmbtest, Ic, {M});
## # Parallelized call v2
## afun = #(x) cmbtest(x, M);
## A = parcellfun(nproc, afun, Ic);
endfunction
# function to apply
function P = cmbtest(indices, matrix)
colset = matrix(:,indices);
product = colset(:,1) .* colset(:,2);
P = sum(product);
endfunction
For both of these examples I generate every combination of two columns and convert those pairs into a cell array that the parcellfun function should split up. In the first, I attempt to convert the input matrix M into a 1x1 cell array so it goes to each parallel instance in the same form. I get the error 'C must be a cell array' but this must be internal to the parcellfun function. In the second, I attempt to define an anonymous function that includes the matrix. The error I get here specifies that 'cmbtest' is undefined.
(Naturally, the actual function I'm trying to apply is far more complex than cmbtest here)
Other things I have tried:
Put M into a global variable so it doesn't need to be passed. Seemed to be impossible to put a global variable in a function file, though I may just be having syntax issues.
Make cmbtest a nested function so it can access M (parcellfun doesn't support that)
I'm out of ideas at this point and could use help figuring out how to get this to work.
Converting my comments above to an answer.
When performing parallel operations, it is useful to think of each parallel worker that will result as separate and independent octave instances, which need to have appropriate access to all functions and variables they will require in order to do their independent work.
Therefore, do not rely on subfunctions when calling parcellfun from a main function, since this might lead to errors if the worker is unable to access the subfunction directly under the hood.
In this case, separating the subfunction into its own file fixed the problem.

Using if conditions inside a TensorFlow graph

In tensorflow CIFAR-10 tutorial in cifar10_inputs.py line 174 it is said you should randomize the order of the operations random_contrast and random_brightness for better data augmentation.
To do so the first thing I think of is drawing a random variable from the uniform distribution between 0 and 1 : p_order. And do:
if p_order>0.5:
distorted_image=tf.image.random_contrast(image)
distorted_image=tf.image.random_brightness(distorted_image)
else:
distorted_image=tf.image.random_brightness(image)
distorted_image=tf.image.random_contrast(distorted_image)
However there are two possible options for getting p_order:
1) Using numpy which disatisfies me as I wanted pure TF and that TF discourages its user to mix numpy and tensorflow
2) Using TF, however as p_order can only be evaluated in a tf.Session()
I do not really know if I should do:
with tf.Session() as sess2:
p_order_tensor=tf.random_uniform([1,],0.,1.)
p_order=float(p_order_tensor.eval())
All those operations are inside the body of a function and are run from another script which has a different session/graph. Or I could pass the graph from the other script as an argument to this function but I am confused.
Even the fact that tensorflow functions like this one or inference for example seem to define the graph in a global fashion without explicitly returning it as an output is a bit hard to understand for me.
You can use tf.cond(pred, fn1, fn2, name=None) (see doc).
This function allows you to use the boolean value of pred inside the TensorFlow graph (no need to call self.eval() or sess.run(), hence no need of a Session).
Here is an example of how to use it:
def fn1():
distorted_image=tf.image.random_contrast(image)
distorted_image=tf.image.random_brightness(distorted_image)
return distorted_image
def fn2():
distorted_image=tf.image.random_brightness(image)
distorted_image=tf.image.random_contrast(distorted_image)
return distorted_image
# Uniform variable in [0,1)
p_order = tf.random_uniform(shape=[], minval=0., maxval=1., dtype=tf.float32)
pred = tf.less(p_order, 0.5)
distorted_image = tf.cond(pred, fn1, fn2)

Random number in Lua script Load Impact

I'm trying to create a random number generator in Lua. I found out that I can just use math.random(1,100) to randomize a number between 1 and 100 and that should be sufficient.
But I don't really understand how to use the randomize number as variables in the script.
Tried this but of course it didn't work.
$randomCorr = math.random(1,100);
http.request_batch({
{"POST", "https://store.thestore.com/priceAndOrder/selectProduct", headers={["Content-Type"]="application/json;charset=UTF-8"}, data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\"$randomCorr\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}", auto_decompress=true},
{"GET", "https://store.thestore.com/api/checkout/getproduct?correlationId=$randomCorr", auto_decompress=true},
})
In Lua, you can not start a variable name with $. This is where your main issue is at. Once the $ is removed from your code, we can easily see how to refer to variables in Lua.
randomCorr = math.random(100)
print("The random number:", randomCorr)
randomCorr = math.random(100)
print("New Random Number:", randomCorr)
Also, concatenation does not work the way you are implying it into your Http array. You have to concatenate the value in using .. in Lua
Take a look at the following example:
ran = math.random(100)
data = "{\""..ran.."\"}"
print(data)
--{"14"}
The same logic can be implied into your code:
data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\""..randomCorr.."\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}"
Or you can format the value in using one of the methods provided by the string library
Take a look at the following example:
ran = math.random(100)
data = "{%q}"
print(string.format(data,ran))
--{"59"}
The %q specifier will take whatever you put as input, and safely surround it with quotations
The same logic can be applied to your Http Data.
Here is a corrected version of the code snippet:
local randomCorr = math.random(1,100)
http.request_batch({
{"POST", "https://store.thestore.com/priceAndOrder/selectProduct", headers={["Content-Type"]="application/json;charset=UTF-8"}, data="{\"ChoosenPhoneModelId\":4,\"PricePlanId\":\"phone\",\"CorrelationId\":\"" .. randomCorr .. "\",\"DeliveryTime\":\"1 vecka\",\"$$hashKey\":\"006\"},\"ChoosenAmortization\":{\"AmortizationLength\":0,\"ChoosenDataPackage\":{\"Description\":\"6 GB\",\"PricePerMountInKr\":245,\"DataAmountInGb\":6,\"$$hashKey\":\"00W\"},\"ChoosenPriceplan\":{\"IsPostpaid\":true,\"Title\":\"Fastpris\",\"Description\":\"Fasta kostnader till fast pris\",\"MonthlyAmount\":0,\"AvailiableDataPackages\":null,\"SubscriptionBinding\":0,\"$$hashKey\":\"00K\"}}", auto_decompress=true},
{"GET", "https://store.thestore.com/api/checkout/getproduct?correlationId=" .. randomCorr, auto_decompress=true},
})
There is something called $$hashKey also, in the quoted string. Not sure if that is supposed to be referencing a variable or not. If it is, it also needs to be concatenated into the resulting string, using the .. operator (just like with the randomCorr variable).

How to setup my function with blockproc to process the image in parts?

I have an image:
I want to divide this image into 3 equal parts and calculate the SIFT for each part individually and then concatenate the results.
I found out that Matlab's blockproc does just that, but I do not know how to get it to work with my function. Here is what I have:
[r c] = size(image);
c_new = floor(c/3); %round it
B = blockproc(image, [r c_new], #block_fun)
So according to Matlabs documentation the function, block_fun will be applied to the original image in blocks of size r and c_new.
this is what I wrote as block_fun
function feats = block_fun(img)
[keypoints, descriptors] = vl_sift(single(img));
feats = descriptors;
end
So, my matrix B should be a concatenation of the SIFT descriptors of all three parts of the same image? right?
But the error that I get when I run the command:
B = blockproc(image, [r c_new], #block_fun)
Function BLOCKPROC encountered an error while evaluating the user
supplied function handle, FUN.
The cause of the error was:
Error using single Conversion to single from struct is not possible.
For your custom function, blockproc sends in a structure where the image data is stored in a field called data. As such, you simply need to change your function so that it accesses the data field in the input. Like so:
function feats = block_fun(block_struct) %// Change
[keypoints, descriptors] = vl_sift(single(block_struct.data)); %// Change
feats = descriptors;
end
This error is caused by the fact that the function that is called via its handle by blockproc expects a block struct.
The real problem is that blockproc will attempt to concatenate all results and you will have a different set of 128xN feature vectors for each block, which blockproc doesn't allow.
I think that using im2col and reshape would be much more simple.

How do I add rows/columns to a matrix in ilnumerics?

In Matlab this takes my two 1x102 variables (in1 and in2) and makes one that's 2x102 (out).
out = [in1 in2]
When I try this in VB/ILnumerics - with two well-formed 1x102 inputs - the output is 2x1 with both values being 0.
I'm doing it in VB like this:
Dim out As ILArray(Of Double) = {in1, in2}
It feels like I might have to extract all of the values, put them in double arrays, and pass those back in to get the results I want. What do you think?
You have theses options:
in1.concat(in2,1);
ILMath.horzcat(in1,in2);
There is also ILMath.vertcat<T>(a,b) available.
General ILArray documentation: http://ilnumerics.net/Arrays.html

Resources